The provided LmhpRemoteMcastSetup.c/h
package implements the protocol to remotely create multicast channels defined by the LoRa-Alliance.
Please find specification document at following link https://lora-alliance.org/wp-content/uploads/2020/11/remote_multicast_setup_v1.0.0.pdf
As I understand you would like to create the multicast channels locally once for all.
The MAC layer provides the following API to manage the multicast channels:
/*!
* \brief LoRaMAC multicast channel setup service
*
* \details Sets up a multicast channel.
*
* \param [IN] channel - Multicast channel to set.
*
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
* \ref LORAMAC_STATUS_OK,
* \ref LORAMAC_STATUS_BUSY,
* \ref LORAMAC_STATUS_PARAMETER_INVALID,
* \ref LORAMAC_STATUS_MC_GROUP_UNDEFINED.
*/
LoRaMacStatus_t LoRaMacMcChannelSetup( McChannelParams_t *channel );
/*!
* \brief LoRaMAC multicast channel removal service
*
* \details Removes/Disables a multicast channel.
*
* \param [IN] groupID - Multicast channel ID to be removed/disabled
*
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
* \ref LORAMAC_STATUS_OK,
* \ref LORAMAC_STATUS_BUSY,
* \ref LORAMAC_STATUS_MC_GROUP_UNDEFINED.
*/
LoRaMacStatus_t LoRaMacMcChannelDelete( AddressIdentifier_t groupID );
/*!
* \brief LoRaMAC multicast channel get groupId from MC address.
*
* \param [IN] mcAddress - Multicast address to be checked
*
* \retval groupID Multicast channel ID associated to the address.
* Returns 0xFF if the address isn't found.
*/
uint8_t LoRaMacMcChannelGetGroupId( uint32_t mcAddress );
/*!
* \brief LoRaMAC multicast channel Rx parameters setup service
*
* \details Sets up a multicast channel reception parameters.
*
* \param [IN] groupID - Multicast channel ID
* \param [IN] rxParams - Reception parameters
* \param [OUT] status - Status mask [UNDEF_ID | FREQ_ERR | DR_ERR | GROUP_ID]
*
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
* \ref LORAMAC_STATUS_OK,
* \ref LORAMAC_STATUS_BUSY,
* \ref LORAMAC_STATUS_PARAMETER_INVALID,
* \ref LORAMAC_STATUS_MC_GROUP_UNDEFINED.
*/
LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRxParams_t *rxParams, uint8_t *status );
Looking at the LmhpRemoteMcastSetup.c/h
package you can see an example on how these APIs can be used.
Some time ago the LoRaMac-node project provided an example on how to locally create a Class B multicast channel. You may refer and adapt it to your needs. The example can be found at following link http://stackforce.github.io/LoRaMac-doc/LoRaMac-doc-v4.4.5/class_b_2_nucleo_l476_2main_8c-example.html. It has to be noted that the APIs may have been updated since then.
The required steps are:
- After calling
LoRaMacInitialization
API add something similar to the bellow code.
The below example uses default unicast keys as simplification. However it is recommended to use a different set of keys for multicast channels.
#if ( LOCAL_MULTICAST_SETUP_ENABLED == 1 )
// Initialize local Multicast Channel
// Multicast session keys
uint8_t localMcAppSKey[] = LORAWAN_APP_S_KEY;
uint8_t localMcNwkSKey[] = LORAWAN_NWK_S_ENC_KEY;
uint32_t localMcAddress = 0x01020304;
// AS923, AU915, CN470, CN779, EU433, EU868, KR920, IN865, US915, RU864
#if( LOCAL_MULTICAST_SETUP_DISABLE_SLOT_HOP == 1 )
const uint32_t frequencies[] = { 923200000, 923300000, 505300000, 786000000, 434665000, 869525000, 921900000, 866550000, 923300000, 869100000 };
#else
const uint32_t frequencies[] = { 923200000, 0 , 0, 786000000, 434665000, 869525000, 921900000, 866550000, 0, 69100000 };
#endif
const int8_t dataRates[] = { DR_2, DR_2, DR_0, DR_0, DR_0, DR_0, DR_0, DR_0, DR_0, DR_0 };
McChannelParams_t channel =
{
.IsRemotelySetup = false,
.Class = CLASS_B,
.IsEnabled = true,
.GroupID = MULTICAST_0_ADDR,
.Address = localMcAddress,
.McKeys =
{
.Session =
{
.McAppSKey = localMcAppSKey,
.McNwkSKey = localMcNwkSKey,
},
},
.FCountMin = 0,
.FCountMax = UINT32_MAX,
.RxParams.ClassB =
{
.Frequency = frequencies[ACTIVE_REGION],
.Datarate = dataRates[ACTIVE_REGION],
.Periodicity = REGION_COMMON_DEFAULT_PING_SLOT_PERIODICITY,
}
};
status = LoRaMacMcChannelSetup( &channel );
if( status == LORAMAC_STATUS_OK )
{
uint8_t mcChannelSetupStatus = 0x00;
if( LoRaMacMcChannelSetupRxParams( channel.GroupID, &channel.RxParams, &mcChannelSetupStatus ) == LORAMAC_STATUS_OK )
{
if( ( mcChannelSetupStatus & 0xFC ) == 0x00 )
{
printf("MC #%d setup, OK\n", ( mcChannelSetupStatus & 0x03 ) );
}
else
{
printf("MC #%d setup, ERROR - ", ( mcChannelSetupStatus & 0x03 ) );
if( ( mcChannelSetupStatus & 0x10 ) == 0x10 )
{
printf("MC group UNDEFINED - ");
}
else
{
printf("MC group OK - ");
}
if( ( mcChannelSetupStatus & 0x08 ) == 0x08 )
{
printf("MC Freq ERROR - ");
}
else
{
printf("MC Freq OK - ");
}
if( ( mcChannelSetupStatus & 0x04 ) == 0x04 )
{
printf("MC datarate ERROR\n");
}
else
{
printf("MC datarate OK\n");
}
}
}
else
{
printf( "MC Rx params setup, error: %s \n", MacStatusStrings[status] );
}
}
else
{
printf( "MC setup, error: %s \n", MacStatusStrings[status] );
}
#endif
- Then request the firmware to switch to the required Class. In previous code example the setup was done for Class B.
- Once operating in the required Class each time the MAC layer detects a reception on a multicast channel it will notify the application.
You may also look at fuota-test-01
example which implements a simple file transfer from the network.
For instructions on how to use it with Chirpstack you may refer to following issue https://github.com/Lora-net/LoRaMac-node/issues/827. Please note that in the mean time Chirpstak has changed the way the FUOTA packages are handled. You may refer to https://github.com/brocaar/chirpstack-fuota-server