Sending multiple MAC command

Hi,
I am trying to reproduce an issue that was found on another network server using chirpstack. The issue was on a variation of AU915 while the one I tried to reproduce on is EU868, it is not ideal but that is what I can use right now.

One of the sequences on the issue was the server sends these MAC commands in one frame:

  • 3 LinkADRReq
  • 1 DutyCycleReq
  • 1 RXParamSetupReq

I can separately send those group of MAC commands using the python chirpstack grpc network server API.

...
cmd_pack = ... # prepare command payload
mac_cmd = ns_pb2.CreateMACCommandQueueItemRequest()
mac_cmd.dev_eui = dev_eui
mac_cmd.cid = 0x03
for bt in list(cmd_pack):
    mac_cmd.commands.append(bt.to_bytes(1, 'little'))
response = stub.CreateMACCommandQueueItem(mac_cmd)

However, I found problems when I tried to send the following commands in one frame:

  1. Send 3 LinkADRReq + 1 DutyCycleReq
    Results in:
panic: interface conversion: lorawan.MACCommandPayload is *lorawan.DutyCycleReqPayload, not *lorawan.LinkADRReqPayload
  1. Send 3 LinkADRReq + 1 RXParamSetupReq
    Results in:
panic: interface conversion: lorawan.MACCommandPayload is *lorawan.RXParamSetupReqPayload, not *lorawan.LinkADRReqPayload
  1. Send 3 LinkADRReq
    This one works fine, i.e. the device and server continue to work after the command is sent.

  2. Send 1 RXParamSetupReq + 1 DutyCycleReq
    This one works fine, i.e. the device and server continue to work after the command is sent. Here I still set the cid of CreateMACCommandQueueItem to 0x03 (LinkADRReq)

So my questions are:

  1. Is it correct that the cid parameter of CreateMACCommandQueueItem can be LinkADRReq while the payload contains different MAC commands (with their cid specified in the commands)?
  2. Could the panic issue from the network server that I encounter be specific for the EU868 that I currently use?

Currently, I am deploying the server by using chirpstack-docker from commit hash: 2c9ee5e.

Thanks,
Zul

These are the snippets of how I prepare the dummy commands

def createLinkADRReq():
    """ LinkADRReq """
    cid = 0x03
    datarate = 5
    tx_power = 6
    channel_mask = 0x00EF
    redundancy = 2

    cmd = pack("<BBHB", cid, ((datarate << 4) + tx_power),
               channel_mask, redundancy)

    return cmd


def createDutyCycleReq():
    """ DutyCycleReq """
    cid = 0x04
    max_duty_cycle = 0
    cmd = pack("<BB", cid, max_duty_cycle)

    return cmd


def createRXParamSetupReq():
    """ RXParamSetupReq """
    cid = 0x05
    rfu = 0
    rx1_dr_offset = 1  # 3 bits
    rx2_datarate = 0  # 4 bits
    dl_settings = (rfu << 7) + (rx1_dr_offset << 4) + rx2_datarate
    frequency = 8683000  # 24 bits signed, in 100 Hz

    cmd = pack("<BBBH", cid, dl_settings,
               (frequency >> 16), (frequency & 0xFFFF))

    return cmd

cmd_pack = []
cmd_pack += createLinkADRReq()
cmd_pack += createLinkADRReq()
cmd_pack += createLinkADRReq()
cmd_pack += createDutyCycleReq()
cmd_pack += createRXParamSetupReq()

Please note that manually sending mac-commands is not recommended. This feature was added a long time ago, but other than experimentation, it has no use.

ChirpStack sends mac-commands when it detects that device settings are out-of-sync with the NS settings. If you are manually sending mac-commands, then this does not change the NS state. E.g. when you manually try to change the RX2 parameters of your device with your own mac-commands, then this doesn’t update the NS side.

If you want to customize ADR, then look into the ADR plugin feature. For the other mac-commands, it should be sufficient to change the chirpstack-network-server.toml config to update the device configuration through mac-commands.

2 Likes