static void transmit_downward(uint16_t type, void *data) { if (type == MSG_STACK_TO_HC_HCI_CMD) { transmit_command((BT_HDR *)data, NULL, NULL, NULL); HCI_TRACE_WARNING("%s legacy transmit of command. Use transmit_command instead.\n", __func__); } else { fixed_queue_enqueue(hci_host_env.packet_queue, data); } hci_host_task_post(TASK_POST_BLOCKING); }
void btu_stop_timer_oneshot(TIMER_LIST_ENT *p_tle) { assert(p_tle != NULL); if (p_tle->in_use == FALSE) { return; } p_tle->in_use = FALSE; // Get the alarm for the timer list entry. osi_alarm_t *alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle); if (alarm == NULL) { HCI_TRACE_WARNING("%s Unable to find expected alarm in hashmap", __func__); return; } osi_alarm_cancel(alarm); }
// Returns true if the event was intercepted and should not proceed to // higher layers. Also inspects an incoming event for interesting // information, like how many commands are now able to be sent. static bool filter_incoming_event(BT_HDR *packet) { waiting_command_t *wait_entry = NULL; uint8_t *stream = packet->data + packet->offset; uint8_t event_code; command_opcode_t opcode; STREAM_TO_UINT8(event_code, stream); STREAM_SKIP_UINT8(stream); // Skip the parameter total length field HCI_TRACE_DEBUG("Receive packet event_code=0x%x\n", event_code); if (event_code == HCI_COMMAND_COMPLETE_EVT) { STREAM_TO_UINT8(hci_host_env.command_credits, stream); STREAM_TO_UINT16(opcode, stream); wait_entry = get_waiting_command(opcode); if (!wait_entry) { HCI_TRACE_WARNING("%s command complete event with no matching command. opcode: 0x%x.", __func__, opcode); } else if (wait_entry->complete_callback) { wait_entry->complete_callback(packet, wait_entry->context); } else if (wait_entry->complete_future) { future_ready(wait_entry->complete_future, packet); } goto intercepted; } else if (event_code == HCI_COMMAND_STATUS_EVT) { uint8_t status; STREAM_TO_UINT8(status, stream); STREAM_TO_UINT8(hci_host_env.command_credits, stream); STREAM_TO_UINT16(opcode, stream); // If a command generates a command status event, it won't be getting a command complete event wait_entry = get_waiting_command(opcode); if (!wait_entry) { HCI_TRACE_WARNING("%s command status event with no matching command. opcode: 0x%x", __func__, opcode); } else if (wait_entry->status_callback) { wait_entry->status_callback(status, wait_entry->command, wait_entry->context); } goto intercepted; } return false; intercepted: restart_command_waiting_response_timer(&hci_host_env.cmd_waiting_q); /*Tell HCI Host Task to continue TX Pending commands*/ if (hci_host_env.command_credits && !fixed_queue_is_empty(hci_host_env.command_queue)) { hci_host_task_post(TASK_POST_BLOCKING); } if (wait_entry) { // If it has a callback, it's responsible for freeing the packet if (event_code == HCI_COMMAND_STATUS_EVT || (!wait_entry->complete_callback && !wait_entry->complete_future)) { osi_free(packet); } // If it has a callback, it's responsible for freeing the command if (event_code == HCI_COMMAND_COMPLETE_EVT || !wait_entry->status_callback) { osi_free(wait_entry->command); } osi_free(wait_entry); } else { osi_free(packet); } return true; }