Merge pull request #690 from DJ2LS/dev-max-bandwidth

set maximum bandwidth
This commit is contained in:
DJ2LS 2024-03-24 14:17:30 -07:00 committed by GitHub
commit cb70ed8445
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 51 additions and 28 deletions

View file

@ -2,7 +2,7 @@
"name": "FreeDATA",
"description": "FreeDATA Client application for connecting to FreeDATA server",
"private": true,
"version": "0.14.4-alpha",
"version": "0.14.5-alpha",
"main": "dist-electron/main/index.js",
"scripts": {
"start": "vite",

View file

@ -165,20 +165,20 @@ const audioStore = useAudioStore();
</div>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Enable 250Hz bandwidth mode</label>
<label class="input-group-text w-50">
<div class="form-check form-switch form-check-inline">
<input
class="form-check-input"
type="checkbox"
id="250HzModeSwitch"
v-model="settings.remote.MODEM.enable_low_bandwidth_mode"
@change="onChange"
/>
<label class="form-check-label" for="250HzModeSwitch">250Hz</label>
</div>
</label>
<label class="input-group-text w-50">Maximum used bandwidth</label>
<select
class="form-select form-select-sm"
id="maximum_bandwidth"
@change="onChange"
v-model.number="settings.remote.MODEM.maximum_bandwidth"
>
<option value="250">250 Hz</option>
<option value="563">563 Hz</option>
<option value="1700">1700 Hz</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Respond to CQ</label>
<label class="input-group-text w-50">

View file

@ -54,11 +54,11 @@ const defaultConfig = {
enable_protocol: false,
},
MODEM: {
enable_low_bandwidth_mode: false,
respond_to_cq: false,
tx_delay: 0,
enable_hamc: false,
enable_morse_identifier: false,
maximum_bandwidth: 3000,
},
RADIO: {
control: "disabled",

View file

@ -16,16 +16,19 @@ class ARQSession:
'mode': codec2.FREEDV_MODE.datac4,
'min_snr': -10,
'duration_per_frame': 5.17,
'bandwidth': 250,
},
1: {
'mode': codec2.FREEDV_MODE.datac3,
'min_snr': 0,
'duration_per_frame': 3.19,
'bandwidth': 563,
},
2: {
'mode': codec2.FREEDV_MODE.datac1,
'min_snr': 3,
'duration_per_frame': 4.18,
'bandwidth': 1700,
},
}
@ -161,11 +164,20 @@ class ARQSession:
return stats
def get_appropriate_speed_level(self, snr):
# Start with the lowest speed level as default
# In case of a not fitting SNR, we return the lowest speed level
def get_appropriate_speed_level(self, snr, maximum_bandwidth=None):
if maximum_bandwidth is None:
maximum_bandwidth = self.config['MODEM']['maximum_bandwidth']
# Adjust maximum_bandwidth based on special conditions or invalid configurations
if maximum_bandwidth == 0:
# Use the maximum available bandwidth from the speed level dictionary
maximum_bandwidth = max(details['bandwidth'] for details in self.SPEED_LEVEL_DICT.values())
# Initialize appropriate_speed_level to the lowest level that meets the minimum criteria
appropriate_speed_level = min(self.SPEED_LEVEL_DICT.keys())
for level, details in self.SPEED_LEVEL_DICT.items():
if snr >= details['min_snr'] and level > appropriate_speed_level:
if snr >= details['min_snr'] and details['bandwidth'] <= maximum_bandwidth and level > appropriate_speed_level:
appropriate_speed_level = level
return appropriate_speed_level

View file

