diff --git a/core/net/mac/contikimac.c b/core/net/mac/contikimac.c index c8a603ad0..ed501d582 100644 --- a/core/net/mac/contikimac.c +++ b/core/net/mac/contikimac.c @@ -550,7 +550,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ /* Create the MAC header for the data packet. */ hdrlen = NETSTACK_FRAMER.create(); - if(hdrlen == 0) { + if(hdrlen < 0) { /* Failed to send */ PRINTF("contikimac: send failed, too large header\n"); packetbuf_hdr_remove(sizeof(struct hdr)); @@ -560,7 +560,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ #else /* Create the MAC header for the data packet. */ hdrlen = NETSTACK_FRAMER.create(); - if(hdrlen == 0) { + if(hdrlen < 0) { /* Failed to send */ PRINTF("contikimac: send failed, too large header\n"); return MAC_TX_ERR_FATAL; @@ -877,7 +877,7 @@ input_packet(void) /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/ - if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse()) { + if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) { #if WITH_CONTIKIMAC_HEADER struct hdr *chdr; diff --git a/core/net/mac/cxmac.c b/core/net/mac/cxmac.c index 4e1c336fb..ea3fcb070 100644 --- a/core/net/mac/cxmac.c +++ b/core/net/mac/cxmac.c @@ -454,7 +454,7 @@ send_packet(void) packetbuf_attr(PACKETBUF_ATTR_ERELIABLE); len = NETSTACK_FRAMER.create(); strobe_len = len + sizeof(struct cxmac_hdr); - if(len == 0 || strobe_len > (int)sizeof(strobe)) { + if(len < 0 || strobe_len > (int)sizeof(strobe)) { /* Failed to send */ PRINTF("cxmac: send failed, too large header\n"); return MAC_TX_ERR_FATAL; @@ -565,7 +565,7 @@ send_packet(void) len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); - if(NETSTACK_FRAMER.parse()) { + if(NETSTACK_FRAMER.parse() >= 0) { hdr = packetbuf_dataptr(); if(hdr->dispatch == DISPATCH && hdr->type == TYPE_STROBE_ACK) { if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), @@ -713,7 +713,7 @@ input_packet(void) { struct cxmac_hdr *hdr; - if(NETSTACK_FRAMER.parse()) { + if(NETSTACK_FRAMER.parse() >= 0) { hdr = packetbuf_dataptr(); if(hdr->dispatch != DISPATCH) { @@ -768,7 +768,7 @@ input_packet(void) packetbuf_addr(PACKETBUF_ADDR_SENDER)); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); packetbuf_compact(); - if(NETSTACK_FRAMER.create()) { + if(NETSTACK_FRAMER.create() >= 0) { /* We turn on the radio in anticipation of the incoming packet. */ someone_is_sending = 1; @@ -832,7 +832,7 @@ send_announcement(void *ptr) packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &rimeaddr_null); packetbuf_set_attr(PACKETBUF_ATTR_RADIO_TXPOWER, announcement_radio_txpower); - if(NETSTACK_FRAMER.create()) { + if(NETSTACK_FRAMER.create() >= 0) { NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()); } } diff --git a/core/net/mac/framer-802154.c b/core/net/mac/framer-802154.c index a95685a8f..7580f87b0 100644 --- a/core/net/mac/framer-802154.c +++ b/core/net/mac/framer-802154.c @@ -180,7 +180,7 @@ create(void) return len; } else { PRINTF("15.4-OUT: too large header: %u\n", len); - return 0; + return FRAMER_FAILED; } } /*---------------------------------------------------------------------------*/ @@ -197,7 +197,7 @@ parse(void) frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); - return 0; + return FRAMER_FAILED; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t *)&frame.dest_addr); @@ -215,7 +215,7 @@ parse(void) return len - frame.payload_len; } - return 0; + return FRAMER_FAILED; } /*---------------------------------------------------------------------------*/ const struct framer framer_802154 = { diff --git a/core/net/mac/framer-nullmac.c b/core/net/mac/framer-nullmac.c index 9671f204d..10e5eb288 100644 --- a/core/net/mac/framer-nullmac.c +++ b/core/net/mac/framer-nullmac.c @@ -69,7 +69,7 @@ create(void) return sizeof(struct nullmac_hdr); } PRINTF("PNULLMAC-UT: too large header: %u\n", len); - return 0; + return FRAMER_FAILED; } /*---------------------------------------------------------------------------*/ static int @@ -88,7 +88,7 @@ parse(void) return sizeof(struct nullmac_hdr); } - return 0; + return FRAMER_FAILED; } /*---------------------------------------------------------------------------*/ const struct framer framer_nullmac = { diff --git a/core/net/mac/framer.h b/core/net/mac/framer.h index 1624cb312..d13478bcf 100644 --- a/core/net/mac/framer.h +++ b/core/net/mac/framer.h @@ -42,6 +42,8 @@ #ifndef __FRAMER_H__ #define __FRAMER_H__ +#define FRAMER_FAILED -1 + struct framer { int (* create)(void); diff --git a/core/net/mac/lpp.c b/core/net/mac/lpp.c index 7b5188d6f..35987c9d8 100644 --- a/core/net/mac/lpp.c +++ b/core/net/mac/lpp.c @@ -61,6 +61,7 @@ #include "net/packetbuf.h" #include "net/rime/announcement.h" #include "sys/compower.h" +#include "net/mac/framer.h" #include #include @@ -437,7 +438,7 @@ send_probe(void) packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &rimeaddr_null); { int hdrlen = NETSTACK_FRAMER.create(); - if(hdrlen == 0) { + if(hdrlen < 0) { /* Failed to send */ return; } @@ -651,7 +652,7 @@ send_packet(mac_callback_t sent, void *ptr) { int hdrlen = NETSTACK_FRAMER.create(); - if(hdrlen == 0) { + if(hdrlen < 0) { /* Failed to send */ mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 0); return; @@ -783,7 +784,7 @@ input_packet(void) reception_time = clock_time(); - if(!NETSTACK_FRAMER.parse()) { + if(NETSTACK_FRAMER.parse() < 0) { printf("lpp input_packet framer error\n"); } diff --git a/core/net/mac/nullrdc.c b/core/net/mac/nullrdc.c index 76faad92e..957926126 100644 --- a/core/net/mac/nullrdc.c +++ b/core/net/mac/nullrdc.c @@ -109,7 +109,7 @@ send_packet(mac_callback_t sent, void *ptr) packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); #endif /* NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW */ - if(NETSTACK_FRAMER.create() == 0) { + if(NETSTACK_FRAMER.create() < 0) { /* Failed to allocate space for headers */ PRINTF("nullrdc: send failed, too large header\n"); ret = MAC_TX_ERR_FATAL; @@ -220,7 +220,7 @@ packet_input(void) /* PRINTF("nullrdc: ignored ack\n"); */ } else #endif /* NULLRDC_802154_AUTOACK */ - if(NETSTACK_FRAMER.parse() == 0) { + if(NETSTACK_FRAMER.parse() < 0) { PRINTF("nullrdc: failed to parse %u\n", packetbuf_datalen()); #if NULLRDC_ADDRESS_FILTER } else if(!rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), diff --git a/core/net/mac/xmac.c b/core/net/mac/xmac.c index 7b03bf055..64d21c4a3 100644 --- a/core/net/mac/xmac.c +++ b/core/net/mac/xmac.c @@ -497,7 +497,7 @@ send_packet(void) packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); len = NETSTACK_FRAMER.create(); strobe_len = len + sizeof(struct xmac_hdr); - if(len == 0 || strobe_len > (int)sizeof(strobe)) { + if(len < 0 || strobe_len > (int)sizeof(strobe)) { /* Failed to send */ PRINTF("xmac: send failed, too large header\n"); return MAC_TX_ERR_FATAL; @@ -612,7 +612,7 @@ send_packet(void) len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); - if(NETSTACK_FRAMER.parse()) { + if(NETSTACK_FRAMER.parse() >= 0) { hdr = packetbuf_dataptr(); if(hdr->dispatch == DISPATCH && hdr->type == TYPE_STROBE_ACK) { if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), @@ -777,7 +777,7 @@ input_packet(void) { struct xmac_hdr *hdr; - if(NETSTACK_FRAMER.parse()) { + if(NETSTACK_FRAMER.parse() >= 0) { hdr = packetbuf_dataptr(); if(hdr->dispatch != DISPATCH) { @@ -855,7 +855,7 @@ input_packet(void) packetbuf_addr(PACKETBUF_ADDR_SENDER)); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); packetbuf_compact(); - if(NETSTACK_FRAMER.create()) { + if(NETSTACK_FRAMER.create() >= 0) { /* We turn on the radio in anticipation of the incoming packet. */ someone_is_sending = 1; @@ -920,7 +920,7 @@ send_announcement(void *ptr) packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &rimeaddr_null); packetbuf_set_attr(PACKETBUF_ATTR_RADIO_TXPOWER, announcement_radio_txpower); - if(NETSTACK_FRAMER.create()) { + if(NETSTACK_FRAMER.create() >= 0) { NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()); } } diff --git a/examples/ipv6/native-border-router/border-router-rdc.c b/examples/ipv6/native-border-router/border-router-rdc.c new file mode 100644 index 000000000..0d82a167e --- /dev/null +++ b/examples/ipv6/native-border-router/border-router-rdc.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2010, 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: nullrdc.c,v 1.4 2010/11/23 18:11:00 nifi Exp $ + */ + +/** + * \file + * A null RDC implementation that uses framer for headers. + * \author + * Adam Dunkels + * Niclas Finne + */ + +#include "net/packetbuf.h" +#include "net/queuebuf.h" +#include "net/netstack.h" +#include +#include "packetbuf.h" +#include "packetutils.h" + +#define DEBUG 1 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define MAX_CALLBACKS 16 +static int callback_pos; + +/* a structure for calling back when packet data is coming back + from radio... */ +struct tx_callback { + mac_callback_t cback; + int status; + int tx; + void *ptr; + struct packetbuf_attr attr; + struct packetbuf_addr addr; +}; + +static void send_callback(struct tx_callback *tx); + + +static struct tx_callback callbacks[MAX_CALLBACKS]; + +void packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx) +{ + if(sessionid < MAX_CALLBACKS) { + struct tx_callback *callback; + callback = &callbacks[sessionid]; + packetbuf_attr_copyfrom(&callback->attr, &callback->addr); + callback->status = status; + callback->tx = tx; + send_callback(callback); + } else { + printf("*** ERROR: too high session id %d\n", sessionid); + } +} + +static int + setup_callback(mac_callback_t sent, void *ptr) +{ + int tmp = callback_pos; + struct tx_callback *callback; + callback = &callbacks[callback_pos]; + callback->cback = sent; + callback->ptr = ptr; + packetbuf_attr_copyto(&callback->attr, &callback->addr); + + callback_pos++; + if(callback_pos >= MAX_CALLBACKS) + callback_pos = 0; + + return tmp; +} +/*---------------------------------------------------------------------------*/ +static void +send_packet(mac_callback_t sent, void *ptr) +{ + int ret; + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); + + /* ack or not ? */ + packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); + + if(NETSTACK_FRAMER.create() == FRAMER_FAILED) { + /* Failed to allocate space for headers */ + PRINTF("br-rdc: send failed, too large header\n"); + ret = MAC_TX_ERR_FATAL; + } else { + int is_broadcast; + uint8_t dsn; + uint8_t sid; + int size; + uint8_t attbuf[64]; /* 3 bytes per attribute - hopefully enough with 64 */ + + sid = setup_callback(sent, ptr); + + dsn = ((uint8_t *)packetbuf_hdrptr())[2] & 0xff; + + is_broadcast = rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), + &rimeaddr_null); + + /* here we send the data over SLIP to the radio-chip */ + /* NETSTACK_RADIO.transmit(packetbuf_totlen())); */ + /* and store the "call" with a timeout - for fail and if success + we just make a callback */ + /* TODO: store the call for later "ack" / feedback handling... */ + if((size = packetutils_serialize_atts(attbuf, sizeof(attbuf))) > 0) { + /* alloc and copy attributes */ + packetbuf_hdralloc(size); + memcpy(packetbuf_hdrptr(), attbuf, size); + packetbuf_hdralloc(3); + uint8_t *buf = (uint8_t *) packetbuf_hdrptr(); + buf[0] = '!'; + buf[1] = 'S'; + buf[2] = sid; /* sequence or session number for this packet */ + write_to_slip(packetbuf_hdrptr(), packetbuf_totlen()); + } + } +} + +/* */ +static void send_callback(struct tx_callback *tx) +{ + mac_call_sent_callback(tx->cback, tx->ptr, tx->status, tx->tx); +} + +/*---------------------------------------------------------------------------*/ +static void +send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) +{ + if(buf_list != NULL) { + queuebuf_to_packetbuf(buf_list->buf); + send_packet(sent, ptr); + } +} +/*---------------------------------------------------------------------------*/ +static void +packet_input(void) +{ + if(NETSTACK_FRAMER.parse() == FRAMER_FAILED) { + PRINTF("br-rdc: failed to parse %u\n", packetbuf_datalen()); + } else { + NETSTACK_MAC.input(); + } +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(int keep_radio_on) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +channel_check_interval(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + callback_pos = 0; +} +/*---------------------------------------------------------------------------*/ +const struct rdc_driver border_router_rdc_driver = { + "br-rdc", + init, + send_packet, + send_list, + packet_input, + on, + off, + channel_check_interval, +}; +/*---------------------------------------------------------------------------*/