uint32_t mesh_packet_adv_data_sanitize(mesh_packet_t* p_packet) { mesh_adv_data_t* p_mesh_adv_data = mesh_packet_adv_data_get(p_packet); if (p_mesh_adv_data == NULL) { return NRF_ERROR_INVALID_DATA; } if (((uint8_t*)p_mesh_adv_data) != &p_packet->payload[0]) { /* must move the adv data to the beginning of the advertisement payload */ const uint8_t adv_data_length = p_mesh_adv_data->adv_data_length + 1; for (uint32_t i = 0; i < adv_data_length; ++i) { /* memcpy is unsafe for overlapping memory, memmove is slower than necessary -> move it manually. */ p_packet->payload[i] = *(((uint8_t*) p_mesh_adv_data) + i); } p_mesh_adv_data = (mesh_adv_data_t*) &p_packet->payload[0]; } /* only fit mesh adv data */ p_packet->header.length = MESH_PACKET_OVERHEAD - MESH_PACKET_ADV_OVERHEAD + p_mesh_adv_data->adv_data_length; return NRF_SUCCESS; }
/* radio callback, executed in STACK_LOW */ static void tx_cb(uint8_t* data) { rbc_mesh_event_t tx_event; mesh_adv_data_t* p_adv_data = mesh_packet_adv_data_get((mesh_packet_t*) data); bool doing_tx_event = false; if (p_adv_data != NULL && vh_tx_event_flag_get(p_adv_data->handle, &doing_tx_event) == NRF_SUCCESS && doing_tx_event ) { tx_event.event_type = RBC_MESH_EVENT_TYPE_TX; tx_event.value_handle = p_adv_data->handle; tx_event.data = p_adv_data->data; tx_event.data_len = p_adv_data->adv_data_length - MESH_PACKET_ADV_OVERHEAD; tx_event.version_delta = 0; APP_ERROR_CHECK(rbc_mesh_event_push(&tx_event)); #if RBC_MESH_SERIAL mesh_aci_rbc_event_handler(&tx_event); #endif } mesh_packet_ref_count_dec((mesh_packet_t*) data); /* radio ref removed (pushed in tc_tx) */ vh_order_update(timer_get_timestamp()); /* tell the vh, so that it can push more updates */ }
static void rx_cb(mesh_packet_t* p_packet) { mesh_adv_data_t* p_adv_data = mesh_packet_adv_data_get(p_packet); if (p_adv_data && p_adv_data->handle > RBC_MESH_APP_MAX_HANDLE) { bl_cmd_t rx_cmd; rx_cmd.type = BL_CMD_TYPE_RX; rx_cmd.params.rx.p_dfu_packet = (dfu_packet_t*) &p_adv_data->handle; rx_cmd.params.rx.length = p_adv_data->adv_data_length - 3; bl_cmd_handler(&rx_cmd); } }
rbc_mesh_value_handle_t mesh_packet_handle_get(mesh_packet_t* p_packet) { mesh_adv_data_t* p_adv_data = mesh_packet_adv_data_get(p_packet); if (p_adv_data == NULL) { return RBC_MESH_INVALID_HANDLE; } else { return p_adv_data->handle; } }
/* 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); }
void local_packet_push(void* p_context) { mesh_packet_t* p_packet = (mesh_packet_t*) p_context; mesh_adv_data_t* p_adv = mesh_packet_adv_data_get(p_packet); if (p_adv != NULL) { handle_info_t info = { .version = p_adv->version, .p_packet = p_packet }; uint16_t handle_index = handle_entry_get(p_adv->handle, true); if (handle_index != HANDLE_CACHE_ENTRY_INVALID) { info.version = m_handle_cache[handle_index].version; version_increment(&info.version); } p_adv->version = info.version; handle_storage_info_set(p_adv->handle, &info); } mesh_packet_ref_count_dec(p_packet); /* for the event queue */ }