📄 myapp_ex04a.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
* = MyApp_Ex04a.c - Coordinator responds to an Associate request = This file ==
* 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 on MyApp_Ex03a.c. In Ex03a it was demonstrated
* how to start a PAN coordinator. In the present example we will enable the
* coordinator to respond to associate requests from devices.
*
* Associations are used for making a logical connection between devices and
* coordinators. One advantage of associations is that the communication can be
* performed using 2 byte addresses instead of 8 byte addresses. The benefit of
* this is longer battery life since less power is required for the radio.
*
* It is the coordinator that assigns short addresses to devices wishing to
* associate. The devices do so by sending out an Associate Request command.
* On the coordinator the command becomes an Associate Indication at the
* network/application layer which then must select a unique short address for
* the new device. The network or application layer of the coordinator accepts
* the associate request by sending an Associate Response message to the MLME.
* When the MLME has sent the Associate Response to the device, it will send
* an MLME-Comm-Status Indication to the network or application layer with the
* status code for the transmission of the response. In this example we ignore
* the MLME-Comm-Status Indication to keep the code as simple as possible.
*
* Some devices may chose not to request a short address. In such cases, the
* coordinator must assign the address 0xfffe to the device meaning that it
* is associated, but that the devices long address is used in every
* communication between the device and coordinator.
*
* The steps required for responding to an Associate Request are:
* 1) Receive an Associate Indication message.
* 2) Determine if we want or are able to accept the Associate Request.
* 3) Send an Associate Response with either gSuccess_c or an error code,
* and the short address if any was assigned.
*
* Step 1-3 are all performed in the 'stateListen' 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 for memcpy, memcmp. */
/* 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);
void App_HandleScanEdConfirm(nwkMessage_t *pMsg);
uint8_t App_StartCoordinator(void);
uint8_t App_HandleMlmeInput(nwkMessage_t *pMsg);
uint8_t App_SendAssociateResponse(nwkMessage_t *pMsgIn);
uint8_t App_WaitMsg(nwkMessage_t *pMsg, uint8_t msgType);
/* The various states of the application state machine. */
enum {
stateInit,
stateScanEdStart,
stateScanEdWaitConfirm,
stateStartCoordinator,
stateStartCoordinatorWaitConfirm,
stateListen,
stateTerminate
};
/* Error codes */
enum {
errorNoError,
errorWrongConfirm,
errorNotSuccessful,
errorNoMessage,
errorAllocFailed,
errorInvalidParameter,
errorNoScanResults
};
/* The current state of the applications state machine */
uint8_t state;
/* The status parameter of the latest confirm message from the MLME */
uint8_t confirmStatus;
/* The current logical channel (frequency band) */
uint8_t logicalChannel;
/* These byte arrays stores an associated
devices long and short addresses. */
uint8_t deviceShortAddress[2];
uint8_t deviceLongAddress[8];
/* We want the coordinators short address to be 0xCAFE. */
const uint8_t shortAddress[2] = { 0xFE, 0xCA };
/* PAN ID is 0xBEEF */
const uint8_t panId[2] = { 0xEF, 0xBE };
/* Application input queues */
anchor_t mMlmeNwkInputQueue;
/* Application Main Loop */
void main(void)
{
/* Pointer for storing the messages from MLME */
void *pMsgIn;
/* Stores the error/success code returned by some functions. */
uint8_t ret;
/* 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 return code to contain the success code */
ret = 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 = stateScanEdStart;
/* Print a welcome message to the UART */
Uart_Print("The Myapp_Ex04a demo application is initialized and ready.\n\n");
break;
case stateScanEdStart:
/* Start the Energy Detection scan, and goto wait for confirm state. */
Uart_Print("Initiating the Energy Detection Scan\n");
ret = App_StartScan(gScanModeED_c);
if(ret == errorNoError)
{
state = stateScanEdWaitConfirm;
}
break;
case stateScanEdWaitConfirm:
/* Stay in this state until the MLME Scan confirm message arrives,
and has been processed. Then goto Start Coordinator state. */
ret = App_WaitMsg(pMsgIn, gNwkScanCnf_c);
if(ret == errorNoError)
{
/* Process the ED scan confirm. The logical
channel is selected by this function. */
App_HandleScanEdConfirm(pMsgIn);
state = stateStartCoordinator;
}
break;
case stateStartCoordinator:
/* Start up as a PAN Coordinator on the selected channel. */
Uart_Print("\nStarting as PAN coordinator on channel 0x");
Uart_PrintHex(&logicalChannel, 1, FALSE);
Uart_Print("\n");
ret = App_StartCoordinator();
if(ret == errorNoError)
{
/* If the Start request was sent successfully to
the MLME, then goto Wait for confirm state. */
state = stateStartCoordinatorWaitConfirm;
}
break;
case stateStartCoordinatorWaitConfirm:
/* Stay in this state until the Start confirm message
arrives, and then goto the Listen state. */
ret = App_WaitMsg(pMsgIn, gNwkStartCnf_c);
if(ret == errorNoError)
{
Uart_Print("Started the coordinator with PAN ID 0x");
Uart_PrintHex((uint8_t *)panId, 2, 0);
Uart_Print(", and short address 0x");
Uart_PrintHex((uint8_t *)shortAddress, 2, 0);
Uart_Print(".\n");
state = stateListen;
}
break;
case stateListen:
/* Stay in this state forever. Handles associate, disassociate etc. */
ret = App_HandleMlmeInput(pMsgIn);
break;
}
if(pMsgIn)
{
/* Messages from the MLME must always be freed. */
MSG_Free(pMsgIn);
}
/* Call the MAC main function continuously. */
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_HandleScanEdConfirm(nwkMessage_t *pMsg) function will handle the
* ED scan confirm message received from the MLME when the ED scan has completed.
* The message contains the ED scan result list. This function will search the
* list in order to select the logical channel with the least energy. The
* selected channel is stored in the global variable called 'logicalChannel'.
*
******************************************************************************/
void App_HandleScanEdConfirm(nwkMessage_t *pMsg)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -