-
Notifications
You must be signed in to change notification settings - Fork 22
Description
This ticket follows a discussion I had on the RAKwireless forum.
There seems to be a problem with the RUI3 API for switching to multicast mode, using the example Lorawan_Multicast project below:
void setup() {
Serial.begin(115200);
#define OTAA_BAND (RAK_REGION_EU868)
// OTAA Device EUI MSB
uint8_t node_device_eui[8] = { 0x50, 0x59, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01 };
// OTAA Application EUI MSB
uint8_t node_app_eui[8] = { 0x0E, 0x0D, 0x0D, 0x01, 0x0E, 0x01, 0x02, 0x0E };
// OTAA Application Key MSB
uint8_t node_app_key[16] = { 0x45, 0x53, 0x43, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x4e, 0x61, 0x69, 0x61, 0x14, 0x17 };
//LoRaWan Multicast Session
uint8_t node_mc_address[4] = { 0x01, 0x02, 0x03, 0x04 };
uint8_t node_mc_AppSKey[16] = { 0x45, 0x53, 0x43, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x4e, 0x61, 0x69, 0x61, 0x14, 0x17 };
uint8_t node_mc_NwkSKey[16] = { 0x45, 0x53, 0x43, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x4e, 0x61, 0x69, 0x61, 0x14, 0x17 };
RAK_LORA_McSession session = {
.McDevclass = 2,
.McAddress = node_mc_address[0] << 24 | node_mc_address[1] << 16 | node_mc_address[2] << 8 | node_mc_address[3],
.McFrequency = 869525000,
.McDatarate = 0,
.McPeriodicity = 0,
.McGroupID = 2,
.entry = 0,
};
memcpy(session.McAppSKey, node_mc_AppSKey, 16);
memcpy(session.McNwkSKey, node_mc_NwkSKey, 16);
api.lorawan.appeui.set(node_app_eui, 8);
api.lorawan.appkey.set(node_app_key, 16);
api.lorawan.deui.set(node_device_eui, 8);
api.lorawan.band.set(OTAA_BAND);
api.lorawan.njm.set(1);
api.lorawan.deviceClass.set(RAK_LORA_CLASS_C);
api.lorawan.join();
//Wait for Join success
while (api.lorawan.njs.get() == 0) {
Serial.print("Waiting for Lorawan join…\r\n");
api.lorawan.join();
delay(10000);
}
// Get device address
api.lorawan.daddr.get(node_mc_address, 4);
Serial.printf("Device Address is % 02X % 02X % 02X % 02X\r\n", node_mc_address[0], node_mc_address[1], node_mc_address[2], node_mc_address[3]); // Check Device Address
// Add address to MC session
session.McAddress = node_mc_address[0] << 24 | node_mc_address[1] << 16 | node_mc_address[2] << 8 | node_mc_address[3];
Serial.printf("Session McAddress is % X\r\n", session.McAddress); // Check Device Address
api.lorawan.adr.set(true);
api.lorawan.rety.set(1);
api.lorawan.cfm.set(1);
//LoRaWAN Multicast Setting
if (api.lorawan.addmulc(session) == true) {
Serial.println("Add Multicast Success");
} else {
Serial.println("Add Multicast Fail");
}
}
void loop() {
}
I get the following result:
Waiting for Lorawan join…
+EVT:JOINED
Device Address is 01 D1 F1 25
Session McAddress is 1D1F125
Add Multicast Fail
Current Work Mode: LoRaWAN.
I’ve found a workaround that allows me to switch to multicast. However, this solution makes me think that there may be a bug in the RAK3172 API.
I debugged the program to find out what was going wrong and I realised that the problem was with the ‘service_lora_addmulc’ function called when the ‘api.lorawan.addmulc’ function was called.
I noticed that the function iterates over the McSession_group to find one with an address of 0 (*1). However, in my case, none of them is 0, and so I end up with the error ‘UDRV_PARAM_ERR’ (*2).
int32_t service_lora_addmulc(McSession_t McSession)
{
LoRaMacStatus_t lorastatus;
uint8_t i, j;
McChannelParams_t channel;
uint8_t status = 0x00;
for (i = 0; i < 4; i++)
{
if (McSession.Address == McSession_group[i].Address)
return -UDRV_PARAM_ERR;
}
for (i = 0; i < 4; i++)
{
if (McSession_group[i].Address == 0) (*1)
{
…
}
}
if (i == 4)
{
memset(&McSession_group[i], 0, sizeof(McSession_t));
return -UDRV_PARAM_ERR; (*2)
}
return UDRV_RETURN_OK;
}
I suspect that this involves the use of an uninitialised variable ‘McSession_t McSession_group[LORAMAC_MAX_MC_CTX];’. This structure can be initialised via the ‘service_lora_clear_multicast’ or ‘service_lora_rmvmulc’ functions, but these are never called in the example code.
I therefore modified the ‘api.lorawan.addmulc’ function to add the initialisation of the ‘McSession_group’ variable at the start of the call:
//Multicast
bool RAKLorawan::addmulc(RAK_LORA_McSession session) {
if (SERVICE_LORAWAN != service_lora_get_nwm())
{
return false;
}
service_lora_clear_multicast(); // Added by Me
//create McSession_t instance
McSession_t McSession;
McSession.Devclass = session.McDevclass;
McSession.Address = session.McAddress;
memcpy(McSession.McAppSKey, session.McAppSKey, 16);
memcpy(McSession.McNwkSKey, session.McNwkSKey, 16);
McSession.Frequency = session.McFrequency;
McSession.Datarate = session.McDatarate;
McSession.Periodicity = session.McPeriodicity;
McSession.GroupID = session.McGroupID;
if (service_lora_addmulc(McSession) == UDRV_RETURN_OK) {
return true;
} else {
return false;
}
}
This allows me to connect in multicast mode.