1.2.4 Using the G3 ADP Module

The G3 ADP module is the access point to the G3 Stack for:

  • Initialization

  • Configuration

  • Route Discovery

  • Data Exchange

Following examples show how to initialize, configure, and Join/Start a Network. For Data Exchange examples, follow Application code on provided example applications.

Example application for a G3 Device

// *****************************************************************************
// *****************************************************************************
// Section: Application Types and Variables
// *****************************************************************************
// *****************************************************************************

typedef enum
{
    /* Application's state machine's initial state. Open ADP. */
    APP_G3_STATE_ADP_OPEN = 0,
    /* State to wait for ADP to be ready */
    APP_G3_STATE_WAIT_ADP_READY,
    /* Back-off delay state before start network discovery (scan) */
    APP_G3_STATE_BACKOFF_DISCOVERY,
    /* Network discovery (scan) in progress */
    APP_G3_STATE_SCANNING,
    /* Back-off delay state before join to the network */
    APP_G3_STATE_BACKOFF_JOIN,
    /* Join to the network in progress */
    APP_G3_STATE_JOINING,
    /* Joined to the network */
    APP_G3_STATE_JOINED,
} APP_G3_STATES;

// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************

static void _ADP_DiscoveryConfirm(uint8_t status)
{
    if ((status == G3_SUCCESS) && (app_g3_managementData.bestNetwork.panId != 0xFFFF) &&
            (app_g3_managementData.bestNetwork.lbaAddress != 0xFFFF))
    {
        /* Good network found. Start Join to that network */
        app_g3_managementData.state = APP_G3_STATE_BACKOFF_JOIN;
    }
    else
    {
        /* No network found. Go back to network discovery */
        app_g3_managementData.state = APP_G3_STATE_BACKOFF_DISCOVERY;
    }
}

static void _ADP_DiscoveryIndication(ADP_PAN_DESCRIPTOR* pPanDescriptor)
{
    /* Check minimum Link Quality and maximum route cost to Coordinator */
    if ((pPanDescriptor->linkQuality >= APP_G3_LQI_MIN) && (pPanDescriptor->rcCoord < APP_G3_ROUTE_COST_COORD_MAX))
    {
        /* Update best network if route cost to Coordinator is better or if it is equal and Link Quality is better */
        if ((pPanDescriptor->rcCoord < app_g3_managementData.bestNetwork.rcCoord) ||
                ((pPanDescriptor->rcCoord == app_g3_managementData.bestNetwork.rcCoord) &&
                (pPanDescriptor->linkQuality > app_g3_managementData.bestNetwork.linkQuality)))
        {
            app_g3_managementData.bestNetwork = *pPanDescriptor;
        }
    }
}

static void _LBP_ADP_NetworkJoinConfirm(LBP_ADP_NETWORK_JOIN_CFM_PARAMS* pNetworkJoinCfm)
{
    if (pNetworkJoinCfm->status == G3_SUCCESS)
    {
        ADP_GET_CFM_PARAMS getConfirm;

        /* Successful join */
        app_g3_managementData.state = APP_G3_STATE_JOINED;

        /* Start a route request to coordinator */
        ADP_GetRequestSync(ADP_IB_COORD_SHORT_ADDRESS, 0, &getConfirm);
        if (getConfirm.status == G3_SUCCESS)
        {
            uint16_t coordShortAddress = *((uint16_t*) getConfirm.attributeValue);
            ADP_RouteDiscoveryRequest(coordShortAddress, APP_G3_MAX_HOPS);
        }
    }
    else
    {
        /* Unsuccessful join. Try again. */
        app_g3_managementData.state = APP_G3_STATE_BACKOFF_JOIN;
    }
}

// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

