22
33import ctypes
44import random
5+ import time
56from collections .abc import Callable
67
78from infuse_iot import rpc
@@ -25,11 +26,15 @@ def __init__(
2526 rx_cb : Callable [[ClientNotification ], None ] | None = None ,
2627 ):
2728 self ._request_id = random .randint (0 , 2 ** 31 - 1 )
29+ self ._timeout = 10.0
2830 self ._client = client
2931 self ._id = infuse_id
3032 self ._max_payload = max_payload
3133 self ._rx_cb = rx_cb
3234
35+ def set_timeout (self , timeout : float ):
36+ self ._timeout = timeout
37+
3338 def _finalise_command (
3439 self , rpc_rsp : PacketReceived , rsp_decoder : Callable [[bytes ], ctypes .LittleEndianStructure ]
3540 ) -> tuple [rpc .ResponseHeader , ctypes .LittleEndianStructure | None ]:
@@ -48,8 +53,9 @@ def _client_recv(self) -> ClientNotification | None:
4853 self ._rx_cb (rsp )
4954 return rsp
5055
51- def _wait_data_ack (self ) -> PacketReceived :
52- while True :
56+ def _wait_data_ack (self ) -> PacketReceived | None :
57+ timeout = time .time () + self ._timeout
58+ while time .time () < timeout :
5359 rsp = self ._client_recv ()
5460 if rsp is None :
5561 continue
@@ -66,10 +72,12 @@ def _wait_data_ack(self) -> PacketReceived:
6672 if data_ack .request_id != self ._request_id :
6773 continue
6874 return rsp .epacket
75+ return None
6976
70- def _wait_rpc_rsp (self ) -> PacketReceived :
77+ def _wait_rpc_rsp (self ) -> PacketReceived | None :
78+ timeout = time .time () + self ._timeout
7179 # Wait for responses
72- while True :
80+ while time . time () < timeout :
7381 rsp = self ._client_recv ()
7482 if rsp is None :
7583 continue
@@ -83,6 +91,7 @@ def _wait_rpc_rsp(self) -> PacketReceived:
8391 if rsp_header .request_id != self ._request_id :
8492 continue
8593 return rsp .epacket
94+ return None
8695
8796 def _run_data_send_core (
8897 self ,
@@ -94,7 +103,7 @@ def _run_data_send_core(
94103 packet_idx : bool ,
95104 progress_cb : Callable [[int ], None ] | None ,
96105 rsp_decoder : Callable [[bytes ], ctypes .LittleEndianStructure ],
97- ) -> tuple [rpc .ResponseHeader , ctypes .LittleEndianStructure | None ]:
106+ ) -> tuple [rpc .ResponseHeader | None , ctypes .LittleEndianStructure | None ]:
98107 self ._request_id += 1
99108 ack_period = 2
100109 header = rpc .RequestHeader (self ._request_id , cmd_id ) # type: ignore
@@ -112,6 +121,8 @@ def _run_data_send_core(
112121
113122 # Wait for initial ACK
114123 recv = self ._wait_data_ack ()
124+ if recv is None :
125+ return None , None
115126 if recv .ptype == InfuseType .RPC_RSP :
116127 return self ._finalise_command (recv , rsp_decoder )
117128
@@ -133,6 +144,8 @@ def _run_data_send_core(
133144 # Wait for ACKs at the period
134145 if ack_cnt == ack_period :
135146 recv = self ._wait_data_ack ()
147+ if recv is None :
148+ return None , None
136149 if recv .ptype == InfuseType .RPC_RSP :
137150 return self ._finalise_command (recv , rsp_decoder )
138151 ack_cnt = 0
@@ -142,6 +155,9 @@ def _run_data_send_core(
142155 progress_cb (chunk_id + 1 if packet_idx else offset )
143156
144157 recv = self ._wait_rpc_rsp ()
158+ if recv is None :
159+ return None , None
160+
145161 return self ._finalise_command (recv , rsp_decoder )
146162
147163 def run_data_send_cmd (
@@ -152,7 +168,7 @@ def run_data_send_cmd(
152168 data : bytes ,
153169 progress_cb : Callable [[int ], None ] | None ,
154170 rsp_decoder : Callable [[bytes ], ctypes .LittleEndianStructure ],
155- ) -> tuple [rpc .ResponseHeader , ctypes .LittleEndianStructure | None ]:
171+ ) -> tuple [rpc .ResponseHeader | None , ctypes .LittleEndianStructure | None ]:
156172 # Maxmimum payload size of interface
157173 size = self ._max_payload - ctypes .sizeof (rpc .DataHeader )
158174 # Round payload down to multiple of 4 bytes
@@ -170,7 +186,7 @@ def run_data_send_cmd_chunked(
170186 data : list [bytes ],
171187 progress_cb : Callable [[int ], None ] | None ,
172188 rsp_decoder : Callable [[bytes ], ctypes .LittleEndianStructure ],
173- ) -> tuple [rpc .ResponseHeader , ctypes .LittleEndianStructure | None ]:
189+ ) -> tuple [rpc .ResponseHeader | None , ctypes .LittleEndianStructure | None ]:
174190 return self ._run_data_send_core (cmd_id , auth , params , data , len (data ), True , progress_cb , rsp_decoder )
175191
176192 def run_data_recv_cmd (
@@ -225,7 +241,7 @@ def run_data_recv_cmd(
225241
226242 def run_standard_cmd (
227243 self , cmd_id : int , auth : Auth , params : bytes , rsp_decoder : Callable [[bytes ], ctypes .LittleEndianStructure ]
228- ) -> tuple [rpc .ResponseHeader , ctypes .LittleEndianStructure | None ]:
244+ ) -> tuple [rpc .ResponseHeader | None , ctypes .LittleEndianStructure | None ]:
229245 self ._request_id += 1
230246 header = rpc .RequestHeader (self ._request_id , cmd_id ) # type: ignore
231247
@@ -239,4 +255,6 @@ def run_standard_cmd(
239255 req = GatewayRequestEpacketSend (pkt )
240256 self ._client .send (req )
241257 recv = self ._wait_rpc_rsp ()
258+ if recv is None :
259+ return None , None
242260 return self ._finalise_command (recv , rsp_decoder )
0 commit comments