void transport_control_step(void) { uint64_t next_time; uint64_t time_now = timer_get_timestamp() + global_time; trickle_time_update(time_now); uint32_t error_code = mesh_srv_get_next_processing_time(&next_time); if (error_code != NRF_SUCCESS) { return; } if (next_time < time_now) { async_event_t async_evt; async_evt.callback.generic = trickle_step_callback; async_evt.type = EVENT_TYPE_GENERIC; event_handler_push(&async_evt); } else { if (next_time < global_time + timeslot_get_end_time()) { timer_abort(step_timer_index); step_timer_index = timer_order_cb(next_time - global_time, trickle_step_callback); } } }
/** * @brief Async event dispatcher, works in APP LOW */ void QDEC_IRQHandler(void) { while (true) { bool got_evt = false; got_evt |= event_fifo_pop(&g_async_evt_fifo); if (timeslot_get_end_time() > 0) /* in timeslot */ { got_evt |= event_fifo_pop(&g_async_evt_fifo_ts); } if (!got_evt) { break; } } }
/** * @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); } }