diff --git a/gui/daemon.js b/gui/daemon.js index 42687476..cc108659 100644 --- a/gui/daemon.js +++ b/gui/daemon.js @@ -11,7 +11,7 @@ var configPath = path.join(configFolder, 'config.json') const config = require(configPath); var daemon = new net.Socket(); -var msg = ''; // Current message, per connection. +var socketchunk = ''; // Current message, per connection. setTimeout(connectDAEMON, 500) @@ -20,7 +20,7 @@ function connectDAEMON() { console.log('connecting to DAEMON...') //clear message buffer after reconnecting or inital connection - msg = ''; + socketchunk = ''; if (config.tnclocation == 'localhost') { daemon.connect(3001, '127.0.0.1') @@ -97,50 +97,90 @@ writeDaemonCommand = function(command) { // "https://stackoverflow.com/questions/9070700/nodejs-net-createserver-large-amount-of-data-coming-in" -daemon.on('data', function(data) { +daemon.on('data', function(socketdata) { - data = data.toString('utf8'); /* convert data to string */ - msg += data.toString('utf8'); /*append data to buffer so we can stick long data together */ + /* + inspired by: + stackoverflow.com questions 9070700 nodejs-net-createserver-large-amount-of-data-coming-in + */ - /* check if we reached an EOF, if true, clear buffer and parse JSON data */ - if (data.endsWith('}\n')) { - /*console.log(msg)*/ - try { - /*console.log(msg)*/ - data = JSON.parse(msg) - } catch (e) { - console.log(e); /* "SyntaxError */ - } - msg = ''; - /*console.log("EOF detected!")*/ - if (data['command'] == 'daemon_state') { - let Data = { - input_devices: data['input_devices'], - output_devices: data['output_devices'], - python_version: data['python_version'], - hamlib_version: data['hamlib_version'], - serial_devices: data['serial_devices'], - tnc_running_state: data['daemon_state'][0]['status'], - ram_usage: data['ram'], - cpu_usage: data['cpu'], - version: data['version'], - }; - ipcRenderer.send('request-update-daemon-state', Data); - } + socketdata = socketdata.toString('utf8'); // convert data to string + socketchunk += socketdata// append data to buffer so we can stick long data together - if (data['command'] == 'test_hamlib') { - let Data = { - hamlib_result: data['result'], - - }; - ipcRenderer.send('request-update-hamlib-test', Data); + + // check if we received begin and end of json data + if (socketchunk.startsWith('{"') && socketchunk.endsWith('"}\n')) { + + var data = '' + + // split data into chunks if we received multiple commands + socketchunk = socketchunk.split("\n"); + data = JSON.parse(socketchunk[0]) + + + // search for empty entries in socketchunk and remove them + for (i = 0; i < socketchunk.length; i++) { + if (socketchunk[i] === ''){ + socketchunk.splice(i, 1); + } } - ////// check if EOF ... + //iterate through socketchunks array to execute multiple commands in row + for (i = 0; i < socketchunk.length; i++) { + + //check if data is not empty + if(socketchunk[i].length > 0){ + + //try to parse JSON + try { + + data = JSON.parse(socketchunk[i]) + + } catch (e) { + console.log(e); // "SyntaxError + console.log(socketchunk[i]) + socketchunk = '' + + } + + } + + + + + if (data['command'] == 'daemon_state') { + let Data = { + input_devices: data['input_devices'], + output_devices: data['output_devices'], + python_version: data['python_version'], + hamlib_version: data['hamlib_version'], + serial_devices: data['serial_devices'], + tnc_running_state: data['daemon_state'][0]['status'], + ram_usage: data['ram'], + cpu_usage: data['cpu'], + version: data['version'], + }; + ipcRenderer.send('request-update-daemon-state', Data); + } + + if (data['command'] == 'test_hamlib') { + let Data = { + hamlib_result: data['result'], + + }; + ipcRenderer.send('request-update-hamlib-test', Data); + } + + + + } + + //finally delete message buffer + socketchunk = ''; + } - }); function hexToBytes(hex) { diff --git a/gui/preload-main.js b/gui/preload-main.js index ad305457..7fc36c40 100644 --- a/gui/preload-main.js +++ b/gui/preload-main.js @@ -988,6 +988,7 @@ ipcRenderer.on('action-update-tnc-state', (event, arg) => { toast.show() } // ARQ RECEIVING SUCCESS TOAST + console.log(arg.info[i]) if (arg.info[i] == "ARQ;RECEIVING;SUCCESS"){ document.getElementById("transmission_progress").className = "progress-bar progress-bar-striped bg-success"; @@ -1288,12 +1289,13 @@ ipcRenderer.on('action-update-daemon-connection', (event, arg) => { }); ipcRenderer.on('action-update-rx-buffer', (event, arg) => { - + var data = arg.data["data"] var tbl = document.getElementById("rx-data"); document.getElementById("rx-data").innerHTML = '' + for (i = 0; i < arg.data.length; i++) { // first we update the PING window @@ -1308,6 +1310,8 @@ ipcRenderer.on('action-update-rx-buffer', (event, arg) => { } + + // now we update the received files list var row = document.createElement("tr"); @@ -1338,10 +1342,11 @@ ipcRenderer.on('action-update-rx-buffer', (event, arg) => { dxGrid.appendChild(dxGridText); */ + console.log(arg.data) var fileName = document.createElement("td"); var fileNameText = document.createElement('span'); - var fileNameString = arg.data[i]['rxdata'][0]['fn'] - + var fileNameString = arg.data[i]['data'][0]['fn'] + fileNameText.innerText = fileNameString fileName.appendChild(fileNameText); @@ -1349,7 +1354,6 @@ ipcRenderer.on('action-update-rx-buffer', (event, arg) => { row.appendChild(dxCall); // row.appendChild(dxGrid); row.appendChild(fileName); - tbl.appendChild(row); // https://stackoverflow.com/a/26227660 @@ -1368,8 +1372,8 @@ ipcRenderer.on('action-update-rx-buffer', (event, arg) => { }); - // write file to rxdata folder - var base64String = arg.data[i]['rxdata'][0]['d'] + // write file to data folder + var base64String = arg.data[i]['data'][0]['d'] // remove header from base64 String // https://www.codeblocq.com/2016/04/Convert-a-base64-string-to-a-file-in-Node/ var base64Data = base64String.split(';base64,').pop() diff --git a/gui/sock.js b/gui/sock.js index f77aedba..a3848ff5 100644 --- a/gui/sock.js +++ b/gui/sock.js @@ -11,7 +11,7 @@ var configPath = path.join(configFolder, 'config.json') const config = require(configPath); var client = new net.Socket(); -var msg = ''; // Current message, per connection. +var socketchunk = ''; // Current message, per connection. // globals for getting new data only if available so we are saving bandwith var rxBufferLengthTnc = 0 @@ -27,7 +27,7 @@ function connectTNC() { //console.log('connecting to TNC...') //clear message buffer after reconnecting or inital connection - msg = ''; + socketchunk = ''; if (config.tnclocation == 'localhost') { client.connect(3000, '127.0.0.1') @@ -99,123 +99,173 @@ writeTncCommand = function(command) { } } -client.on('data', function(data) { +client.on('data', function(socketdata) { /* + inspired by: stackoverflow.com questions 9070700 nodejs-net-createserver-large-amount-of-data-coming-in */ - data = data.toString('utf8'); // convert data to string - msg += data.toString('utf8'); // append data to buffer so we can stick long data together - //console.log(data) - // check if we reached an EOF, if true, clear buffer and parse JSON data - if (data.endsWith('"EOF":"EOF"}\n') || data.endsWith('"}\n')) { - //console.log(msg) - try { - //console.log(msg) - data = JSON.parse(msg) - } catch (e) { - console.log(e); /* "SyntaxError*/ + + socketdata = socketdata.toString('utf8'); // convert data to string + socketchunk += socketdata// append data to buffer so we can stick long data together + + + // check if we received begin and end of json data + if (socketchunk.startsWith('{"') && socketchunk.endsWith('"}\n')) { + + var data = '' + + // split data into chunks if we received multiple commands + socketchunk = socketchunk.split("\n"); + data = JSON.parse(socketchunk[0]) + + + // search for empty entries in socketchunk and remove them + for (i = 0; i < socketchunk.length; i++) { + if (socketchunk[i] === ''){ + socketchunk.splice(i, 1); + } } - msg = ''; - /* console.log("EOF detected!") */ - - - - if (data['command'] == 'tnc_state') { - //console.log(data) - // set length of RX Buffer to global variable - rxBufferLengthTnc = data['rx_buffer_length'] - rxMsgBufferLengthTnc = data['rx_msg_buffer_length'] - - let Data = { - ptt_state: data['ptt_state'], - busy_state: data['tnc_state'], - arq_state: data['arq_state'], - //channel_state: data['CHANNEL_STATE'], - frequency: data['frequency'], - mode: data['mode'], - bandwith: data['bandwith'], - rms_level: (data['audio_rms'] / 1000) * 100, - fft: data['fft'], - scatter: data['scatter'], - info: data['info'], - rx_buffer_length: data['rx_buffer_length'], - rx_msg_buffer_length: data['rx_msg_buffer_length'], - tx_n_max_retries: data['tx_n_max_retries'], - arq_tx_n_frames_per_burst: data['arq_tx_n_frames_per_burst'], - arq_tx_n_bursts: data['arq_tx_n_bursts'], - arq_tx_n_current_arq_frame: data['arq_tx_n_current_arq_frame'], - arq_tx_n_total_arq_frames: data['arq_tx_n_total_arq_frames'], - arq_rx_frame_n_bursts: data['arq_rx_frame_n_bursts'], - arq_rx_n_current_arq_frame: data['arq_rx_n_current_arq_frame'], - arq_n_arq_frames_per_data_frame: data['arq_n_arq_frames_per_data_frame'], - arq_bytes_per_minute: data['arq_bytes_per_minute'], - arq_compression_factor: data['arq_compression_factor'], - total_bytes: data['total_bytes'], - arq_transmission_percent: data['arq_transmission_percent'], - stations: data['stations'], - beacon_state: data['beacon_state'], - }; - //console.log(Data) - ipcRenderer.send('request-update-tnc-state', Data); - } - - /* A TEST WITH THE NEW STREAMING DATA .... */ - if (data['arq'] == 'received') { + + //iterate through socketchunks array to execute multiple commands in row + for (i = 0; i < socketchunk.length; i++) { - rxBufferLengthGui = data['data'].length + //check if data is not empty + if(socketchunk[i].length > 0){ - console.log(data['uuid']) - console.log(data['type']) - - let Data = { - data: data['data'], - }; - alert(data['data']) - ipcRenderer.send('request-update-rx-buffer', Data); - } + //try to parse JSON + try { - if (data['command'] == 'rx_buffer') { + data = JSON.parse(socketchunk[i]) - console.log(data['data-array']) - // iterate through buffer list and sort it to file or message array - dataArray = [] - messageArray = [] - for (i = 0; i < data['data-array'].length; i++) { - - if(data['data-array'][i]['rxdata'][0]['dt'] == 'f'){ - dataArray.push(data['data-array'][i]) - - } - - if(data['data-array'][i]['rxdata'][0]['dt'] == 'm'){ - messageArray.push(data['data-array'][i]) + } catch (e) { + console.log(e); // "SyntaxError + console.log(socketchunk[i]) + socketchunk = '' } - - + } - rxBufferLengthGui = dataArray.length - let Files = { - data: dataArray, - }; - ipcRenderer.send('request-update-rx-buffer', Files); - - rxMsgBufferLengthGui = messageArray.length - let Messages = { - data: messageArray, - }; - ipcRenderer.send('request-update-rx-msg-buffer', Messages); + if (data['command'] == 'tnc_state') { + //console.log(data) + // set length of RX Buffer to global variable + rxBufferLengthTnc = data['rx_buffer_length'] + rxMsgBufferLengthTnc = data['rx_msg_buffer_length'] + + let Data = { + ptt_state: data['ptt_state'], + busy_state: data['tnc_state'], + arq_state: data['arq_state'], + //channel_state: data['CHANNEL_STATE'], + frequency: data['frequency'], + mode: data['mode'], + bandwith: data['bandwith'], + rms_level: (data['audio_rms'] / 1000) * 100, + fft: data['fft'], + scatter: data['scatter'], + info: data['info'], + rx_buffer_length: data['rx_buffer_length'], + rx_msg_buffer_length: data['rx_msg_buffer_length'], + tx_n_max_retries: data['tx_n_max_retries'], + arq_tx_n_frames_per_burst: data['arq_tx_n_frames_per_burst'], + arq_tx_n_bursts: data['arq_tx_n_bursts'], + arq_tx_n_current_arq_frame: data['arq_tx_n_current_arq_frame'], + arq_tx_n_total_arq_frames: data['arq_tx_n_total_arq_frames'], + arq_rx_frame_n_bursts: data['arq_rx_frame_n_bursts'], + arq_rx_n_current_arq_frame: data['arq_rx_n_current_arq_frame'], + arq_n_arq_frames_per_data_frame: data['arq_n_arq_frames_per_data_frame'], + arq_bytes_per_minute: data['arq_bytes_per_minute'], + arq_compression_factor: data['arq_compression_factor'], + total_bytes: data['total_bytes'], + arq_transmission_percent: data['arq_transmission_percent'], + stations: data['stations'], + beacon_state: data['beacon_state'], + }; + + ipcRenderer.send('request-update-tnc-state', Data); + } + + /* A TEST WITH STREAMING DATA .... */ + if (data['arq'] == 'received') { + dataArray = [] + messageArray = [] + + + if(data['data'][0]['dt'] == 'f'){ + dataArray.push(data) + } + + if(data['data'][0]['dt'] == 'm'){ + messageArray.push(data) + } + + + + rxBufferLengthGui = dataArray.length + let Files = { + data: dataArray, + }; + ipcRenderer.send('request-update-rx-buffer', Files); + + rxMsgBufferLengthGui = messageArray.length + let Messages = { + data: messageArray, + }; + ipcRenderer.send('request-update-rx-msg-buffer', Messages); + + } + + if (data['command'] == 'rx_buffer') { + + // iterate through buffer list and sort it to file or message array + dataArray = [] + messageArray = [] + + + for (i = 0; i < data['data-array'].length; i++) { + try{ + if(data['data-array'][i]['data'][0]['dt'] == 'f'){ + dataArray.push(data['data-array'][i]) + + } + + if(data['data-array'][i]['data'][0]['dt'] == 'm'){ + messageArray.push(data['data-array'][i]) + + } + } catch (e) { + console.log(e) + } + } + console.log(dataArray) + + + rxBufferLengthGui = dataArray.length + let Files = { + data: dataArray, + }; + ipcRenderer.send('request-update-rx-buffer', Files); + + rxMsgBufferLengthGui = messageArray.length + let Messages = { + data: messageArray, + }; + ipcRenderer.send('request-update-rx-msg-buffer', Messages); + + } + } - + + //finally delete message buffer + socketchunk = ''; + } - }); function hexToBytes(hex) { @@ -237,11 +287,6 @@ exports.getDataState = function() { //writeTncCommand(command) } -//Get Heard Stations -//exports.getHeardStations = function() { -// command = '{"type" : "GET", "command" : "HEARD_STATIONS", "timestamp" : ' + Date.now() + '}'; -// writeTncCommand(command) -//} // Send Ping exports.sendPing = function(dxcallsign) { diff --git a/tnc/data_handler.py b/tnc/data_handler.py index 20567eb5..a771706e 100644 --- a/tnc/data_handler.py +++ b/tnc/data_handler.py @@ -386,7 +386,7 @@ class DATA(): # check if data_frame_crc is equal with received crc if data_frame_crc == data_frame_crc_received: structlog.get_logger("structlog").info("[TNC] ARQ | RX | DATA FRAME SUCESSFULLY RECEIVED") - static.INFO.append("ARQ;RECEIVING;SUCCESS") + # decompression data_frame_decompressed = zlib.decompress(data_frame) @@ -418,25 +418,8 @@ class DATA(): jsondata = {"arq":"received", "uuid" : static.RX_BUFFER[i][0], "timestamp": static.RX_BUFFER[i][1], "dxcallsign": str(static.RX_BUFFER[i][2], 'utf-8'), "dxgrid": str(static.RX_BUFFER[i][3], 'utf-8'), "data": [rawdata]} data_out = json.dumps(jsondata) sock.SOCKET_QUEUE.put(data_out) - - ''' - if rawdata["dt"] == "f" or rawdata["dt"] == "m": - #structlog.get_logger("structlog").debug("RECEIVED FILE --> MOVING DATA TO RX BUFFER") - static.RX_BUFFER.append([uuid4(), datatype ,static.DXCALLSIGN,static.DXGRID,int(time.time()), data_frame]) - jsondata = {"arq":"received", "uuid" : static.RX_BUFFER[i][0], "type" : static.RX_BUFFER[i][1], "dxcallsign": str(static.RX_BUFFER[i][2], 'utf-8'), "dxgrid": str(static.RX_BUFFER[i][3], 'utf-8'), "timestamp": static.RX_BUFFER[i][4], "data": [rawdata]} - data_out = json.dumps(jsondata) - sock.SOCKET_QUEUE.put(data_out) - # if datatype is a file, we append to RX_MSG_BUFFER, which contains messages only - #elif rawdata["dt"] == "m": - # static.RX_MSG_BUFFER.append([static.DXCALLSIGN,static.DXGRID,int(time.time()), data_frame]) + static.INFO.append("ARQ;RECEIVING;SUCCESS") - # here we should have our raw data - else: - static.RX_BUFFER.append([static.DXCALLSIGN,static.DXGRID,int(time.time()), data_frame]) - jsondata = {"arq":"raw", "dxcallsign": str(static.RX_BUFFER[i][0], 'utf-8'), "dxgrid": str(static.RX_BUFFER[i][1], 'utf-8'), "timestamp": static.RX_BUFFER[i][2], "data": [rawdata]} - data_out = json.dumps(jsondata) - sock.SOCKET_QUEUE.put(data_out) - ''' # BUILDING ACK FRAME FOR DATA FRAME ack_frame = bytearray(14) ack_frame[:1] = bytes([61]) diff --git a/tnc/sock.py b/tnc/sock.py index 77c11670..36d0c1dd 100644 --- a/tnc/sock.py +++ b/tnc/sock.py @@ -67,13 +67,16 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler): sock_data = bytes(data, 'utf-8') sock_data += b'\n' # append line limiter # send data to all clients - for client in CONNECTED_CLIENTS: - try: - client.send(sock_data) - except: - print("connection lost...") - CONNECTED_CLIENTS.remove(self.request) - + try: + for client in CONNECTED_CLIENTS: + try: + client.send(sock_data) + except: + print("connection lost...") + CONNECTED_CLIENTS.remove(self.request) + except: + print("client not anymore in client list") + # we want to transmit scatter data only once to reduce network traffic static.SCATTER = [] # we want to display INFO messages only once @@ -135,135 +138,156 @@ def process_tnc_commands(data): received_json = json.loads(data) # CQ CQ CQ ----------------------------------------------------- if received_json["command"] == "cqcqcq": - data_handler.DATA_QUEUE_TRANSMIT.put(['CQ']) - + try: + data_handler.DATA_QUEUE_TRANSMIT.put(['CQ']) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) # START_BEACON ----------------------------------------------------- if received_json["command"] == "start_beacon": - - static.BEACON_STATE = True - interval = int(received_json["parameter"]) - data_handler.DATA_QUEUE_TRANSMIT.put(['BEACON', interval, True]) - - + try: + static.BEACON_STATE = True + interval = int(received_json["parameter"]) + data_handler.DATA_QUEUE_TRANSMIT.put(['BEACON', interval, True]) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + # STOP_BEACON ----------------------------------------------------- if received_json["command"] == "stop_beacon": - static.BEACON_STATE = False - structlog.get_logger("structlog").warning("[TNC] Stopping beacon!") - data_handler.DATA_QUEUE_TRANSMIT.put(['BEACON', None, False]) - + try: + static.BEACON_STATE = False + structlog.get_logger("structlog").warning("[TNC] Stopping beacon!") + data_handler.DATA_QUEUE_TRANSMIT.put(['BEACON', None, False]) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) # PING ---------------------------------------------------------- if received_json["type"] == 'ping' and received_json["command"] == "ping": # send ping frame and wait for ACK - dxcallsign = received_json["dxcallsign"] - data_handler.DATA_QUEUE_TRANSMIT.put(['PING', dxcallsign]) - + try: + dxcallsign = received_json["dxcallsign"] + data_handler.DATA_QUEUE_TRANSMIT.put(['PING', dxcallsign]) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) # TRANSMIT RAW DATA ------------------------------------------- if received_json["type"] == 'arq' and received_json["command"] == "send_raw": - dxcallsign = received_json["parameter"][0]["dxcallsign"] - mode = int(received_json["parameter"][0]["mode"]) - n_frames = int(received_json["parameter"][0]["n_frames"]) - data = received_json["parameter"][0]["data"] + try: + dxcallsign = received_json["parameter"][0]["dxcallsign"] + mode = int(received_json["parameter"][0]["mode"]) + n_frames = int(received_json["parameter"][0]["n_frames"]) + data = received_json["parameter"][0]["data"] - static.DXCALLSIGN = bytes(dxcallsign, 'utf-8') - static.DXCALLSIGN_CRC = helpers.get_crc_16(static.DXCALLSIGN) - rawdata = {"raw": data} - dataframe = json.dumps(rawdata) - data_out = bytes(dataframe, 'utf-8') - data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_RAW', data_out, mode, n_frames]) - print(data_handler.DATA_QUEUE_TRANSMIT.qsize()) - + static.DXCALLSIGN = bytes(dxcallsign, 'utf-8') + static.DXCALLSIGN_CRC = helpers.get_crc_16(static.DXCALLSIGN) + rawdata = {"raw": data} + dataframe = json.dumps(rawdata) + data_out = bytes(dataframe, 'utf-8') + data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_RAW', data_out, mode, n_frames]) + print(data_handler.DATA_QUEUE_TRANSMIT.qsize()) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) # TRANSMIT FILE ---------------------------------------------------------- if received_json["type"] == 'arq' and received_json["command"] == "send_file": - static.TNC_STATE = 'BUSY' + try: + static.TNC_STATE = 'BUSY' - # on a new transmission we reset the timer - static.ARQ_START_OF_TRANSMISSION = int(time.time()) + # on a new transmission we reset the timer + static.ARQ_START_OF_TRANSMISSION = int(time.time()) - dxcallsign = received_json["parameter"][0]["dxcallsign"] - mode = int(received_json["parameter"][0]["mode"]) - n_frames = int(received_json["parameter"][0]["n_frames"]) - filename = received_json["parameter"][0]["filename"] - filetype = received_json["parameter"][0]["filetype"] - data = received_json["parameter"][0]["data"] - checksum = received_json["parameter"][0]["checksum"] - + dxcallsign = received_json["parameter"][0]["dxcallsign"] + mode = int(received_json["parameter"][0]["mode"]) + n_frames = int(received_json["parameter"][0]["n_frames"]) + filename = received_json["parameter"][0]["filename"] + filetype = received_json["parameter"][0]["filetype"] + data = received_json["parameter"][0]["data"] + checksum = received_json["parameter"][0]["checksum"] + - static.DXCALLSIGN = bytes(dxcallsign, 'utf-8') - static.DXCALLSIGN_CRC = helpers.get_crc_16(static.DXCALLSIGN) + static.DXCALLSIGN = bytes(dxcallsign, 'utf-8') + static.DXCALLSIGN_CRC = helpers.get_crc_16(static.DXCALLSIGN) - # dt = datatype - # --> f = file - # --> m = message - # fn = filename - # ft = filetype - # d = data - # crc = checksum - rawdata = {"dt": "f", "fn": filename, "ft": filetype,"d": data, "crc": checksum} - dataframe = json.dumps(rawdata) - data_out = bytes(dataframe, 'utf-8') - data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_FILE', data_out, mode, n_frames]) - print(data_handler.DATA_QUEUE_TRANSMIT.qsize()) + # dt = datatype + # --> f = file + # --> m = message + # fn = filename + # ft = filetype + # d = data + # crc = checksum + rawdata = {"dt": "f", "fn": filename, "ft": filetype,"d": data, "crc": checksum} + dataframe = json.dumps(rawdata) + data_out = bytes(dataframe, 'utf-8') + data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_FILE', data_out, mode, n_frames]) + print(data_handler.DATA_QUEUE_TRANSMIT.qsize()) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) # TRANSMIT MESSAGE ---------------------------------------------------------- if received_json["type"] == 'arq' and received_json["command"] == "send_message": - static.TNC_STATE = 'BUSY' - print(received_json) - # on a new transmission we reset the timer - static.ARQ_START_OF_TRANSMISSION = int(time.time()) + try: + static.TNC_STATE = 'BUSY' + print(received_json) + # on a new transmission we reset the timer + static.ARQ_START_OF_TRANSMISSION = int(time.time()) - dxcallsign = received_json["parameter"][0]["dxcallsign"] - mode = int(received_json["parameter"][0]["mode"]) - n_frames = int(received_json["parameter"][0]["n_frames"]) - data = received_json["parameter"][0]["data"] # d = data - checksum = received_json["parameter"][0]["checksum"] # crc = checksum - + dxcallsign = received_json["parameter"][0]["dxcallsign"] + mode = int(received_json["parameter"][0]["mode"]) + n_frames = int(received_json["parameter"][0]["n_frames"]) + data = received_json["parameter"][0]["data"] # d = data + checksum = received_json["parameter"][0]["checksum"] # crc = checksum + - static.DXCALLSIGN = bytes(dxcallsign, 'utf-8') - static.DXCALLSIGN_CRC = helpers.get_crc_16(static.DXCALLSIGN) - - # dt = datatype - # --> f = file - # --> m = message - # fn = filename - # ft = filetype - # d = data - # crc = checksum - rawdata = {"dt": "m","d": data, "crc": checksum} - dataframe = json.dumps(rawdata) - data_out = bytes(dataframe, 'utf-8') - - data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_MESSAGE', data_out, mode, n_frames]) + static.DXCALLSIGN = bytes(dxcallsign, 'utf-8') + static.DXCALLSIGN_CRC = helpers.get_crc_16(static.DXCALLSIGN) + + # dt = datatype + # --> f = file + # --> m = message + # fn = filename + # ft = filetype + # d = data + # crc = checksum + rawdata = {"dt": "m","d": data, "crc": checksum} + dataframe = json.dumps(rawdata) + data_out = bytes(dataframe, 'utf-8') + data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_MESSAGE', data_out, mode, n_frames]) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) # STOP TRANSMISSION ---------------------------------------------------------- if received_json["type"] == 'arq' and received_json["command"] == "stop_transmission": - if static.TNC_STATE == 'BUSY' or static.ARQ_STATE: - data_handler.DATA_QUEUE_TRANSMIT.put(['STOP']) - structlog.get_logger("structlog").warning("[TNC] Stopping transmission!") - static.TNC_STATE = 'IDLE' - static.ARQ_STATE = False - + try: + if static.TNC_STATE == 'BUSY' or static.ARQ_STATE: + data_handler.DATA_QUEUE_TRANSMIT.put(['STOP']) + structlog.get_logger("structlog").warning("[TNC] Stopping transmission!") + static.TNC_STATE = 'IDLE' + static.ARQ_STATE = False + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + if received_json["type"] == 'get' and received_json["command"] == 'rx_buffer': - output = { - "command": "rx_buffer", - "data-array": [], - "EOF": "EOF", - } - - for i in range(0, len(static.RX_BUFFER)): - rawdata = json.loads(static.RX_BUFFER[i][4]) - output["data-array"].append({"uuid": static.RX_BUFFER[i][0],"timestamp": static.RX_BUFFER[i][1], "dxcallsign": str(static.RX_BUFFER[i][2], 'utf-8'), "dxgrid": str(static.RX_BUFFER[i][3], 'utf-8'), "rxdata": [rawdata]}) + try: + output = { + "command": "rx_buffer", + "data-array": [], + } + + for i in range(0, len(static.RX_BUFFER)): + rawdata = json.loads(static.RX_BUFFER[i][4]) + output["data-array"].append({"uuid": static.RX_BUFFER[i][0],"timestamp": static.RX_BUFFER[i][1], "dxcallsign": str(static.RX_BUFFER[i][2], 'utf-8'), "dxgrid": str(static.RX_BUFFER[i][3], 'utf-8'), "data": [rawdata]}) - jsondata = json.dumps(output) - #self.request.sendall(bytes(jsondata, encoding)) - SOCKET_QUEUE.put(jsondata) + jsondata = json.dumps(output) + #self.request.sendall(bytes(jsondata, encoding)) + print(jsondata) + SOCKET_QUEUE.put(jsondata) + + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + ''' if received_json["type"] == 'GET' and received_json["command"] == 'rx_msg_buffer': output = { "command": "rx_msg_buffer", "data-array": [], - "EOF": "EOF", } for i in range(0, len(static.RX_MSG_BUFFER)): @@ -275,17 +299,21 @@ def process_tnc_commands(data): SOCKET_QUEUE.put(jsondata) ''' if received_json["type"] == 'set' and received_json["command"] == 'del_rx_buffer': - static.RX_BUFFER = [] - + try: + static.RX_BUFFER = [] + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + ''' if received_json["type"] == 'set' and received_json["command"] == 'del_rx_msg_buffer': static.RX_MSG_BUFFER = [] ''' # exception, if JSON cant be decoded except Exception as e: - structlog.get_logger("structlog").error("[TNC] Network error", e=e) + structlog.get_logger("structlog").error("[TNC] JSON decoding error", e=e) def send_tnc_state(): + encoding = 'utf-8' output = { @@ -313,7 +341,6 @@ def send_tnc_state(): "mycallsign": str(static.MYCALLSIGN, encoding), "dxcallsign": str(static.DXCALLSIGN, encoding), "dxgrid": str(static.DXGRID, encoding), - "EOF": "EOF", } # add heard stations to heard stations object @@ -329,96 +356,110 @@ def process_daemon_commands(data): received_json = json.loads(data) if received_json["type"] == 'set' and received_json["command"] == 'mycallsign': - callsign = received_json["parameter"] - print(received_json) - if bytes(callsign, 'utf-8') == b'': - self.request.sendall(b'INVALID CALLSIGN') - structlog.get_logger("structlog").warning("[DMN] SET MYCALL FAILED", call=static.MYCALLSIGN, crc=static.MYCALLSIGN_CRC) - else: - static.MYCALLSIGN = bytes(callsign, 'utf-8') - static.MYCALLSIGN_CRC = helpers.get_crc_16(static.MYCALLSIGN) - - structlog.get_logger("structlog").info("[DMN] SET MYCALL", call=static.MYCALLSIGN, crc=static.MYCALLSIGN_CRC) + try: + callsign = received_json["parameter"] + print(received_json) + if bytes(callsign, 'utf-8') == b'': + self.request.sendall(b'INVALID CALLSIGN') + structlog.get_logger("structlog").warning("[DMN] SET MYCALL FAILED", call=static.MYCALLSIGN, crc=static.MYCALLSIGN_CRC) + else: + static.MYCALLSIGN = bytes(callsign, 'utf-8') + static.MYCALLSIGN_CRC = helpers.get_crc_16(static.MYCALLSIGN) + structlog.get_logger("structlog").info("[DMN] SET MYCALL", call=static.MYCALLSIGN, crc=static.MYCALLSIGN_CRC) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + + if received_json["type"] == 'set' and received_json["command"] == 'mygrid': - mygrid = received_json["parameter"] - - if bytes(mygrid, 'utf-8') == b'': - self.request.sendall(b'INVALID GRID') - else: - static.MYGRID = bytes(mygrid, 'utf-8') - structlog.get_logger("structlog").info("[DMN] SET MYGRID", grid=static.MYGRID) + try: + mygrid = received_json["parameter"] + if bytes(mygrid, 'utf-8') == b'': + self.request.sendall(b'INVALID GRID') + else: + static.MYGRID = bytes(mygrid, 'utf-8') + structlog.get_logger("structlog").info("[SCK] SET MYGRID", grid=static.MYGRID) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + + if received_json["type"] == 'set' and received_json["command"] == 'start_tnc' and not static.TNCSTARTED: - mycall = str(received_json["parameter"][0]["mycall"]) - mygrid = str(received_json["parameter"][0]["mygrid"]) - rx_audio = str(received_json["parameter"][0]["rx_audio"]) - tx_audio = str(received_json["parameter"][0]["tx_audio"]) - devicename = str(received_json["parameter"][0]["devicename"]) - deviceport = str(received_json["parameter"][0]["deviceport"]) - serialspeed = str(received_json["parameter"][0]["serialspeed"]) - pttprotocol = str(received_json["parameter"][0]["pttprotocol"]) - pttport = str(received_json["parameter"][0]["pttport"]) - data_bits = str(received_json["parameter"][0]["data_bits"]) - stop_bits = str(received_json["parameter"][0]["stop_bits"]) - handshake = str(received_json["parameter"][0]["handshake"]) - radiocontrol = str(received_json["parameter"][0]["radiocontrol"]) - rigctld_ip = str(received_json["parameter"][0]["rigctld_ip"]) - rigctld_port = str(received_json["parameter"][0]["rigctld_port"]) - DAEMON_QUEUE.put(['STARTTNC', \ - mycall, \ - mygrid, \ - rx_audio, \ - tx_audio, \ - devicename, \ - deviceport, \ - serialspeed, \ - pttprotocol, \ - pttport, \ - data_bits, \ - stop_bits, \ - handshake, \ - radiocontrol, \ - rigctld_ip, \ - rigctld_port \ - ]) - + try: + mycall = str(received_json["parameter"][0]["mycall"]) + mygrid = str(received_json["parameter"][0]["mygrid"]) + rx_audio = str(received_json["parameter"][0]["rx_audio"]) + tx_audio = str(received_json["parameter"][0]["tx_audio"]) + devicename = str(received_json["parameter"][0]["devicename"]) + deviceport = str(received_json["parameter"][0]["deviceport"]) + serialspeed = str(received_json["parameter"][0]["serialspeed"]) + pttprotocol = str(received_json["parameter"][0]["pttprotocol"]) + pttport = str(received_json["parameter"][0]["pttport"]) + data_bits = str(received_json["parameter"][0]["data_bits"]) + stop_bits = str(received_json["parameter"][0]["stop_bits"]) + handshake = str(received_json["parameter"][0]["handshake"]) + radiocontrol = str(received_json["parameter"][0]["radiocontrol"]) + rigctld_ip = str(received_json["parameter"][0]["rigctld_ip"]) + rigctld_port = str(received_json["parameter"][0]["rigctld_port"]) + DAEMON_QUEUE.put(['STARTTNC', \ + mycall, \ + mygrid, \ + rx_audio, \ + tx_audio, \ + devicename, \ + deviceport, \ + serialspeed, \ + pttprotocol, \ + pttport, \ + data_bits, \ + stop_bits, \ + handshake, \ + radiocontrol, \ + rigctld_ip, \ + rigctld_port \ + ]) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) if received_json["type"] == 'get' and received_json["command"] == 'test_hamlib': - - devicename = str(received_json["parameter"][0]["devicename"]) - deviceport = str(received_json["parameter"][0]["deviceport"]) - serialspeed = str(received_json["parameter"][0]["serialspeed"]) - pttprotocol = str(received_json["parameter"][0]["pttprotocol"]) - pttport = str(received_json["parameter"][0]["pttport"]) - data_bits = str(received_json["parameter"][0]["data_bits"]) - stop_bits = str(received_json["parameter"][0]["stop_bits"]) - handshake = str(received_json["parameter"][0]["handshake"]) - radiocontrol = str(received_json["parameter"][0]["radiocontrol"]) - rigctld_ip = str(received_json["parameter"][0]["rigctld_ip"]) - rigctld_port = str(received_json["parameter"][0]["rigctld_port"]) - DAEMON_QUEUE.put(['TEST_HAMLIB', \ - devicename, \ - deviceport, \ - serialspeed, \ - pttprotocol, \ - pttport, \ - data_bits, \ - stop_bits, \ - handshake, \ - radiocontrol, \ - rigctld_ip, \ - rigctld_port \ - ]) - + try: + devicename = str(received_json["parameter"][0]["devicename"]) + deviceport = str(received_json["parameter"][0]["deviceport"]) + serialspeed = str(received_json["parameter"][0]["serialspeed"]) + pttprotocol = str(received_json["parameter"][0]["pttprotocol"]) + pttport = str(received_json["parameter"][0]["pttport"]) + data_bits = str(received_json["parameter"][0]["data_bits"]) + stop_bits = str(received_json["parameter"][0]["stop_bits"]) + handshake = str(received_json["parameter"][0]["handshake"]) + radiocontrol = str(received_json["parameter"][0]["radiocontrol"]) + rigctld_ip = str(received_json["parameter"][0]["rigctld_ip"]) + rigctld_port = str(received_json["parameter"][0]["rigctld_port"]) + DAEMON_QUEUE.put(['TEST_HAMLIB', \ + devicename, \ + deviceport, \ + serialspeed, \ + pttprotocol, \ + pttport, \ + data_bits, \ + stop_bits, \ + handshake, \ + radiocontrol, \ + rigctld_ip, \ + rigctld_port \ + ]) + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + if received_json["type"] == 'set' and received_json["command"] == 'stop_tnc': - static.TNCPROCESS.kill() - structlog.get_logger("structlog").warning("[DMN] Stopping TNC") - static.TNCSTARTED = False - - + try: + static.TNCPROCESS.kill() + structlog.get_logger("structlog").warning("[DMN] Stopping TNC") + static.TNCSTARTED = False + except Exception as e: + structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json) + def send_daemon_state(): python_version = str(sys.version_info[0]) + "." + str(sys.version_info[1])