void APP_G3_Initialize ( void )
{
    ADP_MANAGEMENT_NOTIFICATIONS adpMngNotifications;

    /* Set ADP management call-backs */
    adpMngNotifications.discoveryConfirm = _ADP_DiscoveryConfirm;
    adpMngNotifications.discoveryIndication = _ADP_DiscoveryIndication;
    adpMngNotifications.networkStartConfirm = NULL;
    adpMngNotifications.resetConfirm = NULL;
    adpMngNotifications.setConfirm = NULL;
    adpMngNotifications.getConfirm = NULL;
    adpMngNotifications.macSetConfirm = NULL;
    adpMngNotifications.getConfirm = NULL;
    adpMngNotifications.macGetConfirm = NULL;
    adpMngNotifications.routeDiscoveryConfirm = NULL;
    adpMngNotifications.pathDiscoveryConfirm = NULL;
    adpMngNotifications.networkStatusIndication = NULL;
    adpMngNotifications.preqIndication = NULL;
    adpMngNotifications.nonVolatileDataIndication = NULL;
    adpMngNotifications.routeNotFoundIndication = NULL;
    adpMngNotifications.bufferIndication = NULL;
    ADP_SetManagementNotifications(&adpMngNotifications);

    /* Set the application's state machine in its initial state. */
    app_g3_managementData.state = APP_G3_STATE_ADP_OPEN;
}

void APP_G3_Tasks ( void )
{
    /* Refresh Watchdog */
    CLEAR_WATCHDOG();

    if (app_g3_managementData.state > APP_G3_STATE_WAIT_ADP_READY)
    {
        /* LBP Device tasks */
        LBP_TasksDev();
    }

    /* Check the application's current state */
    switch ( app_g3_managementData.state )
    {
        /* Application's initial state. */
        case APP_G3_STATE_ADP_OPEN:
        {
            /* Open G3 Adaptation Layer (ADP) */
            ADP_Open(ADP_BAND_CENELEC_A);

            /* Get Extended Address from storage application */
            APP_STORAGE_GetExtendedAddress(app_g3_managementData.eui64.value);

            /* Next state: Wait for ADP to be ready */
            app_g3_managementData.state = APP_G3_STATE_WAIT_ADP_READY;

            break;
        }

        /* State to wait for ADP to be ready */
        case APP_G3_STATE_WAIT_ADP_READY:
        {
            /* Check ADP status */
            ADP_STATUS adpStatus = ADP_Status();
            if (adpStatus >= ADP_STATUS_READY)
            {
                LBP_NOTIFICATIONS_DEV lbpDevNotifications;
                LBP_SET_PARAM_CONFIRM lbpSetConfirm;
                ADP_SET_CFM_PARAMS setConfirm;

                /* ADP is ready. We can set ADP/MAC parameters. */
                ADP_MacSetRequestSync(MAC_WRP_PIB_MANUF_EXTENDED_ADDRESS, 0, 8, (const uint8_t*) app_g3_managementData.eui64.value, &setConfirm);
                ADP_SetRequestSync(ADP_IB_MAX_JOIN_WAIT_TIME, 0, 2, (const uint8_t*) &app_g3_managementConst.maxJoinWaitTime, &setConfirm);

                /* Initialize LoWPAN Bootstrapping Protocol (LBP) in Device mode set call-backs and set PSK key */
                LBP_InitDev();
                lbpDevNotifications.adpNetworkJoinConfirm = _LBP_ADP_NetworkJoinConfirm;
                lbpDevNotifications.adpNetworkLeaveConfirm = NULL;
                lbpDevNotifications.adpNetworkLeaveIndication = NULL;
                LBP_SetNotificationsDev(&lbpDevNotifications);
                LBP_SetParamDev(LBP_IB_PSK, 0, 16, (const uint8_t*) &app_g3_managementConst.psk, &lbpSetConfirm);

                /* Initialize back-off window for network discovery */
                app_g3_managementData.backoffWindowLow = APP_G3_DISCOVERY_BACKOFF_LOW_MIN;
                app_g3_managementData.backoffWindowHigh = APP_G3_DISCOVERY_BACKOFF_HIGH_MIN;

                /* Next state: Start Network discovery. */
                app_g3_managementData.state = APP_G3_STATE_BACKOFF_DISCOVERY;

                SYS_DEBUG_MESSAGE(SYS_ERROR_INFO, "APP_G3_MANAGEMENT: ADP initialized successfully\r\n");
            }

            break;
        }

        /* Back-off delay state before start network discovery (scan) */
        case APP_G3_STATE_BACKOFF_DISCOVERY:
        {
            /* Start network discovery */
            ADP_DiscoveryRequest(APP_G3_DISCOVERY_DURATION);
            app_g3_managementData.state = APP_G3_STATE_SCANNING;

            /* Initialize best network PAN descriptor */
            app_g3_managementData.bestNetwork.panId = 0xFFFF;
            app_g3_managementData.bestNetwork.lbaAddress = 0xFFFF;
            app_g3_managementData.bestNetwork.rcCoord = 0xFFFF;
            app_g3_managementData.bestNetwork.linkQuality = 0xFF;

            break;
        }

        /* Network discovery (scan) in progress */
        case APP_G3_STATE_SCANNING:
        {
            /* Nothing to do, state will be changed from _ADP_DiscoveryConfirm callback */
            break;
        }

        /* Back-off delay state before join to the network */
        case APP_G3_STATE_BACKOFF_JOIN:
        {
            /* Try to join to the network */
            LBP_AdpNetworkJoinRequest(app_g3_managementData.bestNetwork.panId, app_g3_managementData.bestNetwork.lbaAddress, app_g3_managementData.bestNetwork.mediaType);
            app_g3_managementData.state = APP_G3_STATE_JOINING;

            break;
        }

        /* Join to the network in progress */
        case APP_G3_STATE_JOINING:
        {
            /* Nothing to do, state will be changed from _LBP_ADP_NetworkJoinConfirm callback */
            break;
        }

        /* Joined to the network */
        case APP_G3_STATE_JOINED:
        {
            /* Nothing to do. The device is joined to the network */
            break;
        }

        /* The default state should never be executed. */
        default:
        {
            break;
        }
    }
}

