Explicit args on modem primitive methods. API error format.

This commit is contained in:
Pedro 2023-11-22 14:56:52 +01:00
parent eda5580f83
commit 8c2c6a8ce0
6 changed files with 63 additions and 53 deletions

5
modem/api_validations.py Normal file
View file

@ -0,0 +1,5 @@
import re
def validate_freedata_callsign(callsign):
regexp = "^[a-zA-Z]+\d+\w+-\d{1,2}$"
return re.compile(regexp).match(callsign) is not None

View file

@ -165,9 +165,10 @@ class DATA:
self.arq.arq_session_handler(data[1], data[2])
elif data[0] == "PING":
# [1] mycallsign
# [1] mycallsign // this is being injected as None
# [2] dxcallsign
self.ping.transmit_ping(data[1], data[2])
mycallsign = f"{self.config['STATION']['mycall']}-{self.config['STATION']['myssid']}"
self.ping.transmit_ping(mycallsign, data[2])
elif data[0] == "BEACON":
# [1] INTERVAL int

View file

@ -13,12 +13,12 @@ class PING:
self.config = config
# ---------- PING
def transmit_ping(self, mycallsign: bytes, dxcallsign: bytes) -> None:
def transmit_ping(self, mycallsign: str, dxcallsign: str) -> None:
"""
Funktion for controlling pings
Function for controlling pings
Args:
mycallsign:bytes:
dxcallsign:bytes:
mycallsign
dxcallsign
"""
# check if specific callsign is set with different SSID than the Modem is initialized
@ -40,14 +40,15 @@ class PING:
self.dxcallsign = dxcallsign
self.dxcallsign_crc = helpers.get_crc_24(self.dxcallsign)
self.send_data_to_socket_queue(
freedata="modem-message",
ping="transmitting",
dxcallsign=str(dxcallsign, "UTF-8"),
)
self.event_queue.put({
'freedata': "modem-message",
'ping': "transmitting",
'dxcallsign': str(dxcallsign, "UTF-8"),
})
self.log.info(
"[Modem] PING REQ ["
+ mycallsign
+ str(mycallsign, "UTF-8")
+ "] >>> ["
+ str(dxcallsign, "UTF-8")
+ "]"

View file

@ -1,4 +1,4 @@
from flask import Flask, request, jsonify, make_response
from flask import Flask, request, jsonify, make_response, abort, Response
from flask_sock import Sock
from flask_cors import CORS
import os
@ -12,6 +12,7 @@ import state_manager
import threading
import ujson as json
import websocket_manager as wsm
import api_validations as validations
app = Flask(__name__)
CORS(app)
@ -55,9 +56,22 @@ service_manager.SM(app)
app.modem_service.put("start")
# returns a standard API response
def api_response(data):
return make_response(jsonify(data), 200)
def api_response(data, status = 200):
return make_response(jsonify(data), status)
def api_abort(message, code):
jsonError = json.dumps({'error': message})
abort(Response(jsonError, code))
# validates a parameter
def validate(req, param, validator, isRequired = True):
if param not in req:
if isRequired:
api_abort(f"Required parameter '{param}' is missing.", 400)
else:
return True
if not validator(req[param]):
api_abort(f"Value of '{param}' is invalid.", 400)
## REST API
@app.route('/', methods=['GET'])
@ -104,23 +118,26 @@ def post_cqcqcq():
if request.method not in ['POST']:
return api_response({"info": "endpoint for triggering a CQ via POST"})
if app.states.is_modem_running:
server_commands.cqcqcq(request.json)
server_commands.cqcqcq()
return api_response({"cmd": "cqcqcq"})
@app.route('/modem/beacon', methods=['POST'])
def post_beacon():
if request.method not in ['POST']:
return api_response({"info": "endpoint for controlling BEACON STATE via POST"})
if app.states.is_modem_running:
server_commands.beacon(request.json)
if not app.states.is_modem_running:
api_abort('Modem not running', 503)
server_commands.beacon(request.json['enable_beacon'])
return api_response(request.json)
@app.route('/modem/ping_ping', methods=['POST'])
def post_ping():
if request.method not in ['POST']:
return api_response({"info": "endpoint for controlling PING via POST"})
if app.states.is_modem_running:
server_commands.ping_ping(request.json)
if not app.states.is_modem_running:
api_abort('Modem not running', 503)
validate(request.json, 'dxcall', validations.validate_freedata_callsign)
server_commands.ping_ping(request.json['dxcall'])
return api_response(request.json)
@app.route('/modem/send_test_frame', methods=['POST'])

View file

@ -5,28 +5,23 @@ import threading
from random import randrange
log = structlog.get_logger("COMMANDS")
def cqcqcq(data):
def cqcqcq():
try:
DATA_QUEUE_TRANSMIT.put(["CQ"])
return
except Exception as err:
log.warning("[CMD] error while transmiting CQ", e=err, command=data)
log.warning("[CMD] error while transmiting CQ", e=err)
def ping_ping(data):
def ping_ping(dxcall):
try:
dxcallsign = data["dxcall"]
if not str(dxcallsign).strip():
return
DATA_QUEUE_TRANSMIT.put(["PING", None, dxcallsign])
DATA_QUEUE_TRANSMIT.put(["PING", None, dxcall])
except Exception as err:
log.warning(
"[CMD] PING command execution error", e=err, command=data
"[CMD] PING command execution error", e=err
)
def beacon(data, interval=300):
beacon_state = data['enabled'] in [True]
def beacon(beacon_state, interval=300):
log.info(
"[CMD] Changing beacon state", state=beacon_state
)
@ -41,18 +36,12 @@ def modem_send_test_frame():
)
DATA_QUEUE_TRANSMIT.put(["SEND_TEST_FRAME"])
def modem_arq_send_raw(data):
def modem_arq_send_raw(mycallsign, dxcallsign, payload, arq_uuid = "no-uuid"):
# wait some random time
threading.Event().wait(randrange(5, 25, 5) / 10.0)
base64data = data["data"]
# check if transmission uuid provided else set no-uuid
try:
arq_uuid = data["uuid"]
except Exception:
arq_uuid = "no-uuid"
base64data = payload
if len(base64data) % 4:
raise TypeError
@ -60,36 +49,26 @@ def modem_arq_send_raw(data):
binarydata = base64.b64decode(base64data)
DATA_QUEUE_TRANSMIT.put(
["ARQ_RAW", binarydata, arq_uuid, data["mycallsign"], data["dxcallsign"]]
["ARQ_RAW", binarydata, arq_uuid, mycallsign, dxcallsign]
)
def modem_fec_transmit(data):
def modem_fec_transmit(mode, wakeup, base64data, mycallsign = None):
log.info(
"[CMD] Send fec frame"
)
mode = data["mode"]
wakeup = data["wakeup"]
base64data = data["payload"]
if len(base64data) % 4:
raise TypeError
payload = base64.b64decode(base64data)
try:
mycallsign = data["mycallsign"]
except:
mycallsign = None
DATA_QUEUE_TRANSMIT.put(["FEC", mode, wakeup, payload, mycallsign])
def modem_fec_is_writing(data):
def modem_fec_is_writing(mycallsign):
try:
mycallsign = data["mycallsign"]
DATA_QUEUE_TRANSMIT.put(["FEC_IS_WRITING", mycallsign])
except Exception as err:
log.warning(
"[SCK] Send fec frame command execution error",
e=err,
command=data,
)

View file

@ -26,10 +26,17 @@ def handle_connection(sock, client_list, event_queue):
def transmit_sock_data_worker(client_list, event_queue):
while True:
event = event_queue.get()
if isinstance(event, str):
print(f"WARNING: Queue event:\n'{event}'\n still in string format")
json_event = event
else:
json_event = json.dumps(event)
clients = client_list.copy()
for client in clients:
try:
client.send(event)
client.send(json_event)
except Exception:
client_list.remove(client)