added 802.15.4 frame packeter

This commit is contained in:
nifi 2009-04-06 13:19:03 +00:00
parent 3b2ad9cfc4
commit 9f2ff48fda
5 changed files with 826 additions and 1 deletions

View file

@ -1 +1 @@
CONTIKI_SOURCEFILES += xmac.c nullmac.c lpp.c #xmac2.c CONTIKI_SOURCEFILES += xmac.c nullmac.c lpp.c frame802154.c sicslowmac.c

352
core/net/mac/frame802154.c Normal file
View file

@ -0,0 +1,352 @@
/*
*
* 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.
*
* $Id: frame802154.c,v 1.1 2009/04/06 13:19:03 nifi Exp $
*/
/*
* \brief This file is where the main functions that relate to frame
* manipulation will reside.
*/
/**
* \addtogroup frame802154
* @{
*/
/**
* \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.
*/
#include "sys/cc.h"
#include "net/mac/frame802154.h"
#include <string.h>
/**
* \brief Structure that contains the lengths of the various addressing and security fields
* in the 802.15.4 header. This structure is used in \ref frame802154_create()
*/
typedef struct {
uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */
uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */
uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */
uint8_t src_addr_len; /**< Length (in bytes) of source address field */
uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */
} field_length_t;
/*----------------------------------------------------------------------------*/
CC_INLINE static uint8_t
addr_len(uint8_t mode)
{
switch(mode) {
case FRAME802154_SHORTADDRMODE: /* 16-bit address */
return 2;
case FRAME802154_LONGADDRMODE: /* 64-bit address */
return 8;
default:
return 0;
}
}
/*----------------------------------------------------------------------------*/
static void
field_len(frame802154_t *p, field_length_t *flen)
{
/* 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.dest_addr_mode) {
flen->dest_pid_len = 2;
}
if(p->fcf.src_addr_mode) {
flen->src_pid_len = 2;
}
/* Set PAN ID compression bit if src pan id matches dest pan id. */
if(p->fcf.dest_addr_mode && p->fcf.src_addr_mode && p->src_pid == p->dest_pid) {
p->fcf.panid_compression = 1;
/* compressed header, only do dest pid */
flen->src_pid_len = 0;
} else {
p->fcf.panid_compression = 0;
}
/* determine address lengths */
flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode);
flen->src_addr_len = addr_len(p->fcf.src_addr_mode);
/* Aux security header */
if(p->fcf.security_enabled) {
/* TODO Aux security header not yet implemented */
#if 0
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;
}
#endif
}
}
/*----------------------------------------------------------------------------*/
/**
* \brief Calculates the length of the frame header. This function is
* meant to be called by a higher level function, that interfaces to a MAC.
*
* \param p Pointer to frame802154_t_t struct, which specifies the
* frame to send.
*
* \return The length of the frame header.
*/
uint8_t
frame802154_hdrlen(frame802154_t *p)
{
field_length_t flen;
field_len(p, &flen);
return 3 + flen.dest_pid_len + flen.dest_addr_len +
flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len;
}
/*----------------------------------------------------------------------------*/
/**
* \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 frame802154_t struct, which specifies the
* frame to send.
*
* \param buf Pointer to the buffer to use for the frame.
*
* \param buf_len The length of the buffer to use for the frame.
*
* \return The length of the frame header or 0 if there was
* insufficient space in the buffer for the frame headers.
*/
uint8_t
frame802154_create(frame802154_t *p, uint8_t *buf, uint8_t buf_len)
{
int c;
field_length_t flen;
uint8_t *tx_frame_buffer;
uint8_t pos;
field_len(p, &flen);
if(3 + flen.dest_pid_len + flen.dest_addr_len +
flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len > buf_len) {
/* Too little space for headers. */
return 0;
}
/* OK, now we have field lengths. Time to actually construct */
/* the outgoing frame, and store it in tx_frame_buffer */
tx_frame_buffer = buf;
tx_frame_buffer[0] = (p->fcf.frame_type) |
(p->fcf.security_enabled << 3) | (p->fcf.frame_pending << 4) |
(p->fcf.ack_required << 5) | (p->fcf.panid_compression << 6);
tx_frame_buffer[1] = (p->fcf.dest_addr_mode << 2) |
(p->fcf.frame_version << 4) | (p->fcf.src_addr_mode << 6);
/* sequence number */
tx_frame_buffer[2] = p->seq;
pos = 3;
/* Destination PAN ID */
if(flen.dest_pid_len == 2) {
tx_frame_buffer[pos++] = p->dest_pid & 0xff;
tx_frame_buffer[pos++] = (p->dest_pid >> 8) & 0xff;
}
/* Destination address */
for(c = flen.dest_addr_len; c > 0; c--) {
tx_frame_buffer[pos++] = p->dest_addr.u8[c - 1];
}
/* Source PAN ID */
if(flen.src_pid_len == 2) {
tx_frame_buffer[pos++] = p->src_pid & 0xff;
tx_frame_buffer[pos++] = (p->src_pid >> 8) & 0xff;
}
/* Source address */
for(c = flen.src_addr_len; c > 0; c--) {
tx_frame_buffer[pos++] = p->src_addr.u8[c - 1];
}
/* Aux header */
if(flen.aux_sec_len) {
/* TODO Aux security header not yet implemented */
/* pos += flen.aux_sec_len; */
}
return pos;
}
/*----------------------------------------------------------------------------*/
/**
* \brief Parses an input frame. Scans the input frame to find each
* section, and stores the information of each section in a
* frame802154_t structure.
*
* \param data The input data from the radio chip.
* \param len The size of the input data
* \param pf The frame802154_t struct to store the parsed frame information.
*/
uint8_t
frame802154_parse(uint8_t *data, uint8_t len, frame802154_t *pf)
{
uint8_t *p;
frame802154_fcf_t fcf;
uint8_t c;
if(len < 3) {
return 0;
}
p = data;
/* decode the FCF */
fcf.frame_type = p[0] & 7;
fcf.security_enabled = (p[0] >> 3) & 1;
fcf.frame_pending = (p[0] >> 4) & 1;
fcf.ack_required = (p[0] >> 5) & 1;
fcf.panid_compression = (p[0] >> 6) & 1;
fcf.dest_addr_mode = (p[1] >> 2) & 3;
fcf.frame_version = (p[1] >> 4) & 3;
fcf.src_addr_mode = (p[1] >> 6) & 3;
/* copy fcf and seqNum */
pf->fcf = fcf;
pf->seq = p[2];
p += 3; /* Skip first three bytes */
/* Destination address, if any */
if(fcf.dest_addr_mode) {
/* Destination PAN */
pf->dest_pid = p[0] + (p[1] << 8);
p += 2;
/* Destination address */
/* l = addr_len(fcf.dest_addr_mode); */
/* for(c = 0; c < l; c++) { */
/* pf->dest_addr.u8[c] = p[l - c - 1]; */
/* } */
/* p += l; */
if(fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) {
rimeaddr_copy(&(pf->dest_addr), &rimeaddr_null);
pf->dest_addr.u8[0] = p[1];
pf->dest_addr.u8[1] = p[0];
p += 2;
} else if(fcf.dest_addr_mode == FRAME802154_LONGADDRMODE) {
for(c = 0; c < 8; c++) {
pf->dest_addr.u8[c] = p[7 - c];
}
p += 8;
}
} else {
rimeaddr_copy(&(pf->dest_addr), &rimeaddr_null);
pf->dest_pid = 0;
}
/* Source address, if any */
if(fcf.src_addr_mode) {
/* Source PAN */
if(!fcf.panid_compression) {
pf->src_pid = p[0] + (p[1] << 8);
p += 2;
} else {
pf->src_pid = pf->dest_pid;
}
/* Source address */
/* l = addr_len(fcf.src_addr_mode); */
/* for(c = 0; c < l; c++) { */
/* pf->src_addr.u8[c] = p[l - c - 1]; */
/* } */
/* p += l; */
if(fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) {
rimeaddr_copy(&(pf->src_addr), &rimeaddr_null);
pf->src_addr.u8[0] = p[1];
pf->src_addr.u8[1] = p[0];
p += 2;
} else if(fcf.src_addr_mode == FRAME802154_LONGADDRMODE) {
for(c = 0; c < 8; c++) {
pf->src_addr.u8[c] = p[7 - c];
}
p += 8;
}
} else {
rimeaddr_copy(&(pf->src_addr), &rimeaddr_null);
pf->src_pid = 0;
}
if(fcf.security_enabled) {
/* TODO aux security header, not yet implemented */
/* return 0; */
}
/* header length */
c = p - data;
/* payload length */
pf->payload_len = len - c;
/* payload */
pf->payload = p;
/* return header length if successful */
return c > len ? 0 : c;
}
/** \} */

