Rewrote LPP so that it uses 802.15.4 headers. A number of bugfixes with respect to alignment. Avoid turning off the radio in the middle of packet reception.
This commit is contained in:
parent
55b6129bd2
commit
e606c674c2
1 changed files with 93 additions and 57 deletions
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*
|
*
|
||||||
* $Id: lpp.c,v 1.32 2010/02/23 20:09:11 nifi Exp $
|
* $Id: lpp.c,v 1.33 2010/04/30 07:31:44 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
#define PRINTF(...)
|
#define PRINTF(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WITH_ACK_OPTIMIZATION 1
|
#define WITH_ACK_OPTIMIZATION 0
|
||||||
#define WITH_PROBE_AFTER_RECEPTION 0
|
#define WITH_PROBE_AFTER_RECEPTION 0
|
||||||
#define WITH_PROBE_AFTER_TRANSMISSION 0
|
#define WITH_PROBE_AFTER_TRANSMISSION 0
|
||||||
#define WITH_ENCOUNTER_OPTIMIZATION 1
|
#define WITH_ENCOUNTER_OPTIMIZATION 1
|
||||||
|
@ -82,20 +82,11 @@
|
||||||
#define WITH_PENDING_BROADCAST 1
|
#define WITH_PENDING_BROADCAST 1
|
||||||
#define WITH_STREAMING 1
|
#define WITH_STREAMING 1
|
||||||
|
|
||||||
#ifdef LPP_CONF_LISTEN_TIME
|
|
||||||
#define LISTEN_TIME LPP_CONF_LISTEN_TIME
|
|
||||||
#else
|
|
||||||
#define LISTEN_TIME (CLOCK_SECOND / 128)
|
#define LISTEN_TIME (CLOCK_SECOND / 128)
|
||||||
#endif /** LP_CONF_LISTEN_TIME */
|
|
||||||
|
|
||||||
#ifdef LPP_CONF_OFF_TIME
|
|
||||||
#define OFF_TIME LPP_CONF_OFF_TIME
|
|
||||||
#else
|
|
||||||
#define OFF_TIME (CLOCK_SECOND / MAC_CHANNEL_CHECK_RATE - LISTEN_TIME)
|
#define OFF_TIME (CLOCK_SECOND / MAC_CHANNEL_CHECK_RATE - LISTEN_TIME)
|
||||||
#endif /* LPP_CONF_OFF_TIME */
|
|
||||||
|
|
||||||
#define PACKET_LIFETIME (LISTEN_TIME + OFF_TIME)
|
#define PACKET_LIFETIME (LISTEN_TIME + OFF_TIME)
|
||||||
#define UNICAST_TIMEOUT (4 * PACKET_LIFETIME)
|
#define UNICAST_TIMEOUT (1 * PACKET_LIFETIME)
|
||||||
#define PROBE_AFTER_TRANSMISSION_TIME (LISTEN_TIME * 2)
|
#define PROBE_AFTER_TRANSMISSION_TIME (LISTEN_TIME * 2)
|
||||||
|
|
||||||
#define LOWEST_OFF_TIME (CLOCK_SECOND / 8)
|
#define LOWEST_OFF_TIME (CLOCK_SECOND / 8)
|
||||||
|
@ -190,6 +181,11 @@ static struct ctimer stream_probe_timer, stream_off_timer;
|
||||||
#define STREAM_PROBE_TIME CLOCK_SECOND / 128
|
#define STREAM_PROBE_TIME CLOCK_SECOND / 128
|
||||||
#define STREAM_OFF_TIME CLOCK_SECOND / 2
|
#define STREAM_OFF_TIME CLOCK_SECOND / 2
|
||||||
#endif /* WITH_STREAMING */
|
#endif /* WITH_STREAMING */
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||||
|
#endif /* MIN */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
turn_radio_on(void)
|
turn_radio_on(void)
|
||||||
|
@ -316,7 +312,8 @@ turn_radio_on_for_neighbor(rimeaddr_t *neighbor, struct queue_list_item *i)
|
||||||
time with modulo OFF_TIME. */
|
time with modulo OFF_TIME. */
|
||||||
|
|
||||||
now = clock_time();
|
now = clock_time();
|
||||||
wait = ((clock_time_t)(e->time - now)) % (OFF_TIME + LISTEN_TIME) - LISTEN_TIME;
|
wait = (((clock_time_t)(e->time - now)) % (OFF_TIME + LISTEN_TIME)) -
|
||||||
|
2 * LISTEN_TIME;
|
||||||
|
|
||||||
/* printf("now %d e %d e-n %d w %d %d\n", now, e->time, e->time - now, (e->time - now) % (OFF_TIME), wait);
|
/* printf("now %d e %d e-n %d w %d %d\n", now, e->time, e->time - now, (e->time - now) % (OFF_TIME), wait);
|
||||||
|
|
||||||
|
@ -358,6 +355,8 @@ remove_queued_packet(void *item)
|
||||||
PRINTF("%d.%d: removing queued packet\n",
|
PRINTF("%d.%d: removing queued packet\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
||||||
|
|
||||||
|
|
||||||
|
queuebuf_to_packetbuf(i->packet);
|
||||||
|
|
||||||
ctimer_stop(&i->removal_timer);
|
ctimer_stop(&i->removal_timer);
|
||||||
queuebuf_free(i->packet);
|
queuebuf_free(i->packet);
|
||||||
|
@ -414,9 +413,19 @@ send_probe(void)
|
||||||
hdr = packetbuf_dataptr();
|
hdr = packetbuf_dataptr();
|
||||||
hdr->type = TYPE_PROBE;
|
hdr->type = TYPE_PROBE;
|
||||||
rimeaddr_copy(&hdr->sender, &rimeaddr_node_addr);
|
rimeaddr_copy(&hdr->sender, &rimeaddr_node_addr);
|
||||||
rimeaddr_copy(&hdr->receiver, packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
/* rimeaddr_copy(&hdr->receiver, packetbuf_addr(PACKETBUF_ADDR_RECEIVER));*/
|
||||||
|
rimeaddr_copy(&hdr->receiver, &rimeaddr_null);
|
||||||
|
|
||||||
|
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &rimeaddr_null);
|
||||||
|
{
|
||||||
|
int hdrlen = NETSTACK_FRAMER.create();
|
||||||
|
if(hdrlen == 0) {
|
||||||
|
/* Failed to send */
|
||||||
|
PRINTF("contikimac: send failed, too large header\n");
|
||||||
|
return MAC_TX_ERR_FATAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Construct the announcements */
|
/* Construct the announcements */
|
||||||
adata = (struct announcement_msg *)((char *)hdr + sizeof(struct lpp_hdr));
|
adata = (struct announcement_msg *)((char *)hdr + sizeof(struct lpp_hdr));
|
||||||
|
|
||||||
|
@ -542,8 +551,10 @@ dutycycle(void *ptr)
|
||||||
/* If we are not listening for announcements, we turn the radio
|
/* If we are not listening for announcements, we turn the radio
|
||||||
off and wait until we send the next probe. */
|
off and wait until we send the next probe. */
|
||||||
if(is_listening == 0) {
|
if(is_listening == 0) {
|
||||||
turn_radio_off();
|
if(!NETSTACK_RADIO.receiving_packet()) {
|
||||||
compower_accumulate(&compower_idle_activity);
|
turn_radio_off();
|
||||||
|
compower_accumulate(&compower_idle_activity);
|
||||||
|
}
|
||||||
ctimer_set(t, off_time + off_time_adjustment, (void (*)(void *))dutycycle, t);
|
ctimer_set(t, off_time + off_time_adjustment, (void (*)(void *))dutycycle, t);
|
||||||
off_time_adjustment = 0;
|
off_time_adjustment = 0;
|
||||||
PT_YIELD(&dutycycle_pt);
|
PT_YIELD(&dutycycle_pt);
|
||||||
|
@ -610,8 +621,17 @@ send_packet(mac_callback_t sent, void *ptr)
|
||||||
|
|
||||||
packetbuf_hdralloc(sizeof(struct lpp_hdr));
|
packetbuf_hdralloc(sizeof(struct lpp_hdr));
|
||||||
memcpy(packetbuf_hdrptr(), &hdr, sizeof(struct lpp_hdr));
|
memcpy(packetbuf_hdrptr(), &hdr, sizeof(struct lpp_hdr));
|
||||||
|
|
||||||
packetbuf_compact();
|
packetbuf_compact();
|
||||||
|
|
||||||
|
{
|
||||||
|
int hdrlen = NETSTACK_FRAMER.create();
|
||||||
|
if(hdrlen == 0) {
|
||||||
|
/* Failed to send */
|
||||||
|
PRINTF("contikimac: send failed, too large header\n");
|
||||||
|
return MAC_TX_ERR_FATAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PRINTF("%d.%d: queueing packet to %d.%d, channel %d\n",
|
PRINTF("%d.%d: queueing packet to %d.%d, channel %d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
hdr.receiver.u8[0], hdr.receiver.u8[1],
|
hdr.receiver.u8[0], hdr.receiver.u8[1],
|
||||||
|
@ -688,38 +708,52 @@ send_packet(mac_callback_t sent, void *ptr)
|
||||||
static void
|
static void
|
||||||
input_packet(void)
|
input_packet(void)
|
||||||
{
|
{
|
||||||
struct lpp_hdr *hdr;
|
struct lpp_hdr hdr;
|
||||||
clock_time_t reception_time;
|
clock_time_t reception_time;
|
||||||
|
|
||||||
reception_time = clock_time();
|
reception_time = clock_time();
|
||||||
|
|
||||||
hdr = packetbuf_dataptr();
|
if(!NETSTACK_FRAMER.parse()) {
|
||||||
|
printf("lpp input_packet framer error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&hdr, packetbuf_dataptr(), sizeof(struct lpp_hdr));;
|
||||||
packetbuf_hdrreduce(sizeof(struct lpp_hdr));
|
packetbuf_hdrreduce(sizeof(struct lpp_hdr));
|
||||||
/* PRINTF("got packet type %d\n", hdr->type);*/
|
/* PRINTF("got packet type %d\n", hdr->type);*/
|
||||||
|
|
||||||
if(hdr->type == TYPE_PROBE) {
|
if(hdr.type == TYPE_PROBE) {
|
||||||
/* Parse incoming announcements */
|
struct announcement_msg adata;
|
||||||
struct announcement_msg *adata = packetbuf_dataptr();
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* PRINTF("%d.%d: probe from %d.%d with %d announcements\n",
|
/* Register the encounter with the sending node. We now know the
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
neighbor's phase. */
|
||||||
hdr->sender.u8[0], hdr->sender.u8[1], adata->num);*/
|
register_encounter(&hdr.sender, reception_time);
|
||||||
|
|
||||||
for(i = 0; i < adata->num; ++i) {
|
/* Parse incoming announcements */
|
||||||
|
memcpy(&adata, packetbuf_dataptr(),
|
||||||
|
MIN(packetbuf_datalen(), sizeof(adata)));
|
||||||
|
#if 0
|
||||||
|
PRINTF("%d.%d: probe from %d.%d with %d announcements\n",
|
||||||
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
|
hdr.sender.u8[0], hdr.sender.u8[1], adata->num);
|
||||||
|
|
||||||
|
if(adata.num / sizeof(struct announcement_data) > sizeof(struct announcement_msg)) {
|
||||||
|
/* Sanity check. The number of announcements is too large -
|
||||||
|
corrupt packet has been received. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < adata.num; ++i) {
|
||||||
/* PRINTF("%d.%d: announcement %d: %d\n",
|
/* PRINTF("%d.%d: announcement %d: %d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
adata->data[i].id,
|
adata->data[i].id,
|
||||||
adata->data[i].value);*/
|
adata->data[i].value);*/
|
||||||
|
|
||||||
announcement_heard(&hdr->sender,
|
announcement_heard(&hdr.sender,
|
||||||
adata->data[i].id,
|
adata.data[i].id,
|
||||||
adata->data[i].value);
|
adata.data[i].value);
|
||||||
}
|
}
|
||||||
|
#endif /* 0 */
|
||||||
/* Register the encounter with the sending node. We now know the
|
|
||||||
neighbor's phase. */
|
|
||||||
register_encounter(&hdr->sender, reception_time);
|
|
||||||
|
|
||||||
/* Go through the list of packets to be sent to see if any of
|
/* Go through the list of packets to be sent to see if any of
|
||||||
them match the sender of the probe, or if they are a
|
them match the sender of the probe, or if they are a
|
||||||
|
@ -727,11 +761,11 @@ input_packet(void)
|
||||||
if(list_length(queued_packets_list) > 0) {
|
if(list_length(queued_packets_list) > 0) {
|
||||||
struct queue_list_item *i;
|
struct queue_list_item *i;
|
||||||
for(i = list_head(queued_packets_list); i != NULL; i = i->next) {
|
for(i = list_head(queued_packets_list); i != NULL; i = i->next) {
|
||||||
struct lpp_hdr *qhdr;
|
const rimeaddr_t *receiver;
|
||||||
|
|
||||||
qhdr = queuebuf_dataptr(i->packet);
|
receiver = queuebuf_addr(i->packet, PACKETBUF_ADDR_RECEIVER);
|
||||||
if(rimeaddr_cmp(&qhdr->receiver, &hdr->sender) ||
|
if(rimeaddr_cmp(receiver, &hdr.sender) ||
|
||||||
rimeaddr_cmp(&qhdr->receiver, &rimeaddr_null)) {
|
rimeaddr_cmp(receiver, &rimeaddr_null)) {
|
||||||
queuebuf_to_packetbuf(i->packet);
|
queuebuf_to_packetbuf(i->packet);
|
||||||
|
|
||||||
#if WITH_PENDING_BROADCAST
|
#if WITH_PENDING_BROADCAST
|
||||||
|
@ -740,15 +774,16 @@ input_packet(void)
|
||||||
i->num_transmissions = 1;
|
i->num_transmissions = 1;
|
||||||
NETSTACK_RADIO.send(queuebuf_dataptr(i->packet),
|
NETSTACK_RADIO.send(queuebuf_dataptr(i->packet),
|
||||||
queuebuf_datalen(i->packet));
|
queuebuf_datalen(i->packet));
|
||||||
|
turn_radio_off();
|
||||||
PRINTF("%d.%d: got a probe from %d.%d, sent packet to %d.%d\n",
|
PRINTF("%d.%d: got a probe from %d.%d, sent packet to %d.%d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
hdr->sender.u8[0], hdr->sender.u8[1],
|
hdr.sender.u8[0], hdr.sender.u8[1],
|
||||||
qhdr->receiver.u8[0], qhdr->receiver.u8[1]);
|
receiver->u8[0], receiver->u8[1]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PRINTF("%d.%d: got a probe from %d.%d, did not send packet\n",
|
PRINTF("%d.%d: got a probe from %d.%d, did not send packet\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
hdr->sender.u8[0], hdr->sender.u8[1]);
|
hdr.sender.u8[0], hdr.sender.u8[1]);
|
||||||
}
|
}
|
||||||
#else /* WITH_PENDING_BROADCAST */
|
#else /* WITH_PENDING_BROADCAST */
|
||||||
i->num_transmissions = 1;
|
i->num_transmissions = 1;
|
||||||
|
@ -756,11 +791,11 @@ input_packet(void)
|
||||||
queuebuf_datalen(i->packet));
|
queuebuf_datalen(i->packet));
|
||||||
PRINTF("%d.%d: got a probe from %d.%d, sent packet to %d.%d\n",
|
PRINTF("%d.%d: got a probe from %d.%d, sent packet to %d.%d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
hdr->sender.u8[0], hdr->sender.u8[1],
|
hdr.sender.u8[0], hdr.sender.u8[1],
|
||||||
qhdr->receiver.u8[0], qhdr->receiver.u8[1]);
|
receiver->u8[0], receiver->u8[1]);
|
||||||
#endif /* WITH_PENDING_BROADCAST */
|
#endif /* WITH_PENDING_BROADCAST */
|
||||||
|
|
||||||
|
/* off();*/
|
||||||
|
|
||||||
/* Attribute the energy spent on listening for the probe
|
/* Attribute the energy spent on listening for the probe
|
||||||
to this packet transmission. */
|
to this packet transmission. */
|
||||||
|
@ -770,7 +805,7 @@ input_packet(void)
|
||||||
now. Broadcast packets should be transmitted to all
|
now. Broadcast packets should be transmitted to all
|
||||||
neighbors, and are dequeued by the dutycycling function
|
neighbors, and are dequeued by the dutycycling function
|
||||||
instead, after the appropriate time. */
|
instead, after the appropriate time. */
|
||||||
if(!rimeaddr_cmp(&qhdr->receiver, &rimeaddr_null)) {
|
if(!rimeaddr_cmp(receiver, &rimeaddr_null)) {
|
||||||
remove_queued_packet(i);
|
remove_queued_packet(i);
|
||||||
|
|
||||||
#if WITH_PROBE_AFTER_TRANSMISSION
|
#if WITH_PROBE_AFTER_TRANSMISSION
|
||||||
|
@ -799,22 +834,23 @@ input_packet(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(hdr->type == TYPE_DATA) {
|
} else if(hdr.type == TYPE_DATA) {
|
||||||
if(!rimeaddr_cmp(&hdr->receiver, &rimeaddr_null)) {
|
turn_radio_off();
|
||||||
if(!rimeaddr_cmp(&hdr->receiver, &rimeaddr_node_addr)) {
|
if(!rimeaddr_cmp(&hdr.receiver, &rimeaddr_null)) {
|
||||||
|
if(!rimeaddr_cmp(&hdr.receiver, &rimeaddr_node_addr)) {
|
||||||
/* Not broadcast or for us */
|
/* Not broadcast or for us */
|
||||||
PRINTF("%d.%d: data not for us from %d.%d\n",
|
PRINTF("%d.%d: data not for us from %d.%d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
hdr->sender.u8[0], hdr->sender.u8[1]);
|
hdr.sender.u8[0], hdr.sender.u8[1]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &hdr->receiver);
|
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &hdr.receiver);
|
||||||
}
|
}
|
||||||
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &hdr->sender);
|
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &hdr.sender);
|
||||||
|
|
||||||
PRINTF("%d.%d: got data from %d.%d\n",
|
PRINTF("%d.%d: got data from %d.%d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
hdr->sender.u8[0], hdr->sender.u8[1]);
|
hdr.sender.u8[0], hdr.sender.u8[1]);
|
||||||
|
|
||||||
/* Accumulate the power consumption for the packet reception. */
|
/* Accumulate the power consumption for the packet reception. */
|
||||||
compower_accumulate(¤t_packet);
|
compower_accumulate(¤t_packet);
|
||||||
|
@ -829,7 +865,7 @@ input_packet(void)
|
||||||
compower_clear(¤t_packet);
|
compower_clear(¤t_packet);
|
||||||
|
|
||||||
#if WITH_PENDING_BROADCAST
|
#if WITH_PENDING_BROADCAST
|
||||||
if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_null)) {
|
if(rimeaddr_cmp(&hdr.receiver, &rimeaddr_null)) {
|
||||||
/* This is a broadcast packet. Check the list of pending
|
/* This is a broadcast packet. Check the list of pending
|
||||||
packets to see if we are currently sending a broadcast. If
|
packets to see if we are currently sending a broadcast. If
|
||||||
so, we refrain from sending our broadcast until one sleep
|
so, we refrain from sending our broadcast until one sleep
|
||||||
|
@ -853,7 +889,7 @@ input_packet(void)
|
||||||
/* XXX send probe after receiving a packet to facilitate data
|
/* XXX send probe after receiving a packet to facilitate data
|
||||||
streaming. We must first copy the contents of the packetbuf into
|
streaming. We must first copy the contents of the packetbuf into
|
||||||
a queuebuf to avoid overwriting the data with the probe packet. */
|
a queuebuf to avoid overwriting the data with the probe packet. */
|
||||||
if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_node_addr)) {
|
if(rimeaddr_cmp(&hdr.receiver, &rimeaddr_node_addr)) {
|
||||||
struct queuebuf *q;
|
struct queuebuf *q;
|
||||||
q = queuebuf_new_from_packetbuf();
|
q = queuebuf_new_from_packetbuf();
|
||||||
if(q != NULL) {
|
if(q != NULL) {
|
||||||
|
|
Loading…
Reference in a new issue