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

📄 endpoint.c

📁 该代码为Jennic的基于IEEE802.15.4协议的Zigbee协议栈星型网源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    sMlmeReqRsp.uParam.sReqScan.u8ScanType = MAC_MLME_SCAN_TYPE_ACTIVE;
    sMlmeReqRsp.uParam.sReqScan.u32ScanChannels = DEMO_CHANNEL_BITMAP;
    sMlmeReqRsp.uParam.sReqScan.u8ScanDuration = 3;
    vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);

    /* Check immediate response */
    if (sMlmeSyncCfm.u8Status != MAC_MLME_CFM_DEFERRED)
    {
        /* Unexpected result: scan request should result in a deferred
           confirmation (i.e. we will receive it later) */
        vDisplayError("Scan request returned error",
                      ((uint32)sMlmeSyncCfm.u8Status) << 8
                      | (uint32)sMlmeSyncCfm.uParam.sCfmScan.u8Status);
    }
}

/****************************************************************************
 *
 * NAME: vStartSync
 *
 * DESCRIPTION:
 * Sends an MLME request to the 802.15.4 to start synchronisation on the
 * channel determined by a previous scan. There is no confirmation for this.
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vStartSync(void)
{
    MAC_MlmeReqRsp_s  sMlmeReqRsp;
    MAC_MlmeSyncCfm_s sMlmeSyncCfm;

    sDemoData.sSystem.eState = E_STATE_SYNCING;

#ifdef UART0_DEBUG
    vDebug("Sy ");
#endif

    /* Set the coordinator source address before syncing to avoid PAN conflict
       indication */
    s_psMacPib->u16CoordShortAddr = DEMO_COORD_ADDR;

    /* Create sync request on channel selected during scan */
    sMlmeReqRsp.u8Type = MAC_MLME_REQ_SYNC;
    sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqSync_s);
    sMlmeReqRsp.uParam.sReqSync.u8Channel = sDemoData.sSystem.u8Channel;
    sMlmeReqRsp.uParam.sReqSync.u8TrackBeacon = TRUE;

    /* Put in sync request. There is no deferred confirm for this, we just get
       a SYNC-LOSS later if it didn't work */
    vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);
}

/****************************************************************************
 *
 * NAME: vStartAssociate
 *
 * DESCRIPTION:
 * Sends an MLME request to the 802.15.4 to request an association with the
 * coordinator found during a previous scan. If the  returned confirmation is
 * not 'deferred', a fatal error is assumed.
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vStartAssociate(void)
{
    MAC_MlmeReqRsp_s  sMlmeReqRsp;
    MAC_MlmeSyncCfm_s sMlmeSyncCfm;

    sDemoData.sSystem.eState = E_STATE_ASSOCIATING;

#ifdef UART0_DEBUG
    vDebug("As ");
#endif

    /* Create associate request. We know short address and PAN ID of
       coordinator as this is preset and we have checked that received
       beacon matched this */
    sMlmeReqRsp.u8Type = MAC_MLME_REQ_ASSOCIATE;
    sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqAssociate_s);
    sMlmeReqRsp.uParam.sReqAssociate.u8LogicalChan = sDemoData.sSystem.u8Channel;
    sMlmeReqRsp.uParam.sReqAssociate.u8Capability = 0x80; /* We want short address, other features off */
    sMlmeReqRsp.uParam.sReqAssociate.u8SecurityEnable = FALSE;
    sMlmeReqRsp.uParam.sReqAssociate.sCoord.u8AddrMode = 2;
    sMlmeReqRsp.uParam.sReqAssociate.sCoord.u16PanId = DEMO_PAN_ID;
    sMlmeReqRsp.uParam.sReqAssociate.sCoord.uAddr.u16Short = DEMO_COORD_ADDR;

    /* Put in associate request and check immediate confirm. Should be
       deferred, in which case response is handled by event handler */
    vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);
    if (sMlmeSyncCfm.u8Status != MAC_MLME_CFM_DEFERRED)
    {
        /* Unexpected result */
        vDisplayError("Associate request returned error",
                      ((uint32)sMlmeSyncCfm.u8Status) << 8
                      | (uint32)sMlmeSyncCfm.uParam.sCfmAssociate.u8Status);
    }
}