170
core/net/mac/frame802154.h Normal file
View file

@ -0,0 +1,170 @@
/*
* 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 frame802154
* @{
*/
/**
* \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.
*
* $Id: frame802154.h,v 1.1 2009/04/06 13:19:03 nifi Exp $
*/
/* Includes */
#ifndef FRAME_802154_H
#define FRAME_802154_H
#include "contiki-conf.h"
#include "net/rime/rimeaddr.h"
#ifdef IEEE802154_CONF_PANID
#define IEEE802154_PANID IEEE802154_CONF_PANID
#else
#define IEEE802154_PANID 0xABCD
#endif
/* 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_SECURITY_LEVEL_NONE (0)
#define FRAME802154_SECURITY_LEVEL_128 (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; /**< Frame type field, see 802.15.4 */
uint8_t security_enabled : 1; /**< True if security is used in this frame */
uint8_t frame_pending : 1; /**< True if sender has more data to send */
uint8_t ack_required : 1; /**< Is an ack frame required? */
uint8_t panid_compression : 1; /**< Is this a compressed header? */
uint8_t reserved : 3; /**< Unused bits */
uint8_t dest_addr_mode : 2; /**< Destination address mode, see 802.15.4 */
uint8_t frame_version : 2; /**< 802.15.4 frame version */
uint8_t src_addr_mode : 2; /**< 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; /**< security level */
uint8_t key_id_mode : 2; /**< Key identifier mode */
uint8_t reserved : 3; /**< Reserved bits */
} frame802154_scf_t;
/** \brief 802.15.4 Aux security header */
typedef struct {
frame802154_scf_t security_control; /**< Security control bitfield */
uint32_t frame_counter; /**< Frame counter, used for security */
uint8_t key[9]; /**< The key itself, or an index to the key */
} 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 {
frame802154_fcf_t fcf; /**< Frame control field */
uint8_t seq; /**< Sequence number */
uint16_t dest_pid; /**< Destination PAN ID */
rimeaddr_t dest_addr; /**< Destination address */
uint16_t src_pid; /**< Source PAN ID */
rimeaddr_t src_addr; /**< Source address */
frame802154_aux_hdr_t aux_hdr; /**< Aux security header */
uint8_t *payload; /**< Pointer to 802.15.4 frame payload */
uint8_t payload_len; /**< Length of payload field */
} frame802154_t;
/* Prototypes */
uint8_t frame802154_hdrlen(frame802154_t *p);
uint8_t frame802154_create(frame802154_t *p, uint8_t *buf, uint8_t buf_len);
uint8_t frame802154_parse(uint8_t *data, uint8_t length, frame802154_t *pf);
/** @} */
#endif /* FRAME_802154_H */