@ -76,6 +76,8 @@ class ARQSessionIRS(arq_session.ARQSession):
self.received_bytes = 0
self.received_crc = None
self.maximum_bandwidth = 0
self.abort = False
def all_data_received(self):
@ -98,6 +100,12 @@ class ARQSessionIRS(arq_session.ARQSession):
thread_wait.start()
def send_open_ack(self, open_frame):
self.maximum_bandwidth = open_frame['maximum_bandwidth']
# check for maximum bandwidth. If ISS bandwidth is higher than own, then use own
if open_frame['maximum_bandwidth'] > self.config['MODEM']['maximum_bandwidth']:
self.maximum_bandwidth = self.config['MODEM']['maximum_bandwidth']
self.event_manager.send_arq_session_new(
False, self.id, self.dxcall, 0, self.state.name)
ack_frame = self.frame_factory.build_arq_session_open_ack(
@ -211,7 +219,7 @@ class ARQSessionIRS(arq_session.ARQSession):
received_speed_level = 0
latest_snr = self.snr if self.snr else -10
appropriate_speed_level = self.get_appropriate_speed_level(latest_snr)
appropriate_speed_level = self.get_appropriate_speed_level(latest_snr, self.maximum_bandwidth)
modes_to_decode = {}
# Log the latest SNR, current, appropriate speed levels, and the previous speed level

View file

@ -104,9 +104,10 @@ class ARQSessionISS(arq_session.ARQSession):
twr.start()
def start(self):
maximum_bandwidth = self.config['MODEM']['maximum_bandwidth']
self.event_manager.send_arq_session_new(
True, self.id, self.dxcall, self.total_length, self.state.name)
session_open_frame = self.frame_factory.build_arq_session_open(self.dxcall, self.id)
session_open_frame = self.frame_factory.build_arq_session_open(self.dxcall, self.id, maximum_bandwidth)
self.launch_twr(session_open_frame, self.TIMEOUT_CONNECT_ACK, self.RETRIES_CONNECT, mode=FREEDV_MODE.signalling)
self.set_state(ISS_State.OPEN_SENT)

View file

@ -45,10 +45,10 @@ enable_protocol = False
[MODEM]
enable_hmac = False
enable_low_bandwidth_mode = False
enable_morse_identifier = False
respond_to_cq = True
tx_delay = 200
tx_delay = 50
maximum_bandwidth = 1700
[MESSAGES]
enable_auto_repeat = False

View file

@ -57,7 +57,7 @@ class CONFIG:
'MODEM': {
'enable_hmac': bool,
'enable_morse_identifier': bool,
'enable_low_bandwidth_mode': bool,
'maximum_bandwidth': int,
'respond_to_cq': bool,
'tx_delay': int
},

View file

@ -98,6 +98,7 @@ class DataFrameFactory:
"destination_crc": 3,
"origin": 6,
"session_id": 1,
"maximum_bandwidth": 2,
}
self.template_list[FR_TYPE.ARQ_SESSION_OPEN_ACK.value] = {
@ -219,7 +220,7 @@ class DataFrameFactory:
elif key in ["session_id", "speed_level",
"frames_per_burst", "version",
"offset", "total_length", "state", "type"]:
"offset", "total_length", "state", "type", "maximum_bandwidth"]:
extracted_data[key] = int.from_bytes(data, 'big')
elif key in ["snr"]:
@ -328,11 +329,12 @@ class DataFrameFactory:
test_frame[:1] = bytes([FR_TYPE.TEST_FRAME.value])
return test_frame
def build_arq_session_open(self, destination, session_id):
def build_arq_session_open(self, destination, session_id, maximum_bandwidth):
payload = {
"destination_crc": helpers.get_crc_24(destination),
"origin": helpers.callsign_to_bytes(self.myfullcall),
"session_id": session_id.to_bytes(1, 'big'),
"maximum_bandwidth": maximum_bandwidth.to_bytes(2, 'big'),
}
return self.construct(FR_TYPE.ARQ_SESSION_OPEN, payload)

View file

@ -33,7 +33,7 @@ from schedule_manager import ScheduleManager
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})
sock = Sock(app)
MODEM_VERSION = "0.14.4-alpha"
MODEM_VERSION = "0.14.5-alpha"
# set config file to use
def set_config():

View file

@ -32,7 +32,7 @@ class TestDataFrameFactory(unittest.TestCase):
def testARQConnect(self):
dxcall = "DJ2LS-4"
session_id = 123
frame = self.factory.build_arq_session_open(dxcall, session_id)
frame = self.factory.build_arq_session_open(dxcall, session_id, 1700)
frame_data = self.factory.deconstruct(frame)
self.assertEqual(frame_data['origin'], self.factory.myfullcall)