/***************************************************************************** * MyWirelessApp Demo Framework * * (c) Copyright 2008, Freescale, Inc. All rights reserved. * * * No part of this document must be reproduced in any form - including copied, * transcribed, printed or by any electronic means - without specific written * permission from Freescale Semiconductor. * *****************************************************************************/#include "MApp.h"#include "NVM_Interface.h"/************************************************************************************ ************************************************************************************* * Private macros ************************************************************************************* ************************************************************************************/#define CHANNEL_MAX 26#define CHANNEL_MIN 11/** Maximum size in bytes of a packet's data unit. */#define MAX_MSDU_SIZE 10 //102/************************************************************************************ ************************************************************************************* * Private prototypes ************************************************************************************* ************************************************************************************/static void App_HandleKeys(key_event_t events);void AppTask(event_t events);static uint8_t waitForMessage(nwkMessage_t *pMsg, uint8_t msgType);static uint8_t config(void);static uint8_t send(void);/************************************************************************************ ************************************************************************************* * Private type definitions ************************************************************************************* ************************************************************************************/enum { eState_stopped, eState_start, eState_waitStartConfirm, eState_send,};/** Error codes */enum { errorNoError, errorWrongConfirm, errorNotSuccessful, errorNoMessage, errorAllocFailed, errorInvalidParameter, errorNoScanResults};/************************************************************************************ ************************************************************************************* * Private memory declarations ************************************************************************************* ************************************************************************************//** Flags when the module should next send a packet. Used to add delays between * packets. */bool_t isReadyToSend_test= TRUE;//****** Private global variables *********************************************/** Test state */static uint8_t state = eState_start;/** Application input queue for MLME messages. */static anchor_t mMlmeNwkInputQueue;/** Application input queue for MCPS messages. */static anchor_t mMcpsNwkInputQueue;/** The device's address, always 0x11 22 */static uint8_t shortAddress[2] = { 0x11, 0x22 };/** The Gateway's 802.15.4 PAN. */static uint8_t panId[2] = { 0xEF, 0xBE };/** The current logical channel (frequency band) */static uint8_t logicalChannel= CHANNEL_MIN;/** Total number of packets sent */static uint32_t sentCnt = 0;/** Number of packets sent with an error */static uint32_t errorCnt = 0;/** Number of packets data confirmations*/static uint32_t confCnt = 0;/** Sequence number for next packet */static uint8_t seqNumber = 0;static bool_t firstStart= TRUE;static uint8_t delayCounter = 0;/************************************************************************************ ************************************************************************************* * Public memory declarations ************************************************************************************* ************************************************************************************//* The current state of the applications state machine */uint8_t gState;/* This data set contains application variables to be preserved across resets */NvDataItemDescription_t const gaNvAppDataSet[] = { { NULL, 0 } /* Required end-of-table marker. */};/************************************************************************************ ************************************************************************************* * Public functions ************************************************************************************* ************************************************************************************/void DeepSleepWakeupStackProc(void);/***************************************************************************** * Initialization function for the App Task. This is called during * initialization and should contain any application specific initialization * (ie. hardware initialization/setup, table initialization, power up * notificaiton. * * Interface assumptions: None * * Return value: None * *****************************************************************************/void MApp_init(void) { /* The initial application state */ gState = stateInit; /* Initialize the MAC 802.15.4 extended address */ Init_MacExtendedAddress(); /* register keyboard callback function */ KBD_Init(App_HandleKeys); /* initialize LED Module */ LED_Init(); /* Initialize the LPM module */ PWRLib_Init(); MSG_InitQueue(&mMlmeNwkInputQueue); MSG_InitQueue(&mMcpsNwkInputQueue); /* Enable MCU interrupts */ IrqControlLib_EnableAllIrqs(); /*signal app ready*/ Led2On(); Led1Off(); // Start running the AppTask. TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c);}/***************************************************************************** *Mac Application Task event processor. This function is called to * process all events for the task. Events include timers, messages and any * other user defined events * * Interface assumptions: None * * Return value: None *****************************************************************************/void AppTask(event_t events) { /* Pointer for storing the messages */ void *pMsgIn; /* Stores the status code returned by some functions. */ uint8_t rc; /* Preset return code 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 eState_start: sentCnt = 0; errorCnt = 0; confCnt = 0; seqNumber = 0; rc = config(); if (rc == errorNoError) state = eState_waitStartConfirm; break; case eState_waitStartConfirm: /* Stay in this state until the Start confirm message arrives. */ rc = waitForMessage(pMsgIn, gNwkStartCnf_c); if (rc == errorNoError) { state = eState_send; } break; case eState_send: if (isReadyToSend_test) { rc = send(); sentCnt++; isReadyToSend_test = FALSE; } } if (pMsgIn) { /* Messages must always be freed. */ MSG_Free(pMsgIn); } /* Call the MAC main function until the function returns false, indicating * there is no more work to do. */ //Mlme_Main(); /* Just to avoid the compiler warning */ (void)events; // Let AppTask run again TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c);}/************************************************************************************ ************************************************************************************* * Private functions ************************************************************************************* ************************************************************************************//***************************************************************************** * Handles all key events for this device. * Interface assumptions: None * Return value: None *****************************************************************************/static void App_HandleKeys(key_event_t events /*IN: Events from keyboard module */) { switch (events) { case gKBD_EventSW1_c: case gKBD_EventSW2_c: case gKBD_EventSW3_c: case gKBD_EventSW4_c: case gKBD_EventLongSW1_c: case gKBD_EventLongSW2_c: case gKBD_EventLongSW3_c: case gKBD_EventLongSW4_c: //LED_ToggleLed(LED2); //TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c); break; }}void nextChannel_test(void) { logicalChannel++; if (logicalChannel > CHANNEL_MAX) logicalChannel = CHANNEL_MIN;}void stop_test(void) { state = eState_stopped;}/** * This function analyzes the supplied message to determine whether or not the * message is of the expected type. It does not, as the name implies, wait for * a message, thus blocking the execution of the state machine. * * @return one of the following values: * <ul> * <li>errorNoError: The message was of the expected type.</li> * <li>errorNoMessage: The message pointer is NULL.</li> * <li>errorWrongConfirm: The message is not of the expected type.</li> * </ul> */uint8_t waitForMessage(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;}uint8_t config(void) { /* Message for the MLME will be allocated and attached to this pointer */ mlmeMessage_t *pMsg; /* Pointer which is used for easy access inside the allocated message */ mlmeStartReq_t *pStartReq; /* Return value from MSG_send - used for avoiding compiler warnings */ uint8_t ret; /* Allocate a message for the MLME*/ pMsg = MSG_AllocType(mlmeMessage_t); if (pMsg == NULL) // Allocation of a message buffer failed. */ return errorAllocFailed; /* Set-up MAC PIB attributes. Please note that Set, Get, and Reset messages are not freed by the MLME. */ /* We must always set the short address to something else than 0xFFFF before starting a PAN. */ pMsg->msgType = gMlmeSetReq_c; pMsg->msgData.setReq.pibAttribute = gMPibShortAddress_c; pMsg->msgData.setReq.pibAttributeValue = (uint8_t *)shortAddress; ret = MSG_Send(NWK_MLME, pMsg); /* This is a MLME-START.req command */ pMsg->msgType = gMlmeStartReq_c; /* Create the Start request message data. */ pStartReq = &pMsg->msgData.startReq; FLib_MemCpy(pStartReq->panId, (void *)panId, 2); pStartReq->logicalChannel = logicalChannel; pStartReq->beaconOrder = 0x0F; // beacons off pStartReq->superFrameOrder = 0x0F; // turn off beacons pStartReq->panCoordinator = TRUE; pStartReq->batteryLifeExt = FALSE; pStartReq->coordRealignment = FALSE; pStartReq->securityEnable = FALSE; /* Send the Start request to the MLME. */ ret = MSG_Send(NWK_MLME, pMsg); if (ret == gSuccess_c) return errorNoError; else return errorInvalidParameter;}uint8_t send(void) { uint8_t checksum = 0; uint8_t i = 0; nwkToMcpsMessage_t *pPacket; /* Allocate packet */// pPacket = MSG_Alloc(sizeof(nwkToMcpsMessage_t) - 1 + MAX_MSDU_SIZE); pPacket = MSG_Alloc(gMaxRxTxDataLength_c); if (pPacket == NULL) return errorAllocFailed; // Prepend with sequence number pPacket->msgData.dataReq.pMsdu[0] = seqNumber; for (i = 1; i < (MAX_MSDU_SIZE - 1); i++) { pPacket->msgData.dataReq.pMsdu[i] = 0x11; // dummy data } // Apped checksum to packet pPacket->msgData.dataReq.pMsdu[MAX_MSDU_SIZE - 1] = checksum; // Build MCPS-Data Request message pPacket->msgType = gMcpsDataReq_c; pPacket->msgData.dataReq.srcAddr[0] = shortAddress[0]; pPacket->msgData.dataReq.srcAddr[1] = shortAddress[1]; pPacket->msgData.dataReq.dstAddr[0] = 0xFF; // broadcast pPacket->msgData.dataReq.dstAddr[1] = 0xFF; // broadcast pPacket->msgData.dataReq.dstPanId[0] = 0xFF; // broadcast pPacket->msgData.dataReq.dstPanId[1] = 0xFF; // broadcast pPacket->msgData.dataReq.srcPanId[0] = panId[0]; pPacket->msgData.dataReq.srcPanId[1] = panId[1]; pPacket->msgData.dataReq.dstAddrMode = gAddrModeShort_c; pPacket->msgData.dataReq.srcAddrMode = gAddrModeShort_c; pPacket->msgData.dataReq.msduLength = MAX_MSDU_SIZE; pPacket->msgData.dataReq.msduHandle = seqNumber; pPacket->msgData.dataReq.txOptions = 0; // no ack, no security seqNumber++; /* Send the Data Request to the MCPS */ return MSG_Send(NWK_MCPS, pPacket);}/***************************************************************************** * The DeepSleepWakeupStackProc(void) function is called each time the * application exits the DeepSleep mode . * * Return value: * None *****************************************************************************/void DeepSleepWakeupStackProc(void) { return;}/****************************************************************************** * 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) { confCnt++; isReadyToSend_test = TRUE; if (pMsg->msgData.dataCnf.status != gSuccess_c) errorCnt++; 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;}/******************************************************************************/