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