diff --git a/tnc/data_handler.py b/tnc/data_handler.py index b5f41e93..9ffe0b86 100644 --- a/tnc/data_handler.py +++ b/tnc/data_handler.py @@ -515,15 +515,14 @@ def frame_nack_received(): def open_dc_and_transmit(data_out, mode, n_frames): if not static.ARQ_READY_FOR_DATA: - - + + # we open the datachannel with the mode, selected from GUI if n_frames != 0: - static.ARQ_TX_N_FRAMES_PER_BURST = int(n_frames) - + static.ARQ_TX_N_FRAMES_PER_BURST = n_frames + # else we do an auto selection --> future feature: path calculation else: static.ARQ_TX_N_FRAMES_PER_BURST = get_n_frames_per_burst() - asyncio.run(arq_open_data_channel(mode)) # wait until data channel is open while not static.ARQ_READY_FOR_DATA: @@ -608,16 +607,13 @@ def arq_received_data_channel_opener(data_in): connection_frame[3:9] = static.MYCALLSIGN connection_frame[12:13] = bytes([static.ARQ_DATA_CHANNEL_MODE]) - modem.transmit_signalling(connection_frame, 2) while static.CHANNEL_STATE == 'SENDING_SIGNALLING': time.sleep(0.01) logging.info("DATA [" + str(static.MYCALLSIGN, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN, 'utf-8') + "] [SNR:" + str(static.SNR) + "]") - - #time.sleep(1) - + wait_until_receive_data = time.time() + 1 while time.time() < wait_until_receive_data: pass @@ -633,11 +629,9 @@ def arq_received_channel_is_open(data_in): static.ARQ_DATA_CHANNEL_LAST_RECEIVED = int(time.time()) - if static.ARQ_DATA_CHANNEL_MODE == int.from_bytes(bytes(data_in[12:13]), "big"): logging.info("DATA [" + str(static.MYCALLSIGN, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN, 'utf-8') + "] [SNR:" + str(static.SNR) + "]") - helpers.wait(1) static.ARQ_STATE = 'DATA' @@ -665,9 +659,7 @@ def transmit_ping(callsign): # wait while sending.... modem.transmit_signalling(ping_frame, 1) - print("ping=?") while static.CHANNEL_STATE == 'SENDING_SIGNALLING': - print("PING....") time.sleep(0.01) diff --git a/tnc/modem.py b/tnc/modem.py index 846725bf..4367da06 100644 --- a/tnc/modem.py +++ b/tnc/modem.py @@ -403,25 +403,28 @@ class RF(): # -------------- transmit audio self.ptt_and_wait(True) + # this triggers writing buffer to audio stream + # this way we are able to run this non blocking + # this needs to be optimized! self.audio_writing_to_stream = True - # wait until audio has been processed while self.audio_writing_to_stream: time.sleep(0.01) static.CHANNEL_STATE = 'SENDING_DATA' - static.CHANNEL_STATE = 'RECEIVING_SIGNALLING' self.ptt_and_wait(False) + # close codec2 instance self.c_lib.freedv_close(freedv) # -------------------------------------------------------------------------------------------------------- def receive(self, mode): force = False + # create new codec2 instance self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte) freedv = self.c_lib.freedv_open(mode) bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv) / 8) @@ -466,27 +469,25 @@ class RF(): nin = int(nin*(static.AUDIO_SAMPLE_RATE_RX/static.MODEM_SAMPLE_RATE)) data_in = self.stream_rx.read(nin, exception_on_overflow=False) + + data_in = audioop.ratecv(data_in,2,1,static.AUDIO_SAMPLE_RATE_RX, static.MODEM_SAMPLE_RATE, None) + data_in = data_in[0] self.calculate_fft(data_in) - - data_in = audioop.ratecv(data_in,2,1,static.AUDIO_SAMPLE_RATE_RX, static.MODEM_SAMPLE_RATE, None) - data_in = data_in[0] static.AUDIO_RMS = audioop.rms(data_in, 2) nbytes = self.c_lib.freedv_rawdatarx(freedv, bytes_out, data_in) # demodulate audio #print("listening-" + str(mode) + " - " + "nin: " + str(nin) + " - " + str(self.c_lib.freedv_get_rx_status(freedv))) + + # get scatter data and snr data + self.get_scatter(freedv) self.calculate_snr(freedv) # forward data only if broadcast or we are the receiver # bytes_out[1:2] == callsign check for signalling frames, bytes_out[6:7] == callsign check for data frames, bytes_out[1:2] == b'\x01' --> broadcasts like CQ # we could also create an own function, which returns True. In this case we could add callsign blacklists and so on - - - - # lets get scatter data - self.get_scatter(freedv) if nbytes == bytes_per_frame and bytes(bytes_out[1:2]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[6:7]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[1:2]) == b'\x01': self.calculate_snr(freedv) @@ -663,7 +664,8 @@ class RF(): try: dfft = 10.*np.log10(abs(np.fft.rfft(audio_data))) except: - dfft = [0] + dfft = 0 + dfftlist = dfft.tolist() # send fft only if receiving diff --git a/tnc/sock.py b/tnc/sock.py index 07067b0c..264d1a18 100644 --- a/tnc/sock.py +++ b/tnc/sock.py @@ -91,22 +91,11 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler): # PING ---------------------------------------------------------- if received_json["type"] == 'PING' and received_json["command"] == "PING": # send ping frame and wait for ACK - print(received_json) dxcallsign = received_json["dxcallsign"] #asyncio.run(data_handler.transmit_ping(dxcallsign)) PING_THREAD = threading.Thread(target=data_handler.transmit_ping, args=[dxcallsign], name="CQ") PING_THREAD.start() - if received_json["type"] == 'ARQ' and received_json["command"] == "OPEN_DATA_CHANNEL": - static.ARQ_READY_FOR_DATA = False - static.TNC_STATE = 'BUSY' - - dxcallsign = received_json["dxcallsign"] - static.DXCALLSIGN = bytes(dxcallsign, 'utf-8') - static.DXCALLSIGN_CRC8 = helpers.get_crc_8(static.DXCALLSIGN) - - asyncio.run(data_handler.arq_open_data_channel()) - if received_json["type"] == 'ARQ' and received_json["command"] == "sendFile":# and static.ARQ_READY_FOR_DATA == True: # and static.ARQ_STATE == 'CONNECTED' : static.TNC_STATE = 'BUSY' @@ -132,11 +121,7 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler): print(dataframe) data_out = bytes(dataframe, 'utf-8') print(data_out) - - - #ARQ_DATA_THREAD = threading.Thread(target=data_handler.arq_transmit, args=[data_out], name="ARQ_DATA") - #ARQ_DATA_THREAD.start() - + ARQ_DATA_THREAD = threading.Thread(target=data_handler.open_dc_and_transmit, args=[data_out, mode, n_frames], name="ARQ_DATA") ARQ_DATA_THREAD.start() # asyncio.run(data_handler.arq_transmit(data_out)) @@ -213,8 +198,7 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler): for i in range(0, len(static.HEARD_STATIONS)): output["STATIONS"].append({"DXCALLSIGN": str(static.HEARD_STATIONS[i][0], 'utf-8'),"DXGRID": str(static.HEARD_STATIONS[i][1], 'utf-8'), "TIMESTAMP": static.HEARD_STATIONS[i][2], "DATATYPE": static.HEARD_STATIONS[i][3], "SNR": static.HEARD_STATIONS[i][4]}) - - + try: jsondata = json.dumps(output) except ValueError as e: