diff --git a/modem/data_frame_factory.py b/modem/data_frame_factory.py index 560bdb35..4577a0ea 100644 --- a/modem/data_frame_factory.py +++ b/modem/data_frame_factory.py @@ -205,7 +205,18 @@ class DataFrameFactory: "sequence_id": 1, } - + # heartbeat for "is alive" + self.template_list[FR_TYPE.P2P_CONNECTION_DISCONNECT.value] = { + "frame_length": self.LENGTH_SIG1_FRAME, + "session_id": 1, + } + + # ack heartbeat + self.template_list[FR_TYPE.P2P_CONNECTION_DISCONNECT_ACK.value] = { + "frame_length": self.LENGTH_SIG1_FRAME, + "session_id": 1, + } + def construct(self, frametype, content, frame_length = LENGTH_SIG1_FRAME): @@ -520,4 +531,16 @@ class DataFrameFactory: "session_id": session_id.to_bytes(1, 'big'), "sequence_id": sequence_id.to_bytes(1, 'big'), } - return self.construct(FR_TYPE.P2P_CONNECTION_PAYLOAD_ACK, payload) \ No newline at end of file + return self.construct(FR_TYPE.P2P_CONNECTION_PAYLOAD_ACK, payload) + + def build_p2p_connection_disconnect(self, session_id): + payload = { + "session_id": session_id.to_bytes(1, 'big'), + } + return self.construct(FR_TYPE.P2P_CONNECTION_DISCONNECT, payload) + + def build_p2p_connection_disconnect_ack(self, session_id): + payload = { + "session_id": session_id.to_bytes(1, 'big'), + } + return self.construct(FR_TYPE.P2P_CONNECTION_DISCONNECT_ACK, payload) diff --git a/modem/frame_dispatcher.py b/modem/frame_dispatcher.py index 88ddaf94..e2a37ab2 100644 --- a/modem/frame_dispatcher.py +++ b/modem/frame_dispatcher.py @@ -27,6 +27,9 @@ class DISPATCHER(): FR_TYPE.ARQ_SESSION_INFO.value: {"class": ARQFrameHandler, "name": "ARQ Data Channel Info"}, FR_TYPE.P2P_CONNECTION_CONNECT.value: {"class": P2PConnectionFrameHandler, "name": "P2P Connection CONNECT"}, FR_TYPE.P2P_CONNECTION_CONNECT_ACK.value: {"class": P2PConnectionFrameHandler, "name": "P2P Connection CONNECT ACK"}, + FR_TYPE.P2P_CONNECTION_DISCONNECT.value: {"class": P2PConnectionFrameHandler, "name": "P2P Connection DISCONNECT"}, + FR_TYPE.P2P_CONNECTION_DISCONNECT_ACK.value: {"class": P2PConnectionFrameHandler, + "name": "P2P Connection DISCONNECT ACK"}, FR_TYPE.P2P_CONNECTION_PAYLOAD.value: {"class": P2PConnectionFrameHandler, "name": "P2P Connection PAYLOAD"}, FR_TYPE.P2P_CONNECTION_PAYLOAD_ACK.value: {"class": P2PConnectionFrameHandler, diff --git a/modem/frame_handler.py b/modem/frame_handler.py index 89493bbe..7375b6c2 100644 --- a/modem/frame_handler.py +++ b/modem/frame_handler.py @@ -60,7 +60,7 @@ class FrameHandler(): self.config['STATION']['ssid_list']) #check for p2p connection - elif ft in ['P2P_CONNECTION_CONNECT_ACK', 'P2P_CONNECTION_PAYLOAD', 'P2P_CONNECTION_PAYLOAD_ACK']: + elif ft in ['P2P_CONNECTION_CONNECT_ACK', 'P2P_CONNECTION_PAYLOAD', 'P2P_CONNECTION_PAYLOAD_ACK', 'P2P_CONNECTION_DISCONNECT', 'P2P_CONNECTION_DISCONNECT_ACK']: session_id = self.details['frame']['session_id'] if session_id in self.states.p2p_connection_sessions: valid = True diff --git a/modem/frame_handler_p2p_connection.py b/modem/frame_handler_p2p_connection.py index 13315487..7dc4931d 100644 --- a/modem/frame_handler_p2p_connection.py +++ b/modem/frame_handler_p2p_connection.py @@ -39,6 +39,8 @@ class P2PConnectionFrameHandler(frame_handler.FrameHandler): elif frame['frame_type_int'] in [ FR.P2P_CONNECTION_CONNECT_ACK.value, + FR.P2P_CONNECTION_DISCONNECT.value, + FR.P2P_CONNECTION_DISCONNECT_ACK.value, FR.P2P_CONNECTION_PAYLOAD.value, FR.P2P_CONNECTION_PAYLOAD_ACK.value, ]: diff --git a/modem/modem_frametypes.py b/modem/modem_frametypes.py index da46a033..fbe33f77 100644 --- a/modem/modem_frametypes.py +++ b/modem/modem_frametypes.py @@ -20,6 +20,8 @@ class FRAME_TYPE(Enum): P2P_CONNECTION_HEARTBEAT_ACK = 33 P2P_CONNECTION_PAYLOAD = 34 P2P_CONNECTION_PAYLOAD_ACK = 35 + P2P_CONNECTION_DISCONNECT = 36 + P2P_CONNECTION_DISCONNECT_ACK = 37 MESH_BROADCAST = 100 MESH_SIGNALLING_PING = 101 MESH_SIGNALLING_PING_ACK = 102 diff --git a/modem/p2p_connection.py b/modem/p2p_connection.py index facdf296..a50b62f3 100644 --- a/modem/p2p_connection.py +++ b/modem/p2p_connection.py @@ -34,9 +34,19 @@ class P2PConnection: FRAME_TYPE.P2P_CONNECTION_CONNECT.value: 'connected_irs', FRAME_TYPE.P2P_CONNECTION_CONNECT_ACK.value: 'connected_iss', FRAME_TYPE.P2P_CONNECTION_PAYLOAD.value: 'received_data', + FRAME_TYPE.P2P_CONNECTION_DISCONNECT.value: 'received_disconnect', + }, + States.PAYLOAD_SENT: { FRAME_TYPE.P2P_CONNECTION_PAYLOAD_ACK.value: 'process_data_queue', + }, + States.DISCONNECTING: { + FRAME_TYPE.P2P_CONNECTION_DISCONNECT_ACK.value: 'received_disconnect_ack', + }, + States.DISCONNECTED: { + FRAME_TYPE.P2P_CONNECTION_DISCONNECT.value: 'received_disconnect', + FRAME_TYPE.P2P_CONNECTION_DISCONNECT_ACK.value: 'received_disconnect_ack', - } + }, } def __init__(self, config: dict, modem, origin: str, destination: str, state_manager): @@ -183,9 +193,10 @@ class P2PConnection: self.set_state(States.FAILED) def process_data_queue(self, frame=None): - print("processing data....") - print(self.p2p_tx_queue.empty()) if not self.p2p_tx_queue.empty(): + print("processing data....") + + self.set_state(States.PAYLOAD_SENT) data = self.p2p_tx_queue.get() sequence_id = random.randint(0,255) data = data.encode('utf-8') @@ -198,6 +209,7 @@ class P2PConnection: mode=mode) return print("ALL DATA SENT!!!!!") + self.disconnect() def prepare_data_chunk(self, data, mode): return data @@ -209,3 +221,20 @@ class P2PConnection: def transmit_data_ack(self, frame): print(frame) + + def disconnect(self): + self.set_state(States.DISCONNECTING) + disconnect_frame = self.frame_factory.build_p2p_connection_disconnect(self.session_id) + self.launch_twr(disconnect_frame, self.TIMEOUT_CONNECT, self.RETRIES_CONNECT, mode=FREEDV_MODE.signalling) + return + + def received_disconnect(self, frame): + self.log("DISCONNECTED...............") + self.set_state(States.DISCONNECTED) + self.is_ISS = False + disconnect_ack_frame = self.frame_factory.build_p2p_connection_disconnect_ack(self.session_id) + self.launch_twr_irs(disconnect_ack_frame, self.ENTIRE_CONNECTION_TIMEOUT, mode=FREEDV_MODE.signalling) + + def received_disconnect_ack(self, frame): + self.log("DISCONNECTED...............") + self.set_state(States.DISCONNECTED)