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

📄 mac_beacon_handler.c

📁 ucos在NEC平台下的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
        // Remain in this state until the beacon transmission can begin
        if ((mtimInfo.bosCounter - bacupBosCounter) == MBCN_TX_PREPARE_TIME) {
    
            // Resume transmission of direct packets after the beacon transmission
                        
            mtimSetCallback(mtxResumeAfterBeaconCallback, (pPacket->duration + MBCN_TX_STARTUP_OVERHEAD )); 
                        
            // Set the RX interval (if any)
            if (mpib.macSuperframeOrder != 15) {
                if (mpib.macRxOnWhenIdle) {
                
                    // On:
                    mrxAutoIncrOnCounter();

                    // Off:
                    if (mpib.macBattLifeExt) {
                        // Soft off
                        mtimSetCallback(mrxDecrOnCounter, pPacket->duration + mpib.macBattLifeExtPeriods - MBCN_TX_PREPARE_TIME);
                    } else {
                        // Force when the superframe is shorter than the beacon interval
                        mtimSetCallback((mpib.macBeaconOrder == mpib.macSuperframeOrder) ? mrxDecrOnCounter : mrxForceRxOff, msupCalcSuperframeDuration() - MBCN_TX_PREPARE_TIME);
                    }
                }
            }
            
            // Transform this task into an mtxStartTransmission()
            pTask->state = MTX_STATE_TURN_ON_RX;
            pTask->taskData = (WORD) pPacket;
            pTask->pTaskFunc = mtxStartTransmission;
            
        // Disaster :(
        // The prepare time was too short!!! (DEBUG: Add a breakpoint here if beacons are missing)
        } else if ((mtimInfo.bosCounter - bacupBosCounter) > MBCN_TX_PREPARE_TIME) {
            
            // Don't transmit the beacon
            mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM | MSCH_KEEP_TASK_IN_PROGRESS_BM);
        }
        break;
    }
    
} // mbcnTxPeriodicalBeaconTask