/****************************************************************************
 *
 * NAME: vProcessInterrupts
 *
 * DESCRIPTION:
 * Loops around checking for upward events from the Application Queue API.
 * To save power, the CPU is set to doze at the start of the loop. If an event
 * is generated, the CPU is woken up and processes it, then the code here is
 * allowed to continue.
 *
 * For each type of event, the queue is checked and, if there is something to
 * process, the appropriate handler is called. The buffer is then returned to
 * the Application Queue API. This continues until all events have been
 * processed. If the hardware event handler detects that a 'reset' button
 * press sequence has happened, the loop is exited.
 *
 * Note that the buttons are configured to generate interrupts when they are
 * pressed.
 *
 * RETURNS:
 * void when a 'reset' button press sequence is detected.
 *
 ****************************************************************************/
PRIVATE void vProcessInterrupts(void)
{
    MAC_MlmeDcfmInd_s *psMlmeInd;
    MAC_McpsDcfmInd_s *psMcpsInd;
    AppQApiHwInd_s    *psAHI_Ind;
    bool_t             bDone;

    /* Wait for events */
    bDone = FALSE;
    do
    {

        /* Doze CPU: it will wake when interrupt occurs, then process
           interrupts, then this code will be able to process queue */
        vAHI_CpuDoze();

        /* Check for anything on the MCPS upward queue */
        do
        {
            psMcpsInd = psAppQApiReadMcpsInd();
            if (psMcpsInd != NULL)
            {
                vProcessIncomingMcps(psMcpsInd);
                vAppQApiReturnMcpsIndBuffer(psMcpsInd);
            }
        } while (psMcpsInd != NULL);

        /* Check for anything on the MLME upward queue */
        do
        {
            psMlmeInd = psAppQApiReadMlmeInd();
            if (psMlmeInd != NULL)
            {
                vProcessIncomingMlme(psMlmeInd);
                vAppQApiReturnMlmeIndBuffer(psMlmeInd);
            }
        } while (psMlmeInd != NULL);

        /* Check for anything on the AHI upward queue */
        do
        {
            psAHI_Ind = psAppQApiReadHwInd();
            if (psAHI_Ind != NULL)
            {
                /* We don't bother to pass the queue data as we are only
                   expecting key press interrupts and, if we get anything else,
                   reading the keys won't have any unfortunate side effects */
                if (bProcessKeyPress() == TRUE)
                {
                    bDone = TRUE;
                }
                vAppQApiReturnHwIndBuffer(psAHI_Ind);
            }
        } while (psAHI_Ind != NULL);

    } while (bDone == FALSE);
}

/****************************************************************************
 *
 * NAME: vProcessIncomingMcps
 *
 * DESCRIPTION:
 * Deals with any incoming MCPS data events. Only deferred confirmations of
 * frame transmission requests are specifically handled, to move the state
 * machine forward.
 *
 * PARAMETERS: Name        RW  Usage
 *             psMcpsInd   R   Pointer to structure containing MCPS event
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vProcessIncomingMcps(MAC_McpsDcfmInd_s *psMcpsInd)
{
    /* Process MCPS indication by checking if it is a confirmation of our
       outgoing frame */
    if ((psMcpsInd->u8Type == MAC_MCPS_DCFM_DATA)
        && (sDemoData.sSystem.eState == E_STATE_TX_DATA))
    {
        if (psMcpsInd->uParam.sDcfmData.u8Handle == sDemoData.sTransceiver.u8CurrentTxHandle)
        {
            /* Increment handle for next time. Increment failures */
            sDemoData.sTransceiver.u8CurrentTxHandle++;

            /* Start to read sensors. This takes a while but rather than
               wait for an interrupt we just poll and, once finished, move back
               to the running state to wait for the next beacon. Not a power
               saving solution! */
            sDemoData.sSystem.eState = E_STATE_READ_SENSORS;
            vProcessRead();
            sDemoData.sSystem.eState = E_STATE_RUNNING;
        }
    }
}

