summaryrefslogtreecommitdiff
path: root/tests/examplefiles/IPDispatchP.nc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/examplefiles/IPDispatchP.nc')
-rw-r--r--tests/examplefiles/IPDispatchP.nc671
1 files changed, 0 insertions, 671 deletions
diff --git a/tests/examplefiles/IPDispatchP.nc b/tests/examplefiles/IPDispatchP.nc
deleted file mode 100644
index 628f39a0..00000000
--- a/tests/examplefiles/IPDispatchP.nc
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * "Copyright (c) 2008 The Regents of the University of California.
- * All rights reserved."
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
- * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
- *
- */
-
-#include <lib6lowpan/blip-tinyos-includes.h>
-#include <lib6lowpan/6lowpan.h>
-#include <lib6lowpan/lib6lowpan.h>
-#include <lib6lowpan/ip.h>
-#include <lib6lowpan/in_cksum.h>
-#include <lib6lowpan/ip_malloc.h>
-
-#include "blip_printf.h"
-#include "IPDispatch.h"
-#include "BlipStatistics.h"
-#include "table.h"
-
-/*
- * Provides IP layer reception to applications on motes.
- *
- * @author Stephen Dawson-Haggerty <stevedh@cs.berkeley.edu>
- */
-
-module IPDispatchP {
- provides {
- interface SplitControl;
- // interface for protocols not requiring special hand-holding
- interface IPLower;
-
- interface BlipStatistics<ip_statistics_t>;
-
- }
- uses {
- interface Boot;
-
-
- /* link-layer wiring */
- interface SplitControl as RadioControl;
-
- interface Packet as BarePacket;
- interface Send as Ieee154Send;
- interface Receive as Ieee154Receive;
-
- /* context lookup */
- interface NeighborDiscovery;
-
- interface ReadLqi;
- interface PacketLink;
- interface LowPowerListening;
-
- /* buffers for outgoing fragments */
- interface Pool<message_t> as FragPool;
- interface Pool<struct send_info> as SendInfoPool;
- interface Pool<struct send_entry> as SendEntryPool;
- interface Queue<struct send_entry *> as SendQueue;
-
- /* expire reconstruction */
- interface Timer<TMilli> as ExpireTimer;
-
- interface Leds;
-
- }
- provides interface Init;
-} implementation {
-
-#define HAVE_LOWPAN_EXTERN_MATCH_CONTEXT
-int lowpan_extern_read_context(struct in6_addr *addr, int context) {
- return call NeighborDiscovery.getContext(context, addr);
-}
-
-int lowpan_extern_match_context(struct in6_addr *addr, uint8_t *ctx_id) {
- return call NeighborDiscovery.matchContext(addr, ctx_id);
-}
-
- // generally including source files like this is a no-no. I'm doing
- // this in the hope that the optimizer will do a better job when
- // they're part of a component.
-#include <lib6lowpan/ieee154_header.c>
-#include <lib6lowpan/lib6lowpan.c>
-#include <lib6lowpan/lib6lowpan_4944.c>
-#include <lib6lowpan/lib6lowpan_frag.c>
-
- enum {
- S_RUNNING,
- S_STOPPED,
- S_STOPPING,
- };
- uint8_t state = S_STOPPED;
- bool radioBusy;
- uint8_t current_local_label = 0;
- ip_statistics_t stats;
-
- // this in theory could be arbitrarily large; however, it needs to
- // be large enough to hold all active reconstructions, and any tags
- // which we are dropping. It's important to keep dropped tags
- // around for a while, or else there are pathological situations
- // where you continually allocate buffers for packets which will
- // never complete.
-
- ////////////////////////////////////////
- //
- //
-
- table_t recon_cache;
-
- // table of packets we are currently receiving fragments from, that
- // are destined to us
- struct lowpan_reconstruct recon_data[N_RECONSTRUCTIONS];
-
- //
- //
- ////////////////////////////////////////
-
- // task void sendTask();
-
- void reconstruct_clear(void *ent) {
- struct lowpan_reconstruct *recon = (struct lowpan_reconstruct *)ent;
- memclr((uint8_t *)&recon->r_meta, sizeof(struct ip6_metadata));
- recon->r_timeout = T_UNUSED;
- recon->r_buf = NULL;
- }
-
- struct send_info *getSendInfo() {
- struct send_info *ret = call SendInfoPool.get();
- if (ret == NULL) return ret;
- ret->_refcount = 1;
- ret->upper_data = NULL;
- ret->failed = FALSE;
- ret->link_transmissions = 0;
- ret->link_fragments = 0;
- ret->link_fragment_attempts = 0;
- return ret;
- }
-#define SENDINFO_INCR(X) ((X)->_refcount)++
-void SENDINFO_DECR(struct send_info *si) {
- if (--(si->_refcount) == 0) {
- call SendInfoPool.put(si);
- }
-}
-
- command error_t SplitControl.start() {
- return call RadioControl.start();
- }
-
- command error_t SplitControl.stop() {
- if (!radioBusy) {
- state = S_STOPPED;
- return call RadioControl.stop();
- } else {
- // if there's a packet in the radio, wait for it to exit before
- // stopping
- state = S_STOPPING;
- return SUCCESS;
- }
- }
-
- event void RadioControl.startDone(error_t error) {
-#ifdef LPL_SLEEP_INTERVAL
- call LowPowerListening.setLocalWakeupInterval(LPL_SLEEP_INTERVAL);
-#endif
-
- if (error == SUCCESS) {
- call Leds.led2Toggle();
- call ExpireTimer.startPeriodic(FRAG_EXPIRE_TIME);
- state = S_RUNNING;
- radioBusy = FALSE;
- }
-
- signal SplitControl.startDone(error);
- }
-
- event void RadioControl.stopDone(error_t error) {
- signal SplitControl.stopDone(error);
- }
-
- command error_t Init.init() {
- // ip_malloc_init needs to be in init, not booted, because
- // context for coap is initialised in init
- ip_malloc_init();
- return SUCCESS;
- }
-
- event void Boot.booted() {
- call BlipStatistics.clear();
-
- /* set up our reconstruction cache */
- table_init(&recon_cache, recon_data, sizeof(struct lowpan_reconstruct), N_RECONSTRUCTIONS);
- table_map(&recon_cache, reconstruct_clear);
-
- call SplitControl.start();
- }
-
- /*
- * Receive-side code.
- */
- void deliver(struct lowpan_reconstruct *recon) {
- struct ip6_hdr *iph = (struct ip6_hdr *)recon->r_buf;
-
- // printf("deliver [%i]: ", recon->r_bytes_rcvd);
- // printf_buf(recon->r_buf, recon->r_bytes_rcvd);
-
- /* the payload length field is always compressed, have to put it back here */
- iph->ip6_plen = htons(recon->r_bytes_rcvd - sizeof(struct ip6_hdr));
- signal IPLower.recv(iph, (void *)(iph + 1), &recon->r_meta);
-
- // printf("ip_free(%p)\n", recon->r_buf);
- ip_free(recon->r_buf);
- recon->r_timeout = T_UNUSED;
- recon->r_buf = NULL;
- }
-
- /*
- * Bulletproof recovery logic is very important to make sure we
- * don't get wedged with no free buffers.
- *
- * The table is managed as follows:
- * - unused entries are marked T_UNUSED
- * - entries which
- * o have a buffer allocated
- * o have had a fragment reception before we fired
- * are marked T_ACTIVE
- * - entries which have not had a fragment reception during the last timer period
- * and were active are marked T_ZOMBIE
- * - zombie receptions are deleted: their buffer is freed and table entry marked unused.
- * - when a fragment is dropped, it is entered into the table as T_FAILED1.
- * no buffer is allocated
- * - when the timer fires, T_FAILED1 entries are aged to T_FAILED2.
- * - T_FAILED2 entries are deleted. Incomming fragments with tags
- * that are marked either FAILED1 or FAILED2 are dropped; this
- * prevents us from allocating a buffer for a packet which we
- * have already dropped fragments from.
- *
- */
- void reconstruct_age(void *elt) {
- struct lowpan_reconstruct *recon = (struct lowpan_reconstruct *)elt;
- if (recon->r_timeout != T_UNUSED)
- printf("recon src: 0x%x tag: 0x%x buf: %p recvd: %i/%i\n",
- recon->r_source_key, recon->r_tag, recon->r_buf,
- recon->r_bytes_rcvd, recon->r_size);
- switch (recon->r_timeout) {
- case T_ACTIVE:
- recon->r_timeout = T_ZOMBIE; break; // age existing receptions
- case T_FAILED1:
- recon->r_timeout = T_FAILED2; break; // age existing receptions
- case T_ZOMBIE:
- case T_FAILED2:
- // deallocate the space for reconstruction
- printf("timing out buffer: src: %i tag: %i\n", recon->r_source_key, recon->r_tag);
- if (recon->r_buf != NULL) {
- printf("ip_free(%p)\n", recon->r_buf);
- ip_free(recon->r_buf);
- }
- recon->r_timeout = T_UNUSED;
- recon->r_buf = NULL;
- break;
- }
- }
-
- void ip_print_heap() {
-#ifdef PRINTFUART_ENABLED
- bndrt_t *cur = (bndrt_t *)heap;
- while (((uint8_t *)cur) - heap < IP_MALLOC_HEAP_SIZE) {
- printf ("heap region start: %p length: %u used: %u\n",
- cur, (*cur & IP_MALLOC_LEN), (*cur & IP_MALLOC_INUSE) >> 15);
- cur = (bndrt_t *)(((uint8_t *)cur) + ((*cur) & IP_MALLOC_LEN));
- }
-#endif
- }
-
- event void ExpireTimer.fired() {
- table_map(&recon_cache, reconstruct_age);
-
-
- printf("Frag pool size: %i\n", call FragPool.size());
- printf("SendInfo pool size: %i\n", call SendInfoPool.size());
- printf("SendEntry pool size: %i\n", call SendEntryPool.size());
- printf("Forward queue length: %i\n", call SendQueue.size());
- ip_print_heap();
- printfflush();
- }
-
- /*
- * allocate a structure for recording information about incomming fragments.
- */
-
- struct lowpan_reconstruct *get_reconstruct(uint16_t key, uint16_t tag) {
- struct lowpan_reconstruct *ret = NULL;
- int i;
-
- // printf("get_reconstruct: %x %i\n", key, tag);
-
- for (i = 0; i < N_RECONSTRUCTIONS; i++) {
- struct lowpan_reconstruct *recon = (struct lowpan_reconstruct *)&recon_data[i];
-
- if (recon->r_tag == tag &&
- recon->r_source_key == key) {
-
- if (recon->r_timeout > T_UNUSED) {
- recon->r_timeout = T_ACTIVE;
- ret = recon;
- goto done;
-
- } else if (recon->r_timeout < T_UNUSED) {
- // if we have already tried and failed to get a buffer, we
- // need to drop remaining fragments.
- ret = NULL;
- goto done;
- }
- }
- if (recon->r_timeout == T_UNUSED)
- ret = recon;
- }
- done:
- // printf("got%p\n", ret);
- return ret;
- }
-
- event message_t *Ieee154Receive.receive(message_t *msg, void *msg_payload, uint8_t len) {
- struct packed_lowmsg lowmsg;
- struct ieee154_frame_addr frame_address;
- uint8_t *buf = msg_payload;
-
- // printf(" -- RECEIVE -- len : %i\n", len);
-
- BLIP_STATS_INCR(stats.rx_total);
-
- /* unpack the 802.15.4 address fields */
- buf = unpack_ieee154_hdr(msg_payload, &frame_address);
- len -= buf - (uint8_t *)msg_payload;
-
- /* unpack and 6lowpan headers */
- lowmsg.data = buf;
- lowmsg.len = len;
- lowmsg.headers = getHeaderBitmap(&lowmsg);
- if (lowmsg.headers == LOWMSG_NALP) {
- goto fail;
- }
-
- if (hasFrag1Header(&lowmsg) || hasFragNHeader(&lowmsg)) {
- // start reassembly
- int rv;
- struct lowpan_reconstruct *recon;
- uint16_t tag, source_key;
-
- source_key = ieee154_hashaddr(&frame_address.ieee_src);
- getFragDgramTag(&lowmsg, &tag);
- recon = get_reconstruct(source_key, tag);
- if (!recon) {
- goto fail;
- }
-
- /* fill in metadata: on fragmented packets, it applies to the
- first fragment only */
- memcpy(&recon->r_meta.sender, &frame_address.ieee_src,
- sizeof(ieee154_addr_t));
- recon->r_meta.lqi = call ReadLqi.readLqi(msg);
- recon->r_meta.rssi = call ReadLqi.readRssi(msg);
-
- if (hasFrag1Header(&lowmsg)) {
- if (recon->r_buf != NULL) goto fail;
- rv = lowpan_recon_start(&frame_address, recon, buf, len);
- } else {
- rv = lowpan_recon_add(recon, buf, len);
- }
-
- if (rv < 0) {
- recon->r_timeout = T_FAILED1;
- goto fail;
- } else {
- // printf("start recon buf: %p\n", recon->r_buf);
- recon->r_timeout = T_ACTIVE;
- recon->r_source_key = source_key;
- recon->r_tag = tag;
- }
-
- if (recon->r_size == recon->r_bytes_rcvd) {
- deliver(recon);
- }
-
- } else {
- /* no fragmentation, just deliver it */
- int rv;
- struct lowpan_reconstruct recon;
-
- /* fill in metadata */
- memcpy(&recon.r_meta.sender, &frame_address.ieee_src,
- sizeof(ieee154_addr_t));
- recon.r_meta.lqi = call ReadLqi.readLqi(msg);
- recon.r_meta.rssi = call ReadLqi.readRssi(msg);
-
- buf = getLowpanPayload(&lowmsg);
- if ((rv = lowpan_recon_start(&frame_address, &recon, buf, len)) < 0) {
- goto fail;
- }
-
- if (recon.r_size == recon.r_bytes_rcvd) {
- deliver(&recon);
- } else {
- // printf("ip_free(%p)\n", recon.r_buf);
- ip_free(recon.r_buf);
- }
- }
- goto done;
- fail:
- BLIP_STATS_INCR(stats.rx_drop);
- done:
- return msg;
- }
-
-
- /*
- * Send-side functionality
- */
- task void sendTask() {
- struct send_entry *s_entry;
-
- // printf("sendTask() - sending\n");
-
- if (radioBusy || state != S_RUNNING) return;
- if (call SendQueue.empty()) return;
- // this does not dequeue
- s_entry = call SendQueue.head();
-
-#ifdef LPL_SLEEP_INTERVAL
- call LowPowerListening.setRemoteWakeupInterval(s_entry->msg,
- call LowPowerListening.getLocalWakeupInterval());
-#endif
-
- if (s_entry->info->failed) {
- dbg("Drops", "drops: sendTask: dropping failed fragment\n");
- goto fail;
- }
-
- if ((call Ieee154Send.send(s_entry->msg,
- call BarePacket.payloadLength(s_entry->msg))) != SUCCESS) {
- dbg("Drops", "drops: sendTask: send failed\n");
- goto fail;
- } else {
- radioBusy = TRUE;
- }
-
- return;
- fail:
- printf("SEND FAIL\n");
- post sendTask();
- BLIP_STATS_INCR(stats.tx_drop);
-
- // deallocate the memory associated with this request.
- // other fragments associated with this packet will get dropped.
- s_entry->info->failed = TRUE;
- SENDINFO_DECR(s_entry->info);
- call FragPool.put(s_entry->msg);
- call SendEntryPool.put(s_entry);
- call SendQueue.dequeue();
- }
-
-
- /*
- * it will pack the message into the fragment pool and enqueue
- * those fragments for sending
- *
- * it will set
- * - payload length
- * - version, traffic class and flow label
- *
- * the source and destination IP addresses must be set by higher
- * layers.
- */
- command error_t IPLower.send(struct ieee154_frame_addr *frame_addr,
- struct ip6_packet *msg,
- void *data) {
- struct lowpan_ctx ctx;
- struct send_info *s_info;
- struct send_entry *s_entry;
- message_t *outgoing;
-
- int frag_len = 1;
- error_t rc = SUCCESS;
-
- if (state != S_RUNNING) {
- return EOFF;
- }
-
- /* set version to 6 in case upper layers forgot */
- msg->ip6_hdr.ip6_vfc &= ~IPV6_VERSION_MASK;
- msg->ip6_hdr.ip6_vfc |= IPV6_VERSION;
-
- ctx.tag = current_local_label++;
- ctx.offset = 0;
-
- s_info = getSendInfo();
- if (s_info == NULL) {
- rc = ERETRY;
- goto cleanup_outer;
- }
- s_info->upper_data = data;
-
- while (frag_len > 0) {
- s_entry = call SendEntryPool.get();
- outgoing = call FragPool.get();
-
- if (s_entry == NULL || outgoing == NULL) {
- if (s_entry != NULL)
- call SendEntryPool.put(s_entry);
- if (outgoing != NULL)
- call FragPool.put(outgoing);
- // this will cause any fragments we have already enqueued to
- // be dropped by the send task.
- s_info->failed = TRUE;
- printf("drops: IP send: no fragments\n");
- rc = ERETRY;
- goto done;
- }
-
- call BarePacket.clear(outgoing);
- frag_len = lowpan_frag_get(call Ieee154Send.getPayload(outgoing, 0),
- call BarePacket.maxPayloadLength(),
- msg,
- frame_addr,
- &ctx);
- if (frag_len < 0) {
- printf(" get frag error: %i\n", frag_len);
- }
-
- printf("fragment length: %i offset: %i\n", frag_len, ctx.offset);
- call BarePacket.setPayloadLength(outgoing, frag_len);
-
- if (frag_len <= 0) {
- call FragPool.put(outgoing);
- call SendEntryPool.put(s_entry);
- goto done;
- }
-
- if (call SendQueue.enqueue(s_entry) != SUCCESS) {
- BLIP_STATS_INCR(stats.encfail);
- s_info->failed = TRUE;
- printf("drops: IP send: enqueue failed\n");
- goto done;
- }
-
- s_info->link_fragments++;
- s_entry->msg = outgoing;
- s_entry->info = s_info;
-
- /* configure the L2 */
- if (frame_addr->ieee_dst.ieee_mode == IEEE154_ADDR_SHORT &&
- frame_addr->ieee_dst.i_saddr == IEEE154_BROADCAST_ADDR) {
- call PacketLink.setRetries(s_entry->msg, 0);
- } else {
- call PacketLink.setRetries(s_entry->msg, BLIP_L2_RETRIES);
- }
- call PacketLink.setRetryDelay(s_entry->msg, BLIP_L2_DELAY);
-
- SENDINFO_INCR(s_info);}
-
- // printf("got %i frags\n", s_info->link_fragments);
- done:
- BLIP_STATS_INCR(stats.sent);
- SENDINFO_DECR(s_info);
- post sendTask();
- cleanup_outer:
- return rc;
- }
-
- event void Ieee154Send.sendDone(message_t *msg, error_t error) {
- struct send_entry *s_entry = call SendQueue.head();
-
- radioBusy = FALSE;
-
- // printf("sendDone: %p %i\n", msg, error);
-
- if (state == S_STOPPING) {
- call RadioControl.stop();
- state = S_STOPPED;
- goto done;
- }
-
- s_entry->info->link_transmissions += (call PacketLink.getRetries(msg));
- s_entry->info->link_fragment_attempts++;
-
- if (!call PacketLink.wasDelivered(msg)) {
- printf("sendDone: was not delivered! (%i tries)\n",
- call PacketLink.getRetries(msg));
- s_entry->info->failed = TRUE;
- signal IPLower.sendDone(s_entry->info);
-/* if (s_entry->info->policy.dest[0] != 0xffff) */
-/* dbg("Drops", "drops: sendDone: frag was not delivered\n"); */
- // need to check for broadcast frames
- // BLIP_STATS_INCR(stats.tx_drop);
- } else if (s_entry->info->link_fragment_attempts ==
- s_entry->info->link_fragments) {
- signal IPLower.sendDone(s_entry->info);
- }
-
- done:
- // kill off any pending fragments
- SENDINFO_DECR(s_entry->info);
- call FragPool.put(s_entry->msg);
- call SendEntryPool.put(s_entry);
- call SendQueue.dequeue();
-
- post sendTask();
- }
-
-#if 0
- command struct tlv_hdr *IPExtensions.findTlv(struct ip6_ext *ext, uint8_t tlv_val) {
- int len = ext->len - sizeof(struct ip6_ext);
- struct tlv_hdr *tlv = (struct tlv_hdr *)(ext + 1);
- while (len > 0) {
- if (tlv->type == tlv_val) return tlv;
- if (tlv->len == 0) return NULL;
- tlv = (struct tlv_hdr *)(((uint8_t *)tlv) + tlv->len);
- len -= tlv->len;
- }
- return NULL;
- }
-#endif
-
-
- /*
- * BlipStatistics interface
- */
- command void BlipStatistics.get(ip_statistics_t *statistics) {
-#ifdef BLIP_STATS_IP_MEM
- stats.fragpool = call FragPool.size();
- stats.sendinfo = call SendInfoPool.size();
- stats.sendentry= call SendEntryPool.size();
- stats.sndqueue = call SendQueue.size();
- stats.heapfree = ip_malloc_freespace();
- printf("frag: %i sendinfo: %i sendentry: %i sendqueue: %i heap: %i\n",
- stats.fragpool,
- stats.sendinfo,
- stats.sendentry,
- stats.sndqueue,
- stats.heapfree);
-#endif
- memcpy(statistics, &stats, sizeof(ip_statistics_t));
-
- }
-
- command void BlipStatistics.clear() {
- memclr((uint8_t *)&stats, sizeof(ip_statistics_t));
- }
-
-/* default event void IP.recv[uint8_t nxt_hdr](struct ip6_hdr *iph, */
-/* void *payload, */
-/* struct ip_metadata *meta) { */
-/* } */
-
-/* default event void Multicast.recv[uint8_t scope](struct ip6_hdr *iph, */
-/* void *payload, */
-/* struct ip_metadata *meta) { */
-/* } */
-}