Skip to content

Multicast Fail with RAK3372 #16

@dev-sce

Description

@dev-sce

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions