Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multicast Fail with RAK3372 #16

Open
dev-sce opened this issue Oct 6, 2024 · 10 comments
Open

Multicast Fail with RAK3372 #16

dev-sce opened this issue Oct 6, 2024 · 10 comments

Comments

@dev-sce
Copy link

dev-sce commented Oct 6, 2024

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.

@IoTThinks
Copy link

@dev-sce
I have the same issue with RAK3172 and ChirpStack too.

After I add this line "service_lora_clear_multicast();"
I have this success
image

Do you see anything here in ChirpStack?
Should I expect the node to add itself here after joining multicast group in the code, right?
image

I trigger the sending to the multicast group.
ChirpStack replies OK. But nothing is in the gateway frames.
https://xyx.com/api/multicast-groups/xxxxxxc9-04e2-446d-8bc1-f85e1b1a1730/queue
image

I added the callback but can not see anything in the console too.
image

image

@IoTThinks
Copy link

IoTThinks commented Nov 5, 2024

Are you able to receive any multicast with RAK3172 and Chirpstack?


And why McGroupID is 2?
Can it be 0 or 1 or 2 or 3?
I read it can be 0 to 3.

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,
};

In ChirpStack, Multicast group is a string instead of 0 to 3.
Is the something incompatible here?
image

Thanks a lot for any advice.

@IoTThinks
Copy link

I managed to use the default LoRaWAN_OTAA example.
https://github.com/RAKWireless/RAK-STM32-RUI/tree/main/libraries/RUI_V3_examples/examples/Example/LoRaWan_OTAA

Then I added the device to Multicast group using ChirpStack API.
Then I added the message to Multicast group using ChirpStack API.

The LoRaWAN_OTAA example can receive the downlink in Base64.
I think it is better to use server to add devices to multicast group.

So I will skip this issue in RAK code.

@IoTThinks
Copy link

IoTThinks commented Nov 10, 2024

Correction.

  1. After doing a full chip erase, I need to use the code in Multicast example to receive the Multicast downlink.
    Else I can not receive the Multicast downlink at node.
    https://github.com/RAKWireless/RAK-STM32-RUI/tree/main/libraries/RUI_V3_examples/examples/Example/LoRaWan_Multicast

After that it seems RAK will save the Multicast session in flash.
This multicast session will still be kept even after Upload new firmware in Arduino IDE.
That explains this comment: #16 (comment)

Conclusion, we will need the code to join multicast in Arduino code for RAK module.

  1. At the beginning, I also hit Add Multicast Fail.
    After, after a full chip erase by STM32CubeProgrammer and comment out this added line
    image

I still can not reproduce the "Add Multicast Fail" issue again. Weird.
image

Conclusion: this "service_lora_clear_multicast();" fixes this issue the very first time the RAK module join multicast.

@IoTThinks
Copy link

Update.
Full Erase Chip using STM32CubeProgrammer and change Group ID in LoRaWAN_Multicast example will trigger "Add Multicast Fail".

And the fix by @dev-sce works.

@IoTThinks
Copy link

Setting the Multicast key using AT command works perfectly.
No idea why there is different behavior with api.lorawan.addmulc(session)
AT+ADDMULC=C:xxxxxxxx:xxxxxx89848A2A66DA3FF0751E6A66:xxxxxx8C624E2BB88C019F6B9CC295:921400000:02:0

@dev-sce
Copy link
Author

dev-sce commented Nov 10, 2024

Unfortunately, I haven't had the time this week to work on this subject. I'll be working on it again at the end of next week.

Setting the Multicast key using AT command is a good idea.

Switching to multicast with api.lorawan.addmulc works on rare occasions for me too. I suspect it's linked to the uninitialised variable as explained in my first post, which might explain why it only works in rare cases.

In my case, even with my fix, I can't get any multicast data from ChirpStack to the devices. Unfortunately, I haven't made any progress on this point. Maybe in the second half of next week. If I understand correctly, you did manage to multicast data to a device. Are you sure it was multicast as in my discussion? If so, I'd like to know how.

Concerning the McGroupID, I don't think it matters and it was on 2 as in the previous example from the RAK forum.

@IoTThinks
Copy link

Yes, I managed to receive multicast downlink.
image

For McGroupID, It is 0, 1, 2 and 3.
A node can have up to 4 multicast groups.

In RAK, McGroupID is array index of the multicast group array.
AT+LSTMULC=?
C:0187D93F:D099ECA789848A2A66DA3FF0751E6A66:7D28EE2F8C624E2BB88C019F6B9CC295:921400000:02:0,
0:00000000:00000000000000000000000000000000:00000000000000000000000000000000:000000000:00:0,
0:00000000:00000000000000000000000000000000:00000000000000000000000000000000:000000000:00:0,
0:00000000:00000000000000000000000000000000:00000000000000000000000000000000:000000000:00:0

@IoTThinks
Copy link

Unfortunately, I haven't had the time this week to work on this subject. I'll be working on it again at the end of next week.

Setting the Multicast key using AT command is a good idea.

Hope it helps you during your debugging.
BTW, I still want your fix to addmulc to dynamically receive and set multicast address and keys from unitcast downlink.

https://iotthinks.com/create-lorawan-multicast-group-and-send-multicast-downlink/
and
https://iotthinks.com/configure-rak-module-to-join-multicast-group/

@dev-sce
Copy link
Author

dev-sce commented Nov 18, 2024

I did some tests at the end of last week and I can confirm that using the AT commands (AT+ADDMULC) works fine and that using the RAK API (api.lorawan.addmulc) does not work.

I've finally been able to switch to multicast with your help @IoTThinks, and I'd like to thank you for it.

However, I still can't achieve multicasting in B mode, but the problem seems to lie in the fact that our Lorawan gateway (RAK2287) doesn't have GPS. We ordered the version with GPS input to test B-mode multicasting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants