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:
Vadim Yanitskiy 2023-01-18 01:33:44 +06:00
parent fa71a8a40d
commit afed084c77
1 changed files with 21 additions and 4 deletions

View File

@ -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