#!/usr/bin/env python # Copyright 2016 NXP # All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause from .codec import MessageType class RequestError(RuntimeError): pass class ClientManager(object): def __init__(self, transport=None, codecClass=None): self._transport = transport self._arbitrator = None self._codecClass = codecClass self._sequence = 0 @property def transport(self): return self._transport @transport.setter def transport(self, value): self._transport = value @property def arbitrator(self): return self._arbitrator @arbitrator.setter def arbitrator(self, arb): self._arbitrator = arb @property def codec_class(self): return self._codecClass @codec_class.setter def codec_class(self, value): self._codecClass = value @property def sequence(self): self._sequence += 1 return self._sequence def create_request(self, isOneway=False): msg = bytearray() codec = self.codec_class() codec.buffer = msg return RequestContext(self.sequence, msg, codec, isOneway) def perform_request(self, request): # Arbitrate requests. token = None if self._arbitrator is not None and not request.is_oneway: token = self._arbitrator.prepare_client_receive(request) # Send serialized request to server. self.transport.send(request.codec.buffer) if not request.is_oneway: if token is not None: msg = self._arbitrator.client_receive(token) else: msg = self.transport.receive() request.codec.buffer = msg info = request.codec.start_read_message() if info.type != MessageType.kReplyMessage: raise RequestError("invalid reply message type") if info.sequence != request.sequence: raise RequestError("unexpected sequence number in reply (was %d, expected %d)" % (info.sequence, request.sequence)) class RequestContext(object): def __init__(self, sequence, message, codec, isOneway): self._sequence = sequence self._message = message self._codec = codec self._isOneway = isOneway @property def sequence(self): return self._sequence @property def message(self): return self._message @property def codec(self): return self._codec @property def is_oneway(self): return self._isOneway