Example application for a G3 Coordinator

// *****************************************************************************
// *****************************************************************************
// Section: Application Types and Variables
// *****************************************************************************
// *****************************************************************************

typedef enum
{
    /* Application's state machine's initial state. Open ADP ADP. */
    APP_G3_STATE_ADP_OPEN = 0,
    /* State to wait for ADP to be ready */
    APP_G3_STATE_WAIT_ADP_READY,
    /* Network discovery (scan) in progress */
    APP_G3_STATE_SCANNING,
    /* Starting G3 network */
    APP_G3_STATE_STARTING_NETWORK,
    /* G3 network started, accepting connection of devices */
    APP_G3_STATE_NETWORK_STARTED,
} APP_G3_STATES;

// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************

static void _ADP_NetworkStartConfirm(uint8_t status)
{
    if (status == G3_SUCCESS)
    {
        /* Network started */
        app_g3_managementData.state = APP_G3_STATE_NETWORK_STARTED;
    }
    else
    {
        /* Error in Network Start. Try with another PAN ID */
        app_g3_managementData.panId += 1;
        ADP_NetworkStartRequest(app_g3_managementData.panId);
    }
}

static void _ADP_DiscoveryIndication(ADP_PAN_DESCRIPTOR* pPanDescriptor)
{
    if (app_g3_managementData.numNetworksFound < APP_G3_PAN_ID_LIST_SIZE)
    {
        /* Store PAN ID in order to not repeat it */
        app_g3_managementPanIdList[app_g3_managementData.numNetworksFound++] = pPanDescriptor->panId;
    }
}

static void _ADP_DiscoveryConfirm(uint8_t status)
{
    for (uint8_t i = 0; i < app_g3_managementData.numNetworksFound; i++)
    {
        if (app_g3_managementPanIdList[i] == app_g3_managementData.panId)
        {
            /* Change PAN ID */
            app_g3_managementData.panId += 1;
        }
    }

    /* Start G3 network */
    app_g3_managementData.state = APP_G3_STATE_STARTING_NETWORK;
    ADP_NetworkStartRequest(app_g3_managementData.panId);
}

// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

void APP_G3_Initialize ( void )
{
    ADP_MANAGEMENT_NOTIFICATIONS adpMngNotifications;

    /* Set ADP management call-backs */
    adpMngNotifications.discoveryConfirm = _ADP_DiscoveryConfirm;
    adpMngNotifications.discoveryIndication = _ADP_DiscoveryIndication;
    adpMngNotifications.networkStartConfirm = _ADP_NetworkStartConfirm;
    adpMngNotifications.resetConfirm = NULL;
    adpMngNotifications.setConfirm = NULL;
    adpMngNotifications.getConfirm = NULL;
    adpMngNotifications.macSetConfirm = NULL;
    adpMngNotifications.getConfirm = NULL;
    adpMngNotifications.macGetConfirm = NULL;
    adpMngNotifications.routeDiscoveryConfirm = NULL;
    adpMngNotifications.pathDiscoveryConfirm = NULL;
    adpMngNotifications.networkStatusIndication = NULL;
    adpMngNotifications.preqIndication = NULL;
    adpMngNotifications.nonVolatileDataIndication = NULL;
    adpMngNotifications.routeNotFoundIndication = NULL;
    adpMngNotifications.bufferIndication = NULL;
    ADP_SetManagementNotifications(&adpMngNotifications);

    /* Place the application's state machine in its initial state. */
    app_g3_managementData.state = APP_G3_STATE_ADP_OPEN;
}

void APP_G3_Tasks ( void )
{
    /* Refresh Watchdog */
    CLEAR_WATCHDOG();

    /* Check the application's current state. */
    switch ( app_g3_managementData.state )
    {
        /* Application's initial state. */
        case APP_G3_STATE_ADP_OPEN:
        {
            /* Open G3 Adaptation Layer (ADP) */
            ADP_Open(ADP_BAND_CENELEC_A);

            /* Get Extended Address from storage application */
            APP_STORAGE_GetExtendedAddress(app_g3_managementData.eui64.value);

            /* Next state: Wait for ADP to be ready */
            app_g3_managementData.state = APP_G3_STATE_WAIT_ADP_READY;

            break;
        }

        /* State to wait for ADP to be ready */
        case APP_G3_STATE_WAIT_ADP_READY:
        {
            /* Check ADP status */
            ADP_STATUS adpStatus = ADP_Status();
            if (adpStatus >= ADP_STATUS_READY)
            {
                ADP_SET_CFM_PARAMS setConfirm;

                /* ADP is ready. We can set ADP/MAC parameters. */
                ADP_MacSetRequestSync(MAC_WRP_PIB_MANUF_EXTENDED_ADDRESS, 0, 8, (const uint8_t*) app_g3_managementData.eui64.value, &setConfirm);
                ADP_MacSetRequestSync(MAC_WRP_PIB_SHORT_ADDRESS, 0, 2, (const uint8_t*) &app_g3_managementConst.shortAddress, &setConfirm);

                /* Look for G3 networks in order to not repeat PAN ID */
                ADP_DiscoveryRequest(15);
                app_g3_managementData.numNetworksFound = 0;
                app_g3_managementData.state = APP_G3_STATE_SCANNING;
            }

            break;
        }

        /* Network discovery (scan) in progress */
        case APP_G3_STATE_SCANNING:
        {
            /* Nothing to do, state will be changed from _ADP_DiscoveryConfirm callback */
            break;
        }

        /* Starting G3 network */
        case APP_G3_STATE_STARTING_NETWORK:
        {
            /* Nothing to do, state will be changed from _ADP_NetworkStartConfirm callback */
            break;
        }

        /* G3 network started */
        case APP_G3_STATE_NETWORK_STARTED:
        {
            /* Nothing to do */
            break;
        }

        /* The default state should never be executed. */
        default:
        {
            break;
        }
    }
}