📄 myapp_ex03b.c
字号:
/******************************************************************************
* MyApp_Ex01.c - Initialization and main loop.
* MyApp_Ex02.c - Energy Detection Scan
* MyApp_Ex03a.c - A PAN Coordinator is started
* = MyApp_Ex03b.c - Device locates coordinator using Active Scan = This file ==
* MyApp_Ex04a.c - Coordinator responds to an Associate request
* MyApp_Ex04b.c - Device Associates to the PAN coordinator
* MyApp_Ex05a.c - Coordinator receives data from device
* MyApp_Ex05b.c - Device sends direct data to the coordinator
* MyApp_Ex06a.c - Coordinator sends indirect data to device
* MyApp_Ex06b.c - Device polls for data from the coordinator
* MyApp_Ex07a.c - Coordinator starts a beaconed network
* MyApp_Ex07b.c - Device receives data using automatic polling
* MyApp_Ex08a.c - Coordinator uses security
* MyApp_Ex08b.c - Device uses security
*
* This demo application builds upon MyApp_Ex01.c. The primary purpose of this
* application is to demonstrate how to use the Active Scan feature of the MAC
* in order to locate a coordinator that we will associate to later.
*
* The steps required for locating a coordinator are:
* 1) Build and send an MLME-Scan Request message to the MAC.
* 2) Wait for the MLME-Scan Confirm message from the MAC.
*
* Step 1 is performed by the 'stateScanActiveStart' state, and step 2 is
* performed by the 'stateScanActiveWaitConfirm' state.
*
******************************************************************************/
#include "802_15_4.h" /* Include everything related to the 802.15.4 interface*/
#include "Uart.h" /* Defines the interface of the demo UART. */
#include "ToolBox.h"
/* Defines the channels to scan. Each bit represents one channel. Use
0x07FFF800 to scan all 16 802.15.4 channels in the 2.4GHz band. */
#define SCAN_CHANNELS 0x07FFF800
/* Forward declarations of helper functions */
uint8_t App_StartScan(uint8_t scanType);
uint8_t App_HandleScanActiveConfirm(nwkMessage_t *pMsg);
uint8_t App_WaitMsg(nwkMessage_t *pMsg, uint8_t msgType);
/* All states in the applications state machine */
enum {
stateInit,
stateScanActiveStart,
stateScanActiveWaitConfirm,
stateListen,
stateTerminate
};
/* Error codes */
enum {
errorNoError,
errorWrongConfirm,
errorNotSuccessful,
errorNoMessage,
errorAllocFailed,
errorInvalidParameter,
errorNoScanResults
};
/* The current state of the applications state machine */
uint8_t state;
/* Information about the PAN we are part of */
panDescriptor_t coordInfo;
/* Application input queues */
anchor_t mMlmeNwkInputQueue;
/* Application Main Loop */
void main(void)
{
/* Pointer for storing the messages from MLME, MCPS, and ASP. */
void *pMsgIn;
/* Stores the status code returned by some functions. */
uint8_t rc;
/* return value of Mlme_Main() - not used yet */
uint8_t macStatus;
/* Initialize variables */
state = stateInit;
/* Prepare input queues.*/
MSG_InitQueue(&mMlmeNwkInputQueue);
/* Execute the application state machine */
while(state < stateTerminate)
{
/* Preset error to contain the success code */
rc = errorNoError;
/* Try to get a message from MLME */
if(MSG_Pending(&mMlmeNwkInputQueue))
pMsgIn = MSG_DeQueue(&mMlmeNwkInputQueue);
else
pMsgIn = NULL;
switch(state)
{
case stateInit:
/* Initialize the UART so that we can print out status messages */
Uart_Init();
/* Initialize the 802.15.4 stack */
Init_802_15_4();
/* Goto Energy Detection state. */
state = stateScanActiveStart;
/* Print a welcome message to the UART */
Uart_Print("The Myapp_Ex03b demo application is initialized and ready.\n\n");
break;
case stateScanActiveStart:
/* Start the Active scan, and goto wait for confirm state. */
Uart_Print("Start scanning for a PAN coordinator\n");
rc = App_StartScan(gScanModeActive_c);
if(rc == errorNoError)
{
state = stateScanActiveWaitConfirm;
}
break;
case stateScanActiveWaitConfirm:
/* Stay in this state until the Scan confirm message
arrives, and then goto the listen state. */
/* ALWAYS free the beacon frame contained in the beacon notify indication.*/
rc = App_WaitMsg(pMsgIn, gNwkBeaconNotifyInd_c);
if(rc == errorNoError) {
MSG_Free(((nwkMessage_t *)pMsgIn)->msgData.beaconNotifyInd.pBufferRoot);
Uart_Print("Received an MLME-Beacon Notify Indication\n");
}
/* Handle the Scan Confirm message. */
rc = App_WaitMsg(pMsgIn, gNwkScanCnf_c);
if(rc == errorNoError)
{
rc = App_HandleScanActiveConfirm(pMsgIn);
if(rc == errorNoError)
{
Uart_Print("Found a coordinator with the following properties:\n");
Uart_Print("----------------------------------------------------");
Uart_Print("\nAddress...........0x"); Uart_PrintHex(coordInfo.coordAddress, coordInfo.coordAddrMode == gAddrModeShort_c ? 2 : 8, 0);
Uart_Print("\nPAN ID............0x"); Uart_PrintHex(coordInfo.coordPanId, 2, 0);
Uart_Print("\nLogical Channel...0x"); Uart_PrintHex(&coordInfo.logicalChannel, 1, 0);
Uart_Print("\nBeacon Spec.......0x"); Uart_PrintHex(coordInfo.superFrameSpec, 2, 0);
Uart_Print("\nLink Quality......0x"); Uart_PrintHex(&coordInfo.linkQuality, 1, 0);
Uart_Print("\n\n");
state = stateListen;
}
else
Uart_Print("Scan did not find a suitable coordinator\n");
}
break;
case stateListen:
/* Stay in this state forever. */
break;
}
if(pMsgIn)
/* ALWAYS free messages from MLME */
MSG_Free(pMsgIn);
/* Call the MAC main function. */
macStatus = Mlme_Main();
}
}
/******************************************************************************
* The App_StartScan(scanType) function will start the scan process of the
* specified type in the MAC. This is accomplished by allocating a MAC message,
* which is then assigned the desired scan parameters and sent to the MLME
* service access point.
* The function may return either of the following values:
* errorNoError: The Scan message was sent successfully.
* errorInvalidParameter: The MLME service access point rejected the
* message due to an invalid parameter.
* errorAllocFailed: A message buffer could not be allocated.
*
******************************************************************************/
uint8_t App_StartScan(uint8_t scanType)
{
mlmeMessage_t *pMsg;
mlmeScanReq_t *pScanReq;
Uart_Print("Sending the MLME-Scan Request message to the MAC...");
/* Allocate a message for the MLME (We should check for NULL). */
pMsg = MSG_AllocType(mlmeMessage_t);
if(pMsg != NULL)
{
/* This is a MLME-START.req command */
pMsg->msgType = gMlmeScanReq_c;
/* Create the Start request message data. */
pScanReq = &pMsg->msgData.scanReq;
/* gScanModeED_c, gScanModeActive_c, gScanModePassive_c, or gScanModeOrphan_c */
pScanReq->scanType = scanType;
/* ChannelsToScan & 0xFF - LSB, always 0x00 */
pScanReq->scanChannels[0] = (uint8_t)((SCAN_CHANNELS) & 0xFF);
/* ChannelsToScan>>8 & 0xFF */
pScanReq->scanChannels[1] = (uint8_t)((SCAN_CHANNELS>>8) & 0xFF);
/* ChannelsToScan>>16 & 0xFF */
pScanReq->scanChannels[2] = (uint8_t)((SCAN_CHANNELS>>16) & 0xFF);
/* ChannelsToScan>>24 & 0xFF - MSB */
pScanReq->scanChannels[3] = (uint8_t)((SCAN_CHANNELS>>24) & 0xFF);
/* Duration per channel 0-14 (dc). T[sec] = (16*960*((2^dc)+1))/1000000.
A scan duration of 5 on 16 channels approximately takes 8 secs. */
pScanReq->scanDuration = 5;
/* Send the Scan request to the MLME. */
if(MSG_Send(NWK_MLME, pMsg) == gSuccess_c)
{
Uart_Print("Done\n");
return errorNoError;
}
else
{
Uart_Print("Invalid parameter!\n");
return errorInvalidParameter;
}
}
else
{
/* Allocation of a message buffer failed. */
Uart_Print("Message allocation failed!\n");
return errorAllocFailed;
}
}
/******************************************************************************
* The App_HandleScanActiveConfirm(nwkMessage_t *pMsg) function will handle the
* Active Scan confirm message received from the MLME when the Active scan has
* completed. The message contains a list of PAN descriptors. Based on link
* quality inforamtion in the pan descriptors the nearest coordinator is chosen.
* The corresponding pan descriptor is stored in the global variable coordInfo.
*
* The function may return either of the following values:
* errorNoError: A suitable pan descriptor was found.
* errorNoScanResults: No scan results were present in the confirm message.
*
******************************************************************************/
uint8_t App_HandleScanActiveConfirm(nwkMessage_t *pMsg)
{
uint8_t panDescListSize = pMsg->msgData.scanCnf.resultListSize;
panDescriptor_t *pPanDesc = pMsg->msgData.scanCnf.resList.pPanDescriptorList;
uint8_t rc = errorNoScanResults;
/* Check if the scan resulted in any coordinator responses. */
if(panDescListSize != 0)
{
/* Initialize link quality to very poor. */
uint8_t i, bestLinkQuality = 0;
/* Check all PAN descriptors. */
for(i=0; i<panDescListSize; i++, pPanDesc++)
{
/* Only attempt to associate if the coordinator
accepts associations and is non-beacon. */
if( ( pPanDesc->superFrameSpec[1] & gSuperFrameSpecMsbAssocPermit_c) &&
((pPanDesc->superFrameSpec[0] & gSuperFrameSpecLsbBO_c) == 0x0F) )
{
/* Find the nearest coordinator using the link quality measure. */
if(pPanDesc->linkQuality > bestLinkQuality)
{
/* Save the information of the coordinator candidate. If we
find a better candiate, the information will be replaced. */
memcpy(&coordInfo, pPanDesc, sizeof(panDescriptor_t));
bestLinkQuality = pPanDesc->linkQuality;
rc = errorNoError;
}
}
}
}
/* ALWAYS free the PAN descriptor list */
MSG_Free(pMsg->msgData.scanCnf.resList.pPanDescriptorList);
return rc;
}
/******************************************************************************
* The App_WaitMsg(nwkMessage_t *pMsg, uint8_t msgType) function does not, as
* the name implies, wait for a message, thus blocking the execution of the
* state machine. Instead the function analyzes the supplied message to
* determine whether or not the message is of the expected type.
* The function may return either of the following values:
* errorNoError: The message was of the expected type.
* errorNoMessage: The message pointer is NULL.
* errorWrongConfirm: The message is not of the expected type.
*
******************************************************************************/
uint8_t App_WaitMsg(nwkMessage_t *pMsg, uint8_t msgType)
{
/* Do we have a message? If not, the exit with error code */
if(pMsg == NULL)
return errorNoMessage;
/* Is it the expected message type? If not then exit with error code */
if(pMsg->msgType != msgType)
return errorWrongConfirm;
/* Found the expected message. Return with success code */
return errorNoError;
}
/******************************************************************************
* The following functions are called by the MAC to put messages into the
* Application's queue. They need to be defined even if they are not used
* in order to avoid linker errors.
******************************************************************************/
uint8_t MLME_NWK_SapHandler(nwkMessage_t * pMsg)
{
/* Put the incoming MLME message in the applications input queue. */
MSG_Queue(&mMlmeNwkInputQueue, pMsg);
return gSuccess_c;
}
uint8_t MCPS_NWK_SapHandler(mcpsToNwkMessage_t *pMsg)
{
/* If the message is not handled anywhere it must be freed. */
MSG_Free(pMsg);
return gSuccess_c;
}
uint8_t ASP_APP_SapHandler(aspToAppMsg_t *pMsg)
{
/* If the message is not handled anywhere it must be freed. */
MSG_Free(pMsg);
return gSuccess_c;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -