Implement more commands and remove old code

This commit is contained in:
Pedro 2023-11-26 00:11:39 +01:00
parent dea132203b
commit 8670646ca7
9 changed files with 58 additions and 147 deletions

View file

@ -1,5 +1,5 @@
from data_frame_factory import DataFrameFactory
from modem.modem import RF
from modem import RF
import queue
from codec2 import FREEDV_MODE
@ -26,18 +26,22 @@ class TxCommand():
def build_frame(self):
pass
def get_c2_mode(self):
def get_tx_mode(self):
c2_mode = FREEDV_MODE.fsk_ldpc_0.value if self.config.enable_fsk else FREEDV_MODE.sig0.value
return c2_mode
def transmit(self, tx_frame_queue):
frame = self.build_frame()
tx_queue_item = {
def make_modem_queue_item(self, mode, repeat, repeat_delay, frame):
item = {
'mode': self.get_c2_mode(),
'repeat': 1,
'repeat_delay': 0,
'frame': frame
}
return item
def transmit(self, tx_frame_queue):
frame = self.build_frame()
tx_queue_item = self.make_modem_queue_item(self.get_tx_mode(), 1, 0, frame)
tx_frame_queue.put(tx_queue_item)
def run(self, event_queue: queue.Queue, tx_frame_queue: queue.Queue):

View file

@ -1,3 +1,6 @@
from command import TxCommand
class CQCommand(TxCommand):
def build_frame(self):
return self.frame_factory.build_cq()

View file

@ -22,8 +22,8 @@ class FecCommand(TxCommand):
def transmit(self, tx_frame_queue):
if self.wakeup:
tx_queue_item = [self.get_c2_mode(), 1, 0, self.build_wakeup_frame()]
tx_queue_item = self.make_modem_queue_item(self.get_c2_mode(), 1, 0, self.build_wakeup_frame())
tx_frame_queue.put(tx_queue_item)
tx_queue_item = [self.get_c2_mode(), 1, 0, self.build_frame()]
tx_queue_item = self.make_modem_queue_item(self.get_c2_mode(), 1, 0, self.build_frame())
tx_frame_queue.put(tx_queue_item)

View file

@ -6,10 +6,5 @@ class PingCommand(TxCommand):
self.dxcall = apiParams['dxcall']
return super().setParamsFromApi()
def run(self, modem_state, tx_frame_queue):
frame = self.frame_factory.build_ping(self.dxcall)
return super().execute(modem_state, tx_frame_queue)
def build_frame(self):
return self.frame_factory.build_ping(self.dxcall)

10
modem/command_test.py Normal file
View file

@ -0,0 +1,10 @@
from command import TxCommand
import codec2
class TestCommand(TxCommand):
def build_frame(self):
return self.frame_factory.build_test()
def get_tx_mode(self):
return codec2.FREEDV_MODE.datac13.value

View file

@ -76,3 +76,7 @@ class DataFrameFactory:
fec_frame[:1] = bytes([FR_TYPE.FEC.value])
fec_frame[1:payload_per_frame] = bytes(payload[:fec_payload_length])
return fec_frame
def build_test(self):
test_frame = bytearray(126)
test_frame[:1] = bytes([FR_TYPE.TEST_FRAME.value])

View file

@ -95,13 +95,6 @@ class DISPATCHER():
FR_TYPE.FEC_WAKEUP.value: (self.data_broadcasts.received_fec_wakeup, "FEC WAKEUP"),
}
self.command_dispatcher = {
# "CONNECT": (self.arq_session_handler, "CONNECT"),
"CQ": (self.broadcasts.transmit_cq, "CQ"),
"DISCONNECT": (self.arq_session.close_session, "DISCONNECT"),
"SEND_TEST_FRAME": (self.broadcasts.send_test_frame, "TEST"),
"STOP": (self.arq.stop_transmission, "STOP"),
}
def _initialize_queues(self):
"""Initializes data queues."""
@ -121,47 +114,6 @@ class DISPATCHER():
while True:
command = self.data_queue_transmit.get()
command.execute(self.event_queue, MODEM_TRANSMIT_QUEUE)
continue
# Dispatch commands known to command_dispatcher
if data[0] in self.command_dispatcher:
self.log.debug(f"[Modem] TX {self.command_dispatcher[data[0]][1]}...")
self.command_dispatcher[data[0]][0]()
# Dispatch commands that need more arguments.
elif data[0] == "CONNECT":
# [1] mycallsign
# [2] dxcallsign
self.arq.arq_session_handler(data[1], data[2])
elif data[0] == "PING":
# [1] mycallsign // this is being injected as None
# [2] dxcallsign
mycallsign = f"{self.config['STATION']['mycall']}-{self.config['STATION']['myssid']}"
self.ping.transmit_ping(mycallsign, data[2])
elif data[0] == "ARQ_RAW":
# [1] DATA_OUT bytes
# [2] self.transmission_uuid str
# [3] mycallsign with ssid str
# [4] dxcallsign with ssid str
self.arq_iss.open_dc_and_transmit(data[1], data[2], data[3], data[4])
elif data[0] == "FEC_IS_WRITING":
# [1] DATA_OUT bytes
# [2] MODE str datac0/1/3...
self.broadcasts.send_fec_is_writing(data[1])
elif data[0] == "FEC":
# [1] WAKEUP bool
# [2] MODE str datac0/1/3...
# [3] PAYLOAD
# [4] MYCALLSIGN
self.broadcasts.send_fec(data[1], data[2], data[3], data[4])
else:
self.log.error(
"[Modem] worker_transmit: received invalid command:", data=data
)
def worker_receive(self) -> None:
"""Queue received data for processing"""

