DbgMuxConnHandler: proper handling of the FlowControl message
A FlowControl message basically indicates how many data blocks the remote side is able to receive from us. Whenever the block limit is reached, we should queue outgoing data blocks until the remote side has given us a new quote by sending another FlowControl message.
This commit is contained in:
parent
fa71a8a40d
commit
afed084c77
|
@ -39,7 +39,9 @@ class DbgMuxConnHandler(abc.ABC):
|
|||
def __init__(self):
|
||||
self.conn_state: DbgMuxConnState = DbgMuxConnState.NotEstablished
|
||||
self._rx_data_queue: queue.Queue = queue.Queue()
|
||||
self._tx_data_queue: queue.Queue = queue.Queue()
|
||||
self._tx_queue: Optional[queue.Queue] = None
|
||||
self.DataBlockLimit: int = 0
|
||||
self.ConnRef: int = 0xffff
|
||||
self.DPRef: int = 0xffff
|
||||
|
||||
|
@ -59,8 +61,13 @@ class DbgMuxConnHandler(abc.ABC):
|
|||
def send_data(self, data: bytes) -> None:
|
||||
''' Send connection data to the target '''
|
||||
assert self.conn_state == DbgMuxConnState.Established
|
||||
msg_type = DbgMuxFrame.MsgType.ConnData
|
||||
msg = dict(ConnRef=self.ConnRef, Data=data)
|
||||
self.send_msg(DbgMuxFrame.MsgType.ConnData, msg)
|
||||
if self.DataBlockLimit > 0: # Can we send immediately?
|
||||
self.send_msg(msg_type, msg)
|
||||
self.DataBlockLimit -= 1
|
||||
else: # Postpone transmission until a FlowControl is received
|
||||
self._tx_data_queue.put((msg_type, msg))
|
||||
|
||||
def establish(self, DPRef: int, txq: queue.Queue) -> None:
|
||||
''' Establish connection with a DataProvider '''
|
||||
|
@ -81,9 +88,10 @@ class DbgMuxConnHandler(abc.ABC):
|
|||
def _handle_established(self, ConnRef: int, DataBlockLimit: int) -> None:
|
||||
''' Called on connection establishment '''
|
||||
assert self.conn_state == DbgMuxConnState.Establishing
|
||||
log.info('Connection established: DPRef=0x%04x, ConnRef=0x%04x',
|
||||
self.DPRef, ConnRef)
|
||||
log.info('Connection established: DPRef=0x%04x, ConnRef=0x%04x, DataBlockLimit=%u',
|
||||
self.DPRef, ConnRef, DataBlockLimit)
|
||||
self.conn_state = DbgMuxConnState.Established
|
||||
self.DataBlockLimit = DataBlockLimit
|
||||
self.ConnRef = ConnRef
|
||||
self._conn_established()
|
||||
|
||||
|
@ -102,4 +110,13 @@ class DbgMuxConnHandler(abc.ABC):
|
|||
|
||||
def _handle_flow_control(self, DataBlockLimit: int):
|
||||
''' Called on reciept of FlowControl message '''
|
||||
# TODO: purpose is not yet understood
|
||||
assert self.conn_state == DbgMuxConnState.Established
|
||||
self.DataBlockLimit = DataBlockLimit
|
||||
while self.DataBlockLimit > 0:
|
||||
try:
|
||||
(msg_type, msg) = self._tx_data_queue.get(block=False)
|
||||
self.send_msg(msg_type, msg)
|
||||
self.DataBlockLimit -= 1
|
||||
self._tx_data_queue.task_done()
|
||||
except queue.Empty:
|
||||
break
|
||||
|
|
Loading…
Reference in New Issue