bugfix: remember active transmissions (sender side) instead of last received packets (receiving side). allows several nodes sending to a single receiver.

+ added function for checking if runicast is currently transmitting (non-acked) data
This commit is contained in:
fros4943 2009-03-03 12:19:46 +00:00
parent 35e3efa0a6
commit f701615afa
2 changed files with 22 additions and 14 deletions

View file

@ -34,7 +34,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: runicast.c,v 1.3 2009/02/17 12:40:18 fros4943 Exp $ * $Id: runicast.c,v 1.4 2009/03/03 12:19:46 fros4943 Exp $
*/ */
/** /**
@ -83,6 +83,7 @@ sent_by_stunicast(struct stunicast_conn *stunicast)
c->rxmit++; c->rxmit++;
if(c->rxmit >= c->max_rxmit) { if(c->rxmit >= c->max_rxmit) {
RIMESTATS_ADD(timedout); RIMESTATS_ADD(timedout);
c->is_tx = 0;
stunicast_cancel(&c->c); stunicast_cancel(&c->c);
if(c->u->timedout) { if(c->u->timedout) {
c->u->timedout(c, stunicast_receiver(&c->c), c->rxmit); c->u->timedout(c, stunicast_receiver(&c->c), c->rxmit);
@ -118,6 +119,7 @@ recv_from_stunicast(struct stunicast_conn *stunicast, rimeaddr_t *from)
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
rimebuf_attr(RIMEBUF_ATTR_PACKET_ID)); rimebuf_attr(RIMEBUF_ATTR_PACKET_ID));
c->sndnxt = (c->sndnxt + 1) % (1 << RUNICAST_PACKET_ID_BITS); c->sndnxt = (c->sndnxt + 1) % (1 << RUNICAST_PACKET_ID_BITS);
c->is_tx = 0;
stunicast_cancel(&c->c); stunicast_cancel(&c->c);
if(c->u->sent != NULL) { if(c->u->sent != NULL) {
c->u->sent(c, stunicast_receiver(&c->c), c->rxmit); c->u->sent(c, stunicast_receiver(&c->c), c->rxmit);
@ -160,20 +162,12 @@ recv_from_stunicast(struct stunicast_conn *stunicast, rimeaddr_t *from)
rimebuf_set_attr(RIMEBUF_ATTR_PACKET_ID, packet_seqno); rimebuf_set_attr(RIMEBUF_ATTR_PACKET_ID, packet_seqno);
stunicast_send(&c->c, from); stunicast_send(&c->c, from);
RIMESTATS_ADD(acktx); RIMESTATS_ADD(acktx);
queuebuf_to_rimebuf(q); queuebuf_to_rimebuf(q);
queuebuf_free(q); queuebuf_free(q);
} }
if(c->u->recv != NULL) { if(c->u->recv != NULL) {
if (packet_seqno != c->lastrecv) { c->u->recv(c, from, packet_seqno);
c->u->recv(c, from, packet_seqno);
c->lastrecv = packet_seqno; /* remember last received packet */
} else {
PRINTF("%d.%d: runicast: Supressing duplicate receive callback from %d.%d for %d\n",
rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],
from->u8[0], from->u8[1],
packet_seqno);
}
} }
} }
} }
@ -187,9 +181,9 @@ runicast_open(struct runicast_conn *c, uint16_t channel,
stunicast_open(&c->c, channel, &runicast); stunicast_open(&c->c, channel, &runicast);
channel_set_attributes(channel, attributes); channel_set_attributes(channel, attributes);
c->u = u; c->u = u;
c->is_tx = 0;
c->rxmit = 0; c->rxmit = 0;
c->sndnxt = 0; c->sndnxt = 0;
c->lastrecv = 0xFF;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
@ -198,14 +192,26 @@ runicast_close(struct runicast_conn *c)
stunicast_close(&c->c); stunicast_close(&c->c);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint8_t
runicast_is_transmitting(struct runicast_conn *c)
{
return c->is_tx;
}
/*---------------------------------------------------------------------------*/
int int
runicast_send(struct runicast_conn *c, rimeaddr_t *receiver, uint8_t max_retransmissions) runicast_send(struct runicast_conn *c, rimeaddr_t *receiver, uint8_t max_retransmissions)
{ {
if (runicast_is_transmitting(c)) {
PRINTF("%d.%d: runicast: already transmitting\n",
rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
return 0;
}
rimebuf_set_attr(RIMEBUF_ATTR_RELIABLE, 1); rimebuf_set_attr(RIMEBUF_ATTR_RELIABLE, 1);
rimebuf_set_attr(RIMEBUF_ATTR_PACKET_TYPE, RIMEBUF_ATTR_PACKET_TYPE_DATA); rimebuf_set_attr(RIMEBUF_ATTR_PACKET_TYPE, RIMEBUF_ATTR_PACKET_TYPE_DATA);
rimebuf_set_attr(RIMEBUF_ATTR_PACKET_ID, c->sndnxt); rimebuf_set_attr(RIMEBUF_ATTR_PACKET_ID, c->sndnxt);
c->max_rxmit = max_retransmissions; c->max_rxmit = max_retransmissions;
c->rxmit = 0; c->rxmit = 0;
c->is_tx = 1;
RIMESTATS_ADD(reliabletx); RIMESTATS_ADD(reliabletx);
PRINTF("%d.%d: runicast: sending packet %d\n", PRINTF("%d.%d: runicast: sending packet %d\n",
rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],

View file

@ -45,7 +45,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: runicast.h,v 1.2 2009/02/17 12:40:18 fros4943 Exp $ * $Id: runicast.h,v 1.3 2009/03/03 12:19:46 fros4943 Exp $
*/ */
/** /**
@ -75,7 +75,7 @@ struct runicast_conn {
struct stunicast_conn c; struct stunicast_conn c;
const struct runicast_callbacks *u; const struct runicast_callbacks *u;
uint8_t sndnxt; uint8_t sndnxt;
uint8_t lastrecv; uint8_t is_tx;
uint8_t rxmit; uint8_t rxmit;
uint8_t max_rxmit; uint8_t max_rxmit;
}; };
@ -86,6 +86,8 @@ void runicast_close(struct runicast_conn *c);
int runicast_send(struct runicast_conn *c, rimeaddr_t *receiver, uint8_t max_retransmissions); int runicast_send(struct runicast_conn *c, rimeaddr_t *receiver, uint8_t max_retransmissions);
uint8_t runicast_is_transmitting(struct runicast_conn *c);
#endif /* __RUNICAST_H__ */ #endif /* __RUNICAST_H__ */
/** @} */ /** @} */
/** @} */ /** @} */