uint32_t handle_storage_info_get(uint16_t handle, handle_info_t* p_info)
{
    if (p_info == NULL)
    {
        return NRF_ERROR_NULL;
    }
    memset(p_info, 0, sizeof(handle_info_t));
    if (handle == RBC_MESH_INVALID_HANDLE)
    {
        return NRF_ERROR_INVALID_ADDR;
    }
    event_handler_critical_section_begin();

    uint16_t handle_index = handle_entry_get(handle, false);
    if (handle_index == HANDLE_CACHE_ENTRY_INVALID)
    {
        event_handler_critical_section_end();
        return NRF_ERROR_NOT_FOUND;
    }

    p_info->version = m_handle_cache[handle_index].version;
    if (m_handle_cache[handle_index].data_entry != DATA_CACHE_ENTRY_INVALID)
    {
        if (mesh_packet_ref_count_inc(m_data_cache[m_handle_cache[handle_index].data_entry].p_packet))
        {
            p_info->p_packet = m_data_cache[m_handle_cache[handle_index].data_entry].p_packet;
        }
    }

    event_handler_critical_section_end();
    return NRF_SUCCESS;
}
Пример #2
0
static void relay_packet(dfu_packet_t* p_packet, uint16_t length)
{
    mesh_packet_t* p_mesh_packet = mesh_packet_get_aligned(p_packet);
    if (!p_mesh_packet)
    {
        if (!mesh_packet_acquire(&p_mesh_packet))
        {
            APP_ERROR_CHECK(NRF_ERROR_NO_MEM);
        }
        mesh_packet_build(
            p_mesh_packet,
            p_packet->packet_type,
            p_packet->payload.data.segment,
            (uint8_t*) &p_packet->payload.data.transaction_id,
            length - 4);
    }
    else
    {
        mesh_packet_ref_count_inc(p_mesh_packet);
    }

    mesh_packet_set_local_addr(p_mesh_packet);

    if (transport_tx(p_mesh_packet, TX_REPEATS_DATA, TX_INTERVAL_TYPE_DATA, packet_release_callback))
    {
        mp_sent_packets[(m_sent_packet_index++) & (SENT_PACKET_COUNT - 1)] = p_mesh_packet;
    }
    mesh_packet_ref_count_dec(p_mesh_packet);
}
uint32_t handle_storage_local_packet_push(mesh_packet_t* p_packet)
{
    if (p_packet == NULL)
    {
        return NRF_ERROR_NULL;
    }
    async_event_t evt;
    evt.type = EVENT_TYPE_GENERIC;
    evt.callback.generic.p_context = p_packet;
    evt.callback.generic.cb = local_packet_push;
    uint32_t error_code = event_handler_push(&evt);
    if (error_code == NRF_SUCCESS)
    {
        mesh_packet_ref_count_inc(p_packet);
    }
    return error_code;
}
uint32_t handle_storage_info_set(uint16_t handle, handle_info_t* p_info)
{
    if (p_info == NULL)
    {
        return NRF_ERROR_NULL;
    }
    if (handle == RBC_MESH_INVALID_HANDLE)
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    uint16_t handle_index = handle_entry_get(handle, true);
    if (handle_index == HANDLE_CACHE_ENTRY_INVALID)
    {
        /* couldn't find an existing entry, allocate one */
        handle_index = handle_entry_to_head(handle);
        if (handle_index == HANDLE_CACHE_ENTRY_INVALID)
        {
            return NRF_ERROR_NO_MEM;
        }
    }

    uint16_t data_index = m_handle_cache[handle_index].data_entry;

    if (data_index == DATA_CACHE_ENTRY_INVALID)
    {
        data_index = data_entry_allocate();
        if (data_index == DATA_CACHE_ENTRY_INVALID)
        {
            return NRF_ERROR_NO_MEM;
        }
        m_handle_cache[handle_index].data_entry = data_index;
    }
    trickle_timer_reset(&m_data_cache[data_index].trickle, timer_now());

    m_handle_cache[handle_index].version = p_info->version;
    if (m_data_cache[data_index].p_packet != NULL)
    {
        mesh_packet_ref_count_dec(m_data_cache[data_index].p_packet);
    }

    /* reference for the cache */
    mesh_packet_ref_count_inc(p_info->p_packet);
    m_data_cache[m_handle_cache[handle_index].data_entry].p_packet = p_info->p_packet;
    return NRF_SUCCESS;
}
Пример #5
0
/* radio callback, executed in STACK_LOW */
static void rx_cb(uint8_t* data, bool success, uint32_t crc)
{
    if (success)
    {
        async_event_t evt;
        evt.type = EVENT_TYPE_PACKET;
        evt.callback.packet.payload = data;
        evt.callback.packet.crc = crc;
        evt.callback.packet.timestamp = timer_get_timestamp();
        mesh_packet_ref_count_inc((mesh_packet_t*) data); /* event handler has a ref */
        if (event_handler_push(&evt) != NRF_SUCCESS)
        {
            g_state.queue_saturation = true;
            mesh_packet_ref_count_dec((mesh_packet_t*) data); /* event handler lost its ref */
        }
    }

    /* no longer needed in this context */
    mesh_packet_ref_count_dec((mesh_packet_t*) data);
}
Пример #6
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;
}
uint32_t handle_storage_tx_packets_get(uint32_t time_now, mesh_packet_t** pp_packets, uint32_t* p_count)
{
    /* Continue where we left off */
    static uint16_t data_index = 0;

    uint32_t count = 0;

    for (uint32_t i = 0; i < RBC_MESH_DATA_CACHE_ENTRIES; ++i)
    {
        while (data_index >= RBC_MESH_DATA_CACHE_ENTRIES)
            data_index -= RBC_MESH_DATA_CACHE_ENTRIES;

        if ((m_data_cache[data_index].p_packet != NULL) &&
            (trickle_is_enabled(&m_data_cache[data_index].trickle)) &&
            !TIMER_OLDER_THAN(time_now, m_data_cache[data_index].trickle.t))
        {
            bool do_tx = false;
            trickle_tx_timeout(&m_data_cache[data_index].trickle, &do_tx, time_now);
            if (do_tx)
            {
                mesh_packet_ref_count_inc(m_data_cache[data_index].p_packet); /* return the packet with an additional reference */
                pp_packets[count++] = m_data_cache[data_index].p_packet;
                if (count == *p_count)
                {
                    /* packet array is full */
                    data_index++;
                    return NRF_SUCCESS;
                }
            }
        }
        data_index++;
    }
    *p_count = count;

    return NRF_SUCCESS;
}