//-------------------------------------------------------------------------------------------------------
//  void mbcnPrepareCoordinatorRealignment(MAC_TX_PACKET *pPacket, QWORD *pDestAddr, WORD shortAddr, ...)
//
//  DESCRIPTION:
//      This function prepares a coordinator realignment frame. If the pDestAddr argument points to an
//      extended address, the packet will be transmitted to a single device (doing orphan scanning). If
//      NULL, the packet will be broadcasted to all devices.
//
//  ARGUMENTS:
//      MAC_TX_PACKET *pPacket
//          A pointer to the packet to be transmitted 
//      QWORD *pDestAddr
//          A pointer to the extended address of a specific device (mlmeOrphanResponse), or NULL if the 
//          coordinator realignment is to be broadcasted (mlmeStartRequest)
//      WORD shortAddr
//          The short address of the orphaned device, or 0xFFFF when the coordinator realignment is
//          broadcasted
//      BOOL securityEnable
//          TBD
//      WORD newPanId
//          The PAN ID to be used in the future
//      UINT8 logicalChannel
//          The logical channel (11-26) to be used in the future
//-------------------------------------------------------------------------------------------------------
void mbcnPrepareCoordinatorRealignment(MAC_TX_PACKET *pPacket, QWORD *pDestAddr, WORD shortAddr, BOOL securityEnable, WORD newPanId, UINT8 logicalChannel) {
    WORD broadcast = 0xFFFF;    
    BYTE txOptions;
    UINT8 temp;
    BYTE *pPayload;

    // TX mode
    pPacket->txMode = MTX_MODE_USE_CSMACA_BM;

    // Set the TX options
    txOptions = TX_OPT_NONE;

#if MAC_OPT_SECURITY
    if (securityEnable) txOptions |= TX_OPT_SECURITY_ENABLE;
#endif

    // Generate the packet header
    if (pDestAddr) {
        pPacket->retriesLeft = aMaxFrameRetries;
        txOptions |= TX_OPT_ACK_REQ;
        msupPrepareHeader(pPacket, FT_MAC_COMMAND, SRC_ADDR_EXT | DEST_ADDR_EXT, mpib.macPANId, (ADDRESS*) &aExtendedAddress, broadcast, (ADDRESS*) pDestAddr, txOptions);
    } else {
        // pPacket->retriesLeft will be ignored (no ack)
        pPacket->txMode |= MTX_MODE_MAC_INTERNAL_BM;
        shortAddr = broadcast;
        msupPrepareHeader(pPacket, FT_MAC_COMMAND, SRC_ADDR_EXT | DEST_ADDR_SHORT, mpib.macPANId, (ADDRESS*) &aExtendedAddress, broadcast, (ADDRESS*) &broadcast, txOptions);
    }

    // Store the command type
    pPacket->mc.commandType = CMD_COORDINATOR_REALIGNMENT;///

    // Command frame identifier
    pPayload = pPacket->pPayload;
    *(pPayload++) = CMD_COORDINATOR_REALIGNMENT;
    
#if MAC_OPT_SECURITY
    // #bytes in frame counter + key sequence counter (0 or 5)
    temp = msecProcessSecurityCounters(pPacket, pPayload);

    // In case of frame counter overflow or missing key
    // Generate error with FAILED_SECURITY_CHECK or UNAVAILABLE_KEY

    // Increment payload pointer when counters inserted
    pPayload += temp;

    // Include command payload length and optional MIC (integrity code) length
    temp += CMD_COORDINATOR_REALIGNMENT_PAYLOAD_LENGTH + pPacket->securitySetup.micLength;

#else
    // No security material included, set MAC payload length
    temp = CMD_COORDINATOR_REALIGNMENT_PAYLOAD_LENGTH;
#endif

    // Set the packet length (four bytes of payload)
    pPacket->length = pPacket->headerLength + temp + MAC_FCS_LENGTH;

    // Generate the packet payload
    *(pPayload++) = (BYTE) newPanId;
    *(pPayload++) = (BYTE) ((newPanId & 0xFF00) >> 8);
    *(pPayload++) = (BYTE) mpib.macShortAddress;
    *(pPayload++) = (BYTE) ((mpib.macShortAddress & 0xFF00) >> 8);
    *(pPayload++) = logicalChannel;
    *(pPayload++) = (BYTE) shortAddr;
    *(pPayload)   = (BYTE) ((shortAddr & 0xFF00) >> 8);

    // Calculate the packet duration (including ack. and IFS)
    pPacket->duration = msupCalcPacketDuration(pPacket->length, txOptions & TX_OPT_ACK_REQ);
    
} // mbcnPrepareCoordinatorRealignment