/****************************************************************************
 *
 * NAME: vProcessIncomingMlme
 *
 * DESCRIPTION:
 * Deals with any incoming MCPS events. There are 4 events that are handled:
 *
 * 1. Scan deferred confirmation
 *    If the scan saw a beacon from the expected coordinator, the stack is
 *    asked to start synchronisation. Otherwise, it tries to scan again.
 *
 * 2. Associate deferred confirmation
 *    If the association was successful, the short address is stored and the
 *    device enters the 'running' state, in which it will respond to beacons
 *    by sending back a frame of sensor information. If the association was
 *    not successful, it is attempted again.
 *
 * 3. Becon notify indication
 *    If synchronising, this is used to indicate that synchronisation is
 *    complete and association is atempted. If in 'running' state, it is
 *    used to trigger the sending of a frame containing sensor information
 *    to the coordinator.
 *
 * 4. Sync loss indication
 *    Device starts another scan.
 *
 * PARAMETERS: Name        RW  Usage
 *             psMlmeInd   R   Pointer to structure containing MLME event
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vProcessIncomingMlme(MAC_MlmeDcfmInd_s *psMlmeInd)
{
    MAC_PanDescr_s *psPanDesc;
    int i;

    /* We respond to several MLME indications and confirmations, depending
       on mode */
    switch (psMlmeInd->u8Type)
    {
    case MAC_MLME_DCFM_SCAN:
#ifdef UART0_DEBUG
        vDebug("MSc ");
#endif
        /* Only respond to this if scanning */
        if (sDemoData.sSystem.eState == E_STATE_SCANNING)
        {
#ifdef UART0_DEBUG
            vDebug("MScSt ");
#endif
            /* Make sure it is what we're after */
            switch (psMlmeInd->uParam.sDcfmScan.u8Status)
            {
            case MAC_ENUM_SUCCESS:
                if (psMlmeInd->uParam.sDcfmScan.u8ScanType == MAC_MLME_SCAN_TYPE_ACTIVE)
                {
#ifdef UART0_DEBUG
                    vDebug("MScOk ");
#endif
                    /* Determine which, if any, network contains demo coordinator.
                       Algorithm for determining which network to connect to is
                       beyond the scope of 802.15.4, and we use a simple approach
                       of matching the required PAN ID and short address, both of
                       which we already know */
                    i = 0;
                    while (i < psMlmeInd->uParam.sDcfmScan.u8ResultListSize)
                    {
                        psPanDesc = &psMlmeInd->uParam.sDcfmScan.uList.asPanDescr[i];
#ifdef UART0_DEBUG
                        vDisplayHex(psPanDesc->u8LogicalChan, 2);
                        vDebug(":");
                        vDisplayHex(psPanDesc->sCoord.u16PanId, 4);
                        vDebug(":");
                        vDisplayHex(psPanDesc->sCoord.uAddr.u16Short, 4);
                        vDebug(" ");
#endif
                        if ((psPanDesc->sCoord.u16PanId == DEMO_PAN_ID)
                            && (psPanDesc->sCoord.u8AddrMode == 2)
                            && (psPanDesc->sCoord.uAddr.u16Short == DEMO_COORD_ADDR))
                        {
#ifdef UART0_DEBUG
                            vDebug("MScUs ");
#endif
                            /* Matched so start to synchronise and associate */
                            sDemoData.sSystem.u8Channel = psPanDesc->u8LogicalChan;
                            vStartSync();
                            return;
                        }
                        i++;
                    }

                    /* Failed to find coordinator: keep trying */
                    vStartScan();
                }
                break;

            case MAC_ENUM_NO_BEACON:
                /* Failed to find coordinator: keep trying */
                vStartScan();
                break;

            default:
                break;
            }
        }
        break;


    case MAC_MLME_DCFM_ASSOCIATE:
        /* Only respond if in associating mode */
        switch (sDemoData.sSystem.eState)
        {
        case E_STATE_ASSOCIATING:
            if (psMlmeInd->uParam.sDcfmAssociate.u8Status == MAC_ENUM_SUCCESS)
            {
                /* Store short address */
                sDemoData.sSystem.u16ShortAddr = psMlmeInd->uParam.sDcfmAssociate.u16AssocShortAddr;

                /* Node is a value between 0 and the number of endpoints - 1.
                   It is determined by the short address */
                sDemoData.sSystem.u8ThisNode = sDemoData.sSystem.u16ShortAddr - DEMO_ENDPOINT_ADDR_BASE;

                /* We are now in the running state */
                sDemoData.sSystem.eState = E_STATE_RUNNING;
            }
            else

⌨️ 快捷键说明

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