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

📄 zmac.c

📁 zigbee精简协议栈代码
💻 C
📖 第 1 页 / 共 5 页
字号:

            // Try again.
            smAssociation = SM_SEND_DISASSOCIATE_REQ;

        }
    }


    return result;
}

#endif

/*********************************************************************
 * Function:        static void MACSendAck(ACK_TYPE typeOfAck)
 *
 * PreCondition:    A valid frame has just arrived.
 *
 * Input:           typeOfAck - either ACK_NO_DATA or ACK_NO_DATA_PENDING
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends ACK frame in response to just received
 *                  frame.
 *
 * Note:            This is a private function
 ********************************************************************/
static void MACSendAck(ACK_TYPE ack)
{
    // First, update the packet length.
    PHYBegin();

    PHYSendAck(ack);

    // Terminate RAM access
    PHYEnd();

    //TODO(DF16) - Investigate error.  Without the following delay the
    //FCS value of the ACK packet gets corrupted/ miscalculated.
    {BYTE i = 0x40; while(++i){nop();}}
}

/*********************************************************************
 * Function:        BOOL MACProcessAssociation(void)
 *
 * PreCondition:    A valid frame is in RX buffer and
 *                  header is already fetched and processed.
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Fetches rest of the frame and processes it if
 *                  is a valid association request frame.
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
BOOL MACProcessAssociation(void)
{
    BOOL lbResult = FALSE;

   

    // There must be exactly two bytes of data in association request frame.
    if( macCurrentFrame.frameLength == 1 )
    {
        // Make sure that current frame is indeed association request.
        // LSB = Mask: 0b00100111 Value: 0b00100011,

        if ( ((BYTE)(macCurrentFrame.frameCONLSB.Val & 0x27) == (BYTE)0x23))
        {
            macCurrentFrame.capInfo.Val = MACGet();

            return TRUE;
        }
    }

    return FALSE;
}

/*********************************************************************
 * Function:        HFRAME MACSendAssociateResponse(
 *                              SHORT_ADDR *assocShortAddr,
 *                              MAC_ASSOCIATE_STATUS status)
 *
 * PreCondition:    assocShortAddr  - Short address to be sent
 *                                    as part of association response
 *                  status          - Association result code to be sent
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Creates and sends valid association response frame
 *                  as per IEEE spec.
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
HFRAME MACSendAssociateResponse(SHORT_ADDR *assocShortAddr,
                              MAC_ASSOCIATE_STATUS status)
{
ConsolePutString("send response\n");
    macInfo.addrMode = MAC_SRC_LONG_ADDR;

    // Use information from macCurrentFrame to build response frame.
    // If we arrive at this point, macCurrentFrame must be a valid
    // Associate Request and as a result, we will only change those fields
    // that needs to changed as part of response frame format.
    macCurrentFrame.src.addrMode = MAC_DST_LONG_ADDR;

    // Dest panID will be same as ours.
    macCurrentFrame.src.panID.Val = macInfo.panID.Val;

    MACPutHeader(&macCurrentFrame.src,         // Dest
                  MAC_FRAME_CMD |           // Frame Control LSB
                  MAC_SECURITY |
                  MAC_FRAME_PENDING_NO |
                  MAC_ACK_YES |
                  MAC_INTRA_PAN_NO);



    PHYBeginTxFIFOAccess();
    PHYPutTxData(MAC_CMD_ASSOCIATE_RPLY);
    PHYPutTxData(assocShortAddr->byte.LSB);
    PHYPutTxData(assocShortAddr->byte.MSB);
    PHYPutTxData((BYTE)status);
    PHYEndTxFIFOAccess();

    // Manually update packet length here instead of calling MACPut() and adding more code
    // and time.
    macPacketLen += 4;

    return MACFlush();

}

/*********************************************************************
 * Function:        HFRAME MACSendRealignment(
 *                          SHORT_ADDR *destShortAddr, BOOL bBroadcast)
 *
 * PreCondition:    MACIsPutReady() = TRUE
 *
 * Input:           destShortAddr - node to whom relignment frame to send
 *                  bBroadcast    - indicates if this is to be broadcast
 *
 * Output:          Handle to frame that was just transmitted.
 *                  Caller must use this handle to determine if this
 *                  frame was ack'ed by intended remote node.
 *
 * Side Effects:    None
 *
 * Overview:        Creates and sends valid relignment frame
 *                  as per IEEE spec.
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
HFRAME MACSendRealignment(SHORT_ADDR *destShortAddr, BOOL bBroadcast)
{
    BYTE frameFlags;

    macInfo.addrMode = MAC_SRC_LONG_ADDR;
    // Other information is already set.

    // If this is a unicast, we need to use LONG address.
    // Since we already have remote device's address information
    // in current frame, we will use current frame's source as
    // destination for this frame.
    if ( bBroadcast == FALSE )
    {
        macCurrentFrame.src.addrMode = MAC_DST_LONG_ADDR;

        // For unicast frame, request ack.
        frameFlags = MAC_FRAME_CMD |
                     MAC_SECURITY |
                     MAC_FRAME_PENDING_NO |
                     MAC_ACK_YES |
                     MAC_INTRA_PAN_NO;
    }

    else
    {
        macCurrentFrame.src.addrMode = MAC_DST_SHORT_ADDR;
        macCurrentFrame.src.shortAddr.Val = 0xffff;

        // For broadcast, do not request ack.
        frameFlags = MAC_FRAME_CMD |
                     MAC_SECURITY |
                     MAC_FRAME_PENDING_NO |
                     MAC_ACK_NO |
                     MAC_INTRA_PAN_NO;
    }

    // The destination PAN will be 0xFFFF
    macCurrentFrame.src.panID.Val = 0xffff;

    MACPutHeader(&macCurrentFrame.src, frameFlags);

    // Now load coord realignment specific payload.
    PHYBegin();
    PHYSelectTxFIFO();
    PHYPut(MAC_CMD_COORD_REALIGNMENT);

    // Current PAN ID.
    PHYPut(macInfo.panID.byte.LSB);
    PHYPut(macInfo.panID.byte.MSB);

    //du 不一定是真正的coord
    PHYPut(macInfo.shortAddr.byte.LSB);
    PHYPut(macInfo.shortAddr.byte.MSB);

    // Logical channel
    PHYPut(macCurrentChannel);

    // If this is a unicast, supply dest short addr.
    if ( bBroadcast == FALSE )
    {	
		//du 收到后被忽略
        PHYPut(destShortAddr->byte.LSB);
        PHYPut(destShortAddr->byte.MSB);
    }
    else
    {
        // For broadcast, this will be 0xffff.
        PHYPut(0xff);
        PHYPut(0xff);
    }

    PHYEnd();

    // Update MACPacketLen manually.
    macPacketLen += 8;

    return MACFlush();

}

/*********************************************************************
 * Function:        BOOL MACProcessDisassociation(void)
 *
 * PreCondition:    MACGetHeader() is already called and this frame
 *                  is identified as Disassociate command frame.
 *
 * Input:           None
 *
 * Output:          TRUE if found valid association frame.
 *                  FALSE othersie
 *
 * Side Effects:    None
 *
 * Overview:        Fetches rest of disassociation frame and validates
 *                  as per IEEE spec.
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
#if defined(I_AM_COORDINATOR)
BOOL MACProcessDisassociation(void)
{
    // There must be exactly two bytes of data in association request frame.
    if( macCurrentFrame.frameLength == 1 )
    {
        // A disassociation request must have
        // 1. Both source and destination addressing mode = 64-bit addresses.
        // 2. Frame pending field set to 0.
        // 3. Acknowledge field set to 1
        //
        // Make sure that current frame is indeed association request.
        // LSB = Mask: 0b00100111 Value: 0b00100011,
        // MSB = Mask: 0b11001100 Value: 0b11001100
        if ( ((BYTE)(macCurrentFrame.frameCONLSB.Val & 0x27) == (BYTE)0x23) &&
             ((BYTE)(macCurrentFrame.frameCONMSB.Val & 0xCC) == (BYTE)0xCC) )
        {
            // Fetch and discard disassociation reason.
            MACGet();

            return TRUE;
        }
    }

    return FALSE;
}
#endif

/*********************************************************************
 * Function:        static void MACSendBeaconReq(void)
 *
 * PreCondition:    MACIsPutready() = TRUE
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends out beacon request
 *
 * Note:            None
 ********************************************************************/
