int gnrc_gomach_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, netopt_enable_t csma_enable)
{
    assert(netif != NULL);
    assert(pkt != NULL);

    /* Enable/disable CSMA according to the input. */
    netif->dev->driver->set(netif->dev, NETOPT_CSMA, &csma_enable,
                            sizeof(netopt_enable_t));

    gnrc_gomach_set_tx_finish(netif, false);
    gnrc_netif_set_tx_feedback(netif, TX_FEEDBACK_UNDEF);
    return _gnrc_gomach_transmit(netif, pkt);
}
Exemple #2
0
/**
 * @brief   Function called by the device driver on device events
 *
 * @param[in] event         type of event
 * @param[in] data          optional parameter
 */
static void _lwmac_event_cb(netdev_t *dev, netdev_event_t event)
{
    gnrc_netif_t *netif = (gnrc_netif_t *) dev->context;

    if (event == NETDEV_EVENT_ISR) {
        msg_t msg;

        msg.type = NETDEV_MSG_TYPE_EVENT;
        msg.content.ptr = (void *) netif;

        if (msg_send(&msg, netif->pid) <= 0) {
            LOG_WARNING("WARNING: [LWMAC] gnrc_netdev: possibly lost interrupt.\n");
        }
    }
    else {
        DEBUG("gnrc_netdev: event triggered -> %i\n", event);
        switch (event) {
            case NETDEV_EVENT_RX_STARTED: {
                LOG_DEBUG("[LWMAC] NETDEV_EVENT_RX_STARTED\n");
                gnrc_netif_set_rx_started(netif, true);
                break;
            }
            case NETDEV_EVENT_RX_COMPLETE: {
                LOG_DEBUG("[LWMAC] NETDEV_EVENT_RX_COMPLETE\n");
                gnrc_pktsnip_t *pkt = netif->ops->recv(netif);

                /* Prevent packet corruption when a packet is sent before the previous
                 * received packet has been downloaded. This happens e.g. when a timeout
                 * expires that causes the tx state machine to send a packet. When a
                 * packet arrives after the timeout, the notification is queued but the
                 * tx state machine continues to send and then destroys the received
                 * packet in the frame buffer. After completion, the queued notification
                 * will be handled a corrupted packet will be downloaded. Therefore
                 * keep track that RX_STARTED is followed by RX_COMPLETE.
                 *
                 * TODO: transceivers might have 2 frame buffers, so make this optional
                 */
                if (pkt == NULL) {
                    gnrc_netif_set_rx_started(netif, false);
                    break;
                }

                gnrc_netif_set_rx_started(netif, false);

                if (!gnrc_mac_queue_rx_packet(&netif->mac.rx, 0, pkt)) {
                    LOG_ERROR("ERROR: [LWMAC] Can't push RX packet @ %p, memory full?\n", pkt);
                    gnrc_pktbuf_release(pkt);
                    break;
                }
                lwmac_schedule_update(netif);
                break;
            }
            case NETDEV_EVENT_TX_STARTED: {
                gnrc_netif_set_tx_feedback(netif, TX_FEEDBACK_UNDEF);
                gnrc_netif_set_rx_started(netif, false);
                break;
            }
            case NETDEV_EVENT_TX_COMPLETE: {
                gnrc_netif_set_tx_feedback(netif, TX_FEEDBACK_SUCCESS);
                gnrc_netif_set_rx_started(netif, false);
                lwmac_schedule_update(netif);
                break;
            }
            case NETDEV_EVENT_TX_NOACK: {
                gnrc_netif_set_tx_feedback(netif, TX_FEEDBACK_NOACK);
                gnrc_netif_set_rx_started(netif, false);
                lwmac_schedule_update(netif);
                break;
            }
            case NETDEV_EVENT_TX_MEDIUM_BUSY: {
                gnrc_netif_set_tx_feedback(netif, TX_FEEDBACK_BUSY);
                gnrc_netif_set_rx_started(netif, false);
                lwmac_schedule_update(netif);
                break;
            }
            default:
                LOG_WARNING("WARNING: [LWMAC] Unhandled netdev event: %u\n", event);
        }
    }

    /* Execute main state machine because something just happend*/
    while (gnrc_lwmac_get_reschedule(netif)) {
        lwmac_update(netif);
    }
}