diff --git a/core/net/mac/csma.c b/core/net/mac/csma.c index 9bb2ef239..99dc50f5f 100644 --- a/core/net/mac/csma.c +++ b/core/net/mac/csma.c @@ -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); @@ -348,49 +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(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); - } + 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"); + 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 {