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

📄 myapp_ex07b.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
* = MyApp_Ex07b.c - Device receives data using automatic polling = This file ==
*   MyApp_Ex08a.c - Coordinator uses security
*   MyApp_Ex08b.c - Device uses security
*
* This demo application builds upon MyApp_Ex06b.c which demonstrated how
* to poll for data from a coordinator. This application will show how to
* syncronize to a beaconing coordinator, and receive data without polling
* for it manually.
*
* It it assumed that the demo application on the coordinator side is Ex07a for
* this example. The Ex07a application has been configured to send out beacons
* (see the top comment in the MyApp_Ex07a.c file). The MAC on the device side
* can be instructed to follow the beacons from the coordinator. This is called
* synchronization, and is initiated by the MLME-Sync Request. A prerequisite 
* for using the sync request is that the logical channel, and the PAN ID of the
* coordinator we wish to communicate with is known. These informations have 
* been acquired during the scan procedure. It's worth mentioning that Passive
* Scan can replace Active Scan if the coordinator is beaconing. In that case
* the Scan Duration parameter must be equal to or grater than the Beacon Order
* of the coordinator. This implies a priori knowledge of the network parameters.
*
* Just a brief explanation of the difference between Active and Passive Scan:
* Active Scan is mostly used in non-beaconed networks. The MAC will broadcast
* a Beacon Request command frame on all channels specified in the channel list.
* Any coordinator listening on a particular channel will respond to the request
* with a beacon frame. Since a coordinator in a beaconed network is sending out
* beacons at some interval, the device need not send out the beacon request.
* This is called Passive Scan. I.e. the device does not trigger the coordinator
* to send out a beacon frame before opening the receiver to listen for it, The
* beacon frame will be send out anyway.
*
* When the device is part of a beaconed PAN, data reception can be simplified
* a great deal since the MAC can be configured for automatic polling of data
* packets from the coordinator. Thus, in this application we will actually
* remove all the polling code from Ex06b, and replace it by the MLME-Sync 
* Request, and a few MLME-Set Requests. These request messages are only sent 
* once right after the scan procedure has completed, and before association.
*
* 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 receiving data from a beaconing coordinator are:
* 1) Perform a Passive Scan for beaconing coordinators. 
*    Previous examples used Active Scan.
* 2) Set the PAN ID attribute, and the Auto Request attribute in the MAC PIB
*    using the MLME-Set Request. Then send an MLME-Sync Request with the
*    logical channel of the coordinator. A confirm message for the Sync
*    Request does not exists, so we must not wait for confirmation after
*    sending the message.
* 3) Associate to the coordinator.
* 4) Listen for MCPS-Data Indication messages. They contain data from the
*    coordinator.
*
* Step 1 has been covered in previous demo applications, except that the scan
* mode is changed to Passive Scan for this application. Step 2 is performed
* by App_HandleScanPassiveConfirm() in state stateScanPassiveWaitConfirm.
* Association in step 3 is handled in the stateAssociate, and stateAssociate-
* WaitConfirm states, and has been covered in previous demo applications.
* Step 4 is performed by the App_HandleMcpsInput() function which is called
* outside the applications state machine.
*
******************************************************************************/

#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

/* 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);
uint8_t App_HandleScanPassiveConfirm(nwkMessage_t *pMsg);
uint8_t App_WaitMsg(nwkMessage_t *pMsg, uint8_t msgType);
uint8_t App_SendAssociateRequest(void);
void    App_HandleAssociateConfirm(nwkMessage_t *pMsg);
void    App_HandleMcpsInput(mcpsToNwkMessage_t *pMsgIn);
void    App_TransmitUartData(void);

/* All states in the applications state machine */
enum {
  stateInit,
  stateScanPassiveStart,
  stateScanPassiveWaitConfirm,
  stateAssociate,
  stateAssociateWaitConfirm,
  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;

/* This is either the short address assigned by the PAN coordinator
   during association, or our own extended MAC address. */
uint8_t myAddress[8];

/* The devices address mode. If 2 (gAddrModeShort_c), then myAddress
   contains the short address assigned by the PAN coordinator. If 3
   (gAddrModeLong_c), then myAddress is equal to the extended address. */
uint8_t myAddrMode;

/* 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, 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);
  MSG_InitQueue(&mMcpsNwkInputQueue);

  /* 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 = stateScanPassiveStart;
      /* Reset number of pending packets */
      numPendingPackets = 0;

      /* Print a welcome message to the UART */
      Uart_Print("The Myapp_Ex07b demo application is initialized and ready.\n\n");
      break;
      
    case stateScanPassiveStart:
      /* Start the Passive scan, and goto wait for confirm state. */
      Uart_Print("Start scanning for a PAN coordinator\n");
      rc = App_StartScan(gScanModePassive_c);
      if(rc == errorNoError)
      {
        state = stateScanPassiveWaitConfirm;
      }
      break;
      
    case stateScanPassiveWaitConfirm:
      /* Stay in this state until the Scan confirm message
         arrives, and then goto the associate 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_HandleScanPassiveConfirm(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 = stateAssociate;
        }
        else
          Uart_Print("Scan did not find a suitable coordinator\n");
      }
      break;

    case stateAssociate:
      /* Associate to the PAN coordinator */
      Uart_Print("Associating to PAN coordinator on channel 0x");
      Uart_PrintHex(&(coordInfo.logicalChannel), 1, gPrtHexNewLine_c);
      rc = App_SendAssociateRequest();
      if(rc == errorNoError)
        state = stateAssociateWaitConfirm;
      break; 

    case stateAssociateWaitConfirm:
      /* Stay in this state until the Associate confirm message
         arrives, and then goto the Listen state. */
      rc = App_WaitMsg(pMsgIn, gNwkAssociateCnf_c);
      if(rc == errorNoError)
      {
        App_HandleAssociateConfirm(pMsgIn);
        state = stateListen;
        Uart_Print("Successfully associated with the coordinator.\n");
        Uart_Print("We were assigned the short address 0x");
        Uart_PrintHex(myAddress, myAddrMode == gAddrModeShort_c ? 2 : 8, 0);
        Uart_Print("\n\nReady to send and receive data over the UART.\n\n");
      }
      break; 
      
    case stateListen:
      /* Stay in this state forever. */
      break;
    }
    
    if(pMsgIn)
      /* ALWAYS free messages from MLME */
      MSG_Free(pMsgIn);

    
    /* If we are associated then check MCPS queue and UART data buffer. */
    if(state == stateListen)
    {
      /* Get input from MCPS. */
      if(MSG_Pending(&mMcpsNwkInputQueue))
      {
        pMsgIn = MSG_DeQueue(&mMcpsNwkInputQueue);
        App_HandleMcpsInput(pMsgIn);
        /* ALWAYS free messages from MCPS */
        MSG_Free(pMsgIn);
      }

      /* Check if the UART buffer has data to be sent. */
      App_TransmitUartData();
    }
  
    /* 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 2 on 16 channels approximately takes 1.2 secs. */
    /* We know beforehand that we will talk to a coordinator with a Beacon
       order of 1. Thus, choosing a Scan Duration of 2 per channel gives us
       a very good chance (100% assuming no interference) of finding the
       coordinator. 1 should be fine too though in an RF quiet environment. */
    pScanReq->scanDuration = 2;
    
    /* Send the Scan request to the MLME. */
    if(MSG_Send(NWK_MLME, pMsg) == gSuccess_c)
    {
      Uart_Print("Done\n");

⌨️ 快捷键说明

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