Пример #1
0
void transmit_packet()
{
	counter++;
    DPRINT("%d tx %d bytes\n", counter, PACKET_LENGTH);
    memcpy(&tx_packet->data, data, PACKET_LENGTH);
    hw_radio_send_packet(tx_packet, &packet_transmitted);
}
void send_packet()
{
	hw_radio_send_packet((hw_radio_packet_t*)(&NG(tx_buffer)), tx_callback);
	log_print_string("Sending packet with counter %u", NG(tx_buffer).counter);
	NG(tx_buffer).counter++;
	timer_post_task_delay(send_packet, TIMER_TICKS_PER_SEC + (get_rnd() %TIMER_TICKS_PER_SEC));
}
static void transmit_packet() {
    DPRINT("transmitting packet");
    current_state = STATE_RUNNING;
    counter++;
    memcpy(data + 1, &id, sizeof(id));
    memcpy(data + 1 + sizeof(id), &counter, sizeof(counter));
    uint16_t crc = __builtin_bswap16(crc_calculate(data, sizeof(data) - 2));
    memcpy(data + sizeof(data) - 2, &crc, 2);
    memcpy(&tx_packet->data, data, sizeof(data));
    tx_cfg.channel_id = current_channel_id;
    tx_packet->tx_meta.tx_cfg = tx_cfg;
    hw_radio_send_packet(tx_packet, &packet_transmitted);
}
Пример #4
0
static void packet_transmitted(hw_radio_packet_t* hw_radio_packet)
{
    assert(dll_state == DLL_STATE_TX_FOREGROUND);
    switch_state(DLL_STATE_TX_FOREGROUND_COMPLETED);
    DPRINT("Transmitted packet with length = %i", hw_radio_packet->length);
    packet_t* packet = packet_queue_find_packet(hw_radio_packet);

    d7anp_signal_packet_transmitted(packet);

    if(process_received_packets_after_tx)
    {
        sched_post_task(&process_received_packets);
        process_received_packets_after_tx = false;
    }

#ifdef RESPONDER_USE_FG_SCAN_OUTSIDE_TRANSACTION // TODO validate if still needed, if yes: needs to be tested
    /*
     * Resume the FG scan only after an unicast packet, otherwise, wait the
     * response period expiration.
     */
    if (resume_fg_scan && packet->dll_header.control_target_address_set)
    {
        switch_state(DLL_STATE_FOREGROUND_SCAN);

        hw_rx_cfg_t rx_cfg = (hw_rx_cfg_t){
            .channel_id.channel_header = current_access_profile->subbands[0].channel_header,
            .channel_id.center_freq_index = current_access_profile->subbands[0].channel_index_start,
            .syncword_class = PHY_SYNCWORD_CLASS1,
        };

        hw_radio_set_rx(&rx_cfg, &packet_received, NULL);
        resume_fg_scan = false;
    }
#else
    if (resume_fg_scan)
    {
        switch_state(DLL_STATE_FOREGROUND_SCAN);

        hw_rx_cfg_t rx_cfg = (hw_rx_cfg_t){
            .channel_id.channel_header = current_access_profile->subbands[0].channel_header,
            .channel_id.center_freq_index = current_access_profile->subbands[0].channel_index_start,
            .syncword_class = PHY_SYNCWORD_CLASS1,
        };

        hw_radio_set_rx(&rx_cfg, &packet_received, NULL);
        resume_fg_scan = false;
    }
#endif

}

static void cca_rssi_valid(int16_t cur_rssi)
{
    // When the radio goes back to Rx state, the rssi_valid callback may be still set. Skip it in this case
    if (dll_state != DLL_STATE_CCA1 && dll_state != DLL_STATE_CCA2)
        return;

    if (cur_rssi <= E_CCA)
    {
        if(dll_state == DLL_STATE_CCA1)
        {
            DPRINT("CCA1 RSSI: %d", cur_rssi);
            switch_state(DLL_STATE_CCA2);
            timer_post_task_delay(&execute_cca, 5);
            return;
        }
        else if(dll_state == DLL_STATE_CCA2)
        {
            // OK, send packet
            DPRINT("CCA2 RSSI: %d", cur_rssi);
            DPRINT("CCA2 succeeded, transmitting ...");
            // log_print_data(current_packet->hw_radio_packet.data, current_packet->hw_radio_packet.length + 1); // TODO tmp

            switch_state(DLL_STATE_TX_FOREGROUND);

            d7anp_signal_packet_csma_ca_insertion_completed(true);
            error_t err = hw_radio_send_packet(&current_packet->hw_radio_packet, &packet_transmitted);
            assert(err == SUCCESS);

            if (!resume_fg_scan)
                hw_radio_set_idle(); // ensure radio goes back to IDLE after transmission instead of to RX
            return;
        }
    }
    else
    {
        DPRINT("Channel not clear, RSSI: %i", cur_rssi);
        switch_state(DLL_STATE_CSMA_CA_RETRY);
        execute_csma_ca();

        //switch_state(DLL_STATE_CCA_FAIL);
        //d7atp_signal_packet_csma_ca_insertion_completed(false);
    }
}

static void execute_cca()
{
    assert(dll_state == DLL_STATE_CCA1 || dll_state == DLL_STATE_CCA2);

    hw_rx_cfg_t rx_cfg =(hw_rx_cfg_t){
        .channel_id.channel_header = current_access_profile->subbands[0].channel_header,
        .channel_id.center_freq_index = current_access_profile->subbands[0].channel_index_start,
        .syncword_class = PHY_SYNCWORD_CLASS1,
    };

    hw_radio_set_rx(&rx_cfg, NULL, &cca_rssi_valid);
}

static uint16_t calculate_tx_duration()
{
    int data_rate = 6; // Normal rate: 6.9 bytes/tick
    // TODO select correct subband
    switch (current_access_profile->subbands[0].channel_header.ch_class)
    {
    case PHY_CLASS_LO_RATE:
        data_rate = 1; // Lo Rate: 1.2 bytes/tick
        break;
    case PHY_CLASS_HI_RATE:
        data_rate = 20; // High rate: 20.83 byte/tick
    }

    uint16_t duration = (current_packet->hw_radio_packet.length / data_rate) + 1;
    return duration;
}