View file

@ -6,14 +6,16 @@ import serial_ports
from config import CONFIG
import audio
import queue
import server_commands
import service_manager
import state_manager
import ujson as json
import websocket_manager as wsm
import api_validations as validations
from command import TxCommand
from command_ping import PingCommand
import command_ping
import command_cq
import command_ping
import command_feq
import command_test
from queues import DATA_QUEUE_TRANSMIT as tx_cmd_queue
app = Flask(__name__)
@ -125,9 +127,10 @@ def get_modem_state():
def post_cqcqcq():
if request.method not in ['POST']:
return api_response({"info": "endpoint for triggering a CQ via POST"})
if app.state_manager.is_modem_running:
server_commands.cqcqcq()
return api_response({"cmd": "cqcqcq"})
if not app.state_manager.is_modem_running:
api_abort('Modem not running', 503)
enqueue_tx_command(command_cq.CQCommand)
return "ok"
@app.route('/modem/beacon', methods=['POST'])
def post_beacon():
@ -147,32 +150,35 @@ def post_ping():
if not app.state_manager.is_modem_running:
api_abort('Modem not running', 503)
validate(request.json, 'dxcall', validations.validate_freedata_callsign)
enqueue_tx_command(PingCommand, request.json)
enqueue_tx_command(command_ping.PingCommand, request.json)
return 'ok'
@app.route('/modem/send_test_frame', methods=['POST'])
def post_send_test_frame():
if request.method not in ['POST']:
return api_response({"info": "endpoint for triggering a TEST_FRAME via POST"})
if app.state_manager.is_modem_running:
server_commands.modem_send_test_frame()
return api_response({"cmd": "test_frame"})
if not app.state_manager.is_modem_running:
api_abort('Modem not running', 503)
enqueue_tx_command(command_test.TestCommand)
return "ok"
@app.route('/modem/fec_transmit', methods=['POST'])
def post_send_fec_frame():
if request.method not in ['POST']:
return api_response({"info": "endpoint for triggering a FEC frame via POST"})
if app.state_manager.is_modem_running:
server_commands.modem_fec_transmit(request.json)
return api_response(request.json)
if not app.state_manager.is_modem_running:
api_abort('Modem not running', 503)
enqueue_tx_command(command_feq.FecCommand, request.json)
return "ok"
@app.route('/modem/fec_is_writing', methods=['POST'])
def post_send_fec_is_writing():
if request.method not in ['POST']:
return api_response({"info": "endpoint for triggering a IS WRITING frame via POST"})
if app.state_manager.is_modem_running:
server_commands.modem_fec_is_writing(request.json)
return api_response(request.json)
if not app.state_manager.is_modem_running:
api_abort('Modem not running', 503)
#server_commands.modem_fec_is_writing(request.json)
return 'Not implemented yet'
@app.route('/modem/start', methods=['POST'])
def post_modem_start():
@ -199,8 +205,11 @@ def get_modem_version():
def post_modem_send_raw():
if request.method not in ['POST']:
return api_response({"info": "endpoint for SENDING RAW DATA via POST"})
server_commands.modem_arq_send_raw(request.json)
return api_response(request.json)
if not app.state_manager.is_modem_running:
api_abort('Modem not running', 503)
# server_commands.modem_arq_send_raw(request.json)
return "Not implemented yet"
# @app.route('/modem/arq_connect', methods=['POST'])
# @app.route('/modem/arq_disconnect', methods=['POST'])

View file

@ -1,66 +0,0 @@
from queues import DATA_QUEUE_TRANSMIT
import base64
import structlog
import threading
from random import randrange
log = structlog.get_logger("COMMANDS")
def cqcqcq():
try:
DATA_QUEUE_TRANSMIT.put(["CQ"])
return
except Exception as err:
log.warning("[CMD] error while transmiting CQ", e=err)
def ping_ping(dxcall):
try:
DATA_QUEUE_TRANSMIT.put(["PING", None, dxcall])
except Exception as err:
log.warning(
"[CMD] PING command execution error", e=err
)
def modem_send_test_frame():
log.info(
"[CMD] Send test frame"
)
DATA_QUEUE_TRANSMIT.put(["SEND_TEST_FRAME"])
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 = payload
if len(base64data) % 4:
raise TypeError
binarydata = base64.b64decode(base64data)
DATA_QUEUE_TRANSMIT.put(
["ARQ_RAW", binarydata, arq_uuid, mycallsign, dxcallsign]
)
def modem_fec_transmit(mode, wakeup, base64data, mycallsign = None):
log.info(
"[CMD] Send fec frame"
)
if len(base64data) % 4:
raise TypeError
payload = base64.b64decode(base64data)
DATA_QUEUE_TRANSMIT.put(["FEC", mode, wakeup, payload, mycallsign])
def modem_fec_is_writing(mycallsign):
try:
DATA_QUEUE_TRANSMIT.put(["FEC_IS_WRITING", mycallsign])
except Exception as err:
log.warning(
"[SCK] Send fec frame command execution error",
e=err,
)