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

📄 frame.c

📁 Contiki是一个开源
💻 C
字号:
/* * *  Copyright (c) 2008, Swedish Institute of Computer Science *  All rights reserved.  * *  Additional fixes for AVR contributed by: * *	Colin O'Flynn coflynn@newae.com *	Eric Gnoske egnoske@gmail.com *	Blake Leverett bleverett@gmail.com *	Mike Vidales mavida404@gmail.com *	Kevin Brown kbrown3@uccs.edu *	Nate Bohlmann nate@elfwerks.com * *   All rights reserved. * *   Redistribution and use in source and binary forms, with or without *   modification, are permitted provided that the following conditions are met: * *   * Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer. *   * Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in *     the documentation and/or other materials provided with the *     distribution. *   * Neither the name of the copyright holders nor the names of *     contributors may be used to endorse or promote products derived *     from this software without specific prior written permission. * *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *  POSSIBILITY OF SUCH DAMAGE. * *  $Id: frame.c,v 1.3 2008/11/08 03:29:15 c_oflynn Exp $*//* *  \brief This file is where the main functions that relate to frame *  manipulation will reside.*//** *   \addtogroup wireless *   @{*//** *  \defgroup frame RF230 Frame handling *  @{ *//** *  \file *  \brief 802.15.4 frame creation and parsing functions * *  This file converts to and from a structure to a packed 802.15.4 *  frame. *//* Includes */#if defined( __GNUC__ )#include <avr/io.h>#include <util/delay.h>#else /* IAR */#include <iom1284.h>#endif#include <stdlib.h>#include <string.h>#include <stdint.h>#include <stdbool.h>#include "at86rf230_registermap.h"#include "radio.h"#include "frame.h"//#include "mac_event.h"#include "zmac.h"#include "process.h"#include "sicslowmac.h"/* Macros & Defines *//* Some version of radio chip need this set to 2, so define it in Makefile */#ifndef AUTO_CRC_PADDING#define AUTO_CRC_PADDING 0#endif/* Protoypes *//* Globals *//*  Frame handling global variables. *///FRAME_t rx_frame;    /**< Structure that holds received frames. */static uint8_t tx_frame_buffer[130];/* Implementation *//*----------------------------------------------------------------------------*//** *   \brief Creates a frame for transmission over the air.  This function is *   meant to be called by a higher level function, that interfaces to a MAC. * *   \param p Pointer to frame_create_params_t struct, which specifies the *   frame to send. * *   \param frame_result Pointer to frame_result_t struct, which will *   receive the results of this function, a pointer to the frame *   created, and the length of the frame. * *   \return Nothing directly, though the frame_result structure will be filled *   in with a pointer to the frame and the frame length.*/voidframe_tx_create(frame_create_params_t *p,frame_result_t *frame_result){    field_length_t flen;    uint8_t index=0;    /* init flen to zeros */    memset(&flen, 0, sizeof(field_length_t));    /* Determine lengths of each field based on fcf and other args */    if (p->fcf.destAddrMode){        flen.dest_pid_len = 2;    }    if (p->fcf.srcAddrMode){        flen.src_pid_len = 2;    }    /* Set PAN ID compression bit it src pan if matches dest pan id. */    if(p->fcf.destAddrMode == p->fcf.srcAddrMode){        p->fcf.panIdCompression = 1;    }    if (p->fcf.panIdCompression){        /* compressed header, only do dest pid */        flen.src_pid_len = 0;    }    /* determine address lengths */    switch (p->fcf.destAddrMode){    case 2:  /* 16-bit address */        flen.dest_addr_len = 2;        break;    case 3:  /* 64-bit address */        flen.dest_addr_len = 8;        break;    default:        break;    }    switch (p->fcf.srcAddrMode){    case 2:  /* 16-bit address */        flen.src_addr_len = 2;        break;    case 3:  /* 64-bit address */        flen.src_addr_len = 8;        break;    default:        break;    }    /* Aux security header */    if (p->fcf.securityEnabled){        switch (p->aux_hdr.security_control.key_id_mode){        case 0:            flen.aux_sec_len = 5; /* minimum value */            break;        case 1:            flen.aux_sec_len = 6;            break;        case 2:            flen.aux_sec_len = 10;            break;        case 3:            flen.aux_sec_len = 14;            break;        default:            break;        }    }    /* OK, now we have field lengths.  Time to actually construct */    /* the outgoing frame, and store it in tx_frame_buffer */    *(uint16_t *)tx_frame_buffer  = p->fcf.word_val; /* FCF */    index = 2;    tx_frame_buffer[index++] = p->seq;           /* sequence number */    /* Destination PAN ID */    if (flen.dest_pid_len == 2){        *(uint16_t *)&tx_frame_buffer[index] = p->dest_pid;        index += 2;    }    /* Destination address */    switch (flen.dest_addr_len){    case 2:    /* two-byte address */        *(uint16_t *)&tx_frame_buffer[index] = p->dest_addr.addr16;        index += 2;        break;    case 8:    /* 8-byte address */        *(uint64_t *)&tx_frame_buffer[index] = p->dest_addr.addr64;        index += 8;        break;    case 0:    default:        break;    }    /* Source PAN ID */    if (flen.src_pid_len == 2){        *(uint16_t *)&tx_frame_buffer[index] = p->src_pid;        index += 2;    }    /* Source address */    switch (flen.src_addr_len){    case 2:    /* two-byte address */        *(uint16_t *)&tx_frame_buffer[index] = p->src_addr.addr16;        index += 2;        break;    case 8:    /* 8-byte address */        *(uint64_t *)&tx_frame_buffer[index] = p->src_addr.addr64;        index += 8;        break;    case 0:    default:        break;    }    /* Aux header */    if (flen.aux_sec_len){        memcpy((char *)&tx_frame_buffer[index],                (char *)&p->aux_hdr,                flen.aux_sec_len);        index += flen.aux_sec_len;    }    /* Frame payload */    memcpy((char *)&tx_frame_buffer[index],            (char *)p->payload,            p->payload_len);    index += p->payload_len;    /* return results */    frame_result->length = index + AUTO_CRC_PADDING;    frame_result->frame = tx_frame_buffer;    return;}/*----------------------------------------------------------------------------*//** *   \brief Parses an input frame.  Scans the input frame to find each *   section, and stores the resulting addresses of each section in a *   parsed_frame_t structure. * *   \param rx_frame The input data from the radio chip. *   \param pf The parsed_frame_t struct that stores a pointer to each *   section of the frame payload. */void rx_frame_parse(hal_rx_frame_t *rx_frame, parsed_frame_t *pf){    /* Pointer to start of AT86RF2xx frame */    uint8_t *p = rx_frame->data;    fcf_t *fcf = (fcf_t *)&rx_frame->data;    static uint8_t frame_dropped = 0;    /* Uh-oh... please don't overwrite me! */    if (pf->in_use) {                /* Only post this once when buffer is busy, otherwise you get many postings... */        if (!frame_dropped) {            event_object_t event;            event.event = MAC_EVENT_DROPPED;            event.data = NULL;            mac_put_event(&event);            process_post(&mac_process, event.event, event.data);        }        frame_dropped = 1;        return;    }    pf->fcf = (fcf_t *)p;    pf->seqNum = p+2;    p += 3;                             /* Skip first three bytes */		if (fcf->frameType == ACKFRAME) {			//ACK frames have no addresses and no payload!		pf->payload_length = 0;		} else {      				/* Destination PID, if any */		if (fcf->frameType != BEACONFRAME){ /* No destination addresses in Beacon frame */			pf->dest_pid = (uint16_t *)p;			p += 2;			/* Destination address */			pf->dest_addr = 0;			if (fcf->destAddrMode == SHORTADDRMODE ||				fcf->destAddrMode == LONGADDRMODE){				pf->dest_addr = (addr_t *)p;				/* Update pointer to account for possible missing addr field */				if (fcf->destAddrMode == SHORTADDRMODE){					p += 2;				}				if (fcf->destAddrMode == LONGADDRMODE){					p += 8;				}			}		}		/* Source PANID */		pf->src_pid = 0;		if (!fcf->panIdCompression){			pf->src_pid = (uint16_t *)p;			p += 2;		}		/* Source address */		pf->src_addr = (addr_t *)p;		if (fcf->srcAddrMode == SHORTADDRMODE){			p += 2;		}		if (fcf->srcAddrMode == LONGADDRMODE){			p += 8;		}		/* aux security header, not yet implemented */		pf->aux_sec_hdr = 0;		/* payload length */		pf->payload_length = rx_frame->length - (p - (uint8_t*)&rx_frame->data) - 2;		/* payload */		pf->payload = p;	}    pf->lqi = rx_frame->lqi;    pf->fcs = rx_frame->crc;    /* pass frame to sicslowmac layer */    event_object_t event;    event.event = MAC_EVENT_RX;    event.data = (uint8_t*)pf;    pf->in_use = 1;    mac_put_event(&event);    process_poll(&mac_process);}/** \}   *//** \}   */

⌨️ 快捷键说明

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