well I just did the naive thing of copying over morsectrl from an ekh03 device running version 2.7.2 onto a halowlink running 2.7.6 and I seem to be able to at least run morsectrl, no guarantees I guess on if it fully works.
also copied it onto a halow link running 2.6.13 where it did not run.
BusyBox v1.36.1 (2024-12-24 23:27:45 UTC) built-in shell (ash)
__ __ __ __ _
| \/ | ___ _ __ ___ ___ | \/ (_) ___ _ __ ___
| |\/| |/ _ \| '__/ __|/ _ \ | |\/| | |/ __| '__/ _ \
| | | | (_) | | \__ \ __/ | | | | | (__| | | (_) |
|_| |_|\___/|_| |___/\___| |_| |_|_|\___|_| \___/
---------------------------------------------------------
OpenWrt 23.05.3, Morse-2.6.13
---------------------------------------------------------
root@halowlink1-4d7b:~# morsectrl mcs 4
Error loading shared library libusb-1.0.so.0: No such file or directory (needed by /sbin/morsectrl)
Error relocating /sbin/morsectrl: libusb_claim_interface: symbol not found
Error relocating /sbin/morsectrl: libusb_bulk_transfer: symbol not found
Error relocating /sbin/morsectrl: libusb_get_device_descriptor: symbol not found
Error relocating /sbin/morsectrl: libusb_free_device_list: symbol not found
Error relocating /sbin/morsectrl: libusb_get_device_list: symbol not found
Error relocating /sbin/morsectrl: libusb_open_device_with_vid_pid: symbol not found
Error relocating /sbin/morsectrl: libusb_exit: symbol not found
Error relocating /sbin/morsectrl: libusb_init: symbol not found
Error relocating /sbin/morsectrl: libusb_close: symbol not found
updating that one to 2.7.6 and testing again.
That seems to work.
root@halowlink1-4d7b:~# morsectrl mcs --help
mcs {auto|0-10}
Set MCS mode
{auto|0-10} MCS rate (0-10) or 'auto' for automatic rate control
root@halowlink1-4d7b:~#
┌─Interface─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│wlan0 - IEEE 802.11ah , phy 2, reg: US , SSID: halowlink1-42ff │
├─Levels────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ │
│link quality: 100% (70/70) │
│===================================================================================================================│
│ │
│ │
│signal level: -15 dBm (0.03 mW) │
│============================================================================================================ │
│ │
├─Packet Counts─────────────────────────────────────────────────────────────────────────────────────────────────────┤
│RX: 5k (891.18 KiB), drop: 6 (0.11%) │
│TX: 5k (2.13 MiB), retries: 44 (0.85%) │
├─Info──────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│mode: Managed, connected to: 94:BB:43:DC:F6:22, time: 2:44m, inactive: 0ms │
│freq: 916.0 MHz, channel: 28 (width: 8 MHz), bands: 1 │
│station flags: WME MFP, preamble: short, slot: short │
│rx rate: 19.500 Mbits/s MCS 4 short GI │
│tx rate: 19.500 Mbits/s MCS 4 short GI │
│tx power: 21 dBm (125.89 mW), power save: on │
│retry short/long: 7/4, rts/cts: 1000, frag: off │
├─Network───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│wlan0 #16 (UP RUNNING BROADCAST MULTICAST) │
│mode: dormant, qdisc: mq, txq: 4, qlen: 1000 │
│mac: 94:83:C4:67:4D:7C │
│ip4: n/a │
│ip6: n/a │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
as an aside what is the best way to collect link statistics from the device(s). I’m thinking mcs, shortgi/longgi, bandwidth, datarates that don’t involve using the web ui.
in the past I’ve run this log_connnection_stats.py
on a device connected over ethernet to the ap
import os
import subprocess
import json
import time
from datetime import datetime
SSH_USER = "root"
ip = "192.168.1.1"
def fetch_and_log(session_log_dir):
try:
# SSH command to fetch JSON data
command = f"ssh {SSH_USER}@{ip} \"ubus call iwinfo assoclist '{{\\\"device\\\": \\\"wlan0\\\"}}'\""
output = subprocess.check_output(command, shell=True, text=True)
# Parse the JSON output
parsed_data = json.loads(output)
associated_devices = parsed_data.get("results", [])
command2 = f"ssh {SSH_USER}@{ip} /root/extract_morse_cli_stats.sh"
output2 = subprocess.check_output(command2, shell=True, text=True)
parsed_data2 = json.loads(output2)
# print(parsed_data2)
# Current timestamp for log entries
timestamp = datetime.now().isoformat()
log_file2 = os.path.join(session_log_dir, f"ap_stats.log")
with open(log_file2, "a") as log2:
log_entry = {
"timestamp": timestamp,
"stats": parsed_data2,
}
log2.write(json.dumps(log_entry) + "\n")
# Process each device
for device in associated_devices:
mac_address = device["mac"].replace(":", "_") # Replace colons in MAC
log_file = os.path.join(session_log_dir, f"{mac_address}.log")
# Create or append to the log file
with open(log_file, "a") as log:
log_entry = {
"timestamp": timestamp,
"signal": device["signal"],
"noise": device["noise"],
"signal_avg": device["signal_avg"],
"connected_time": device["connected_time"],
"rx": device["rx"],
"tx": device["tx"]
}
log.write(json.dumps(log_entry) + "\n") # Write entry as JSON
print(f"Logged data for {mac_address} to {log_file}")
except subprocess.CalledProcessError as e:
print(f"Error executing SSH command: {e}")
except json.JSONDecodeError as e:
print(f"Error parsing JSON output: {e}")
# Main program
if __name__ == "__main__":
base_log_dir = "connection_logs" # Root directory for logs
os.makedirs(base_log_dir, exist_ok=True) # Ensure the base directory exists
# Create a timestamped session directory
timestamp = datetime.now().isoformat()
session_log_dir = os.path.join(base_log_dir, timestamp)
os.makedirs(session_log_dir, exist_ok=True)
while True:
fetch_and_log(session_log_dir)
time.sleep(1) # Wait 1 second before the next run
extract_morse_cli_stats.sh
#!/bin/ash
morse_cli -i wlan0 stats -j -f "Current RF frequency Hz\|Current Operating BW MHz\|Current Primary Channel BW MHz\|AGC Gain\|AGC LNA Status\|AGC FEM Rx Gain\|AGC LNA Bypass\|AGC Interference Detected\|Received Power\|Detected Channel BW\|Noise dBm\|NB INTRF Num\|NB INTRF SIR dB\|RX Total\|TX Total"