cc2420receivep.nc
来自「tinyos-2.x.rar」· NC 代码 · 共 831 行 · 第 1/2 页
NC
831 行
mode = CC2420_CBC_MAC;
micLength = 8;
}else if (secHdr.secLevel == CBC_MAC_16){
mode = CC2420_CBC_MAC;
micLength = 16;
}else if (secHdr.secLevel == CTR){
mode = CC2420_CTR;
micLength = 0;
}else if (secHdr.secLevel == CCM_4){
mode = CC2420_CCM;
micLength = 4;
}else if (secHdr.secLevel == CCM_8){
mode = CC2420_CCM;
micLength = 8;
}else if (secHdr.secLevel == CCM_16){
mode = CC2420_CCM;
micLength = 16;
}else{
atomic SECURITYLOCK = 0;
packetLength = header.length + 1;
m_state = S_RX_LENGTH;
call SpiResource.release();
beginReceive();
return;
}
if(mode < 4 && mode > 0) { // if mode is valid
securityOn = 1;
memcpy(&nonceValue[3], &(secHdr.frameCounter), 4);
skip = secHdr.reserved;
if(mode == CC2420_CBC_MAC || mode == CC2420_CCM){
authentication = 1;
call CSN.clr();
atomic call SECCTRL0.write((mode << CC2420_SECCTRL0_SEC_MODE) |
((micLength-2)/2 << CC2420_SECCTRL0_SEC_M) |
(key << CC2420_SECCTRL0_SEC_RXKEYSEL) |
(1 << CC2420_SECCTRL0_SEC_CBC_HEAD) |
(1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ;
call CSN.set();
}else{
call CSN.clr();
atomic call SECCTRL0.write((mode << CC2420_SECCTRL0_SEC_MODE) |
(1 << CC2420_SECCTRL0_SEC_M) |
(key << CC2420_SECCTRL0_SEC_RXKEYSEL) |
(1 << CC2420_SECCTRL0_SEC_CBC_HEAD) |
(1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ;
call CSN.set();
}
call CSN.clr();
#ifndef TFRAMES_ENABLED
atomic call SECCTRL1.write(skip+11+sizeof(security_header_t)+((skip+11+sizeof(security_header_t))<<8));
#else
atomic call SECCTRL1.write(skip+10+sizeof(security_header_t)+((skip+10+sizeof(security_header_t))<<8));
#endif
call CSN.set();
call CSN.clr();
atomic call RXNONCE.write(0, nonceValue, 16);
call CSN.set();
call CSN.clr();
atomic call SRXDEC.strobe();
call CSN.set();
atomic decLoopCount = 0;
post waitDecTask();
return;
}else{
atomic SECURITYLOCK = 0;
packetLength = header.length + 1;
m_state = S_RX_LENGTH;
call SpiResource.release();
beginReceive();
return;
}
}
}else{
packetLength = header.length + 1;
m_state = S_RX_LENGTH;
call SpiResource.release();
beginReceive();
return;
}
}
#endif
/***************** SpiResource Events ****************/
event void SpiResource.granted() {
#ifdef CC2420_HW_SECURITY
if(m_state == S_RX_DEC){
dec();
}else{
receive();
}
#else
receive();
#endif
}
/***************** RXFIFO Events ****************/
/**
* We received some bytes from the SPI bus. Process them in the context
* of the state we're in. Remember the length byte is not part of the length
*/
async event void RXFIFO.readDone( uint8_t* rx_buf, uint8_t rx_len,
error_t error ) {
cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf );
uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t));
uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header);
rxFrameLength = buf[ 0 ];
switch( m_state ) {
case S_RX_LENGTH:
m_state = S_RX_FCF;
#ifdef CC2420_HW_SECURITY
packetLength = rxFrameLength+1;
#endif
if ( rxFrameLength + 1 > m_bytes_left
#ifdef CC2420_HW_SECURITY
|| flush_flag == 1
#endif
) {
// Length of this packet is bigger than the RXFIFO, flush it out.
flush();
} else {
if ( !call FIFO.get() && !call FIFOP.get() ) {
m_bytes_left -= rxFrameLength + 1;
}
if(rxFrameLength <= MAC_PACKET_SIZE) {
if(rxFrameLength > 0) {
if(rxFrameLength > SACK_HEADER_LENGTH) {
// This packet has an FCF byte plus at least one more byte to read
call RXFIFO.continueRead(buf + 1, SACK_HEADER_LENGTH);
} else {
// This is really a bad packet, skip FCF and get it out of here.
m_state = S_RX_PAYLOAD;
call RXFIFO.continueRead(buf + 1, rxFrameLength);
}
} else {
// Length == 0; start reading the next packet
atomic receivingPacket = FALSE;
call CSN.set();
call SpiResource.release();
waitForNextPacket();
}
} else {
// Length is too large; we have to flush the entire Rx FIFO
flush();
}
}
break;
case S_RX_FCF:
m_state = S_RX_PAYLOAD;
/*
* The destination address check here is not completely optimized. If you
* are seeing issues with dropped acknowledgements, try removing
* the address check and decreasing SACK_HEADER_LENGTH to 2.
* The length byte and the FCF byte are the only two bytes required
* to know that the packet is valid and requested an ack. The destination
* address is useful when we want to sniff packets from other transmitters
* while acknowledging packets that were destined for our local address.
*/
if(call CC2420Config.isAutoAckEnabled() && !call CC2420Config.isHwAutoAckDefault()) {
if (((( header->fcf >> IEEE154_FCF_ACK_REQ ) & 0x01) == 1)
&& ((header->dest == call CC2420Config.getShortAddr())
|| (header->dest == AM_BROADCAST_ADDR))
&& ((( header->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7) == IEEE154_TYPE_DATA)) {
// CSn flippage cuts off our FIFO; SACK and begin reading again
call CSN.set();
call CSN.clr();
call SACK.strobe();
call CSN.set();
call CSN.clr();
call RXFIFO.beginRead(buf + 1 + SACK_HEADER_LENGTH,
rxFrameLength - SACK_HEADER_LENGTH);
return;
}
}
// Didn't flip CSn, we're ok to continue reading.
call RXFIFO.continueRead(buf + 1 + SACK_HEADER_LENGTH,
rxFrameLength - SACK_HEADER_LENGTH);
break;
case S_RX_PAYLOAD:
call CSN.set();
if(!m_missed_packets) {
// Release the SPI only if there are no more frames to download
call SpiResource.release();
}
//new packet is buffered up, or we don't have timestamp in fifo, or ack
if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get()
|| !m_timestamp_size
|| rxFrameLength <= 10) {
call PacketTimeStamp.clear(m_p_rx_buf);
}
else {
if (m_timestamp_size==1)
call PacketTimeStamp.set(m_p_rx_buf, m_timestamp_queue[ m_timestamp_head ]);
m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE;
m_timestamp_size--;
if (m_timestamp_size>0) {
call PacketTimeStamp.clear(m_p_rx_buf);
m_timestamp_head = 0;
m_timestamp_size = 0;
}
}
// We may have received an ack that should be processed by Transmit
// buf[rxFrameLength] >> 7 checks the CRC
if ( ( buf[ rxFrameLength ] >> 7 ) && rx_buf ) {
uint8_t type = ( header->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7;
signal CC2420Receive.receive( type, m_p_rx_buf );
if ( type == IEEE154_TYPE_DATA ) {
post receiveDone_task();
return;
}
}
waitForNextPacket();
break;
default:
atomic receivingPacket = FALSE;
call CSN.set();
call SpiResource.release();
break;
}
}
async event void RXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {
}
/***************** Tasks *****************/
/**
* Fill in metadata details, pass the packet up the stack, and
* get the next packet.
*/
task void receiveDone_task() {
cc2420_metadata_t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf );
cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf);
uint8_t length = header->length;
uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t));
uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header);
metadata->crc = buf[ length ] >> 7;
metadata->lqi = buf[ length ] & 0x7f;
metadata->rssi = buf[ length - 1 ];
if (passesAddressCheck(m_p_rx_buf) && length >= CC2420_SIZE) {
#ifdef CC2420_HW_SECURITY
if(securityOn == 1){
if(m_missed_packets > 0){
m_missed_packets --;
}
if(authentication){
length -= micLength;
}
}
micLength = 0;
securityOn = 0;
authentication = 0;
#endif
m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data,
length - CC2420_SIZE);
}
atomic receivingPacket = FALSE;
waitForNextPacket();
}
/****************** CC2420Config Events ****************/
event void CC2420Config.syncDone( error_t error ) {
}
/****************** Functions ****************/
/**
* Attempt to acquire the SPI bus to receive a packet.
*/
void beginReceive() {
m_state = S_RX_LENGTH;
atomic receivingPacket = TRUE;
if(call SpiResource.isOwner()) {
receive();
} else if (call SpiResource.immediateRequest() == SUCCESS) {
receive();
} else {
call SpiResource.request();
}
}
/**
* Flush out the Rx FIFO
*/
void flush() {
#ifdef CC2420_HW_SECURITY
flush_flag = 0;
pos =0;
packetLength =0;
micLength = 0;
securityOn = 0;
authentication = 0;
#endif
reset_state();
call CSN.set();
call CSN.clr();
call SFLUSHRX.strobe();
call SFLUSHRX.strobe();
call CSN.set();
call SpiResource.release();
waitForNextPacket();
}
/**
* The first byte of each packet is the length byte. Read in that single
* byte, and then read in the rest of the packet. The CC2420 could contain
* multiple packets that have been buffered up, so if something goes wrong,
* we necessarily want to flush out the FIFO unless we have to.
*/
void receive() {
call CSN.clr();
call RXFIFO.beginRead( (uint8_t*)(call CC2420PacketBody.getHeader( m_p_rx_buf )), 1 );
}
/**
* Determine if there's a packet ready to go, or if we should do nothing
* until the next packet arrives
*/
void waitForNextPacket() {
atomic {
if ( m_state == S_STOPPED ) {
call SpiResource.release();
return;
}
atomic receivingPacket = FALSE;
/*
* The FIFOP pin here is high when there are 0 bytes in the RX FIFO
* and goes low as soon as there are bytes in the RX FIFO. The pin
* is inverted from what the datasheet says, and its threshold is 127.
* Whenever the FIFOP line goes low, as you can see from the interrupt
* handler elsewhere in this module, it means we received a new packet.
* If the line stays low without generating an interrupt, that means
* there's still more data to be received.
*/
if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() ) {
// A new packet is buffered up and ready to go
if ( m_missed_packets ) {
m_missed_packets--;
}
#ifdef CC2420_HW_SECURITY
call SpiResource.release();
m_state = S_RX_DEC;
beginDec();
#else
beginReceive();
#endif
} else {
// Wait for the next packet to arrive
m_state = S_STARTED;
m_missed_packets = 0;
call SpiResource.release();
}
}
}
/**
* Reset this component
*/
void reset_state() {
m_bytes_left = RXFIFO_SIZE;
atomic receivingPacket = FALSE;
m_timestamp_head = 0;
m_timestamp_size = 0;
m_missed_packets = 0;
}
/**
* @return TRUE if the given message passes address recognition
*/
bool passesAddressCheck(message_t *msg) {
cc2420_header_t *header = call CC2420PacketBody.getHeader( msg );
if(!(call CC2420Config.isAddressRecognitionEnabled())) {
return TRUE;
}
return (header->dest == call CC2420Config.getShortAddr()
|| header->dest == AM_BROADCAST_ADDR);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?