/**
* @brief Order the radio_control module to do a RX, and report back to
*   search_callback().
*/
static void order_search(void)
{
    radio_event_t search_event;
    search_event.access_address = 1; /* RX: treat as bitfield */
    search_event.callback.rx = search_callback;
    rbc_mesh_channel_get(&search_event.channel);
    search_event.event_type = RADIO_EVENT_TYPE_RX;
    search_event.start_time = 0;

    radio_order(&search_event);
}
Esempio n. 2
0
static void order_search(void)
{
    radio_event_t evt;
    
    evt.event_type = RADIO_EVENT_TYPE_RX_PREEMPTABLE;
    evt.start_time = 0;
    evt.access_address = 1;
    evt.channel = g_state.channel;
    evt.callback.rx = rx_cb;
    
    if (!mesh_packet_acquire((mesh_packet_t**) &evt.packet_ptr))
    {
        return; /* something is hogging all the packets */
    }
    if (!radio_order(&evt))
    {
        /* couldn't queue the packet for reception, immediately free its only ref */
        mesh_packet_ref_count_dec((mesh_packet_t*) evt.packet_ptr);
    }
}
Esempio n. 3
0
uint32_t tc_tx(mesh_packet_t* p_packet)
{
    TICK_PIN(PIN_MESH_TX);
    
    /* queue the packet for transmission */
    radio_event_t event;
    memset(&event, 0, sizeof(radio_event_t));
    event.start_time = 0;
    mesh_packet_ref_count_inc(p_packet); /* queue will have a reference until tx_cb */
    event.packet_ptr = (uint8_t*) p_packet;
    event.access_address = 0;
    event.channel = g_state.channel;
    event.callback.tx = tx_cb;
    event.event_type = RADIO_EVENT_TYPE_TX;
    if (!radio_order(&event))
    {
        mesh_packet_ref_count_dec(p_packet); /* queue couldn't hold the ref */
        return NRF_ERROR_NO_MEM;
    }
    
    return NRF_SUCCESS;
}
/**
* @brief Handle trickle timing events
*/
static void trickle_step_callback(void)
{
    TICK_PIN(6);
    /* check if timeslot is about to end */
    if (timeslot_get_remaining_time() < RADIO_SAFETY_TIMING_US)
        return;

    uint64_t time_now = global_time + timer_get_timestamp();
    trickle_time_update(time_now);

    packet_t packet;
    bool has_anything_to_send = false;

    mesh_srv_packet_assemble(&packet, PACKET_DATA_MAX_LEN * PACKET_MAX_CHAIN_LEN,
        &has_anything_to_send);

    if (has_anything_to_send)
    {
        TICK_PIN(PIN_MESH_TX);
        radio_disable();

        uint8_t packet_and_addr_type = PACKET_TYPE_ADV_NONCONN |
            ((packet.sender.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC)?
            0 :
            PACKET_ADDR_TYPE_MASK);

        uint8_t* temp_data_ptr = &packet.data[0];
        uint8_t* tx_data_ptr = &tx_data[0];
        tx_data_ptr[PACKET_TYPE_POS] = packet_and_addr_type;

        /* Code structured for packet chaining, although this is yet
         to be implemented. */
        do
        {
            uint8_t min_len = ((packet.length > PACKET_DATA_MAX_LEN)?
                PACKET_DATA_MAX_LEN :
                packet.length);

            tx_data_ptr[PACKET_PADDING_POS] = 0;
            tx_data_ptr[PACKET_LENGTH_POS] = (min_len + PACKET_ADDR_LEN);
            tx_data_ptr[PACKET_TYPE_POS] = packet_and_addr_type;

            memcpy(&tx_data_ptr[PACKET_ADDR_POS], packet.sender.addr, PACKET_ADDR_LEN);
            memcpy(&tx_data_ptr[PACKET_DATA_POS], &temp_data_ptr[0], min_len);

            radio_event_t tx_event;
            tx_event.access_address = 0;
            rbc_mesh_channel_get(&tx_event.channel);
            tx_event.event_type = RADIO_EVENT_TYPE_TX;
            tx_event.packet_ptr = &tx_data_ptr[0];
            tx_event.start_time = 0;
            tx_event.callback.tx = NULL;

            radio_order(&tx_event);
            TICK_PIN(0);
        } while (0);

        order_search(); /* search for the rest of the timeslot */
    }

    /* order next processing */
    uint64_t next_time;
    uint64_t end_time = timeslot_get_end_time();
    uint32_t error_code = mesh_srv_get_next_processing_time(&next_time);

    if (error_code == NRF_SUCCESS && next_time < global_time + end_time)
    {
        timer_abort(step_timer_index);
        step_timer_index = timer_order_cb(next_time - global_time, trickle_step_callback);
    }
}