No morsectrl for Halowlink1?

Is there no morsectrl for the halowlink1?

I checked on the version it came with and just updated to 2.7.6 and not seeing it on either.

need this to configure mcs and txrate.
if there is not morsectrl is there another way to modify mcs and get full control with morsectrl txrate as I have in the ekh03:

```
root@EKH03–05US-67f605:~# morsectrl txrate --help

txrate {enable|disable} \[-m {-1|0-10}\] \[-b {1|2|4|8|-1}\] \[-f {-1|\[0-2\]}\]

        \[-t {-1|\[0-1\]}\] \[-s {-1|\[0-1\]}\] \[-n {-1|\[0-4\]}\] \[-l {-1|\[0-1\]}\]

        \[-c {-1|\[0-1\]}\]

    Fix packet transmission rate parameters in firmware

    {enable|disable}              Enable/disable fixed transmission rate parameters

    -m {-1|0-10}                  MCS index (0-10) or -1 for default

    -b {1|2|4|8|-1}               TX bandwidth in MHz, or -1 for default

    -f {-1|\[0-2\]}                 Duplicate format (0, 1, 2) or -1 to use default

    -t {-1|\[0-1\]}                 Traveling pilots (0, 1) or -1 to use default

    -s {-1|\[0-1\]}                 Short guard interval (0, 1) or -1 to use default

    -n {-1|\[0-4\]}                 Spatial streams (1-4) or -1 to use default

    -l {-1|\[0-1\]}                 LDPC (0, 1) or -1 to use default

    -c {-1|\[0-1\]}                 STBC (0, 1) or -1 to use default

```

Hi @Luisschubert

Unfortunately we don’t release morsectrl with the HaLowLink1 as it is more suited to evaluation/development kits rather than “end products”.

The morsectrl source is also not available publicly as it does offer specific control of the radio.

You are welcome to head to Download Dashboard and register for an account there. Afterwards email support@morsemicro.com to request access to the morsectrl source.

I am curious as to why you want to set the MCS and Tx rate manually. Normally this should not be required.

FWIW: the EKH03 and HalowLink1 are identical architectures…

I have found that I can get better throughput when I fix the mcs than when I leave it on auto.
As far as I can tell I can’t fix the MCS across boots or from the UI. So I have been using morsectrl to do that.

I have not used txrate to do this yet, but was planning on testing that as well.

Do you have any recommendations on what I should do instead?

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"

I have found that I can get better throughput when I fix the mcs than when I leave it on auto.

Hm, that’s interesting and definitely not expected. Rate control should pick the best rate for throughput and packet error rate. I do note in your other comment that your reported signal level is -15. Do you find you still have to fix the rate when you move the devices such that the reported signal strength is ~-30dBm or lower?

Do you have any recommendations on what I should do instead?

If you can share more information on the environment + capture the mmrc rate table at /sys/kernel/debug/ieee80211/phy/mmrc_rate_table, that would be helpful in identifying why rate control isn’t performing as it should. Capturing mmrc_rate_table over time (say, every second for several seconds) would also be helpful

well I just did the naive thing of copying over morsectrl from an ekh03 device

:wink:

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.

ubus to iwinfo is what we typically recommend (as you have done in your script. Note that OpenWrt does support ubus over http. See https://openwrt.org/docs/techref/ubus#access_to_ubus_over_http, so depending on your application requirements you might prefer this.There is no ubus front end for morse_cli - though that wouldn’t necessarily be difficult to add, see https://openwrt.org/docs/techref/rpcd (edited)