Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions core/lib/memb.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,18 @@ memb_inmemb(struct memb *m, void *ptr)
(char *)ptr < (char *)m->mem + (m->num * m->size);
}
/*---------------------------------------------------------------------------*/
int
memb_numfree(struct memb *m)
{
int i;
int num_free = 0;

for(i = 0; i < m->num; ++i) {
if(m->count[i] == 0) {
++num_free;
}
}

return num_free;
}
/** @} */
1 change: 1 addition & 0 deletions core/lib/memb.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ char memb_free(struct memb *m, void *ptr);

int memb_inmemb(struct memb *m, void *ptr);

int memb_numfree(struct memb *m);

/** @} */
/** @} */
Expand Down
7 changes: 7 additions & 0 deletions core/net/ipv6/sicslowpan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,13 @@ output(const uip_lladdr_t *localdest)
* IPv6/HC1/HC06/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch.
*/
int estimated_fragments = ((int)uip_len) / ((int)MAC_MAX_PAYLOAD - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
int freebuf = queuebuf_numfree() - 1;
PRINTFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
if(freebuf < estimated_fragments) {
PRINTFO("Dropping packet, not enough free bufs\n");
return 0;
}

PRINTFO("Fragmentation sending packet len %d\n", uip_len);

Expand Down
101 changes: 59 additions & 42 deletions core/net/mac/csma.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ struct neighbor_queue {
#define CSMA_MAX_NEIGHBOR_QUEUES 2
#endif /* CSMA_CONF_MAX_NEIGHBOR_QUEUES */

/* The maximum number of pending packet per neighbor */
#ifdef CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
#define CSMA_MAX_PACKET_PER_NEIGHBOR CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
#else
#define CSMA_MAX_PACKET_PER_NEIGHBOR MAX_QUEUED_PACKETS
#endif /* CSMA_CONF_MAX_PACKET_PER_NEIGHBOR */

#define MAX_QUEUED_PACKETS QUEUEBUF_NUM
MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES);
MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS);
Expand Down Expand Up @@ -173,8 +180,8 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p)
queuebuf_free(p->buf);
memb_free(&metadata_memb, p->ptr);
memb_free(&packet_memb, p);
PRINTF("csma: free_queued_packet, queue length %d\n",
list_length(n->queued_packet_list));
PRINTF("csma: free_queued_packet, queue length %d, free packets %d\n",
list_length(n->queued_packet_list), memb_numfree(&packet_memb));
if(list_head(n->queued_packet_list) != NULL) {
/* There is a next packet. We reset current tx information */
n->transmissions = 0;
Expand Down Expand Up @@ -298,7 +305,11 @@ packet_sent(void *ptr, int status, int num_transmissions)
free_packet(n, q);
mac_call_sent_callback(sent, cptr, status, num_tx);
}
} else {
PRINTF("csma: no metadata\n");
}
} else {
PRINTF("csma: seqno %d not found\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
}
}
/*---------------------------------------------------------------------------*/
Expand Down Expand Up @@ -344,47 +355,53 @@ send_packet(mac_callback_t sent, void *ptr)

if(n != NULL) {
/* Add packet to the neighbor's queue */
q = memb_alloc(&packet_memb);
if(q != NULL) {
q->ptr = memb_alloc(&metadata_memb);
if(q->ptr != NULL) {
q->buf = queuebuf_new_from_packetbuf();
if(q->buf != NULL) {
struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
/* Neighbor and packet successfully allocated */
if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) {
/* Use default configuration for max transmissions */
metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS;
} else {
metadata->max_transmissions =
packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
}
metadata->sent = sent;
metadata->cptr = ptr;

if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
PACKETBUF_ATTR_PACKET_TYPE_ACK) {
list_push(n->queued_packet_list, q);
} else {
list_add(n->queued_packet_list, q);
}

/* If q is the first packet in the neighbor's queue, send asap */
if(list_head(n->queued_packet_list) == q) {
ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n);
}
return;
}
memb_free(&metadata_memb, q->ptr);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
if(list_length(n->queued_packet_list) < CSMA_MAX_PACKET_PER_NEIGHBOR) {
q = memb_alloc(&packet_memb);
if(q != NULL) {
q->ptr = memb_alloc(&metadata_memb);
if(q->ptr != NULL) {
q->buf = queuebuf_new_from_packetbuf();
if(q->buf != NULL) {
struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
/* Neighbor and packet successfully allocated */
if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) {
/* Use default configuration for max transmissions */
metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS;
} else {
metadata->max_transmissions =
packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
}
metadata->sent = sent;
metadata->cptr = ptr;

if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
PACKETBUF_ATTR_PACKET_TYPE_ACK) {
list_push(n->queued_packet_list, q);
} else {
list_add(n->queued_packet_list, q);
}

PRINTF("csma: send_packet, queue length %d, free packets %d\n",
list_length(n->queued_packet_list), memb_numfree(&packet_memb));
/* If q is the first packet in the neighbor's queue, send asap */
if(list_head(n->queued_packet_list) == q) {
ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n);
}
return;
}
memb_free(&metadata_memb, q->ptr);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
}
memb_free(&packet_memb, q);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
}
memb_free(&packet_memb, q);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
}
/* The packet allocation failed. Remove and free neighbor entry if empty. */
if(list_length(n->queued_packet_list) == 0) {
list_remove(neighbor_list, n);
memb_free(&neighbor_memb, n);
/* The packet allocation failed. Remove and free neighbor entry if empty. */
if(list_length(n->queued_packet_list) == 0) {
list_remove(neighbor_list, n);
memb_free(&neighbor_memb, n);
}
} else {
PRINTF("csma: Neighbor queue full\n");
}
PRINTF("csma: could not allocate packet, dropping packet\n");
} else {
Expand Down
10 changes: 10 additions & 0 deletions core/net/queuebuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,16 @@ queuebuf_init(void)
#endif /* QUEUEBUF_STATS */
}
/*---------------------------------------------------------------------------*/
int
queuebuf_numfree(void)
{
if(packetbuf_is_reference()) {
return memb_numfree(&refbufmem);
} else {
return memb_numfree(&bufmem);
}
}
/*---------------------------------------------------------------------------*/
#if QUEUEBUF_DEBUG
struct queuebuf *
queuebuf_new_from_packetbuf_debug(const char *file, int line)
Expand Down
4 changes: 3 additions & 1 deletion core/net/queuebuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ packetbuf_attr_t queuebuf_attr(struct queuebuf *b, uint8_t type);

void queuebuf_debug_print(void);

#endif /* QUEUEBUF_H_ */
int queuebuf_numfree(void);

#endif /* __QUEUEBUF_H__ */

/** @} */
/** @} */