Sending MAC commands with the Application Server REST API

Hi all,

First, congratulations for ChirpStack, which is a great tool.

For testing purposes, I need to send MAC commands to my device.

I did not find a service dedicated to sending MAC commands, so I tried with the “/api/devices{device_queue_item.dev_eui}/queue” service, but when I put an fPort value of 0 (indicating a MAC commands payload), the call is rejected.

{
“error”: “f_port must be > 0”,
“code”: 3,
“message”: “f_port must be > 0”,
“details”: []
}

Am I missing something, or is there another service for this purpose ?

Thank you very much for your support.
Michel Kuenemann

@Michel_Kuenemann

As per the LoRaWAN specification, you cannot send MAC commands from the application server

1 Like

You can’t send downlink payloads from the application server either, but you can still queue them up there via API. :wink:

To answer the OP’s original question, since what you’re looking to do isn’t common enough to be exposed via the application server API, you may need to use the network server gRPC API:

https://www.chirpstack.io/network-server/integrate/api/

Note that some of the links there are broken, you want to look at the chirpstack-api respository.

3 Likes

Hi all,

Thanks a lot for your prompt response and valuable indications. I will dig into that right away.

Regards,
Michel.

Hi all,

I have installed the Chripstack gRPC api sucessfully and I am able to log to my Server thanks to the code example provided in the README.md file.

I am using Node.js

I have tested the createMACCommandQueueItem() service like this:

var grpc = require('grpc');
var networkServerService = require('@chirpstack/chirpstack-api/ns/ns_grpc_pb');
var networkServerServiceMessages = require('@chirpstack/chirpstack-api/ns/ns_pb');

const CSSIP = '192.168.1.4:8080';

const networkServerServiceClient = new networkServerService.NetworkServerServiceClient(
    CSSIP,
  grpc.credentials.createInsecure()
);

function main() 
{
       var dev = Buffer.from('8C192D70000700FF', 'hex');
        var list =  Buffer.from('06', 'hex');

        var jCmd =  {
              devEui: dev,
              cid: 6,
              commandsList: list
            };

         var macCmd = new networkServerServiceMessages.CreateMACCommandQueueItemRequest( jCmd);

          //console.log(macCmd);
          
          networkServerServiceClient.createMACCommandQueueItem( macCmd, (response) => {
          console.log(response);

        });
      }
}

main();

At run time I get the following error:

Error: 12 UNIMPLEMENTED: unknown service ns.NetworkServerService

What is wrong in my code ?

Thank you for your help.

Michel

@Michel_Kuenemann

Follow below URL for NodeJS chirpstack-api API

Hello Sagarpatel and others,

I am now able to prepare a MAC command request, but when I call the createMACCommandQueueItem() service, I get the following error:

details: 'lorawan: 1 byte of data is expected'

My question is:

Which action do I have to perform to avoid this error ?

Thank you

Michel

Hi all,

I am still stucked with the following error when I call createMACCommandQueueItem()

Error: 3 INVALID_ARGUMENT: lorawan: 1 byte of data is expected

I prepare the message this way:

     let devEUI = new Uint8Array( [ 0x8C, 0x19, 0x2D, 0x70, 0x00, 0x07, 0x00, 0xFF]);

     let macCmd = new nsm.CreateMACCommandQueueItemRequest();

    let cmd1 = new Uint8Array([ 1, 2, 3]);
    cList = [ cmd1];        
        
    macCmd.setDevEui( devEUI);
    macCmd.setCid( 1);
    macCmd.setCommandsList( cList);
   
    nsc.createMACCommandQueueItem( macCmd, ( err, res) => { 
        if( !err)
        {
            console.log( 'createMACCommandQueueItem result : ', res); 
            callback( null);
        }
        else
        {
            console.log( 'createMACCommandQueueItem ERROR details: ', err.details);
            callback( err);
        }
    });  

I am getting desperate - What am I missing ?

@brocaar @sagarpatel, please help

Thanks in advance for your help

Michel

@Michel_Kuenemann

As per the command id you are sending below command
ResetInd

Please follow below specification for ResetInd command

Hi all,

Thanks a lot for your advice. It works perfectly now
My new code:

    let macCmd = new nsm.CreateMACCommandQueueItemRequest();

    let devStatusReq = new Uint8Array([ 0x06]);
    let linkAdrReq = new Uint8Array([ 0x03, 0x57, 0xFF, 0x00, 0x01]);

    cList = [ devStatusReq, linkAdrReq, devStatusReq];     
        
    macCmd.setDevEui( devEUI);  
    macCmd.setCid( 1);  
    macCmd.setCommandsList( cList); 
   
    nsc.createMACCommandQueueItem( macCmd, ( err, res) => { 

My device receives this:

Regards,
Michel

1 Like

Hi all,

I have issues in figuring out the meaning of the “cid” field of the createMACCommandQueueItem method input parameters :

I guess that “cid” should be the id of the MAC command to send, but as I send several commands, which value should I put in cid ?

linkAdrReq = new Uint8Array([ 0x03, 0x57, 0xFF, 0x00, 0x01]);
rxTimingSetupReq = new Uint8Array([ 0x08, 0x02]);
rxParamSetupReq = new Uint8Array([ 0x05, 0x05, 0x18, 0x4F, 0x84]);

cList = [ linkAdrReq, rxParamSetupReq, devStatusReq];  

macCmd.setCommandsList( cList); 
macCmd.setDevEui( devEUI);  
macCmd.setCid( ???);  // Which value here ?

nsc.createMACCommandQueueItem( macCmd, ( err, res) => { .... });

Thank you for your help

Michel

you need to put all the CID because CID is command identifier or use for loop for several commands

Thanks a lot for your (very) fast reply.

I don’t understand the relationship between the commands list and the cid:

The commands list is an array of arrays
The cid is a scalar (single number)

Please give me an example of for loop with, 2 or commands.

Thanks a lot for you support
Michel

Hi Michel,
I am also trying to learn how to send MAC commands for manual ADR,
Would you be able to post your complete working script please?
Best Wishes
Patrick

Hello,

I got this error when I am assigning MAC commands to the field commands
“Assignment not allowed to repeated field “commands” in protocol message object”
This is my code.

import grpc
from chirpstack_api.ns import NetworkServerServiceStub
from chirpstack_api.ns.ns_pb2 import CreateMACCommandQueueItemRequest

host = "localhost:8000"


channel = grpc.insecure_channel(host)

ns = NetworkServerServiceStub(channel)

macCmd = CreateMACCommandQueueItemRequest()


devStatusReq = bytes.fromhex("06")

linkAdrReq = bytes.fromhex("0357FF0001")
devEUI = "deadbeefdead0001"

# cList = [devStatusReq, linkAdrReq, devStatusReq]


cList = [linkAdrReq]
macCmd.dev_eui = bytes.fromhex(devEUI)
macCmd.cid = 3
macCmd.commands = cList
print(macCmd.dev_eui)
ns.CreateMACCommandQueueItem(macCmd)

help @Michel_Kuenemann @bconway @brocaar

Hello Michel,
Did you able to write the for loop with 2 commands. I am also stuck here. I would be grateful if you can help me on this.