⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myapp_ex07a.c

📁 This network protcol stack,it is very strong and powerful!
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*   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 
*   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	======== This file ==
*   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_Ex06a.c which demonstrated how data
* could be transmitted indirectly from a coordinator to a device. In this
* application we will show how to start a beaconed network.
* 
* Starting a beaconed network simply means that the application instructs the
* MAC to send out special data packets at regular intervals. The packets,
* called beacon frames, are not addressed to any particular device - i.e. they
* are broadcast to everyone listening. A devices MAC layer will turn on its
* receiver at the time a beacon frame is expected. The beacon frame may carry
* information about indirect data pending in the coordinators transmit queue.
* If the device receiving the beacon frame finds its own address in the list
* of pending data packets, it may automatically send a Poll request to retreive
* the data packet. The benefit of this is that the device do not need to
* schedule Poll Requests at regular intervals. Though, only one automatic Poll
* Request is sent for each beacon frame. If more data from the coordinator is
* required before the next beacon frame, the device still has to poll for it.
*
* On the coordinator side the only change required is changing the values of
* the Beacon Order and Superframe Order. These values are parameters of the
* MLME-Start Request. Default they are both 0xF meaning that a non-beaconed
* network is created. Setting the parameters to values between 0x0 and 0xE
* will result in a beaconed network. The beacon interval is determined by
* the Beacon Order, and calculated as: (960*(2^BO) * 16) / 1000000, or 
* approximately (2^BO)/65.1. The Superframe Order is the duration of the 
* active period after the beacon frame. If the Superframe Order is the same
* as the Beacon Order, the active period stretches over the entire beacon
* interval. The beacon configuration is very application specific. For
* instance, a temperature sensor network might be configured to deliver 
* temperature readings once every minute. The amount of data transferred is
* thus negligible compared to the Beacon Order of the network. A configuration
* could be BO=12 (63secs), and SO=1 (30.7msecs).
* 
* In the preceding example we transferred UART data between the device and
* coordinator. Assuming we dont want the application on the device to poll
* for data regularly, we must find a beacon configuration suitable for our
* band-width requirements. The data rate is 19200bps over the UART, and the
* application specific data size limitation is 80 bytes. We must thus transfer
* 19200/10/80 = 24 packets each second, or one packet each 42msecs. Doing some
* inverse math we find that the BO must be 1. We choose the SO to be the same.
* This configuration supports a bit rate of ~26000bps. 
*
* To test the data transfer from the coordinator to the device, both should be
* connected to a PC with an RS232 terminal at 19200bps, 8N1. When sending an
* ASCII file (send as text) from the coordinators terminal, the file will be 
* printed to the terminal connected to the device. It resembles a bidirectional
* wireless RS232 cable replacement (though, without error checking and flow 
* control in this simple example).
*
* The steps required for starting a beaconed network are:
* 1) Set the relevant PIB attributes, and Build and send an MLME-Start Request 
*    message to the MAC with Beacon Order and Superframe Order less than 0xF.
* 2) Wait for the MLME-Start Confirm message from the MAC.
*
* Step 1 is performed by the 'stateStartCoordinator' state, and step 2 is 
* performed by the 'stateStartCoordinatorWaitConfirm' 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

/* Defines the beaconed network configuration. The values shown
   are suitable for transfer of 19200bps bidirectional UART data. */
#define BEACON_ORDER      1
#define SUPERFRAME_ORDER  1

/* Maximum number of outstanding packets */
#define MAX_PENDING_DATA_PACKETS 2

/* Default size of data payload in MCPS-Data.request.
   The length has no real meaning since MCPS-Data.requests
   are always sent in one-size buffers big enough to hold
   a maximum length data frame. */
#define DEFAULT_DATA_LENGTH 20

/* 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);
void    App_HandleMcpsInput(mcpsToNwkMessage_t *pMsgIn);
void    App_TransmitUartData(void);
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 };

/* Data request packet for sending UART input to the coordinator */
nwkToMcpsMessage_t *pPacket;

/* The MSDU handle is a unique data packet identifier */
uint8_t msduHandle;

/* Number of pending data packets */
uint8_t numPendingPackets;

/* Application input queues */
anchor_t mMlmeNwkInputQueue;
anchor_t mMcpsNwkInputQueue;

/* 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);
  MSG_InitQueue(&mMcpsNwkInputQueue);
  
  /* 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_Ex07a 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\nReady to send and receive data over the UART.\n\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);
    }

    /* If we are associated then check MCPS queue and UART data buffer. */
    if(state == stateListen)
    {
      /* Check for input from MCPS (data related)*/
      if(MSG_Pending(&mMcpsNwkInputQueue))
      {
        /* Get the message from MCPS */
        pMsgIn = MSG_DeQueue(&mMcpsNwkInputQueue);
        /* Process the message */
        App_HandleMcpsInput(pMsgIn);
        /* Messages from the MCPS must always be freed. */
        MSG_Free(pMsgIn);
      }

      /* Check if the UART buffer has data to be sent to the device. */
      App_TransmitUartData();
    }
    
    /* 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)
{  
  uint8_t n, minEnergy;
  uint8_t *pEdList;

  Uart_Print("Recevied the MLME-Scan Confirm message from the MAC\n");
    
  /* Get a pointer to the energy detect results */
  pEdList = pMsg->msgData.scanCnf.resList.pEnergyDetectList;
  
  /* Set the minimum energy to a large value */
  minEnergy = 0xFF;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -