diff --git a/src/btstack_util.c b/src/btstack_util.c index 923f12b6f..322d5d145 100644 --- a/src/btstack_util.c +++ b/src/btstack_util.c @@ -174,12 +174,22 @@ void printf_hexdump(const void *data, int size){ void log_info_hexdump(const void *data, int size){ #ifdef ENABLE_LOG_INFO - char buffer[6*16+1]; - int i, j; + + const int items_per_line = 16; + const int bytes_per_byte = 6; // strlen('0x12, ') const uint8_t low = 0x0F; const uint8_t high = 0xF0; + + char buffer[bytes_per_byte*items_per_line+1]; + int i, j; j = 0; for (i=0; i bytes_per_byte * (items_per_line-1)){ + j = 0; + } + uint8_t byte = ((uint8_t *)data)[i]; buffer[j++] = '0'; buffer[j++] = 'x'; @@ -187,7 +197,8 @@ void log_info_hexdump(const void *data, int size){ buffer[j++] = char_for_nibble(byte & low); buffer[j++] = ','; buffer[j++] = ' '; - if (j >= 6*16 ){ + + if (j >= bytes_per_byte * items_per_line ){ buffer[j] = 0; log_info("%s", buffer); j = 0; @@ -234,9 +245,19 @@ int uuid_has_bluetooth_prefix(uint8_t * uuid128){ static char uuid128_to_str_buffer[32+4+1]; char * uuid128_to_str(uint8_t * uuid){ - sprintf(uuid128_to_str_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], - uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); + int i; + int j = 0; + const uint8_t low = 0x0F; + const uint8_t high = 0xF0; + // after 4, 6, 8, and 10 bytes = XYXYXYXY-XYXY-XYXY-XYXY-XYXYXYXYXYXY, there's a dash + const int dash_locations = (1<<3) | (1<<5) | (1<<7) | (1<<9); + for (i=0;i<16;i++){ + uuid128_to_str_buffer[j++] = char_for_nibble((uuid[i] & high) >> 4); + uuid128_to_str_buffer[j++] = char_for_nibble(uuid[i] & low); + if (dash_locations & (1< hfp_connection->negotiated_codec){ - hfp_connection->negotiated_codec = packet[pos]; - } - } - printf("Negotiated Codec 0x%02x\n", hfp_connection->negotiated_codec); -} -#endif - // UTILS int get_bit(uint16_t bitmap, int position){ return (bitmap >> position) & 1; @@ -319,7 +304,6 @@ static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t b hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); if (hfp_connection) return hfp_connection; hfp_connection = create_hfp_connection_context(); - printf("created hfp_connection for address %s\n", bd_addr_to_str(bd_addr)); memcpy(hfp_connection->remote_addr, bd_addr, 6); return hfp_connection; } diff --git a/src/classic/hfp_ag.c b/src/classic/hfp_ag.c index f8fe311d2..28cbcd621 100644 --- a/src/classic/hfp_ag.c +++ b/src/classic/hfp_ag.c @@ -1130,7 +1130,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_gsm_handle_event(HFP_AG_INCOMING_CALL); hfp_ag_set_callsetup_indicator(); hfp_ag_trigger_incoming_call(); - printf("AG rings\n"); + log_info("AG rings"); break; default: break; @@ -1142,7 +1142,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_gsm_handle_event(HFP_AG_INCOMING_CALL); hfp_ag_set_callsetup_indicator(); hfp_ag_trigger_incoming_call(); - printf("AG call waiting\n"); + log_info("AG call waiting"); break; default: break; @@ -1159,7 +1159,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_call_indicator(); hfp_ag_set_callsetup_indicator(); hfp_ag_ag_accept_call(); - printf("AG answers call, accept call by GSM\n"); + log_info("AG answers call, accept call by GSM"); break; default: break; @@ -1168,7 +1168,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con case HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT: switch (hfp_gsm_callsetup_status()){ case HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS: - printf("AG: current call is placed on hold, incoming call gets active\n"); + log_info("AG: current call is placed on hold, incoming call gets active"); hfp_gsm_handle_event(HFP_AG_INCOMING_CALL_ACCEPTED_BY_AG); hfp_ag_set_callsetup_indicator(); hfp_ag_set_callheld_indicator(); @@ -1187,7 +1187,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con case HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT: switch (hfp_gsm_callheld_status()){ case HFP_CALLHELD_STATUS_CALL_ON_HOLD_OR_SWAPPED: - printf("AG: joining held call with active call\n"); + log_info("AG: joining held call with active call"); hfp_gsm_handle_event(HFP_AG_HELD_CALL_JOINED_BY_AG); hfp_ag_set_callheld_indicator(); hfp_ag_transfer_callheld_state(); @@ -1211,7 +1211,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_callsetup_indicator(); hfp_ag_set_call_indicator(); hfp_ag_hf_accept_call(hfp_connection); - printf("HF answers call, accept call by GSM\n"); + log_info("HF answers call, accept call by GSM"); hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CALL_ANSWERED); break; default: @@ -1236,7 +1236,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_call_indicator(); hfp_ag_set_callsetup_indicator(); hfp_ag_ag_accept_call(); - printf("AG response and hold - hold by AG\n"); + log_info("AG response and hold - hold by AG"); break; default: break; @@ -1260,7 +1260,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_call_indicator(); hfp_ag_set_callsetup_indicator(); hfp_ag_hf_accept_call(hfp_connection); - printf("AG response and hold - hold by HF\n"); + log_info("AG response and hold - hold by HF"); break; default: break; @@ -1279,7 +1279,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_response_and_hold_active = 0; hfp_ag_response_and_hold_state = HFP_RESPONSE_AND_HOLD_HELD_INCOMING_ACCEPTED; hfp_ag_send_response_and_hold_state(hfp_ag_response_and_hold_state); - printf("Held Call accepted and active\n"); + log_info("Held Call accepted and active"); break; case HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_AG: @@ -1304,14 +1304,14 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_callsetup_indicator(); hfp_ag_transfer_callsetup_state(); hfp_ag_trigger_reject_call(); - printf("HF Rejected Incoming call, AG terminate call\n"); + log_info("HF Rejected Incoming call, AG terminate call"); break; case HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_DIALING_STATE: case HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE: hfp_gsm_handle_event(HFP_AG_TERMINATE_CALL_BY_HF); hfp_ag_set_callsetup_indicator(); hfp_ag_transfer_callsetup_state(); - printf("AG terminate outgoing call process\n"); + log_info("AG terminate outgoing call process"); default: break; } @@ -1321,7 +1321,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_call_indicator(); hfp_ag_transfer_call_state(); hfp_connection->call_state = HFP_CALL_IDLE; - printf("AG terminate call\n"); + log_info("AG terminate call"); break; } break; @@ -1334,7 +1334,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_gsm_handle_event(HFP_AG_TERMINATE_CALL_BY_AG); hfp_ag_set_callsetup_indicator(); hfp_ag_trigger_reject_call(); - printf("AG Rejected Incoming call, AG terminate call\n"); + log_info("AG Rejected Incoming call, AG terminate call"); break; default: break; @@ -1344,7 +1344,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_callsetup_indicator(); hfp_ag_set_call_indicator(); hfp_ag_trigger_terminate_call(); - printf("AG terminate call\n"); + log_info("AG terminate call"); break; default: break; @@ -1356,12 +1356,12 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con switch (hfp_gsm_callsetup_status()){ case HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS: hfp_ag_stop_ringing(); - printf("Incoming call interrupted\n"); + log_info("Incoming call interrupted"); break; case HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_DIALING_STATE: case HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE: - printf("Outgoing call interrupted\n"); - printf("AG notify call dropped\n"); + log_info("Outgoing call interrupted\n"); + log_info("AG notify call dropped\n"); break; default: break; @@ -1380,7 +1380,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_callsetup_indicator(); hfp_ag_set_call_indicator(); hfp_ag_trigger_terminate_call(); - printf("AG notify call dropped\n"); + log_info("AG notify call dropped"); break; default: break; @@ -1412,14 +1412,14 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_gsm_handle_event(HFP_AG_OUTGOING_REDIAL_INITIATED); hfp_connection->call_state = HFP_CALL_OUTGOING_INITIATED; - printf("\nRedial last number"); + log_info("Redial last number"); char * last_dialed_number = hfp_gsm_last_dialed_number(); if (strlen(last_dialed_number) > 0){ - printf("\nLast number exists: accept call"); + log_info("Last number exists: accept call"); hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER, last_dialed_number); } else { - printf("\nLast number missing: reject call"); + log_info("log_infoLast number missing: reject call"); hfp_ag_outgoing_call_rejected(); } break; @@ -1457,7 +1457,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con // put current call on hold if active if (put_call_on_hold){ - printf("AG putting current call on hold for new outgoing call\n"); + log_info("AG putting current call on hold for new outgoing calllog_info"); hfp_ag_set_callheld_indicator(); indicator_index = get_ag_indicator_index_for_name("callheld"); hfp_ag_transfer_ag_indicators_status_cmd(hfp_connection->rfcomm_cid, &hfp_ag_indicators[indicator_index]); @@ -1510,7 +1510,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_ag_set_callsetup_indicator(); hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); hfp_connection->call_state = HFP_CALL_ACTIVE; - printf("AG: Call Waiting, User Busy\n"); + log_info("AG: Call Waiting, User Busy"); break; case HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL:{ @@ -1524,11 +1524,11 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con } if (call_setup_in_progress){ - printf("AG: Call Dropped, Accept new call\n"); + log_info("AG: Call Dropped, Accept new call"); hfp_ag_set_callsetup_indicator(); hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); } else { - printf("AG: Call Dropped, Resume held call\n"); + log_info("AG: Call Dropped, Resume held call"); } if (call_held){ hfp_ag_set_callheld_indicator(); @@ -1546,11 +1546,11 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con hfp_gsm_handle_event_with_call_index(HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, hfp_connection->call_index); if (call_setup_in_progress){ - printf("AG: Call on Hold, Accept new call\n"); + log_info("AG: Call on Hold, Accept new call"); hfp_ag_set_callsetup_indicator(); hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); } else { - printf("AG: Swap calls\n"); + log_info("AG: Swap calls"); } hfp_ag_set_callheld_indicator(); @@ -1563,7 +1563,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con case HFP_AG_CALL_HOLD_ADD_HELD_CALL: // Adds a held call to the conversation. if (hfp_gsm_callheld_status() != HFP_CALLHELD_STATUS_NO_CALLS_HELD){ - printf("AG: Join 3-way-call\n"); + log_info("AG: Join 3-way-call"); hfp_gsm_handle_event(HFP_AG_CALL_HOLD_ADD_HELD_CALL); hfp_ag_set_callheld_indicator(); hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); @@ -1574,7 +1574,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con case HFP_AG_CALL_HOLD_EXIT_AND_JOIN_CALLS: // Connects the two calls and disconnects the subscriber from both calls (Explicit Call Transfer) hfp_gsm_handle_event(HFP_AG_CALL_HOLD_EXIT_AND_JOIN_CALLS); - printf("AG: Transfer call -> Connect two calls and disconnect\n"); + log_info("AG: Transfer call -> Connect two calls and disconnect"); hfp_ag_set_call_indicator(); hfp_ag_set_callheld_indicator(); hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); @@ -1609,7 +1609,7 @@ static void hfp_ag_send_call_status(hfp_connection_t * hfp_connection, int call_ offset += snprintf(buffer+offset, sizeof(buffer)-offset, ", \"%s\",%u", number, type); } snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n"); - printf("hfp_ag_send_current_call_status 000 index %d, dir %d, status %d, mode %d, mpty %d, type %d, number %s\n", idx, dir, status, + log_info("hfp_ag_send_current_call_status 000 index %d, dir %d, status %d, mode %d, mpty %d, type %d, number %s", idx, dir, status, mode, mpty, type, number); send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); } @@ -1815,7 +1815,7 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_ break; case HFP_CMD_RESPONSE_AND_HOLD_COMMAND: value = atoi((char *)&hfp_connection->line_buffer[0]); - printf("HF Response and Hold: %u\n", value); + log_info("HF Response and Hold: %u", value); switch(value){ case HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD: hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_ACCEPT_INCOMING_CALL_BY_HF, hfp_connection); @@ -1846,17 +1846,17 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_ hfp_connection->send_error = 1; return; } - printf("HF Indicator 'enhanced security' set to %u\n", value); + log_info("HF Indicator 'enhanced security' set to %u", value); break; case 2: // battery level if (value > 100){ hfp_connection->send_error = 1; return; } - printf("HF Indicator 'battery' set to %u\n", value); + log_info("HF Indicator 'battery' set to %u", value); break; default: - printf("HF Indicator unknown set to %u\n", value); + log_info("HF Indicator unknown set to %u", value); break; } hfp_connection->ok_pending = 1; @@ -1893,14 +1893,14 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_ if (get_bit(hfp_supported_features, HFP_AGSF_EC_NR_FUNCTION)){ hfp_connection->ok_pending = 1; hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_EC_NR_FUNCTION, hfp_connection->ag_echo_and_noise_reduction); - printf("AG: EC/NR = %u\n", hfp_connection->ag_echo_and_noise_reduction); + log_info("AG: EC/NR = %u", hfp_connection->ag_echo_and_noise_reduction); } else { hfp_connection->send_error = 1; } break; case HFP_CMD_CALL_ANSWERED: hfp_connection->command = HFP_CMD_NONE; - printf("HFP: ATA\n"); + log_info("HFP: ATA"); hfp_ag_call_sm(HFP_AG_INCOMING_CALL_ACCEPTED_BY_HF, hfp_connection); break; case HFP_CMD_HANG_UP_CALL: @@ -1972,12 +1972,12 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_ case HFP_CMD_SET_SPEAKER_GAIN: hfp_connection->command = HFP_CMD_NONE; hfp_connection->ok_pending = 1; - printf("HF speaker gain = %u\n", hfp_connection->speaker_gain); + log_info("HF speaker gain = %u", hfp_connection->speaker_gain); break; case HFP_CMD_SET_MICROPHONE_GAIN: hfp_connection->command = HFP_CMD_NONE; hfp_connection->ok_pending = 1; - printf("HF microphone gain = %u\n", hfp_connection->microphone_gain); + log_info("HF microphone gain = %u", hfp_connection->microphone_gain); break; default: break; @@ -2243,7 +2243,7 @@ void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate){ hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); if (!get_bit(hfp_connection->remote_supported_features, HFP_HFSF_VOICE_RECOGNITION_FUNCTION)) { - printf("AG cannot acivate voice recognition - not supported by HF\n"); + log_info("AG cannot acivate voice recognition - not supported by HF"); return; } diff --git a/src/classic/hfp_hf.c b/src/classic/hfp_hf.c index 1506ea854..9cd80cd2a 100644 --- a/src/classic/hfp_hf.c +++ b/src/classic/hfp_hf.c @@ -801,7 +801,7 @@ static void hfp_run_for_context(hfp_connection_t * hfp_connection){ sprintf(buffer, "AT%s=%u,%u\r\n", HFP_TRANSFER_HF_INDICATOR_STATUS, hfp_indicators[i], hfp_indicators_value[i]); send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); } else { - printf("Not sending HF indicator %u as it is disabled\n", hfp_indicators[i]); + log_info("Not sending HF indicator %u as it is disabled", hfp_indicators[i]); } return; } @@ -921,7 +921,7 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){ switch (hfp_connection->hf_query_operator_state){ case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK: - printf("Format set, querying name\n"); + // printf("Format set, querying name\n"); hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; break; case HPF_HF_QUERY_OPERATOR_W4_RESULT: diff --git a/src/classic/hsp_ag.c b/src/classic/hsp_ag.c index d055a3e5c..3aee3d938 100644 --- a/src/classic/hsp_ag.c +++ b/src/classic/hsp_ag.c @@ -286,7 +286,6 @@ void hsp_ag_connect(bd_addr_t bd_addr){ void hsp_ag_disconnect(void){ hsp_ag_release_audio_connection(); - printf(" rfcomm diconnect %d\n", hsp_state); if (hsp_state < HSP_W4_RFCOMM_CONNECTED){ hsp_state = HSP_IDLE; return; @@ -301,8 +300,6 @@ void hsp_ag_disconnect(void){ } void hsp_ag_establish_audio_connection(void){ - printf("hsp_ag_establish_audio_connection state %d\n", hsp_state); - switch (hsp_state){ case HSP_RFCOMM_CONNECTION_ESTABLISHED: hsp_establish_audio_connection = 1; diff --git a/src/hci.c b/src/hci.c index abe2068ba..aae822c09 100644 --- a/src/hci.c +++ b/src/hci.c @@ -83,7 +83,7 @@ static void hci_connection_timestamp(hci_connection_t *connection); static int hci_power_control_on(void); static void hci_power_control_off(void); static void hci_state_reset(void); -static void hci_emit_connection_complete(hci_connection_t *conn, uint8_t status); +static void hci_emit_connection_complete(bd_addr_t address, hci_con_handle_t con_handle, uint8_t status); static void hci_emit_l2cap_check_timeout(hci_connection_t *conn); static void hci_emit_disconnection_complete(hci_con_handle_t con_handle, uint8_t reason); static void hci_emit_nr_connections_changed(void); @@ -885,17 +885,18 @@ static void hci_initialization_timeout_handler(btstack_timer_source_t * ds){ hci_stack->num_cmd_packets = 1; hci_run(); break; - case HCI_INIT_W4_SEND_BAUD_CHANGE: { - uint32_t baud_rate = hci_transport_uart_get_main_baud_rate(); - log_info("Local baud rate change to %"PRIu32"(timeout handler)", baud_rate); - hci_stack->hci_transport->set_baudrate(baud_rate); + case HCI_INIT_W4_SEND_BAUD_CHANGE: + if (hci_stack->hci_transport->set_baudrate){ + uint32_t baud_rate = hci_transport_uart_get_main_baud_rate(); + log_info("Local baud rate change to %"PRIu32"(timeout handler)", baud_rate); + hci_stack->hci_transport->set_baudrate(baud_rate); + } // For CSR, HCI Reset is sent on new baud rate if (hci_stack->manufacturer == COMPANY_ID_CAMBRIDGE_SILICON_RADIO){ hci_stack->substate = HCI_INIT_SEND_RESET_CSR_WARM_BOOT; hci_run(); } break; - } default: break; } @@ -1067,10 +1068,11 @@ static void hci_initializing_run(void){ if (hci_stack->local_name){ hci_send_cmd(&hci_write_local_name, hci_stack->local_name); } else { - char local_name[30]; - // BTstack-11:22:33:44:55:66 - strcpy(local_name, "BTstack "); - strcat(local_name, bd_addr_to_str(hci_stack->local_bd_addr)); + char local_name[8+17+1]; + // BTstack 11:22:33:44:55:66 + memcpy(local_name, "BTstack ", 8); + memcpy(&local_name[8], bd_addr_to_str(hci_stack->local_bd_addr), 17); // strlen(bd_addr_to_str(...)) = 17 + local_name[8+17] = '\0'; log_info("---> Name %s", local_name); hci_send_cmd(&hci_write_local_name, local_name); } @@ -1248,7 +1250,7 @@ static void hci_initializing_event_handler(uint8_t * packet, uint16_t size){ case HCI_INIT_W4_SEND_BAUD_CHANGE: // for STLC2500D, baud rate change already happened. // for others, baud rate gets changed now - if (hci_stack->manufacturer != COMPANY_ID_ST_MICROELECTRONICS){ + if ((hci_stack->manufacturer != COMPANY_ID_ST_MICROELECTRONICS) && need_baud_change){ uint32_t baud_rate = hci_transport_uart_get_main_baud_rate(); log_info("Local baud rate change to %"PRIu32"(w4_send_baud_change)", baud_rate); hci_stack->hci_transport->set_baudrate(baud_rate); @@ -1274,17 +1276,18 @@ static void hci_initializing_event_handler(uint8_t * packet, uint16_t size){ } hci_stack->substate = HCI_INIT_READ_BD_ADDR; return; - case HCI_INIT_W4_SEND_BAUD_CHANGE_BCM: { - uint32_t baud_rate = hci_transport_uart_get_main_baud_rate(); - log_info("Local baud rate change to %"PRIu32"(w4_send_baud_change_bcm))", baud_rate); - hci_stack->hci_transport->set_baudrate(baud_rate); + case HCI_INIT_W4_SEND_BAUD_CHANGE_BCM: + if (need_baud_change){ + uint32_t baud_rate = hci_transport_uart_get_main_baud_rate(); + log_info("Local baud rate change to %"PRIu32"(w4_send_baud_change_bcm))", baud_rate); + hci_stack->hci_transport->set_baudrate(baud_rate); + } if (need_addr_change){ hci_stack->substate = HCI_INIT_SET_BD_ADDR; return; } hci_stack->substate = HCI_INIT_READ_BD_ADDR; return; - } case HCI_INIT_W4_SET_BD_ADDR: // for STLC2500D, bd addr change only gets active after sending reset command if (hci_stack->manufacturer == COMPANY_ID_ST_MICROELECTRONICS){ @@ -2025,11 +2028,16 @@ void hci_close(void){ if (hci_stack->link_key_db) { hci_stack->link_key_db->close(); } - while (hci_stack->connections) { - // cancel all l2cap connections - hci_emit_disconnection_complete(((hci_connection_t *) hci_stack->connections)->con_handle, 0x16); // terminated by local host - hci_shutdown_connection((hci_connection_t *) hci_stack->connections); + + btstack_linked_list_iterator_t lit; + btstack_linked_list_iterator_init(&lit, &hci_stack->connections); + while (btstack_linked_list_iterator_has_next(&lit)){ + // cancel all l2cap connections by emitting dicsconnection complete before shutdown (free) connection + hci_connection_t * connection = (hci_connection_t*) btstack_linked_list_iterator_next(&lit); + hci_emit_disconnection_complete(connection->con_handle, 0x16); // terminated by local host + hci_shutdown_connection(connection); } + hci_power_control(HCI_POWER_OFF); #ifdef HAVE_MALLOC @@ -2807,7 +2815,7 @@ int hci_send_cmd_packet(uint8_t *packet, int size){ conn = create_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_CLASSIC); if (!conn){ // notify client that alloc failed - hci_emit_connection_complete(conn, BTSTACK_MEMORY_ALLOC_FAILED); + hci_emit_connection_complete(addr, 0, BTSTACK_MEMORY_ALLOC_FAILED); return 0; // don't sent packet to controller } conn->state = SEND_CREATE_CONNECTION; @@ -2817,7 +2825,7 @@ int hci_send_cmd_packet(uint8_t *packet, int size){ // if connection active exists case OPEN: // and OPEN, emit connection complete command, don't send to controller - hci_emit_connection_complete(conn, 0); + hci_emit_connection_complete(addr, 0, 0); return 0; case SEND_CREATE_CONNECTION: // connection created by hci, e.g. dedicated bonding @@ -3010,13 +3018,13 @@ void hci_emit_state(void){ hci_emit_event(event, sizeof(event), 1); } -static void hci_emit_connection_complete(hci_connection_t *conn, uint8_t status){ +static void hci_emit_connection_complete(bd_addr_t address, hci_con_handle_t con_handle, uint8_t status){ uint8_t event[13]; event[0] = HCI_EVENT_CONNECTION_COMPLETE; event[1] = sizeof(event) - 2; event[2] = status; - little_endian_store_16(event, 3, conn->con_handle); - reverse_bd_addr(conn->address, &event[5]); + little_endian_store_16(event, 3, con_handle); + reverse_bd_addr(address, &event[5]); event[11] = 1; // ACL connection event[12] = 0; // encryption disabled hci_emit_event(event, sizeof(event), 1); diff --git a/src/hci_dump.c b/src/hci_dump.c index 841cfddd4..0ca0011f0 100644 --- a/src/hci_dump.c +++ b/src/hci_dump.c @@ -176,12 +176,13 @@ void hci_dump_packet(uint8_t packet_type, uint8_t in, uint8_t *packet, uint16_t case HCI_DUMP_STDOUT: { /* Obtain the time of day, and convert it to a tm struct. */ ptm = localtime (&curr_time_secs); + /* assert localtime was successful */ + if (!ptm) break; /* Format the date and time, down to a single second. */ strftime (time_string, sizeof (time_string), "[%Y-%m-%d %H:%M:%S", ptm); /* Compute milliseconds from microseconds. */ uint16_t milliseconds = curr_time.tv_usec / 1000; - /* Print the formatted time, in seconds, followed by a decimal point - and the milliseconds. */ + /* Print the formatted time, in seconds, followed by a decimal point and the milliseconds. */ printf ("%s.%03u] ", time_string, milliseconds); printf_packet(packet_type, in, packet, len); break; diff --git a/src/l2cap.c b/src/l2cap.c index 465315316..3d677c119 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -304,7 +304,7 @@ static l2cap_channel_t * l2cap_channel_for_rtx_timer(btstack_timer_source_t * ts static void l2cap_rtx_timeout(btstack_timer_source_t * ts){ l2cap_channel_t * channel = l2cap_channel_for_rtx_timer(ts); - if (!ts) return; + if (!channel) return; log_info("l2cap_rtx_timeout for local cid 0x%02x", channel->local_cid); diff --git a/src/l2cap_signaling.c b/src/l2cap_signaling.c index e17595400..42055e315 100644 --- a/src/l2cap_signaling.c +++ b/src/l2cap_signaling.c @@ -43,6 +43,7 @@ #include "l2cap_signaling.h" #include "btstack_config.h" +#include "btstack_debug.h" #include "hci.h" #include @@ -60,7 +61,12 @@ static const char *l2cap_signaling_commands_format[] = { "2", // 0x0a information request: InfoType {1=Connectionless MTU, 2=Extended features supported} "22D", // 0x0b information response: InfoType, Result, Data #ifdef ENABLE_BLE -// skip 6 not supported signaling pdus, see below +NULL, // 0x0c non-supported AMP command +NULL, // 0x0d non-supported AMP command +NULL, // 0x0e non-supported AMP command +NULL, // 0x0f non-supported AMP command +NULL, // 0x10 non-supported AMP command +NULL, // 0x11 non-supported AMP command "2222", // 0x12 connection parameter update request: interval min, interval max, slave latency, timeout multipler "2", // 0x13 connection parameter update response: result "22222", // 0X14 le credit based connection request: le psm, source cid, mtu, mps, initial credits @@ -69,6 +75,8 @@ static const char *l2cap_signaling_commands_format[] = { #endif }; +static const int num_l2cap_commands = sizeof(l2cap_signaling_commands_format) / sizeof(const char *); + uint8_t sig_seq_nr = 0xff; uint16_t source_cid = 0x40; @@ -87,6 +95,15 @@ uint16_t l2cap_next_local_cid(void){ static uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer, hci_con_handle_t handle, uint16_t cid, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr){ + const char *format = NULL; + if (cmd > 0 && cmd <= num_l2cap_commands) { + format = l2cap_signaling_commands_format[cmd-1]; + } + if (!format){ + log_error("l2cap_create_signaling_internal: invalid command id 0x%02x", cmd); + return 0; + } + int pb = hci_non_flushable_packet_boundary_flag_supported() ? 0x00 : 0x02; // 0 - Connection handle : PB=pb : BC=00 @@ -100,11 +117,6 @@ static uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer, hci_con_ha // 12 - L2CAP signaling parameters uint16_t pos = 12; - // skip AMP commands - if (cmd >= CONNECTION_PARAMETER_UPDATE_REQUEST){ - cmd = (L2CAP_SIGNALING_COMMANDS) (((int) cmd) - 6); - } - const char *format = l2cap_signaling_commands_format[cmd-1]; uint16_t word; uint8_t * ptr; while (*format) {