247
core/net/mac/sicslowmac.c Normal file
View file

@ -0,0 +1,247 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
* $Id: sicslowmac.c,v 1.1 2009/04/06 13:19:03 nifi Exp $
*/
/**
* \file
* MAC interface for packaging radio packets into 802.15.4 frames
*
* \author
* Adam Dunkels <adam@sics.se>
* Eric Gnoske <egnoske@gmail.com>
* Blake Leverett <bleverett@gmail.com>
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include <string.h>
#include "net/mac/sicslowmac.h"
#include "net/mac/frame802154.h"
#include "net/rime/packetbuf.h"
#include "lib/random.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINTADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7])
#else
#define PRINTF(...)
#define PRINTADDR(addr)
#endif
/** \brief The sequence number (0x00 - 0xff) added to the transmitted
* data or MAC command frame. The default is a random value within
* the range.
*/
static uint8_t mac_dsn;
/** \brief The 16-bit identifier of the PAN on which the device is
* sending to. If this value is 0xffff, the device is not
* associated.
*/
static uint16_t mac_dst_pan_id = IEEE802154_PANID;
/** \brief The 16-bit identifier of the PAN on which the device is
* operating. If this value is 0xffff, the device is not
* associated.
*/
static uint16_t mac_src_pan_id = IEEE802154_PANID;
static const struct radio_driver *radio;
static void (* receiver_callback)(const struct mac_driver *);
/*---------------------------------------------------------------------------*/
static int
is_broadcast_addr(uint8_t mode, uint8_t *addr)
{
int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8;
while(i-- > 0) {
if(addr[i] != 0xff) {
return 0;
}
}
return 1;
}
/*---------------------------------------------------------------------------*/
static int
send_packet(void)
{
frame802154_t params;
uint8_t len;
/* init to zeros */
memset(&params, 0, sizeof(params));
/* Build the FCF. */
params.fcf.frame_type = FRAME802154_DATAFRAME;
params.fcf.security_enabled = 0;
params.fcf.frame_pending = 0;
params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_RELIABLE);
params.fcf.panid_compression = 0;
/* Insert IEEE 802.15.4 (2003) version bit. */
params.fcf.frame_version = FRAME802154_IEEE802154_2003;
/* Increment and set the data sequence number. */
params.seq = mac_dsn++;
/* Complete the addressing fields. */
/**
\todo For phase 1 the addresses are all long. We'll need a mechanism
in the rime attributes to tell the mac to use long or short for phase 2.
*/
params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
params.dest_pid = mac_dst_pan_id;
/*
* If the output address is NULL in the Rime buf, then it is broadcast
* on the 802.15.4 network.
*/
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
/* Broadcast requires short address mode. */
params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
params.dest_pid = FRAME802154_BROADCASTPANDID;
params.dest_addr.u8[0] = 0xFF;
params.dest_addr.u8[1] = 0xFF;
} else {
rimeaddr_copy(&params.dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
}
/* Set the source PAN ID to the global variable. */
params.src_pid = mac_src_pan_id;
/*
* Set up the source address using only the long address mode for
* phase 1.
*/
rimeaddr_copy(&params.src_addr, &rimeaddr_node_addr);
params.payload = packetbuf_dataptr();
params.payload_len = packetbuf_datalen();
len = frame802154_hdrlen(&params);
if(packetbuf_hdralloc(len)) {
frame802154_create(&params, packetbuf_hdrptr(), len);
PRINTF("6MAC-UT: %2X", params.fcf.frame_type);
PRINTADDR(params.dest_addr.u8);
PRINTF("%u %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen());
return radio->send(packetbuf_hdrptr(), packetbuf_totlen());
} else {
PRINTF("6MAC-UT: too large header: %u\n", len);
}
return 0;
}
/*---------------------------------------------------------------------------*/
static void
input_packet(const struct radio_driver *d)
{
if(receiver_callback) {
receiver_callback(&sicslowmac_driver);
}
}
/*---------------------------------------------------------------------------*/
static int
read_packet(void)
{
frame802154_t frame;
int len;
packetbuf_clear();
len = radio->read(packetbuf_dataptr(), PACKETBUF_SIZE);
if(len > 0) {
packetbuf_set_datalen(len);
if(frame802154_parse(packetbuf_dataptr(), len, &frame) &&
packetbuf_hdrreduce(len - frame.payload_len)) {
if(frame.fcf.dest_addr_mode &&
!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr.u8)) {
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &frame.dest_addr);
}
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &frame.src_addr);
PRINTF("6MAC-IN: %2X", frame.fcf.frame_type);
PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
PRINTF("%u\n", packetbuf_datalen());
return packetbuf_datalen();
} else {
PRINTF("6MAC: failed to parse hdr\n");
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
static void
set_receive_function(void (* recv)(const struct mac_driver *))
{
receiver_callback = recv;
}
/*---------------------------------------------------------------------------*/
static int
on(void)
{
return radio->on();
}
/*---------------------------------------------------------------------------*/
static int
off(int keep_radio_on)
{
if(keep_radio_on) {
return radio->on();
} else {
return radio->off();
}
}
/*---------------------------------------------------------------------------*/
const struct mac_driver sicslowmac_driver = {
"sicslowmac",
send_packet,
read_packet,
set_receive_function,
on,
off,
};
/*---------------------------------------------------------------------------*/
const struct mac_driver *
sicslowmac_init(const struct radio_driver *d)
{
mac_dsn = random_rand() % 256;
radio = d;
radio->set_receive_function(input_packet);
radio->on();
return &sicslowmac_driver;
}
/*---------------------------------------------------------------------------*/

56
core/net/mac/sicslowmac.h Normal file
View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
* $Id: sicslowmac.h,v 1.1 2009/04/06 13:19:03 nifi Exp $
*/
/**
* \file
* MAC interface for packaging radio packets into 802.15.4 frames
*
* \author
* Adam Dunkels <adam@sics.se>
* Eric Gnoske <egnoske@gmail.com>
* Blake Leverett <bleverett@gmail.com>
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef __SICSLOWMAC_H__
#define __SICSLOWMAC_H__
#include "net/mac/mac.h"
#include "dev/radio.h"
extern const struct mac_driver sicslowmac_driver;
const struct mac_driver *sicslowmac_init(const struct radio_driver *r);
#endif /* __SICSLOWMAC_H__ */