static void cc2520_sack_rx_done(u8 *buf, u8 len) { // if this packet we just received requires // an ACK, trasmit it. memcpy(cur_rx_buf, buf, len); cur_rx_buf_len = len; // NOTE: this is a big hack right now, // and I'm not sure if it's even needed. // We introduce a strong coupling between // the sack layer and the radio layer here // by providing a mechanism to explicitly // release the buffer. When I was troubleshooting // a terrible concurrency bug I added this // as a possible solution, but I don't // think it's needed anymore. cc2520_radio_release_rx(); spin_lock_irqsave(&sack_sl, flags); if (cc2520_packet_is_ack(cur_rx_buf)) { if (sack_state == CC2520_SACK_TX_WAIT && cc2520_packet_is_ack_to(cur_rx_buf, cur_tx_buf)) { sack_state = CC2520_SACK_IDLE; spin_unlock_irqrestore(&sack_sl, flags); hrtimer_cancel(&timeout_timer); sack_top->tx_done(CC2520_TX_SUCCESS); } else { spin_unlock_irqrestore(&sack_sl, flags); INFO((KERN_INFO "[cc2520] - stray ack received.\n")); } } else { if (cc2520_packet_requires_ack_reply(cur_rx_buf)) { if (sack_state == CC2520_SACK_IDLE) { cc2520_packet_create_ack(cur_rx_buf, ack_buf); sack_state = CC2520_SACK_TX_ACK; spin_unlock_irqrestore(&sack_sl, flags); sack_bottom->tx(ack_buf, IEEE154_ACK_FRAME_LENGTH + 1); sack_top->rx_done(cur_rx_buf, cur_rx_buf_len); } else { spin_unlock_irqrestore(&sack_sl, flags); INFO((KERN_INFO "[cc2520] - ACK skipped, soft-ack layer busy. %d \n", sack_state)); } } else { spin_unlock_irqrestore(&sack_sl, flags); sack_top->rx_done(cur_rx_buf, cur_rx_buf_len); } } }
static void cc2520_sack_rx_done(u8 *buf, u8 len) { // if this packet we just received requires // an ACK, trasmit it. spin_lock(&sack_sl); if (cc2520_packet_is_ack(buf)) { if (sack_state == CC2520_SACK_TX_WAIT && cc2520_packet_is_ack_to(buf, cur_tx_buf)) { sack_state = CC2520_SACK_IDLE; spin_unlock(&sack_sl); hrtimer_cancel(&timeout_timer); sack_top->tx_done(CC2520_TX_SUCCESS); } else { spin_unlock(&sack_sl); INFO((KERN_INFO "[cc2520] - stray ack received.\n")); } } else { if (cc2520_packet_requires_ack_reply(buf)) { if (sack_state == CC2520_SACK_IDLE) { cc2520_packet_create_ack(buf, ack_buf); sack_state = CC2520_SACK_TX_ACK; spin_unlock(&sack_sl); sack_bottom->tx(ack_buf, IEEE154_ACK_FRAME_LENGTH + 1); sack_top->rx_done(buf, len); } else { spin_unlock(&sack_sl); INFO((KERN_INFO "[cc2520] - ACK skipped, soft-ack layer busy. %d \n", sack_state)); } } else { spin_unlock(&sack_sl); sack_top->rx_done(buf, len); } } }