static void MACSendBeaconReq(void)
{
    // Now that we are trying to associate, forget previous PAN ID
    macInfo.addrMode    = MAC_SRC_NO_ADDR;

    // Coordinator info will be same as what was received in beacon.
    // But for time being use hardcoded value to test out...
    macCoordInfo.addrMode       = MAC_DST_SHORT_ADDR;
    macCoordInfo.shortAddr.Val  = 0xffff;
    macCoordInfo.panID.Val      = 0xffff;

    MACPutHeader(&macCoordInfo,             // Dest
                  MAC_FRAME_CMD |           // Frame Control LSB
                  MAC_SECURITY |
                  MAC_FRAME_PENDING_NO |
                  MAC_ACK_NO |
                  MAC_INTRA_PAN_NO);


    // Load beacon req specific bytes in payload area.
    PHYBeginTxFIFOAccess();
    PHYPutTxData(MAC_CMD_BEACON_REQ);
    PHYEndTxFIFOAccess();

    // Manually update packet length here instead of calling MACPut() and adding more code
    // and time.
    macPacketLen++;

    // Mark it as ready to transmit
    MACFlush();


}

/*********************************************************************
 * Function:        static void MACSendBeacon(void)
 *
 * PreCondition:    MACIsPutready() = TRUE
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends out beacon
 *
 * Note:            Available to coordinator only
 ********************************************************************/