//-------------------------------------------------------------------------------------------------------
//  void mbcnPrepareBeacon(void)
//
//  DESCRIPTION:
//      Prepares a valid beacon frame which can be transmitted using the TX engine.
//
//  ARGUMENTS:
//      MAC_TX_PACKET *pPacket
//          A pointer to the packet to be transmitted 
//-------------------------------------------------------------------------------------------------------
void mbcnPrepareBeacon(MAC_TX_PACKET *pPacket) {
    BYTE srcAddrMode;    
    WORD superframeSpec;
    BYTE *pMacBeaconPayload;
    BYTE pendAddrSpec; 
    MAC_TX_PACKET *pIndirectPacket;
    UINT8 n, pendShortAddrCount, pendExtAddrCount;
    BYTE *pPayload = pPacket->pPayload;
    
    // TX mode
    pPacket->txMode = 0; 
    // pPacket->retriesLeft will be ignored (no ack)
    
    // Header    
    srcAddrMode = (mpib.macShortAddress < 0xFFFE) ? SRC_ADDR_SHORT : SRC_ADDR_EXT;
    msupPrepareHeader(pPacket, FT_BEACON, srcAddrMode, mpib.macPANId, (srcAddrMode == SRC_ADDR_SHORT) ? (ADDRESS*) &mpib.macShortAddress : (ADDRESS*) &aExtendedAddress, 0, NULL, GET_MF(MF_BEACON_SECURITY));

    // Superframe specification
    superframeSpec = (mpib.macBeaconOrder << SS_BEACON_ORDER_IDX) |
                     (mpib.macSuperframeOrder << SS_SUPERFRAME_ORDER_IDX) |
                     (15 << SS_FINAL_CAP_SLOT_IDX) |
                     (mpib.macBattLifeExt ? SS_BATT_LIFE_EXT_BM : 0) |
                     (GET_MF(MF_PAN_COORDINATOR) ? SS_PAN_COORDINATOR_BM : 0) |
                     (mpib.macAssociationPermit ? SS_ASSOCIATION_PERMIT_BM : 0);
    *((WORD*) pPayload) = superframeSpec;
    pPayload += 2;
        
    // GTS list (not implemented)
    *(pPayload++) = 0x00;
    
    // Pending address list
    
    // Count the number of pending addresses to get the packet length
    n = miqInfo.firstIndirectPacket;
    pendShortAddrCount = 0;
    pendExtAddrCount = 0;
    while ((n != NO_PACKET) && ((pendShortAddrCount + pendExtAddrCount) < MAX_PENDING_LIST_SIZE)) {
        pIndirectPacket = &pMtxPacketPool[n];
        if (pIndirectPacket->timeToLive > 0) {
            if (pIndirectPacket->isFirstPacket) {
                if ((pIndirectPacket->pHeader[1] & DEST_ADDR_BM) == DEST_ADDR_EXT) {
                    pendExtAddrCount++;
                } else {
                    pendShortAddrCount++;
                }
            }
        }
        n = pIndirectPacket->nextPacket;
    }
    
    // Pending address specification (indicates the number of short and extended addresses)
    pendAddrSpec = pendShortAddrCount + (pendExtAddrCount << 4);        
    *(pPayload++) = pendAddrSpec;
    
    // Address list
    if (pendAddrSpec) {
        
        // Short addresses
        n = miqInfo.firstIndirectPacket;
        do {
            pIndirectPacket = &pMtxPacketPool[n];
            if (pIndirectPacket->isFirstPacket && (pIndirectPacket->timeToLive > 0) && ((pIndirectPacket->pHeader[1] & DEST_ADDR_BM) == DEST_ADDR_SHORT)) {
                
                // Copy the packet destination address
                memcpy(pPayload, pIndirectPacket->pHeader + 5, 2);
                pendShortAddrCount--;
                pPayload += 2;
            }
            n = pIndirectPacket->nextPacket;
        } while (pendShortAddrCount);
        
        // Extended addresses
        n = miqInfo.firstIndirectPacket;
        do {
            pIndirectPacket = &pMtxPacketPool[n];
            if (pIndirectPacket->isFirstPacket && (pIndirectPacket->timeToLive > 0) && ((pIndirectPacket->pHeader[1] & DEST_ADDR_BM) == DEST_ADDR_EXT)) {
                
                // Copy the packet destination address
                memcpy(pPayload, pIndirectPacket->pHeader + 5, 8);
                pendExtAddrCount--;
                pPayload += 8;
            }
            n = pIndirectPacket->nextPacket;
        } while (pendExtAddrCount);
    }
    
    // Beacon payload (safe access to mpib.pMacBeaconPayload)
    DISABLE_GLOBAL_INT();
    pMacBeaconPayload = mpib.pMacBeaconPayload;
    ENABLE_GLOBAL_INT();
    memcpy(pPayload, pMacBeaconPayload, mpib.macBeaconPayloadLength);
    pPayload += mpib.macBeaconPayloadLength;
    

⌨️ 快捷键说明

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