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; }
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; }
/* 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); }
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; }