?? basic_rf.c
字號:
/***********************************************************************************
Filename: basic_rf.c
Description: Basic RF library
***********************************************************************************/
/***********************************************************************************
* INCLUDES
*/
#include "hal_int.h"
#include "hal_mcu.h" // Using halMcuWaitUs()
#include "hal_rf.h"
#ifdef SECURITY_CCM
#include "hal_rf_security.h"
#endif
#include "basic_rf.h"
#ifdef SECURITY_CCM
#include "basic_rf_security.h"
#endif
#include "util.h" // Using min()
#include "string.h"
/***********************************************************************************
* CONSTANTS AND DEFINES
*/
// Packet and packet part lengths
#define PKT_LEN_MIC 8
#define PKT_LEN_SEC PKT_LEN_UNSEC + PKT_LEN_MIC
#define PKT_LEN_AUTH 8
#define PKT_LEN_ENCR 24
// Packet overhead ((frame control field, sequence number, PAN ID,
// destination and source) + (footer))
// Note that the length byte itself is not included included in the packet length
#define BASIC_RF_PACKET_OVERHEAD_SIZE ((2 + 1 + 2 + 2 + 2) + (2))
#define BASIC_RF_MAX_PAYLOAD_SIZE (127 - BASIC_RF_PACKET_OVERHEAD_SIZE - \
BASIC_RF_AUX_HDR_LENGTH - BASIC_RF_LEN_MIC)
#define BASIC_RF_ACK_PACKET_SIZE 5
#define BASIC_RF_FOOTER_SIZE 2
// The time it takes for the acknowledgment packet to be received after the
// data packet has been transmitted.
#define BASIC_RF_ACK_DURATION (0.5 * 32 * 2 * ((4 + 1) + (1) + (2 + 1) + (2)))
#define BASIC_RF_SYMBOL_DURATION (32 * 0.5)
// The length byte
#define BASIC_RF_PLD_LEN_MASK 0x7F
// Frame control field
#define BASIC_RF_FCF_NOACK 0x8841
#define BASIC_RF_FCF_ACK 0x8861
#define BASIC_RF_FCF_ACK_BM 0x0020
#define BASIC_RF_FCF_BM (~BASIC_RF_FCF_ACK_BM)
#define BASIC_RF_ACK_FCF 0x0002
#define BASIC_RF_SEC_ENABLED_FCF_BM 0x0008
// Auxiliary Security header
#define BASIC_RF_AUX_HDR_LENGTH 5
#define BASIC_RF_LEN_AUTH BASIC_RF_PACKET_OVERHEAD_SIZE + \
BASIC_RF_AUX_HDR_LENGTH - BASIC_RF_FOOTER_SIZE
#define BASIC_RF_SECURITY_M 2
#define BASIC_RF_LEN_MIC 8
// Footer
#define BASIC_RF_CRC_OK_BM 0x80
/***********************************************************************************
* TYPEDEFS
*/
// The receive struct
typedef struct {
uint8 seqNumber;
uint16 srcAddr;
uint16 srcPanId;
int8 length;
uint8* pPayload;
uint8 ackRequest;
int8 rssi;
volatile uint8 isReady;
uint8 status;
} basicRfRxInfo_t;
// Tx state
typedef struct {
uint8 txSeqNumber;
volatile uint8 ackReceived;
uint8 receiveOn;
uint32 frameCounter;
} basicRfTxState_t;
// Basic RF packet header (IEEE 802.15.4)
#ifdef __ICC430__
#pragma pack(1)
#endif
typedef struct {
uint8 packetLength;
uint16 frameControlField;
uint8 seqNumber;
uint16 panId;
uint16 destAddr;
uint16 srcAddr;
#ifdef SECURITY_CCM
uint8 securityControl;
uint32 frameCounter;
#endif
} basicRfPktHdr_t;
#ifdef __ICC430__
#pragma pack()
#endif
/***********************************************************************************
* LOCAL VARIABLES
*/
static basicRfRxInfo_t rxi= { 0xFF }; // Make sure sequence numbers are
static basicRfTxState_t txState= { 0x00 }; // initialised and distinct.
static basicRfCfg_t* pConfig;
static uint8 txMpdu[BASIC_RF_MAX_PAYLOAD_SIZE+BASIC_RF_PACKET_OVERHEAD_SIZE+1];
static uint8 rxMpdu[BASIC_RF_MAX_PAYLOAD_SIZE+BASIC_RF_PACKET_OVERHEAD_SIZE+1];
/***********************************************************************************
* GLOBAL VARIABLES
*/
/***********************************************************************************
* LOCAL FUNCTIONS
*/
static uint8 basicRfBuildHeader(uint8* buffer, uint16 destAddr, uint8 payloadLength);
static uint8 basicRfBuildMpdu(uint16 destAddr, uint8* pPayload, uint8 length);
static void basicRfRxFrmDoneIsr(void);
/***********************************************************************************
* @fn basicRfBuildHeader
*
* @brief Builds packet header according to IEEE 802.15.4 frame format
*
* @param buffer - Pointer to buffer to write the header
* destAddr - destination short address
* payloadLength - length of higher layer payload
*
* @return uint8 - length of header
*/
static uint8 basicRfBuildHeader(uint8* buffer, uint16 destAddr, uint8 payloadLength)
{
basicRfPktHdr_t *pHdr;
pHdr= (basicRfPktHdr_t*)buffer;
// Populate packet header
pHdr->packetLength = payloadLength + BASIC_RF_PACKET_OVERHEAD_SIZE;
pHdr->frameControlField = pConfig->ackRequest ? BASIC_RF_FCF_ACK : BASIC_RF_FCF_NOACK;
pHdr->seqNumber= txState.txSeqNumber;
pHdr->panId= pConfig->panId;
pHdr->destAddr= destAddr;
pHdr->srcAddr= pConfig->myAddr;
#ifdef SECURITY_CCM
// Add security to FCF, length and security header
pHdr->frameControlField |= BASIC_RF_SEC_ENABLED_FCF_BM;
pHdr->packetLength += PKT_LEN_MIC;
pHdr->packetLength += BASIC_RF_AUX_HDR_LENGTH;
pHdr->securityControl= SECURITY_CONTROL;
pHdr->frameCounter= txState.frameCounter;
#endif
// Make sure bytefields are network byte order
UINT16_HTON(pHdr->frameControlField);
UINT16_HTON(pHdr->panId);
UINT16_HTON(pHdr->destAddr);
UINT16_HTON(pHdr->srcAddr);
return sizeof(basicRfPktHdr_t);
}
/***********************************************************************************
* @fn basicRfBuildMpdu
*
* @brief Builds mpdu (MAC header + payload) according to IEEE 802.15.4
* frame format
*
* @param destAddr - Destination short address
* pPayload - pointer to buffer with payload
* payloadLength - length of payload buffer
*
* @return uint8 - length of mpdu
*/
static uint8 basicRfBuildMpdu(uint16 destAddr, uint8* pPayload, uint8 payloadLength)
{
uint8 hdrLength, n;
hdrLength = basicRfBuildHeader(txMpdu, destAddr, payloadLength);
for(n=0;n<payloadLength;n++)
{
txMpdu[hdrLength+n] = pPayload[n];
}
return hdrLength + payloadLength; // total mpdu length
}
/***********************************************************************************
* @fn basicRfRxFrmDoneIsr
*
* @brief Interrupt service routine for received frame from radio
* (either data or acknowlegdement)
*
* @param rxi - file scope variable info extracted from the last incoming
* frame
* txState - file scope variable that keeps tx state info
*
* @return none
*/
static void basicRfRxFrmDoneIsr(void)
{
basicRfPktHdr_t *pHdr;
uint8 *pStatusWord;
#ifdef SECURITY_CCM
uint8 authStatus=0;
#endif
// Map header to packet buffer
pHdr= (basicRfPktHdr_t*)rxMpdu;
// Clear interrupt and disable new RX frame done interrupt
halRfDisableRxInterrupt();
// Enable all other interrupt sources (enables interrupt nesting)
halIntOn();
// Read payload length.
halRfReadRxBuf(&pHdr->packetLength,1);
pHdr->packetLength &= BASIC_RF_PLD_LEN_MASK; // Ignore MSB
// Is this an acknowledgment packet?
// Only ack packets may be 5 bytes in total.
if (pHdr->packetLength == BASIC_RF_ACK_PACKET_SIZE) {
// Read the packet
halRfReadRxBuf(&rxMpdu[1], pHdr->packetLength);
// Make sure byte fields are changed from network to host byte order
UINT16_NTOH(pHdr->frameControlField);
UINT16_NTOH(pHdr->panId);
UINT16_NTOH(pHdr->destAddr);
UINT16_NTOH(pHdr->srcAddr);
#ifdef SECURITY_CCM
UINT32_NTOH(pHdr->frameCounter);
#endif
rxi.ackRequest = !!(pHdr->frameControlField & BASIC_RF_FCF_ACK_BM);
// Read the status word and check for CRC OK
pStatusWord= rxMpdu + 4;
// Indicate the successful ACK reception if CRC and sequence number OK
if ((pStatusWord[1] & BASIC_RF_CRC_OK_BM) && (pHdr->seqNumber == txState.txSeqNumber)) {
txState.ackReceived = TRUE;
}
// No, it is data
} else {
// It is assumed that the radio rejects packets with invalid length.
// Subtract the number of bytes in the frame overhead to get actual payload.
rxi.length = pHdr->packetLength - BASIC_RF_PACKET_OVERHEAD_SIZE;
#ifdef SECURITY_CCM
rxi.length -= (BASIC_RF_AUX_HDR_LENGTH + BASIC_RF_LEN_MIC);
authStatus = halRfReadRxBufSecure(&rxMpdu[1], pHdr->packetLength, rxi.length,
BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M);
#else
halRfReadRxBuf(&rxMpdu[1], pHdr->packetLength);
#endif
// Make sure byte fields are changed from network to host byte order
UINT16_NTOH(pHdr->frameControlField);
UINT16_NTOH(pHdr->panId);
UINT16_NTOH(pHdr->destAddr);
UINT16_NTOH(pHdr->srcAddr);
#ifdef SECURITY_CCM
UINT32_NTOH(pHdr->frameCounter);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -