The LoRa Developer Forum is now in read-only mode and new content will not be added. If you require technical support related to LoRa, please contact our experts here. For sales enquiries, please contact us here.

FORUM

Multicast

We want to control the device/node by multicast. How can we set up multicast address?
(We probably didn’t understand the philosophy, is there any routine for setting the mcaddress?)
At the beginning of the program it is necessary to use the
LmHandlerPackageRegister( PACKAGE_ID_REMOTE_MCAST_SETUP, NULL );
routine, this is clear, but how do we set the address?

We use last LoRaMac-node from github…
Thank you.
Jindrich

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