/**
* @brief Handle incoming packets
*/
static void search_callback(uint8_t* data)
{
    SET_PIN(PIN_RX);

    uint32_t checksum = (NRF_RADIO->RXCRC & 0x00FFFFFF);

    /* check if timeslot is about to end */
    uint64_t radio_time_left = timeslot_get_remaining_time();

    if (radio_time_left > RADIO_SAFETY_TIMING_US)
    {
        /* setup next RX */
        order_search();
    }

    CLEAR_PIN(PIN_RX);

    if (data == NULL || !packet_is_data_packet(data))
    {
        return;
    }


    async_event_t async_evt;
    async_evt.type = EVENT_TYPE_PACKET;
    packet_create_from_data(data, &async_evt.callback.packet);
    async_evt.callback.packet.rx_crc = checksum;
    event_handler_push(&async_evt);


    /** @TODO: add packet chain handling */
}
void transport_control_timeslot_begin(uint64_t global_timer_value)
{
    uint32_t aa;
    uint32_t error_code = rbc_mesh_access_address_get(&aa);
    APP_ERROR_CHECK(error_code);

    radio_init(aa);

    step_timer_index = 0xFF;

    global_time = global_timer_value;

    order_search();
    transport_control_step();

}
Esempio n. 3
0
/* packet processing, executed in APP_LOW */
void tc_packet_handler(uint8_t* data, uint32_t crc, uint64_t timestamp)
{
//	LOGi("_6");
    SET_PIN(PIN_RX);
    mesh_packet_t* p_packet = (mesh_packet_t*) data;
//	printArray(p_packet, sizeof(mesh_packet_t));

    if (p_packet->header.length > MESH_PACKET_OVERHEAD + RBC_MESH_VALUE_MAX_LEN)
    {
//    	LOGi("_2");
        /* invalid packet, ignore */
        CLEAR_PIN(PIN_RX);
        mesh_packet_ref_count_dec(p_packet); /* from rx_cb */
        return;
    }
    
    ble_gap_addr_t addr;
    memcpy(addr.addr, p_packet->addr, BLE_GAP_ADDR_LEN);
    addr.addr_type = p_packet->header.addr_type;
    
    mesh_adv_data_t* p_mesh_adv_data = mesh_packet_adv_data_get(p_packet);
    
    
    if (p_mesh_adv_data != NULL)
    {
//    	LOGi("_3");
        /* filter mesh packets on handle range */
        if (p_mesh_adv_data->handle <= RBC_MESH_APP_MAX_HANDLE)
        {
//        	LOGi("_4");
            mesh_app_packet_handle(p_mesh_adv_data, timestamp);
        }
    }
    
    /* this packet is no longer needed in this context */
    mesh_packet_ref_count_dec(p_packet); /* from rx_cb */

    if (g_state.queue_saturation)
    {
//    	LOGi("_5");
        order_search();
        g_state.queue_saturation = false;
    }
    
    CLEAR_PIN(PIN_RX);
}
/**
* @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);
    }
}
Esempio n. 5
0
static void radio_idle_callback(void)
{
    /* If the processor is unable to keep up, we should back down, and give it time */
    if (!g_state.queue_saturation)
        order_search();
}