static void MACSendBeacon(void)
{

    macInfo.addrMode = MAC_SRC_SHORT_ADDR;

    //du beacon frame没有目的地址
    macDestInfo.addrMode = MAC_DST_NO_ADDR;

    MACPutHeader(&macDestInfo,                 // Dest
                  MAC_FRAME_BEACON |            // Frame Control LSB
                  MAC_SECURITY |
                  MAC_FRAME_PENDING_NO |
                  MAC_ACK_NO |
                  MAC_INTRA_PAN_NO);


    // Load beacon specific bytes into payload area.
    PHYBeginTxFIFOAccess();
    PHYPutTxData(SUPERFRAME_SPEC_LSB);
    PHYPutTxData(SUPERFRAME_SPEC_MSB);
    PHYPutTxData(GTS_FIELD_VAL);

    // Pending address field - TBD
    PHYPutTxData(0x00);

    //Protocol ID
    //0x00 as specified in table 45 NWK spec
    PHYPutTxData(0x00);

    //Stack profile (8-11) and nwkcProtocolVersion (12-15)
    //nwkcProtocolVersion = 0x01 because ZigBee v1.0
    PHYPutTxData(0x10);

    //nwkSecurityLevel (16-18)
        //0x00 - no security
    //Device router capacity (19)
        //FALSE because we only do star networks right now (no routers)
    //Device depth (20-22)
        //0x00 because we are coordinator
    //device capacity (23)
        //TRUE - we have room
    PHYPutTxData(0x80);

    //TxOffset
    //only included in multihop beaconing networks
    //PHYPutTxData(TxOffset);

    PHYEndTxFIFOAccess();

    // Manually update packet length here instead of calling MACPut() and adding more code
    // and time.
    //macPacketLen += 4;
    macPacketLen += 7;

    MACFlush();
	ConsolePutString("send beacon successfully\n");
    //while(1){wdt_reset();}
}

/*********************************************************************
 * Function:        void MACStartScan(BOOL bActiveScan)
 *
 * PreCondition:    MACInit(), MACEnable() are called
 *                  And MACIsPutReady() == TRUE
 *
 * Input:           bActiveScan - flag to perform active/passive scan
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        If this is active scan, sends out beacon request
 *
 * Note:            None
 ********************************************************************/
void MACStartScan(BOOL bActiveScan)
{
    // Send beacon if this is active scan
    if ( bActiveScan )
    {
        // First send out a beacon
        MACSendBeaconReq();
	
    }


    // Remember time so that we can know when to abort.
    macStartTick = TickGet();

    // Zero out number of discovered coordinators
    PANDescCount = 0;

}

/*********************************************************************
 * Function:        BOOL MACIsScanComplete(void)
 *
 * PreCondition:    MACStartScan() is called.
 *
 * Input:           None
 *
 * Output:          TRUE if scan is complete

⌨️ 快捷键说明

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