contiki/core/net/mac/frame802154.h
2015-12-04 15:21:50 +01:00

231 lines
9.1 KiB
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
*
* Additional fixes for MSP430 contributed by:
* Joakim Eriksson
* Niclas Finne
* Nicolas Tsiftes
*
* 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.
*/
/**
* \addtogroup net
* @{
*/
/**
* \defgroup frame802154 802.15.4 frame creation and parsing
* @{
*/
/**
* \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 */
#ifndef FRAME_802154_H
#define FRAME_802154_H
#include "contiki-conf.h"
#include "net/linkaddr.h"
#ifdef IEEE802154_CONF_PANID
#define IEEE802154_PANID IEEE802154_CONF_PANID
#else /* IEEE802154_CONF_PANID */
#define IEEE802154_PANID 0xABCD
#endif /* IEEE802154_CONF_PANID */
#ifdef FRAME802154_CONF_VERSION
#define FRAME802154_VERSION FRAME802154_CONF_VERSION
#else /* FRAME802154_CONF_VERSION */
#define FRAME802154_VERSION FRAME802154_IEEE802154_2006
#endif /* FRAME802154_CONF_VERSION */
#ifdef FRAME802154_CONF_SUPPR_SEQNO
#define FRAME802154_SUPPR_SEQNO FRAME802154_CONF_SUPPR_SEQNO
#else /* FRAME802154_CONF_SUPPR_SEQNO */
#define FRAME802154_SUPPR_SEQNO 0
#endif /* FRAME802154_CONF_SUPPR_SEQNO */
/* Macros & Defines */
/** \brief These are some definitions of values used in the FCF. See the 802.15.4 spec for details.
* \name FCF element values definitions
* @{
*/
#define FRAME802154_BEACONFRAME (0x00)
#define FRAME802154_DATAFRAME (0x01)
#define FRAME802154_ACKFRAME (0x02)
#define FRAME802154_CMDFRAME (0x03)
#define FRAME802154_BEACONREQ (0x07)
#define FRAME802154_IEEERESERVED (0x00)
#define FRAME802154_NOADDR (0x00) /**< Only valid for ACK or Beacon frames. */
#define FRAME802154_SHORTADDRMODE (0x02)
#define FRAME802154_LONGADDRMODE (0x03)
#define FRAME802154_NOBEACONS (0x0F)
#define FRAME802154_BROADCASTADDR (0xFFFF)
#define FRAME802154_BROADCASTPANDID (0xFFFF)
#define FRAME802154_IEEE802154_2003 (0x00)
#define FRAME802154_IEEE802154_2006 (0x01)
#define FRAME802154_IEEE802154E_2012 (0x02)
#define FRAME802154_SECURITY_LEVEL_NONE (0)
#define FRAME802154_SECURITY_LEVEL_MIC_32 (1)
#define FRAME802154_SECURITY_LEVEL_MIC_64 (2)
#define FRAME802154_SECURITY_LEVEL_MIC_128 (3)
#define FRAME802154_SECURITY_LEVEL_ENC (4)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_32 (5)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_64 (6)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_128 (7)
#define FRAME802154_IMPLICIT_KEY (0)
#define FRAME802154_1_BYTE_KEY_ID_MODE (1)
#define FRAME802154_5_BYTE_KEY_ID_MODE (2)
#define FRAME802154_9_BYTE_KEY_ID_MODE (3)
/**
* @brief The IEEE 802.15.4 frame has a number of constant/fixed fields that
* can be counted to make frame construction and max payload
* calculations easier.
*
* These include:
* 1. FCF - 2 bytes - Fixed
* 2. Sequence number - 1 byte - Fixed
* 3. Addressing fields - 4 - 20 bytes - Variable
* 4. Aux security header - 0 - 14 bytes - Variable
* 5. CRC - 2 bytes - Fixed
*/
/**
* \brief Defines the bitfields of the frame control field (FCF).
*/
typedef struct {
uint8_t frame_type; /**< 3 bit. Frame type field, see 802.15.4 */
uint8_t security_enabled; /**< 1 bit. True if security is used in this frame */
uint8_t frame_pending; /**< 1 bit. True if sender has more data to send */
uint8_t ack_required; /**< 1 bit. Is an ack frame required? */
uint8_t panid_compression; /**< 1 bit. Is this a compressed header? */
/* uint8_t reserved; */ /**< 1 bit. Unused bit */
uint8_t sequence_number_suppression; /**< 1 bit. Does the header omit sequence number?, see 802.15.4e */
uint8_t ie_list_present; /**< 1 bit. Does the header contain Information Elements?, see 802.15.4e */
uint8_t dest_addr_mode; /**< 2 bit. Destination address mode, see 802.15.4 */
uint8_t frame_version; /**< 2 bit. 802.15.4 frame version */
uint8_t src_addr_mode; /**< 2 bit. Source address mode, see 802.15.4 */
} frame802154_fcf_t;
/** \brief 802.15.4 security control bitfield. See section 7.6.2.2.1 in 802.15.4 specification */
typedef struct {
uint8_t security_level; /**< 3 bit. security level */
uint8_t key_id_mode; /**< 2 bit. Key identifier mode */
uint8_t frame_counter_suppression; /**< 1 bit. Frame counter suppression */
uint8_t frame_counter_size; /**< 1 bit. Frame counter size (0: 4 bytes, 1: 5 bytes) */
uint8_t reserved; /**< 3 bit. Reserved bits */
} frame802154_scf_t;
typedef union {
uint32_t u32;
uint16_t u16[2];
uint8_t u8[4];
} frame802154_frame_counter_t;
typedef union {
uint16_t u16[4];
uint8_t u8[8];
} frame802154_key_source_t;
/** \brief 802.15.4 Aux security header */
typedef struct {
frame802154_scf_t security_control; /**< Security control bitfield */
frame802154_frame_counter_t frame_counter; /**< Frame counter, used for security */
frame802154_key_source_t key_source; /**< Key Source subfield */
uint8_t key_index; /**< Key Index subfield */
} frame802154_aux_hdr_t;
/** \brief Parameters used by the frame802154_create() function. These
* parameters are used in the 802.15.4 frame header. See the 802.15.4
* specification for details.
*/
typedef struct {
/* The fields dest_addr and src_addr must come first to ensure they are aligned to the
* CPU word size. Needed as they are accessed directly as linkaddr_t*. Note we cannot use
* the type linkaddr_t directly here, as we always need 8 bytes, not LINKADDR_SIZE bytes. */
uint8_t dest_addr[8]; /**< Destination address */
uint8_t src_addr[8]; /**< Source address */
frame802154_fcf_t fcf; /**< Frame control field */
uint8_t seq; /**< Sequence number */
uint16_t dest_pid; /**< Destination PAN ID */
uint16_t src_pid; /**< Source PAN ID */
frame802154_aux_hdr_t aux_hdr; /**< Aux security header */
uint8_t *payload; /**< Pointer to 802.15.4 payload */
int payload_len; /**< Length of payload field */
} frame802154_t;
/* Prototypes */
int frame802154_hdrlen(frame802154_t *p);
int frame802154_create(frame802154_t *p, uint8_t *buf);
int frame802154_parse(uint8_t *data, int length, frame802154_t *pf);
/* Get current PAN ID */
uint16_t frame802154_get_pan_id(void);
/* Set current PAN ID */
void frame802154_set_pan_id(uint16_t pan_id);
/* Tells whether a given Frame Control Field indicates a frame with
* source PANID and/or destination PANID */
void frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest_pan_id);
/* Check if the destination PAN ID, if any, matches ours */
int frame802154_check_dest_panid(frame802154_t *frame);
/* Check is the address is a broadcast address, whatever its size */
int frame802154_is_broadcast_addr(uint8_t mode, uint8_t *addr);
/* Check and extract source and destination linkaddr from frame */
int frame802154_extract_linkaddr(frame802154_t *frame, linkaddr_t *source_address, linkaddr_t *dest_address);
/** @} */
#endif /* FRAME_802154_H */
/** @} */
/** @} */