103 lines
2.6 KiB
Python
103 lines
2.6 KiB
Python
#!/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
|