diff --git a/include/btstack/hci_cmds.h b/include/btstack/hci_cmds.h index d3e55a25b..c8d3f91f6 100644 --- a/include/btstack/hci_cmds.h +++ b/include/btstack/hci_cmds.h @@ -679,9 +679,8 @@ extern "C" { #define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED 0x01 /** - * @format 11 + * @format 1 * @param subevent_code - * @param status 0 == OK */ #define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED 0x02 @@ -693,9 +692,8 @@ extern "C" { #define HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED 0x03 /** - * @format 11 + * @format 1 * @param subevent_code - * @param status 0 == OK */ #define HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED 0x04 @@ -707,9 +705,8 @@ extern "C" { #define HFP_SUBEVENT_COMPLETE 0x05 /** - * @format 1111T + * @format 111T * @param subevent_code - * @param status * @param indicator_index * @param indicator_status * @param indicator_name @@ -719,7 +716,6 @@ extern "C" { /** * @format 1111T * @param subevent_code - * @param status * @param network_operator_mode * @param network_operator_format * @param network_operator_name @@ -733,32 +729,135 @@ extern "C" { */ #define HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR 0x08 +/** + * @format 11 + * @param subevent_code + * @param status + */ #define HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE 0x09 + +/** + * @format 1 + * @param subevent_code + */ #define HFP_SUBEVENT_START_RINGINIG 0x0A + +/** + * @format 1 + * @param subevent_code + */ #define HFP_SUBEVENT_STOP_RINGINIG 0x0B + +/** + * @format 1 + * @param subevent_code + */ #define HFP_SUBEVENT_CALL_TERMINATED 0x0C + +/** + * @format 1T + * @param subevent_code + * @param number + */ #define HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER 0x0D -#define HFP_SUBEVENT_REDIAL_LAST_NUMBER 0x0E -#define HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 0x0F + +/** + * @format 1 + * @param subevent_code + */ +#define HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 0x0E + +/** + * @format 1T + * @param subevent_code + * @param number + */ +#define HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG 0x0F + +/** + * @format 1T + * @param subevent_code + * @param dtmf code + */ +#define HFP_SUBEVENT_TRANSMIT_DTMF_CODES 0x10 + +/** + * @format 1 + * @param subevent_code + */ + #define HFP_SUBEVENT_CALL_ANSWERED 0x11 + +/** + * @format 1 + * @param subevent_code + */ +#define HFP_SUBEVENT_CONFERENCE_CALL 0x12 + +/** + * @format 1 + * @param subevent_code + */ +#define HFP_SUBEVENT_RING 0x13 + +/** + * @format 111 + * @param subevent_code + * @param status + * @param gain + */ + #define HFP_SUBEVENT_SPEAKER_VOLUME 0x14 + +/** + * @format 111 + * @param subevent_code + * @param status + * @param gain + */ +#define HFP_SUBEVENT_MICROPHONE_VOLUME 0x15 /** * @format 11T * @param subevent_code - * @param status + * @param type * @param number */ -#define HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG 0x10 -#define HFP_SUBEVENT_TRANSMIT_DTMF_CODES 0x11 -#define HFP_SUBEVENT_TRANSMIT_STATUS_OF_CURRENT_CALL 0x12 -#define HFP_SUBEVENT_CALL_ANSWERED 0x13 -#define HFP_SUBEVENT_CONFERENCE_CALL 0x14 -#define HFP_SUBEVENT_RING 0x15 -#define HFP_SUBEVENT_SPEAKER_VOLUME 0x16 -#define HFP_SUBEVENT_MICROPHONE_VOLUME 0x17 -#define HFP_SUBEVENT_CALL_WAITING_NOTIFICATION 0x18 -#define HFP_SUBEVENT_CALLING_LINE_INDETIFICATION_NOTIFICATION 0x19 -#define HFP_SUBEVENT_ENHANCED_CALL_STATUS 0x1A -#define HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION 0x1B +#define HFP_SUBEVENT_CALL_WAITING_NOTIFICATION 0x16 + +/** + * @format 11T + * @param subevent_code + * @param type + * @param number + */ +#define HFP_SUBEVENT_CALLING_LINE_INDETIFICATION_NOTIFICATION 0x17 + +/** + * @format 111111T + * @param subevent_code + * @param clcc_idx + * @param clcc_dir + * @param clcc_status + * @param clcc_mpty + * @param bnip_type + * @param bnip_number + */ +#define HFP_SUBEVENT_ENHANCED_CALL_STATUS 0x18 + +/** + * @format 111T + * @param subevent_code + * @param status + * @param bnip_type + * @param bnip_number + */ + #define HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION 0x19 + +/** + * @format 1T + * @param subevent_code + * @param value + */ +#define HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS 0x1A // ANCS Client #define ANCS_CLIENT_CONNECTED 0xF0 diff --git a/src/hfp.c b/src/hfp.c index a09443de5..26b13f717 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -97,23 +97,8 @@ static const char * hfp_ag_features[] = { "Reserved for future definition" }; -static int hfp_generic_status_indicators_nr = 0; -static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_HF_INDICATORS]; - static linked_list_t hfp_connections = NULL; -static void parse_sequence(hfp_connection_t * context); - -hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(void){ - return (hfp_generic_status_indicator_t *) &hfp_generic_status_indicators; -} -int get_hfp_generic_status_indicators_nr(void){ - return hfp_generic_status_indicators_nr; -} -void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr){ - if (indicator_nr > HFP_MAX_NUM_HF_INDICATORS) return; - hfp_generic_status_indicators_nr = indicator_nr; - memcpy(hfp_generic_status_indicators, indicators, indicator_nr * sizeof(hfp_generic_status_indicator_t)); -} +static void parse_sequence(hfp_connection_t * hfp_connection); const char * hfp_hf_feature(int index){ if (index > HFP_HF_FEATURES_SIZE){ @@ -140,17 +125,17 @@ int send_str_over_rfcomm(uint16_t cid, char * command){ } #if 0 -void hfp_set_codec(hfp_connection_t * context, uint8_t *packet, uint16_t size){ +void hfp_set_codec(hfp_connection_t * hfp_connection, uint8_t *packet, uint16_t size){ // parse available codecs int pos = 0; int i; for (i=0; i context->negotiated_codec){ - context->negotiated_codec = packet[pos]; + if (packet[pos] > hfp_connection->negotiated_codec){ + hfp_connection->negotiated_codec = packet[pos]; } } - printf("Negotiated Codec 0x%02x\n", context->negotiated_codec); + printf("Negotiated Codec 0x%02x\n", hfp_connection->negotiated_codec); } #endif @@ -196,6 +181,15 @@ int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){ return offset; } +void hfp_emit_simple_event(hfp_callback_t callback, uint8_t event_subtype){ + if (!callback) return; + uint8_t event[3]; + event[0] = HCI_EVENT_HFP_META; + event[1] = sizeof(event) - 2; + event[2] = event_subtype; + (*callback)(event, sizeof(event)); +} + void hfp_emit_event(hfp_callback_t callback, uint8_t event_subtype, uint8_t value){ if (!callback) return; uint8_t event[4]; @@ -237,9 +231,9 @@ hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (connection->rfcomm_cid == cid){ - return connection; + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (hfp_connection->rfcomm_cid == cid){ + return hfp_connection; } } return NULL; @@ -249,9 +243,9 @@ hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (memcmp(connection->remote_addr, bd_addr, 6) == 0) { - return connection; + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0) { + return hfp_connection; } } return NULL; @@ -261,69 +255,66 @@ hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (connection->sco_handle == handle){ - return connection; + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (hfp_connection->sco_handle == handle){ + return hfp_connection; } } return NULL; } -void hfp_reset_context_flags(hfp_connection_t * context){ - if (!context) return; - context->ok_pending = 0; - context->send_error = 0; +void hfp_reset_context_flags(hfp_connection_t * hfp_connection){ + if (!hfp_connection) return; + hfp_connection->ok_pending = 0; + hfp_connection->send_error = 0; - context->keep_byte = 0; + hfp_connection->keep_byte = 0; - context->change_status_update_for_individual_ag_indicators = 0; - context->operator_name_changed = 0; + hfp_connection->change_status_update_for_individual_ag_indicators = 0; + hfp_connection->operator_name_changed = 0; - context->enable_extended_audio_gateway_error_report = 0; - context->extended_audio_gateway_error = 0; + hfp_connection->enable_extended_audio_gateway_error_report = 0; + hfp_connection->extended_audio_gateway_error = 0; - // establish codecs connection - context->suggested_codec = 0; - context->negotiated_codec = 0; - context->codec_confirmed = 0; + // establish codecs hfp_connection + hfp_connection->suggested_codec = 0; + hfp_connection->negotiated_codec = 0; + hfp_connection->codec_confirmed = 0; - context->establish_audio_connection = 0; + hfp_connection->establish_audio_connection = 0; } static hfp_connection_t * create_hfp_connection_context(){ - hfp_connection_t * context = btstack_memory_hfp_connection_get(); - if (!context) return NULL; + hfp_connection_t * hfp_connection = btstack_memory_hfp_connection_get(); + if (!hfp_connection) return NULL; // init state - memset(context,0, sizeof(hfp_connection_t)); + memset(hfp_connection,0, sizeof(hfp_connection_t)); - context->state = HFP_IDLE; - context->call_state = HFP_CALL_IDLE; - context->codecs_state = HFP_CODECS_IDLE; + hfp_connection->state = HFP_IDLE; + hfp_connection->call_state = HFP_CALL_IDLE; + hfp_connection->codecs_state = HFP_CODECS_IDLE; - context->parser_state = HFP_PARSER_CMD_HEADER; - context->command = HFP_CMD_NONE; - context->negotiated_codec = 0; + hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->negotiated_codec = 0; - context->enable_status_update_for_ag_indicators = 0xFF; + hfp_connection->enable_status_update_for_ag_indicators = 0xFF; - context->generic_status_indicators_nr = hfp_generic_status_indicators_nr; - memcpy(context->generic_status_indicators, hfp_generic_status_indicators, hfp_generic_status_indicators_nr * sizeof(hfp_generic_status_indicator_t)); - - linked_list_add(&hfp_connections, (linked_item_t*)context); - return context; + linked_list_add(&hfp_connections, (linked_item_t*)hfp_connection); + return hfp_connection; } -static void remove_hfp_connection_context(hfp_connection_t * context){ - linked_list_remove(&hfp_connections, (linked_item_t*)context); +static void remove_hfp_connection_context(hfp_connection_t * hfp_connection){ + linked_list_remove(&hfp_connections, (linked_item_t*)hfp_connection); } static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){ - hfp_connection_t * context = get_hfp_connection_context_for_bd_addr(bd_addr); - if (context) return context; - context = create_hfp_connection_context(); - printf("created context for address %s\n", bd_addr_to_str(bd_addr)); - memcpy(context->remote_addr, bd_addr, 6); - return context; + 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; } /* @param network. @@ -413,30 +404,30 @@ void hfp_create_sdp_record(uint8_t * service, uint16_t service_uuid, int rfcomm_ } static hfp_connection_t * connection_doing_sdp_query = NULL; -static void handle_query_rfcomm_event(sdp_query_event_t * event, void * context){ +static void handle_query_rfcomm_event(sdp_query_event_t * event, void * query_context){ sdp_query_rfcomm_service_event_t * ve; sdp_query_complete_event_t * ce; - hfp_connection_t * connection = connection_doing_sdp_query; + hfp_connection_t * hfp_connection = connection_doing_sdp_query; - if ( connection->state != HFP_W4_SDP_QUERY_COMPLETE) return; + if ( hfp_connection->state != HFP_W4_SDP_QUERY_COMPLETE) return; switch (event->type){ case SDP_QUERY_RFCOMM_SERVICE: ve = (sdp_query_rfcomm_service_event_t*) event; - if (!connection) { - log_error("handle_query_rfcomm_event alloc connection for RFCOMM port %u failed", ve->channel_nr); + if (!hfp_connection) { + log_error("handle_query_rfcomm_event alloc hfp_connection for RFCOMM port %u failed", ve->channel_nr); return; } - connection->rfcomm_channel_nr = ve->channel_nr; + hfp_connection->rfcomm_channel_nr = ve->channel_nr; break; case SDP_QUERY_COMPLETE: connection_doing_sdp_query = NULL; ce = (sdp_query_complete_event_t*) event; - if (connection->rfcomm_channel_nr > 0){ - connection->state = HFP_W4_RFCOMM_CONNECTED; - log_info("HFP: SDP_QUERY_COMPLETE context %p, addr %s, state %d", connection, bd_addr_to_str( connection->remote_addr), connection->state); - rfcomm_create_channel_internal(NULL, connection->remote_addr, connection->rfcomm_channel_nr); + if (hfp_connection->rfcomm_channel_nr > 0){ + hfp_connection->state = HFP_W4_RFCOMM_CONNECTED; + log_info("HFP: SDP_QUERY_COMPLETE query_context %p, addr %s, state %d", hfp_connection, bd_addr_to_str( hfp_connection->remote_addr), hfp_connection->state); + rfcomm_create_channel_internal(NULL, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr); break; } log_info("rfcomm service not found, status %u.", ce->status); @@ -449,7 +440,7 @@ static void handle_query_rfcomm_event(sdp_query_event_t * event, void * context) void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; uint16_t rfcomm_cid, handle; - hfp_connection_t * context = NULL; + hfp_connection_t * hfp_connection = NULL; // printf("AG packet_handler type %u, packet[0] %x, size %u\n", packet_type, packet[0], size); @@ -471,14 +462,14 @@ void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t case RFCOMM_EVENT_INCOMING_CONNECTION: // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) bt_flip_addr(event_addr, &packet[2]); - context = provide_hfp_connection_context_for_bd_addr(event_addr); + hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr); - if (!context || context->state != HFP_IDLE) return; + if (!hfp_connection || hfp_connection->state != HFP_IDLE) return; - context->rfcomm_cid = READ_BT_16(packet, 9); - context->state = HFP_W4_RFCOMM_CONNECTED; - printf("RFCOMM channel %u requested for %s\n", context->rfcomm_cid, bd_addr_to_str(context->remote_addr)); - rfcomm_accept_connection_internal(context->rfcomm_cid); + hfp_connection->rfcomm_cid = READ_BT_16(packet, 9); + hfp_connection->state = HFP_W4_RFCOMM_CONNECTED; + printf("RFCOMM channel %u requested for %s\n", hfp_connection->rfcomm_cid, bd_addr_to_str(hfp_connection->remote_addr)); + rfcomm_accept_connection_internal(hfp_connection->rfcomm_cid); break; case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE: @@ -486,26 +477,26 @@ void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x, size %u\n", packet_type, packet[0], size); bt_flip_addr(event_addr, &packet[3]); - context = get_hfp_connection_context_for_bd_addr(event_addr); - if (!context || context->state != HFP_W4_RFCOMM_CONNECTED) return; + hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); + if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return; if (packet[2]) { hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, packet[2]); - remove_hfp_connection_context(context); + remove_hfp_connection_context(hfp_connection); } else { - context->con_handle = READ_BT_16(packet, 9); - printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE con_handle 0x%02x\n", context->con_handle); + hfp_connection->con_handle = READ_BT_16(packet, 9); + printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE con_handle 0x%02x\n", hfp_connection->con_handle); - context->rfcomm_cid = READ_BT_16(packet, 12); + hfp_connection->rfcomm_cid = READ_BT_16(packet, 12); uint16_t mtu = READ_BT_16(packet, 14); - printf("RFCOMM channel open succeeded. Context %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", context, context->rfcomm_cid, mtu); + printf("RFCOMM channel open succeeded. hfp_connection %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", hfp_connection, hfp_connection->rfcomm_cid, mtu); - switch (context->state){ + switch (hfp_connection->state){ case HFP_W4_RFCOMM_CONNECTED: - context->state = HFP_EXCHANGE_SUPPORTED_FEATURES; + hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES; break; case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN: - context->state = HFP_W2_DISCONNECT_RFCOMM; + hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; printf("Shutting down RFCOMM.\n"); break; default: @@ -523,32 +514,32 @@ void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t uint8_t status = packet[index++]; if (status != 0){ - log_error("(e)SCO Connection failed status %u", status); + log_error("(e)SCO hfp_connection failed status %u", status); // if outgoing && link_setting != d0 && appropriate error if (status != 0x11 && status != 0x1f) break; // invalid params / unspecified error - context = get_hfp_connection_context_for_bd_addr(event_addr); - if (!context) break; - switch (context->link_setting){ + hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); + if (!hfp_connection) break; + switch (hfp_connection->link_setting){ case HFP_LINK_SETTINGS_D0: return; // no other option left case HFP_LINK_SETTINGS_D1: - // context->link_setting = HFP_LINK_SETTINGS_D0; + // hfp_connection->link_setting = HFP_LINK_SETTINGS_D0; // break; case HFP_LINK_SETTINGS_S1: - // context->link_setting = HFP_LINK_SETTINGS_D1; + // hfp_connection->link_setting = HFP_LINK_SETTINGS_D1; // break; case HFP_LINK_SETTINGS_S2: case HFP_LINK_SETTINGS_S3: case HFP_LINK_SETTINGS_S4: - // context->link_setting = HFP_LINK_SETTINGS_S1; + // hfp_connection->link_setting = HFP_LINK_SETTINGS_S1; // break; case HFP_LINK_SETTINGS_T1: case HFP_LINK_SETTINGS_T2: - // context->link_setting = HFP_LINK_SETTINGS_S3; - context->link_setting = HFP_LINK_SETTINGS_D0; + // hfp_connection->link_setting = HFP_LINK_SETTINGS_S3; + hfp_connection->link_setting = HFP_LINK_SETTINGS_D0; break; } - context->establish_audio_connection = 1; + hfp_connection->establish_audio_connection = 1; break; } @@ -569,14 +560,14 @@ void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t switch (link_type){ case 0x00: - log_info("SCO Connection established."); - if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval); - if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval); - if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length); - if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length); + log_info("SCO hfp_connection established."); + if (transmission_interval != 0) log_error("SCO hfp_connection: transmission_interval not zero: %d.", transmission_interval); + if (retransmission_interval != 0) log_error("SCO hfp_connection: retransmission_interval not zero: %d.", retransmission_interval); + if (rx_packet_length != 0) log_error("SCO hfp_connection: rx_packet_length not zero: %d.", rx_packet_length); + if (tx_packet_length != 0) log_error("SCO hfp_connection: tx_packet_length not zero: %d.", tx_packet_length); break; case 0x02: - log_info("eSCO Connection established. \n"); + log_info("eSCO hfp_connection established. \n"); break; default: log_error("(e)SCO reserved link_type 0x%2x", link_type); @@ -586,56 +577,56 @@ void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle, bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode); - context = get_hfp_connection_context_for_bd_addr(event_addr); + hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); - if (!context) { - log_error("SCO link created, context for address %s not found.", bd_addr_to_str(event_addr)); + if (!hfp_connection) { + log_error("SCO link created, hfp_connection for address %s not found.", bd_addr_to_str(event_addr)); break; } - if (context->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){ + if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){ log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN"); - context->state = HFP_W2_DISCONNECT_SCO; + hfp_connection->state = HFP_W2_DISCONNECT_SCO; break; } - context->sco_handle = sco_handle; - context->establish_audio_connection = 0; - context->state = HFP_AUDIO_CONNECTION_ESTABLISHED; + hfp_connection->sco_handle = sco_handle; + hfp_connection->establish_audio_connection = 0; + hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED; hfp_emit_audio_connection_established_event(callback, packet[2], sco_handle); break; } case RFCOMM_EVENT_CHANNEL_CLOSED: rfcomm_cid = READ_BT_16(packet,2); - context = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid); - if (!context) break; - if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){ - context->state = HFP_IDLE; - hfp_establish_service_level_connection(context->remote_addr, context->service_uuid); + hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid); + if (!hfp_connection) break; + if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){ + hfp_connection->state = HFP_IDLE; + hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid); break; } - hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0); - remove_hfp_connection_context(context); + hfp_emit_simple_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED); + remove_hfp_connection_context(hfp_connection); break; case HCI_EVENT_DISCONNECTION_COMPLETE: handle = READ_BT_16(packet,3); - context = get_hfp_connection_context_for_sco_handle(handle); + hfp_connection = get_hfp_connection_context_for_sco_handle(handle); - if (!context) break; + if (!hfp_connection) break; - if (context->state != HFP_W4_SCO_DISCONNECTED){ + if (hfp_connection->state != HFP_W4_SCO_DISCONNECTED){ log_info("Received gap disconnect in wrong hfp state"); } - log_info("Check SCO handle: incoming 0x%02x, context 0x%02x\n", handle,context->sco_handle); + log_info("Check SCO handle: incoming 0x%02x, hfp_connection 0x%02x\n", handle,hfp_connection->sco_handle); - if (handle == context->sco_handle){ + if (handle == hfp_connection->sco_handle){ log_info("SCO disconnected, w2 disconnect RFCOMM\n"); - context->sco_handle = 0; - context->release_audio_connection = 0; - context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; - hfp_emit_event(callback, HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED, 0); + hfp_connection->sco_handle = 0; + hfp_connection->release_audio_connection = 0; + hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; + hfp_emit_simple_event(callback, HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED); break; } break; @@ -758,10 +749,12 @@ static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ } if (strncmp(line_buffer+offset, HFP_ENABLE_CLIP, strlen(HFP_ENABLE_CLIP)) == 0){ + if (isHandsFree) return HFP_CMD_AG_SENT_CLIP_INFORMATION; return HFP_CMD_ENABLE_CLIP; } if (strncmp(line_buffer+offset, HFP_ENABLE_CALL_WAITING_NOTIFICATION, strlen(HFP_ENABLE_CALL_WAITING_NOTIFICATION)) == 0){ + if (isHandsFree) return HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE; return HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION; } @@ -845,14 +838,14 @@ static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ return HFP_CMD_NONE; } -static void hfp_parser_store_byte(hfp_connection_t * context, uint8_t byte){ - // printf("hfp_parser_store_byte %c at pos %u\n", (char) byte, context->line_size); +static void hfp_parser_store_byte(hfp_connection_t * hfp_connection, uint8_t byte){ + // printf("hfp_parser_store_byte %c at pos %u\n", (char) byte, hfp_connection->line_size); // TODO: add limit - context->line_buffer[context->line_size++] = byte; - context->line_buffer[context->line_size] = 0; + hfp_connection->line_buffer[hfp_connection->line_size++] = byte; + hfp_connection->line_buffer[hfp_connection->line_size] = 0; } -static int hfp_parser_is_buffer_empty(hfp_connection_t * context){ - return context->line_size == 0; +static int hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection){ + return hfp_connection->line_size == 0; } static int hfp_parser_is_end_of_line(uint8_t byte){ @@ -863,8 +856,8 @@ static int hfp_parser_is_end_of_header(uint8_t byte){ return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?'; } -static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t byte){ - if (context->keep_byte == 1) return 1; +static int hfp_parser_found_separator(hfp_connection_t * hfp_connection, uint8_t byte){ + if (hfp_connection->keep_byte == 1) return 1; int found_separator = byte == ',' || byte == '\n'|| byte == '\r'|| byte == ')' || byte == '(' || byte == ':' || @@ -872,129 +865,131 @@ static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t byte){ return found_separator; } -static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ - context->line_size = 0; +static void hfp_parser_next_state(hfp_connection_t * hfp_connection, uint8_t byte){ + hfp_connection->line_size = 0; if (hfp_parser_is_end_of_line(byte)){ - context->parser_item_index = 0; - context->parser_state = HFP_PARSER_CMD_HEADER; + hfp_connection->parser_item_index = 0; + hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; return; } - switch (context->parser_state){ + switch (hfp_connection->parser_state){ case HFP_PARSER_CMD_HEADER: - context->parser_state = HFP_PARSER_CMD_SEQUENCE; - if (context->keep_byte == 1){ - hfp_parser_store_byte(context, byte); - context->keep_byte = 0; + hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE; + if (hfp_connection->keep_byte == 1){ + hfp_parser_store_byte(hfp_connection, byte); + hfp_connection->keep_byte = 0; } break; case HFP_PARSER_CMD_SEQUENCE: - switch (context->command){ + switch (hfp_connection->command){ case HFP_CMD_AG_SENT_PHONE_NUMBER: + case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: + case HFP_CMD_AG_SENT_CLIP_INFORMATION: case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: case HFP_CMD_RETRIEVE_AG_INDICATORS: case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: case HFP_CMD_HF_INDICATOR_STATUS: - context->parser_state = HFP_PARSER_SECOND_ITEM; + hfp_connection->parser_state = HFP_PARSER_SECOND_ITEM; break; default: break; } break; case HFP_PARSER_SECOND_ITEM: - context->parser_state = HFP_PARSER_THIRD_ITEM; + hfp_connection->parser_state = HFP_PARSER_THIRD_ITEM; break; case HFP_PARSER_THIRD_ITEM: - if (context->command == HFP_CMD_RETRIEVE_AG_INDICATORS){ - context->parser_state = HFP_PARSER_CMD_SEQUENCE; + if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS){ + hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE; break; } - context->parser_state = HFP_PARSER_CMD_HEADER; + hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; break; } } -void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){ +void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){ // handle ATD; - if (strncmp((const char*)context->line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){ + if (strncmp((const char*)hfp_connection->line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){ // check for end-of-line or ';' if (byte == ';' || hfp_parser_is_end_of_line(byte)){ - context->line_buffer[context->line_size] = 0; - context->line_size = 0; - context->command = HFP_CMD_CALL_PHONE_NUMBER; + hfp_connection->line_buffer[hfp_connection->line_size] = 0; + hfp_connection->line_size = 0; + hfp_connection->command = HFP_CMD_CALL_PHONE_NUMBER; } else { - context->line_buffer[context->line_size++] = byte; + hfp_connection->line_buffer[hfp_connection->line_size++] = byte; } return; } // TODO: handle space inside word - if (byte == ' ' && context->parser_state > HFP_PARSER_CMD_HEADER) return; + if (byte == ' ' && hfp_connection->parser_state > HFP_PARSER_CMD_HEADER) return; - if (byte == ',' && context->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ - if (context->line_size == 0){ - context->line_buffer[0] = 0; - context->ignore_value = 1; - parse_sequence(context); + if (byte == ',' && hfp_connection->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ + if (hfp_connection->line_size == 0){ + hfp_connection->line_buffer[0] = 0; + hfp_connection->ignore_value = 1; + parse_sequence(hfp_connection); return; } } - if (!hfp_parser_found_separator(context, byte)){ - hfp_parser_store_byte(context, byte); + if (!hfp_parser_found_separator(hfp_connection, byte)){ + hfp_parser_store_byte(hfp_connection, byte); return; } if (hfp_parser_is_end_of_line(byte)) { - if (hfp_parser_is_buffer_empty(context)){ - context->parser_state = HFP_PARSER_CMD_HEADER; + if (hfp_parser_is_buffer_empty(hfp_connection)){ + hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; } } - if (hfp_parser_is_buffer_empty(context)) return; + if (hfp_parser_is_buffer_empty(hfp_connection)) return; - switch (context->parser_state){ + switch (hfp_connection->parser_state){ case HFP_PARSER_CMD_HEADER: // header if (byte == '='){ - context->keep_byte = 1; - hfp_parser_store_byte(context, byte); + hfp_connection->keep_byte = 1; + hfp_parser_store_byte(hfp_connection, byte); return; } if (byte == '?'){ - context->keep_byte = 0; - hfp_parser_store_byte(context, byte); + hfp_connection->keep_byte = 0; + hfp_parser_store_byte(hfp_connection, byte); return; } if (byte == ','){ - context->resolve_byte = 1; + hfp_connection->resolve_byte = 1; } - // printf(" parse header 2 %s, keep separator $ %d\n", context->line_buffer, context->keep_byte); - if (hfp_parser_is_end_of_header(byte) || context->keep_byte == 1){ - // printf(" parse header 3 %s, keep separator $ %d\n", context->line_buffer, context->keep_byte); - char * line_buffer = (char *)context->line_buffer; - context->command = parse_command(line_buffer, isHandsFree); + // printf(" parse header 2 %s, keep separator $ %d\n", hfp_connection->line_buffer, hfp_connection->keep_byte); + if (hfp_parser_is_end_of_header(byte) || hfp_connection->keep_byte == 1){ + // printf(" parse header 3 %s, keep separator $ %d\n", hfp_connection->line_buffer, hfp_connection->keep_byte); + char * line_buffer = (char *)hfp_connection->line_buffer; + hfp_connection->command = parse_command(line_buffer, isHandsFree); - /* resolve command name according to context */ - if (context->command == HFP_CMD_UNKNOWN){ - switch(context->state){ + /* resolve command name according to hfp_connection */ + if (hfp_connection->command == HFP_CMD_UNKNOWN){ + switch(hfp_connection->state){ case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: - context->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; + hfp_connection->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; break; case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: - context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; + hfp_connection->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; break; case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: - context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; + hfp_connection->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; break; case HFP_W4_RETRIEVE_INDICATORS_STATUS: - context->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; + hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; break; case HFP_W4_RETRIEVE_INDICATORS: - context->send_ag_indicators_segment = 0; - context->command = HFP_CMD_RETRIEVE_AG_INDICATORS; + hfp_connection->send_ag_indicators_segment = 0; + hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS; break; default: break; @@ -1004,34 +999,36 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){ break; case HFP_PARSER_CMD_SEQUENCE: - parse_sequence(context); + parse_sequence(hfp_connection); break; case HFP_PARSER_SECOND_ITEM: - switch (context->command){ + switch (hfp_connection->command){ case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: - log_info("format %s, ", context->line_buffer); - context->network_operator.format = atoi((char *)&context->line_buffer[0]); + log_info("format %s, ", hfp_connection->line_buffer); + hfp_connection->network_operator.format = atoi((char *)&hfp_connection->line_buffer[0]); break; case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: - log_info("format %s \n", context->line_buffer); - context->network_operator.format = atoi((char *)&context->line_buffer[0]); + log_info("format %s \n", hfp_connection->line_buffer); + hfp_connection->network_operator.format = atoi((char *)&hfp_connection->line_buffer[0]); break; case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: - context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer); + hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].state = (uint8_t)atoi((char*)hfp_connection->line_buffer); break; case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: - context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer); - log_info("%d \n", context->ag_indicators[context->parser_item_index].status); - context->ag_indicators[context->parser_item_index].status_changed = 1; + hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = (uint8_t)atoi((char*)hfp_connection->line_buffer); + log_info("%d \n", hfp_connection->ag_indicators[hfp_connection->parser_item_index].status); + hfp_connection->ag_indicators[hfp_connection->parser_item_index].status_changed = 1; break; case HFP_CMD_RETRIEVE_AG_INDICATORS: - context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); - log_info("%s, ", context->line_buffer); + hfp_connection->ag_indicators[hfp_connection->parser_item_index].min_range = atoi((char *)hfp_connection->line_buffer); + log_info("%s, ", hfp_connection->line_buffer); break; case HFP_CMD_AG_SENT_PHONE_NUMBER: - context->bnip_type = (uint8_t)atoi((char*)context->line_buffer); + case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: + case HFP_CMD_AG_SENT_CLIP_INFORMATION: + hfp_connection->bnip_type = (uint8_t)atoi((char*)hfp_connection->line_buffer); break; default: break; @@ -1039,237 +1036,239 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){ break; case HFP_PARSER_THIRD_ITEM: - switch (context->command){ + switch (hfp_connection->command){ case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: - strcpy(context->network_operator.name, (char *)context->line_buffer); - log_info("name %s\n", context->line_buffer); + strcpy(hfp_connection->network_operator.name, (char *)hfp_connection->line_buffer); + log_info("name %s\n", hfp_connection->line_buffer); break; case HFP_CMD_RETRIEVE_AG_INDICATORS: - context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); - context->parser_item_index++; - context->ag_indicators_nr = context->parser_item_index; - log_info("%s)\n", context->line_buffer); + hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = atoi((char *)hfp_connection->line_buffer); + hfp_connection->parser_item_index++; + hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index; + log_info("%s)\n", hfp_connection->line_buffer); break; default: break; } break; } - hfp_parser_next_state(context, byte); + hfp_parser_next_state(hfp_connection, byte); - if (context->resolve_byte && context->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ - context->resolve_byte = 0; - context->ignore_value = 1; - parse_sequence(context); - context->line_buffer[0] = 0; - context->line_size = 0; + if (hfp_connection->resolve_byte && hfp_connection->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ + hfp_connection->resolve_byte = 0; + hfp_connection->ignore_value = 1; + parse_sequence(hfp_connection); + hfp_connection->line_buffer[0] = 0; + hfp_connection->line_size = 0; } } -static void parse_sequence(hfp_connection_t * context){ +static void parse_sequence(hfp_connection_t * hfp_connection){ int value; - switch (context->command){ + switch (hfp_connection->command){ case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS: - value = atoi((char *)&context->line_buffer[0]); + value = atoi((char *)&hfp_connection->line_buffer[0]); int i; - switch (context->parser_item_index){ + switch (hfp_connection->parser_item_index){ case 0: - for (i=0;igeneric_status_indicators_nr;i++){ - if (context->generic_status_indicators[i].uuid == value){ - context->parser_indicator_index = i; + for (i=0;igeneric_status_indicators_nr;i++){ + if (hfp_connection->generic_status_indicators[i].uuid == value){ + hfp_connection->parser_indicator_index = i; break; } } break; case 1: - if (context->parser_indicator_index <0) break; - context->generic_status_indicators[context->parser_indicator_index].state = value; + if (hfp_connection->parser_indicator_index <0) break; + hfp_connection->generic_status_indicators[hfp_connection->parser_indicator_index].state = value; log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n", - context->parser_item_index, value); + hfp_connection->parser_item_index, value); break; default: break; } - context->parser_item_index++; + hfp_connection->parser_item_index++; break; case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: - switch(context->parser_item_index){ + switch(hfp_connection->parser_item_index){ case 0: - strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); - context->bnip_number[sizeof(context->bnip_number)-1] = 0; + strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); + hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; break; case 1: - value = atoi((char *)&context->line_buffer[0]); - context->bnip_type = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->bnip_type = value; break; default: break; } - context->parser_item_index++; + hfp_connection->parser_item_index++; break; case HFP_CMD_LIST_CURRENT_CALLS: - switch(context->parser_item_index){ + switch(hfp_connection->parser_item_index){ case 0: - value = atoi((char *)&context->line_buffer[0]); - context->clcc_idx = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->clcc_idx = value; break; case 1: - value = atoi((char *)&context->line_buffer[0]); - context->clcc_dir = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->clcc_dir = value; break; case 2: - value = atoi((char *)&context->line_buffer[0]); - context->clcc_status = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->clcc_status = value; break; case 3: - value = atoi((char *)&context->line_buffer[0]); - context->clcc_mpty = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->clcc_mpty = value; break; case 4: - strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); - context->bnip_number[sizeof(context->bnip_number)-1] = 0; + strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); + hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; break; case 5: - value = atoi((char *)&context->line_buffer[0]); - context->bnip_type = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->bnip_type = value; break; default: break; } - context->parser_item_index++; + hfp_connection->parser_item_index++; break; case HFP_CMD_SET_MICROPHONE_GAIN: - value = atoi((char *)&context->line_buffer[0]); - context->microphone_gain = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->microphone_gain = value; log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value); break; case HFP_CMD_SET_SPEAKER_GAIN: - value = atoi((char *)&context->line_buffer[0]); - context->speaker_gain = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->speaker_gain = value; log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value); break; case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: - value = atoi((char *)&context->line_buffer[0]); - context->ag_activate_voice_recognition = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->ag_activate_voice_recognition = value; log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value); break; case HFP_CMD_TURN_OFF_EC_AND_NR: - value = atoi((char *)&context->line_buffer[0]); - context->ag_echo_and_noise_reduction = value; + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->ag_echo_and_noise_reduction = value; log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value); break; case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: - value = atoi((char *)&context->line_buffer[0]); - context->remote_supported_features = store_bit(context->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value); + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->remote_supported_features = store_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value); log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value); break; case HFP_CMD_HF_CONFIRMED_CODEC: - context->codec_confirmed = atoi((char*)context->line_buffer); - log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", context->codec_confirmed); + hfp_connection->codec_confirmed = atoi((char*)hfp_connection->line_buffer); + log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", hfp_connection->codec_confirmed); break; case HFP_CMD_AG_SUGGESTED_CODEC: - context->suggested_codec = atoi((char*)context->line_buffer); - log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", context->suggested_codec); + hfp_connection->suggested_codec = atoi((char*)hfp_connection->line_buffer); + log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", hfp_connection->suggested_codec); break; case HFP_CMD_SUPPORTED_FEATURES: - context->remote_supported_features = atoi((char*)context->line_buffer); - log_info("Parsed supported feature %d\n", context->remote_supported_features); + hfp_connection->remote_supported_features = atoi((char*)hfp_connection->line_buffer); + log_info("Parsed supported feature %d\n", hfp_connection->remote_supported_features); break; case HFP_CMD_AVAILABLE_CODECS: - log_info("Parsed codec %s\n", context->line_buffer); - context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer); - context->parser_item_index++; - context->remote_codecs_nr = context->parser_item_index; + log_info("Parsed codec %s\n", hfp_connection->line_buffer); + hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint16_t)atoi((char*)hfp_connection->line_buffer); + hfp_connection->parser_item_index++; + hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index; break; case HFP_CMD_RETRIEVE_AG_INDICATORS: - strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); - context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; - log_info("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); + strcpy((char *)hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, (char *)hfp_connection->line_buffer); + hfp_connection->ag_indicators[hfp_connection->parser_item_index].index = hfp_connection->parser_item_index+1; + log_info("Indicator %d: %s (", hfp_connection->ag_indicators_nr+1, hfp_connection->line_buffer); break; case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: - log_info("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer); - context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer); - context->parser_item_index++; + log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer); + hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = atoi((char *) hfp_connection->line_buffer); + hfp_connection->parser_item_index++; break; case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: - context->parser_item_index++; - if (context->parser_item_index != 4) break; - log_info("Parsed Enable indicators: %s\n", context->line_buffer); - value = atoi((char *)&context->line_buffer[0]); - context->enable_status_update_for_ag_indicators = (uint8_t) value; + hfp_connection->parser_item_index++; + if (hfp_connection->parser_item_index != 4) break; + log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer); + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->enable_status_update_for_ag_indicators = (uint8_t) value; break; case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: - log_info("Parsed Support call hold: %s\n", context->line_buffer); - if (context->line_size > 2 ) break; - strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name, (char *)context->line_buffer); - context->remote_call_services_nr++; + log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer); + if (hfp_connection->line_size > 2 ) break; + strcpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_nr].name, (char *)hfp_connection->line_buffer); + hfp_connection->remote_call_services_nr++; break; case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: - log_info("Parsed Generic status indicator: %s\n", context->line_buffer); - context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer); - context->parser_item_index++; - context->generic_status_indicators_nr = context->parser_item_index; + log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer); + hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)atoi((char*)hfp_connection->line_buffer); + hfp_connection->parser_item_index++; + hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index; break; case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: // HF parses inital AG gen. ind. state - log_info("Parsed List generic status indicator %s state: ", context->line_buffer); - context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer); + log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer); + hfp_connection->parser_item_index = (uint8_t)atoi((char*)hfp_connection->line_buffer); break; case HFP_CMD_HF_INDICATOR_STATUS: - context->parser_indicator_index = (uint8_t)atoi((char*)context->line_buffer); - log_info("Parsed HF indicator index %u", context->parser_indicator_index); + hfp_connection->parser_indicator_index = (uint8_t)atoi((char*)hfp_connection->line_buffer); + log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index); break; case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: // AG parses new gen. ind. state - if (context->ignore_value){ - context->ignore_value = 0; - log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", context->parser_item_index, - context->ag_indicators[context->parser_item_index].name, context->ag_indicators[context->parser_item_index].enabled); + if (hfp_connection->ignore_value){ + hfp_connection->ignore_value = 0; + log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", hfp_connection->parser_item_index, + hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled); } - else if (context->ag_indicators[context->parser_item_index].mandatory){ + else if (hfp_connection->ag_indicators[hfp_connection->parser_item_index].mandatory){ log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n", - context->parser_item_index, context->ag_indicators[context->parser_item_index].name); + hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name); } else { - value = atoi((char *)&context->line_buffer[0]); - context->ag_indicators[context->parser_item_index].enabled = value; - log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", context->parser_item_index, - context->ag_indicators[context->parser_item_index].name, value); + value = atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled = value; + log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index, + hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value); } - context->parser_item_index++; + hfp_connection->parser_item_index++; break; case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: // indicators are indexed starting with 1 - context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1; - log_info("Parsed status of the AG indicator %d, status ", context->parser_item_index); + hfp_connection->parser_item_index = atoi((char *)&hfp_connection->line_buffer[0]) - 1; + log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index); break; case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: - context->network_operator.mode = atoi((char *)&context->line_buffer[0]); - log_info("Parsed network operator mode: %d, ", context->network_operator.mode); + hfp_connection->network_operator.mode = atoi((char *)&hfp_connection->line_buffer[0]); + log_info("Parsed network operator mode: %d, ", hfp_connection->network_operator.mode); break; case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: - if (context->line_buffer[0] == '3'){ - log_info("Parsed Set network operator format : %s, ", context->line_buffer); + if (hfp_connection->line_buffer[0] == '3'){ + log_info("Parsed Set network operator format : %s, ", hfp_connection->line_buffer); break; } // TODO emit ERROR, wrong format - log_info("ERROR Set network operator format: index %s not supported\n", context->line_buffer); + log_info("ERROR Set network operator format: index %s not supported\n", hfp_connection->line_buffer); break; case HFP_CMD_ERROR: break; case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: - context->extended_audio_gateway_error = 1; - context->extended_audio_gateway_error_value = (uint8_t)atoi((char*)context->line_buffer); + hfp_connection->extended_audio_gateway_error = 1; + hfp_connection->extended_audio_gateway_error_value = (uint8_t)atoi((char*)hfp_connection->line_buffer); break; case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: - context->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)context->line_buffer); - context->ok_pending = 1; - context->extended_audio_gateway_error = 0; + hfp_connection->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)hfp_connection->line_buffer); + hfp_connection->ok_pending = 1; + hfp_connection->extended_audio_gateway_error = 0; break; case HFP_CMD_AG_SENT_PHONE_NUMBER: - strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); - context->bnip_number[sizeof(context->bnip_number)-1] = 0; + case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: + case HFP_CMD_AG_SENT_CLIP_INFORMATION: + strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); + hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; break; default: break; @@ -1282,64 +1281,64 @@ void hfp_init(uint16_t rfcomm_channel_nr){ } void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){ - hfp_connection_t * context = provide_hfp_connection_context_for_bd_addr(bd_addr); - log_info("hfp_connect %s, context %p", bd_addr_to_str(bd_addr), context); + hfp_connection_t * hfp_connection = provide_hfp_connection_context_for_bd_addr(bd_addr); + log_info("hfp_connect %s, hfp_connection %p", bd_addr_to_str(bd_addr), hfp_connection); - if (!context) { + if (!hfp_connection) { log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr)); return; } - switch (context->state){ + switch (hfp_connection->state){ case HFP_W2_DISCONNECT_RFCOMM: - context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; + hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; return; case HFP_W4_RFCOMM_DISCONNECTED: - context->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; + hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; return; case HFP_IDLE: - memcpy(context->remote_addr, bd_addr, 6); - context->state = HFP_W4_SDP_QUERY_COMPLETE; - connection_doing_sdp_query = context; - context->service_uuid = service_uuid; - sdp_query_rfcomm_channel_and_name_for_uuid(context->remote_addr, service_uuid); + memcpy(hfp_connection->remote_addr, bd_addr, 6); + hfp_connection->state = HFP_W4_SDP_QUERY_COMPLETE; + connection_doing_sdp_query = hfp_connection; + hfp_connection->service_uuid = service_uuid; + sdp_query_rfcomm_channel_and_name_for_uuid(hfp_connection->remote_addr, service_uuid); break; default: break; } } -void hfp_release_service_level_connection(hfp_connection_t * context){ - if (!context) return; - hfp_release_audio_connection(context); +void hfp_release_service_level_connection(hfp_connection_t * hfp_connection){ + if (!hfp_connection) return; + hfp_release_audio_connection(hfp_connection); - if (context->state < HFP_W4_RFCOMM_CONNECTED){ - context->state = HFP_IDLE; + if (hfp_connection->state < HFP_W4_RFCOMM_CONNECTED){ + hfp_connection->state = HFP_IDLE; return; } - if (context->state == HFP_W4_RFCOMM_CONNECTED){ - context->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN; + if (hfp_connection->state == HFP_W4_RFCOMM_CONNECTED){ + hfp_connection->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN; return; } - if (context->state < HFP_W4_SCO_CONNECTED){ - context->state = HFP_W2_DISCONNECT_RFCOMM; + if (hfp_connection->state < HFP_W4_SCO_CONNECTED){ + hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; return; } - if (context->state < HFP_W4_SCO_DISCONNECTED){ - context->state = HFP_W2_DISCONNECT_SCO; + if (hfp_connection->state < HFP_W4_SCO_DISCONNECTED){ + hfp_connection->state = HFP_W2_DISCONNECT_SCO; return; } return; } -void hfp_release_audio_connection(hfp_connection_t * context){ - if (!context) return; - if (context->state >= HFP_W2_DISCONNECT_SCO) return; - context->release_audio_connection = 1; +void hfp_release_audio_connection(hfp_connection_t * hfp_connection){ + if (!hfp_connection) return; + if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return; + hfp_connection->release_audio_connection = 1; } static const struct link_settings { diff --git a/src/hfp.h b/src/hfp.h index 48b44efd3..00aa04614 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -159,7 +159,9 @@ typedef enum { HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, HFP_CMD_ENABLE_CLIP, + HFP_CMD_AG_SENT_CLIP_INFORMATION, HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION, + HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE, HFP_CMD_LIST_GENERIC_STATUS_INDICATORS, HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS, @@ -604,7 +606,7 @@ typedef struct hfp_connection { uint8_t clcc_mpty; uint8_t call_index; - // also used for CLCC if set + // also used for CLCC, CCWA, CLIP if set uint8_t bnip_type; // 0 == not set char bnip_number[25]; // @@ -621,25 +623,22 @@ int store_bit(uint32_t bitmap, int position, uint8_t value); void hfp_create_sdp_record(uint8_t * service, uint16_t service_uuid, int rfcomm_channel_nr, const char * name); void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t *packet, uint16_t size); void hfp_emit_event(hfp_callback_t callback, uint8_t event_subtype, uint8_t value); +void hfp_emit_simple_event(hfp_callback_t callback, uint8_t event_subtype); void hfp_emit_string_event(hfp_callback_t callback, uint8_t event_subtype, const char * value); hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid); hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr); hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle); -int get_hfp_generic_status_indicators_nr(void); -hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(void); -void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr); - linked_list_t * hfp_get_connections(void); -void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree); +void hfp_parse(hfp_connection_t * connection, uint8_t byte, int isHandsFree); void hfp_init(uint16_t rfcomm_channel_nr); void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid); void hfp_release_service_level_connection(hfp_connection_t * connection); -void hfp_reset_context_flags(hfp_connection_t * context); +void hfp_reset_context_flags(hfp_connection_t * connection); -void hfp_release_audio_connection(hfp_connection_t * context); +void hfp_release_audio_connection(hfp_connection_t * connection); void hfp_setup_synchronous_connection(hci_con_handle_t handle, hfp_link_setttings_t link_settings); diff --git a/src/hfp_ag.c b/src/hfp_ag.c index 249868801..be72e3b9d 100644 --- a/src/hfp_ag.c +++ b/src/hfp_ag.c @@ -72,6 +72,9 @@ static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS]; static int hfp_ag_indicators_nr = 0; static hfp_ag_indicator_t hfp_ag_indicators[HFP_MAX_NUM_AG_INDICATORS]; +static int hfp_generic_status_indicators_nr = 0; +static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_HF_INDICATORS]; + static int hfp_ag_call_hold_services_nr = 0; static char *hfp_ag_call_hold_services[6]; static hfp_callback_t hfp_callback; @@ -83,25 +86,27 @@ static int hfp_ag_response_and_hold_active = 0; static hfp_phone_number_t * subscriber_numbers = NULL; static int subscriber_numbers_count = 0; -static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -static void hfp_run_for_context(hfp_connection_t *context); -static void hfp_ag_setup_audio_connection(hfp_connection_t * connection); -static void hfp_ag_hf_start_ringing(hfp_connection_t * context); +static void packet_handler(void * hfp_connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); +static void hfp_run_for_context(hfp_connection_t *hfp_connection); +static void hfp_ag_setup_audio_connection(hfp_connection_t * hfp_connection); +static void hfp_ag_hf_start_ringing(hfp_connection_t * hfp_connection); -hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(); -int get_hfp_generic_status_indicators_nr(); -void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr); -void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr); -int get_hfp_ag_indicators_nr(hfp_connection_t * context); -hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context); -hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context){ - // TODO: save only value, and value changed in the context? - if (context->ag_indicators_nr != hfp_ag_indicators_nr){ - context->ag_indicators_nr = hfp_ag_indicators_nr; - memcpy(context->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); +static int hfp_ag_get_ag_indicators_nr(hfp_connection_t * hfp_connection){ + if (hfp_connection->ag_indicators_nr != hfp_ag_indicators_nr){ + hfp_connection->ag_indicators_nr = hfp_ag_indicators_nr; + memcpy(hfp_connection->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); } - return (hfp_ag_indicator_t *)&(context->ag_indicators); + return hfp_connection->ag_indicators_nr; +} + +hfp_ag_indicator_t * hfp_ag_get_ag_indicators(hfp_connection_t * hfp_connection){ + // TODO: save only value, and value changed in the hfp_connection? + if (hfp_connection->ag_indicators_nr != hfp_ag_indicators_nr){ + hfp_connection->ag_indicators_nr = hfp_ag_indicators_nr; + memcpy(hfp_connection->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); + } + return (hfp_ag_indicator_t *)&(hfp_connection->ag_indicators); } static hfp_ag_indicator_t * get_ag_indicator_for_name(const char * name){ @@ -124,19 +129,6 @@ static int get_ag_indicator_index_for_name(const char * name){ return -1; } -void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr){ - memcpy(hfp_ag_indicators, indicators, indicator_nr * sizeof(hfp_ag_indicator_t)); - hfp_ag_indicators_nr = indicator_nr; -} - -int get_hfp_ag_indicators_nr(hfp_connection_t * context){ - if (context->ag_indicators_nr != hfp_ag_indicators_nr){ - context->ag_indicators_nr = hfp_ag_indicators_nr; - memcpy(context->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); - } - return context->ag_indicators_nr; -} - void hfp_ag_register_packet_handler(hfp_callback_t callback){ if (callback == NULL){ @@ -150,20 +142,20 @@ static int use_in_band_tone(){ return get_bit(hfp_supported_features, HFP_AGSF_IN_BAND_RING_TONE); } -static int has_codec_negotiation_feature(hfp_connection_t * connection){ - int hf = get_bit(connection->remote_supported_features, HFP_HFSF_CODEC_NEGOTIATION); +static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){ + int hf = get_bit(hfp_connection->remote_supported_features, HFP_HFSF_CODEC_NEGOTIATION); int ag = get_bit(hfp_supported_features, HFP_AGSF_CODEC_NEGOTIATION); return hf && ag; } -static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * connection){ - int hf = get_bit(connection->remote_supported_features, HFP_HFSF_THREE_WAY_CALLING); +static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * hfp_connection){ + int hf = get_bit(hfp_connection->remote_supported_features, HFP_HFSF_THREE_WAY_CALLING); int ag = get_bit(hfp_supported_features, HFP_AGSF_THREE_WAY_CALLING); return hf && ag; } -static int has_hf_indicators_feature(hfp_connection_t * connection){ - int hf = get_bit(connection->remote_supported_features, HFP_HFSF_HF_INDICATORS); +static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){ + int hf = get_bit(hfp_connection->remote_supported_features, HFP_HFSF_HF_INDICATORS); int ag = get_bit(hfp_supported_features, HFP_AGSF_HF_INDICATORS); return hf && ag; } @@ -258,38 +250,38 @@ static int string_len_for_uint32(uint32_t i){ } // get size for indicator string -static int hfp_ag_indicators_string_size(hfp_connection_t * context, int i){ +static int hfp_ag_indicators_string_size(hfp_connection_t * hfp_connection, int i){ // template: ("$NAME",($MIN,$MAX)) - return 8 + strlen(get_hfp_ag_indicators(context)[i].name) - + string_len_for_uint32(get_hfp_ag_indicators(context)[i].min_range) - + string_len_for_uint32(get_hfp_ag_indicators(context)[i].min_range); + return 8 + strlen(hfp_ag_get_ag_indicators(hfp_connection)[i].name) + + string_len_for_uint32(hfp_ag_get_ag_indicators(hfp_connection)[i].min_range) + + string_len_for_uint32(hfp_ag_get_ag_indicators(hfp_connection)[i].min_range); } // store indicator -static void hfp_ag_indicators_string_store(hfp_connection_t * context, int i, uint8_t * buffer){ +static void hfp_ag_indicators_string_store(hfp_connection_t * hfp_connection, int i, uint8_t * buffer){ sprintf((char *) buffer, "(\"%s\",(%d,%d)),", - get_hfp_ag_indicators(context)[i].name, - get_hfp_ag_indicators(context)[i].min_range, - get_hfp_ag_indicators(context)[i].max_range); + hfp_ag_get_ag_indicators(hfp_connection)[i].name, + hfp_ag_get_ag_indicators(hfp_connection)[i].min_range, + hfp_ag_get_ag_indicators(hfp_connection)[i].max_range); } // structure: header [indicator [comma indicator]] footer -static int hfp_ag_indicators_cmd_generator_num_segments(hfp_connection_t * context){ - int num_indicators = get_hfp_ag_indicators_nr(context); +static int hfp_ag_indicators_cmd_generator_num_segments(hfp_connection_t * hfp_connection){ + int num_indicators = hfp_ag_get_ag_indicators_nr(hfp_connection); if (!num_indicators) return 2; return 3 + (num_indicators-1) * 2; } // get size of individual segment for hfp_ag_retrieve_indicators_cmd -static int hfp_ag_indicators_cmd_generator_get_segment_len(hfp_connection_t * context, int index){ +static int hfp_ag_indicators_cmd_generator_get_segment_len(hfp_connection_t * hfp_connection, int index){ if (index == 0) { return strlen(HFP_INDICATOR) + 3; // "\n\r%s:"" } index--; - int num_indicators = get_hfp_ag_indicators_nr(context); + int num_indicators = hfp_ag_get_ag_indicators_nr(hfp_connection); int indicator_index = index >> 1; if ((index & 1) == 0){ - return hfp_ag_indicators_string_size(context, indicator_index); + return hfp_ag_indicators_string_size(hfp_connection, indicator_index); } if (indicator_index == num_indicators - 1){ return 8; // "\r\n\r\nOK\r\n" @@ -297,7 +289,7 @@ static int hfp_ag_indicators_cmd_generator_get_segment_len(hfp_connection_t * co return 1; // comma } -static void hgp_ag_indicators_cmd_generator_store_segment(hfp_connection_t * context, int index, uint8_t * buffer){ +static void hgp_ag_indicators_cmd_generator_store_segment(hfp_connection_t * hfp_connection, int index, uint8_t * buffer){ if (index == 0){ *buffer++ = '\r'; *buffer++ = '\n'; @@ -308,10 +300,10 @@ static void hgp_ag_indicators_cmd_generator_store_segment(hfp_connection_t * con return; } index--; - int num_indicators = get_hfp_ag_indicators_nr(context); + int num_indicators = hfp_ag_get_ag_indicators_nr(hfp_connection); int indicator_index = index >> 1; if ((index & 1) == 0){ - hfp_ag_indicators_string_store(context, indicator_index, buffer); + hfp_ag_indicators_string_store(hfp_connection, indicator_index, buffer); return; } if (indicator_index == num_indicators-1){ @@ -325,21 +317,21 @@ static int hfp_hf_indicators_join(char * buffer, int buffer_size){ if (buffer_size < hfp_ag_indicators_nr * 3) return 0; int i; int offset = 0; - for (i = 0; i < get_hfp_generic_status_indicators_nr()-1; i++) { - offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_hfp_generic_status_indicators()[i].uuid); + for (i = 0; i < hfp_generic_status_indicators_nr-1; i++) { + offset += snprintf(buffer+offset, buffer_size-offset, "%d,", hfp_generic_status_indicators[i].uuid); } - if (i < get_hfp_generic_status_indicators_nr()){ - offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_hfp_generic_status_indicators()[i].uuid); + if (i < hfp_generic_status_indicators_nr){ + offset += snprintf(buffer+offset, buffer_size-offset, "%d,", hfp_generic_status_indicators[i].uuid); } return offset; } static int hfp_hf_indicators_initial_status_join(char * buffer, int buffer_size){ - if (buffer_size < get_hfp_generic_status_indicators_nr() * 3) return 0; + if (buffer_size < hfp_generic_status_indicators_nr * 3) return 0; int i; int offset = 0; - for (i = 0; i < get_hfp_generic_status_indicators_nr(); i++) { - offset += snprintf(buffer+offset, buffer_size-offset, "\r\n%s:%d,%d\r\n", HFP_GENERIC_STATUS_INDICATOR, get_hfp_generic_status_indicators()[i].uuid, get_hfp_generic_status_indicators()[i].state); + for (i = 0; i < hfp_generic_status_indicators_nr; i++) { + offset += snprintf(buffer+offset, buffer_size-offset, "\r\n%s:%d,%d\r\n", HFP_GENERIC_STATUS_INDICATOR, hfp_generic_status_indicators[i].uuid, hfp_generic_status_indicators[i].state); } return offset; } @@ -370,10 +362,10 @@ static int hfp_ag_call_services_join(char * buffer, int buffer_size){ return offset; } -static int hfp_ag_cmd_via_generator(uint16_t cid, hfp_connection_t * context, +static int hfp_ag_cmd_via_generator(uint16_t cid, hfp_connection_t * hfp_connection, int start_segment, int num_segments, - int (*get_segment_len)(hfp_connection_t * context, int segment), - void (*store_segment) (hfp_connection_t * context, int segment, uint8_t * buffer)){ + int (*get_segment_len)(hfp_connection_t * hfp_connection, int segment), + void (*store_segment) (hfp_connection_t * hfp_connection, int segment, uint8_t * buffer)){ // assumes: can send now == true // assumes: num segments > 0 @@ -383,9 +375,9 @@ static int hfp_ag_cmd_via_generator(uint16_t cid, hfp_connection_t * context, int offset = 0; int segment = start_segment; while (segment < num_segments){ - int segment_len = get_segment_len(context, segment); + int segment_len = get_segment_len(hfp_connection, segment); if (offset + segment_len <= mtu){ - store_segment(context, segment, data+offset); + store_segment(hfp_connection, segment, data+offset); offset += segment_len; segment++; } @@ -395,9 +387,9 @@ static int hfp_ag_cmd_via_generator(uint16_t cid, hfp_connection_t * context, } // returns next segment to store -static int hfp_ag_retrieve_indicators_cmd_via_generator(uint16_t cid, hfp_connection_t * context, int start_segment){ - int num_segments = hfp_ag_indicators_cmd_generator_num_segments(context); - return hfp_ag_cmd_via_generator(cid, context, start_segment, num_segments, +static int hfp_ag_retrieve_indicators_cmd_via_generator(uint16_t cid, hfp_connection_t * hfp_connection, int start_segment){ + int num_segments = hfp_ag_indicators_cmd_generator_num_segments(hfp_connection); + return hfp_ag_cmd_via_generator(cid, hfp_connection, start_segment, num_segments, hfp_ag_indicators_cmd_generator_get_segment_len, hgp_ag_indicators_cmd_generator_store_segment); } @@ -506,13 +498,13 @@ static int hfp_ag_set_response_and_hold(uint16_t cid, int state){ } -static uint8_t hfp_ag_suggest_codec(hfp_connection_t *context){ +static uint8_t hfp_ag_suggest_codec(hfp_connection_t *hfp_connection){ int i,j; uint8_t codec = HFP_CODEC_CVSD; for (i = 0; i < hfp_codecs_nr; i++){ - for (j = 0; j < context->remote_codecs_nr; j++){ - if (context->remote_codecs[j] == hfp_codecs[i]){ - codec = context->remote_codecs[j]; + for (j = 0; j < hfp_connection->remote_codecs_nr; j++){ + if (hfp_connection->remote_codecs[j] == hfp_codecs[i]){ + codec = hfp_connection->remote_codecs[j]; continue; } } @@ -520,7 +512,7 @@ static uint8_t hfp_ag_suggest_codec(hfp_connection_t *context){ return codec; } -static int codecs_exchange_state_machine(hfp_connection_t * context){ +static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){ /* events ( == commands): HFP_CMD_AVAILABLE_CODECS == received AT+BAC with list of codecs HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP: @@ -529,12 +521,12 @@ static int codecs_exchange_state_machine(hfp_connection_t * context){ HFP_CMD_HF_CONFIRMED_CODEC == received AT+BCS */ - switch (context->codecs_state){ + switch (hfp_connection->codecs_state){ case HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE: - context->command = HFP_CMD_AG_SEND_COMMON_CODEC; + hfp_connection->command = HFP_CMD_AG_SEND_COMMON_CODEC; break; case HFP_CODECS_AG_RESEND_COMMON_CODEC: - context->command = HFP_CMD_AG_SEND_COMMON_CODEC; + hfp_connection->command = HFP_CMD_AG_SEND_COMMON_CODEC; break; default: break; @@ -542,50 +534,50 @@ static int codecs_exchange_state_machine(hfp_connection_t * context){ // printf(" -> State machine: CC\n"); - switch (context->command){ + switch (hfp_connection->command){ case HFP_CMD_AVAILABLE_CODECS: //printf("HFP_CODECS_RECEIVED_LIST \n"); - if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){ - context->codecs_state = HFP_CODECS_RECEIVED_LIST; - hfp_ag_ok(context->rfcomm_cid); + if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){ + hfp_connection->codecs_state = HFP_CODECS_RECEIVED_LIST; + hfp_ag_ok(hfp_connection->rfcomm_cid); return 1; } - switch (context->codecs_state){ + switch (hfp_connection->codecs_state){ case HFP_CODECS_AG_SENT_COMMON_CODEC: case HFP_CODECS_EXCHANGED: - context->codecs_state = HFP_CODECS_AG_RESEND_COMMON_CODEC; + hfp_connection->codecs_state = HFP_CODECS_AG_RESEND_COMMON_CODEC; break; default: break; } - hfp_ag_ok(context->rfcomm_cid); + hfp_ag_ok(hfp_connection->rfcomm_cid); return 1; case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP: //printf(" HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP \n"); - context->codecs_state = HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE; - hfp_ag_ok(context->rfcomm_cid); + hfp_connection->codecs_state = HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE; + hfp_ag_ok(hfp_connection->rfcomm_cid); return 1; case HFP_CMD_AG_SEND_COMMON_CODEC: //printf(" HFP_CMD_AG_SEND_COMMON_CODEC \n"); - context->codecs_state = HFP_CODECS_AG_SENT_COMMON_CODEC; - context->suggested_codec = hfp_ag_suggest_codec(context); - hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec); + hfp_connection->codecs_state = HFP_CODECS_AG_SENT_COMMON_CODEC; + hfp_connection->suggested_codec = hfp_ag_suggest_codec(hfp_connection); + hfp_ag_cmd_suggest_codec(hfp_connection->rfcomm_cid, hfp_connection->suggested_codec); return 1; case HFP_CMD_HF_CONFIRMED_CODEC: //printf("HFP_CMD_HF_CONFIRMED_CODEC \n"); - if (context->codec_confirmed != context->suggested_codec){ - context->codecs_state = HFP_CODECS_ERROR; - hfp_ag_error(context->rfcomm_cid); + if (hfp_connection->codec_confirmed != hfp_connection->suggested_codec){ + hfp_connection->codecs_state = HFP_CODECS_ERROR; + hfp_ag_error(hfp_connection->rfcomm_cid); return 1; } - context->negotiated_codec = context->codec_confirmed; - context->codecs_state = HFP_CODECS_EXCHANGED; + hfp_connection->negotiated_codec = hfp_connection->codec_confirmed; + hfp_connection->codecs_state = HFP_CODECS_EXCHANGED; hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0); - hfp_ag_ok(context->rfcomm_cid); + hfp_ag_ok(hfp_connection->rfcomm_cid); return 1; default: break; @@ -593,125 +585,125 @@ static int codecs_exchange_state_machine(hfp_connection_t * context){ return 0; } -static void hfp_init_link_settings(hfp_connection_t * context){ +static void hfp_init_link_settings(hfp_connection_t * hfp_connection){ // determine highest possible link setting - context->link_setting = HFP_LINK_SETTINGS_D1; - if (hci_remote_eSCO_supported(context->con_handle)){ - context->link_setting = HFP_LINK_SETTINGS_S3; - if ((context->remote_supported_features & (1<link_setting = HFP_LINK_SETTINGS_D1; + if (hci_remote_eSCO_supported(hfp_connection->con_handle)){ + hfp_connection->link_setting = HFP_LINK_SETTINGS_S3; + if ((hfp_connection->remote_supported_features & (1<link_setting = HFP_LINK_SETTINGS_S4; + hfp_connection->link_setting = HFP_LINK_SETTINGS_S4; } } } -static void hfp_ag_slc_established(hfp_connection_t * context){ - context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; +static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){ + hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0); - hfp_init_link_settings(context); + hfp_init_link_settings(hfp_connection); - // if active call exist, set per-connection state active, too (when audio is on) + // if active call exist, set per-hfp_connection state active, too (when audio is on) if (hfp_gsm_call_status() == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - context->call_state = HFP_CALL_W4_AUDIO_CONNECTION_FOR_ACTIVE; + hfp_connection->call_state = HFP_CALL_W4_AUDIO_CONNECTION_FOR_ACTIVE; } // if AG is ringing, also start ringing on the HF if (hfp_gsm_call_status() == HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS && hfp_gsm_callsetup_status() == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ - hfp_ag_hf_start_ringing(context); + hfp_ag_hf_start_ringing(hfp_connection); } } -static int hfp_ag_run_for_context_service_level_connection(hfp_connection_t * context){ - if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; +static int hfp_ag_run_for_context_service_level_connection(hfp_connection_t * hfp_connection){ + if (hfp_connection->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; int done = 0; // printf(" -> State machine: SLC\n"); - switch(context->command){ + switch(hfp_connection->command){ case HFP_CMD_SUPPORTED_FEATURES: - switch(context->state){ + switch(hfp_connection->state){ case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: case HFP_EXCHANGE_SUPPORTED_FEATURES: - if (has_codec_negotiation_feature(context)){ - context->state = HFP_W4_NOTIFY_ON_CODECS; + if (has_codec_negotiation_feature(hfp_connection)){ + hfp_connection->state = HFP_W4_NOTIFY_ON_CODECS; } else { - context->state = HFP_W4_RETRIEVE_INDICATORS; + hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS; } - hfp_ag_exchange_supported_features_cmd(context->rfcomm_cid); + hfp_ag_exchange_supported_features_cmd(hfp_connection->rfcomm_cid); return 1; default: break; } break; case HFP_CMD_AVAILABLE_CODECS: - done = codecs_exchange_state_machine(context); + done = codecs_exchange_state_machine(hfp_connection); - if (context->codecs_state == HFP_CODECS_RECEIVED_LIST){ - context->state = HFP_W4_RETRIEVE_INDICATORS; + if (hfp_connection->codecs_state == HFP_CODECS_RECEIVED_LIST){ + hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS; } return done; case HFP_CMD_RETRIEVE_AG_INDICATORS: - if (context->state == HFP_W4_RETRIEVE_INDICATORS) { - context->command = HFP_CMD_NONE; // prevent reentrance - int next_segment = hfp_ag_retrieve_indicators_cmd_via_generator(context->rfcomm_cid, context, context->send_ag_indicators_segment); - if (next_segment < hfp_ag_indicators_cmd_generator_num_segments(context)){ + if (hfp_connection->state == HFP_W4_RETRIEVE_INDICATORS) { + hfp_connection->command = HFP_CMD_NONE; // prevent reentrance + int next_segment = hfp_ag_retrieve_indicators_cmd_via_generator(hfp_connection->rfcomm_cid, hfp_connection, hfp_connection->send_ag_indicators_segment); + if (next_segment < hfp_ag_indicators_cmd_generator_num_segments(hfp_connection)){ // prepare sending of next segment - context->send_ag_indicators_segment = next_segment; - context->command = HFP_CMD_RETRIEVE_AG_INDICATORS; + hfp_connection->send_ag_indicators_segment = next_segment; + hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS; } else { // done, go to next state - context->send_ag_indicators_segment = 0; - context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS; + hfp_connection->send_ag_indicators_segment = 0; + hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS_STATUS; } return 1; } break; case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: - if (context->state != HFP_W4_RETRIEVE_INDICATORS_STATUS) break; - context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE; - hfp_ag_retrieve_indicators_status_cmd(context->rfcomm_cid); + if (hfp_connection->state != HFP_W4_RETRIEVE_INDICATORS_STATUS) break; + hfp_connection->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE; + hfp_ag_retrieve_indicators_status_cmd(hfp_connection->rfcomm_cid); return 1; case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: - if (context->state != HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE) break; - if (has_call_waiting_and_3way_calling_feature(context)){ - context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL; - } else if (has_hf_indicators_feature(context)){ - context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; + if (hfp_connection->state != HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE) break; + if (has_call_waiting_and_3way_calling_feature(hfp_connection)){ + hfp_connection->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL; + } else if (has_hf_indicators_feature(hfp_connection)){ + hfp_connection->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; } else { - hfp_ag_slc_established(context); + hfp_ag_slc_established(hfp_connection); } - hfp_ag_set_indicator_status_update_cmd(context->rfcomm_cid, 1); + hfp_ag_set_indicator_status_update_cmd(hfp_connection->rfcomm_cid, 1); return 1; case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: - if (context->state != HFP_W4_RETRIEVE_CAN_HOLD_CALL) break; - if (has_hf_indicators_feature(context)){ - context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; + if (hfp_connection->state != HFP_W4_RETRIEVE_CAN_HOLD_CALL) break; + if (has_hf_indicators_feature(hfp_connection)){ + hfp_connection->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; } - hfp_ag_retrieve_can_hold_call_cmd(context->rfcomm_cid); - if (!has_hf_indicators_feature(context)){ - hfp_ag_slc_established(context); + hfp_ag_retrieve_can_hold_call_cmd(hfp_connection->rfcomm_cid); + if (!has_hf_indicators_feature(hfp_connection)){ + hfp_ag_slc_established(hfp_connection); } return 1; case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: - if (context->state != HFP_W4_LIST_GENERIC_STATUS_INDICATORS) break; - context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; - hfp_ag_list_supported_generic_status_indicators_cmd(context->rfcomm_cid); + if (hfp_connection->state != HFP_W4_LIST_GENERIC_STATUS_INDICATORS) break; + hfp_connection->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; + hfp_ag_list_supported_generic_status_indicators_cmd(hfp_connection->rfcomm_cid); return 1; case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: - if (context->state != HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS) break; - context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; - hfp_ag_retrieve_supported_generic_status_indicators_cmd(context->rfcomm_cid); + if (hfp_connection->state != HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS) break; + hfp_connection->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; + hfp_ag_retrieve_supported_generic_status_indicators_cmd(hfp_connection->rfcomm_cid); return 1; case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: - if (context->state != HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS) break; - hfp_ag_slc_established(context); - hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(context->rfcomm_cid); + if (hfp_connection->state != HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS) break; + hfp_ag_slc_established(hfp_connection); + hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(hfp_connection->rfcomm_cid); return 1; default: break; @@ -719,51 +711,51 @@ static int hfp_ag_run_for_context_service_level_connection(hfp_connection_t * co return done; } -static int hfp_ag_run_for_context_service_level_connection_queries(hfp_connection_t * context){ - // if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; +static int hfp_ag_run_for_context_service_level_connection_queries(hfp_connection_t * hfp_connection){ + // if (hfp_connection->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; - int done = codecs_exchange_state_machine(context); + int done = codecs_exchange_state_machine(hfp_connection); if (done) return done; // printf(" -> State machine: SLC Queries\n"); - switch(context->command){ + switch(hfp_connection->command){ case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION: - hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION, context->ag_activate_voice_recognition); - hfp_ag_activate_voice_recognition_cmd(context->rfcomm_cid, context->ag_activate_voice_recognition); + hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION, hfp_connection->ag_activate_voice_recognition); + hfp_ag_activate_voice_recognition_cmd(hfp_connection->rfcomm_cid, hfp_connection->ag_activate_voice_recognition); return 1; case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: if (get_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION)){ - hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION, context->ag_activate_voice_recognition); - hfp_ag_ok(context->rfcomm_cid); - hfp_ag_setup_audio_connection(context); + hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION, hfp_connection->ag_activate_voice_recognition); + hfp_ag_ok(hfp_connection->rfcomm_cid); + hfp_ag_setup_audio_connection(hfp_connection); } else { - hfp_ag_error(context->rfcomm_cid); + hfp_ag_error(hfp_connection->rfcomm_cid); } return 1; case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: - hfp_ag_change_in_band_ring_tone_setting_cmd(context->rfcomm_cid); + hfp_ag_change_in_band_ring_tone_setting_cmd(hfp_connection->rfcomm_cid); return 1; case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: - hfp_ag_report_network_operator_name_cmd(context->rfcomm_cid, context->network_operator); + hfp_ag_report_network_operator_name_cmd(hfp_connection->rfcomm_cid, hfp_connection->network_operator); return 1; case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: - if (context->network_operator.format != 0){ - hfp_ag_error(context->rfcomm_cid); + if (hfp_connection->network_operator.format != 0){ + hfp_ag_error(hfp_connection->rfcomm_cid); } else { - hfp_ag_ok(context->rfcomm_cid); + hfp_ag_ok(hfp_connection->rfcomm_cid); } return 1; case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: - hfp_ag_ok(context->rfcomm_cid); + hfp_ag_ok(hfp_connection->rfcomm_cid); return 1; case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: - if (context->extended_audio_gateway_error){ - context->extended_audio_gateway_error = 0; - hfp_ag_report_extended_audio_gateway_error(context->rfcomm_cid, context->extended_audio_gateway_error_value); + if (hfp_connection->extended_audio_gateway_error){ + hfp_connection->extended_audio_gateway_error = 0; + hfp_ag_report_extended_audio_gateway_error(hfp_connection->rfcomm_cid, hfp_connection->extended_audio_gateway_error_value); return 1; } case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: - hfp_ag_ok(context->rfcomm_cid); + hfp_ag_ok(hfp_connection->rfcomm_cid); return 1; default: break; @@ -771,30 +763,30 @@ static int hfp_ag_run_for_context_service_level_connection_queries(hfp_connectio return 0; } -static int hfp_ag_run_for_audio_connection(hfp_connection_t * context){ - if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || - context->state > HFP_W2_DISCONNECT_SCO) return 0; +static int hfp_ag_run_for_audio_connection(hfp_connection_t * hfp_connection){ + if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || + hfp_connection->state > HFP_W2_DISCONNECT_SCO) return 0; - if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED && context->release_audio_connection){ - context->state = HFP_W4_SCO_DISCONNECTED; - context->release_audio_connection = 0; - gap_disconnect(context->sco_handle); + if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED && hfp_connection->release_audio_connection){ + hfp_connection->state = HFP_W4_SCO_DISCONNECTED; + hfp_connection->release_audio_connection = 0; + gap_disconnect(hfp_connection->sco_handle); return 1; } - if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; + if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; // run codecs exchange - int done = codecs_exchange_state_machine(context); + int done = codecs_exchange_state_machine(hfp_connection); if (done) return done; - // printf(" -> State machine: Audio Connection\n"); + // printf(" -> State machine: Audio hfp_connection\n"); - if (context->codecs_state != HFP_CODECS_EXCHANGED) return done; - if (context->establish_audio_connection){ - context->state = HFP_W4_SCO_CONNECTED; - context->establish_audio_connection = 0; - hfp_setup_synchronous_connection(context->con_handle, context->link_setting); + if (hfp_connection->codecs_state != HFP_CODECS_EXCHANGED) return done; + if (hfp_connection->establish_audio_connection){ + hfp_connection->state = HFP_W4_SCO_CONNECTED; + hfp_connection->establish_audio_connection = 0; + hfp_setup_synchronous_connection(hfp_connection->con_handle, hfp_connection->link_setting); return 1; } return 0; @@ -805,62 +797,62 @@ static hfp_connection_t * hfp_ag_context_for_timer(timer_source_t * ts){ linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if ( &connection->hfp_timeout == ts) { - return connection; + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if ( &hfp_connection->hfp_timeout == ts) { + return hfp_connection; } } return NULL; } static void hfp_timeout_handler(timer_source_t * timer){ - hfp_connection_t * context = hfp_ag_context_for_timer(timer); - if (!context) return; + hfp_connection_t * hfp_connection = hfp_ag_context_for_timer(timer); + if (!hfp_connection) return; - log_info("HFP start ring timeout, con handle 0x%02x", context->con_handle); - context->ag_ring = 1; - context->ag_send_clip = hfp_gsm_clip_type() && context->clip_enabled; + log_info("HFP start ring timeout, con handle 0x%02x", hfp_connection->con_handle); + hfp_connection->ag_ring = 1; + hfp_connection->ag_send_clip = hfp_gsm_clip_type() && hfp_connection->clip_enabled; - run_loop_set_timer(&context->hfp_timeout, 2000); // 5 seconds timeout - run_loop_add_timer(&context->hfp_timeout); + run_loop_set_timer(&hfp_connection->hfp_timeout, 2000); // 5 seconds timeout + run_loop_add_timer(&hfp_connection->hfp_timeout); - hfp_run_for_context(context); + hfp_run_for_context(hfp_connection); } -static void hfp_timeout_start(hfp_connection_t * context){ - run_loop_remove_timer(&context->hfp_timeout); - run_loop_set_timer_handler(&context->hfp_timeout, hfp_timeout_handler); - run_loop_set_timer(&context->hfp_timeout, 2000); // 5 seconds timeout - run_loop_add_timer(&context->hfp_timeout); +static void hfp_timeout_start(hfp_connection_t * hfp_connection){ + run_loop_remove_timer(&hfp_connection->hfp_timeout); + run_loop_set_timer_handler(&hfp_connection->hfp_timeout, hfp_timeout_handler); + run_loop_set_timer(&hfp_connection->hfp_timeout, 2000); // 5 seconds timeout + run_loop_add_timer(&hfp_connection->hfp_timeout); } -static void hfp_timeout_stop(hfp_connection_t * context){ - log_info("HFP stop ring timeout, con handle 0x%02x", context->con_handle); - run_loop_remove_timer(&context->hfp_timeout); +static void hfp_timeout_stop(hfp_connection_t * hfp_connection){ + log_info("HFP stop ring timeout, con handle 0x%02x", hfp_connection->con_handle); + run_loop_remove_timer(&hfp_connection->hfp_timeout); } // // transitition implementations for hfp_ag_call_state_machine // -static void hfp_ag_hf_start_ringing(hfp_connection_t * context){ +static void hfp_ag_hf_start_ringing(hfp_connection_t * hfp_connection){ if (use_in_band_tone()){ - context->call_state = HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING; - hfp_ag_establish_audio_connection(context->remote_addr); + hfp_connection->call_state = HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING; + hfp_ag_establish_audio_connection(hfp_connection->remote_addr); } else { - hfp_timeout_start(context); - context->ag_ring = 1; - context->ag_send_clip = hfp_gsm_clip_type() && context->clip_enabled; - context->call_state = HFP_CALL_RINGING; - hfp_emit_event(hfp_callback, HFP_SUBEVENT_START_RINGINIG, 0); + hfp_timeout_start(hfp_connection); + hfp_connection->ag_ring = 1; + hfp_connection->ag_send_clip = hfp_gsm_clip_type() && hfp_connection->clip_enabled; + hfp_connection->call_state = HFP_CALL_RINGING; + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_START_RINGINIG); } } -static void hfp_ag_hf_stop_ringing(hfp_connection_t * context){ - context->ag_ring = 0; - context->ag_send_clip = 0; - hfp_timeout_stop(context); - hfp_emit_event(hfp_callback, HFP_SUBEVENT_STOP_RINGINIG, 0); +static void hfp_ag_hf_stop_ringing(hfp_connection_t * hfp_connection){ + hfp_connection->ag_ring = 0; + hfp_connection->ag_send_clip = 0; + hfp_timeout_stop(hfp_connection); + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_STOP_RINGINIG); } static void hfp_ag_trigger_incoming_call(void){ @@ -870,16 +862,16 @@ static void hfp_ag_trigger_incoming_call(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - hfp_ag_establish_service_level_connection(connection->remote_addr); - if (connection->call_state == HFP_CALL_IDLE){ - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, indicator_index, 1); - hfp_ag_hf_start_ringing(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_ag_establish_service_level_connection(hfp_connection->remote_addr); + if (hfp_connection->call_state == HFP_CALL_IDLE){ + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1); + hfp_ag_hf_start_ringing(hfp_connection); } - if (connection->call_state == HFP_CALL_ACTIVE){ - connection->call_state = HFP_CALL_W2_SEND_CALL_WAITING; + if (hfp_connection->call_state == HFP_CALL_ACTIVE){ + hfp_connection->call_state = HFP_CALL_W2_SEND_CALL_WAITING; } - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); } } @@ -890,10 +882,10 @@ static void hfp_ag_transfer_callsetup_state(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - hfp_ag_establish_service_level_connection(connection->remote_addr); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, indicator_index, 1); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_ag_establish_service_level_connection(hfp_connection->remote_addr); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1); + hfp_run_for_context(hfp_connection); } } @@ -904,10 +896,10 @@ static void hfp_ag_transfer_call_state(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - hfp_ag_establish_service_level_connection(connection->remote_addr); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, indicator_index, 1); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_ag_establish_service_level_connection(hfp_connection->remote_addr); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1); + hfp_run_for_context(hfp_connection); } } @@ -918,10 +910,10 @@ static void hfp_ag_transfer_callheld_state(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - hfp_ag_establish_service_level_connection(connection->remote_addr); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, indicator_index, 1); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_ag_establish_service_level_connection(hfp_connection->remote_addr); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1); + hfp_run_for_context(hfp_connection); } } @@ -933,28 +925,28 @@ static void hfp_ag_hf_accept_call(hfp_connection_t * source){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (connection->call_state != HFP_CALL_RINGING && - connection->call_state != HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING) continue; + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (hfp_connection->call_state != HFP_CALL_RINGING && + hfp_connection->call_state != HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING) continue; - hfp_ag_hf_stop_ringing(connection); - if (connection == source){ - connection->ok_pending = 1; + hfp_ag_hf_stop_ringing(hfp_connection); + if (hfp_connection == source){ + hfp_connection->ok_pending = 1; if (use_in_band_tone()){ - connection->call_state = HFP_CALL_ACTIVE; + hfp_connection->call_state = HFP_CALL_ACTIVE; } else { - connection->call_state = HFP_CALL_W4_AUDIO_CONNECTION_FOR_ACTIVE; - hfp_ag_establish_audio_connection(connection->remote_addr); + hfp_connection->call_state = HFP_CALL_W4_AUDIO_CONNECTION_FOR_ACTIVE; + hfp_ag_establish_audio_connection(hfp_connection->remote_addr); } - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); } else { - connection->call_state = HFP_CALL_IDLE; + hfp_connection->call_state = HFP_CALL_IDLE; } - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); } } @@ -966,16 +958,16 @@ static void hfp_ag_ag_accept_call(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (connection->call_state != HFP_CALL_RINGING) continue; + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (hfp_connection->call_state != HFP_CALL_RINGING) continue; - hfp_ag_hf_stop_ringing(connection); - connection->call_state = HFP_CALL_TRIGGER_AUDIO_CONNECTION; + hfp_ag_hf_stop_ringing(hfp_connection); + hfp_connection->call_state = HFP_CALL_TRIGGER_AUDIO_CONNECTION; - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); break; // only single } } @@ -985,13 +977,13 @@ static void hfp_ag_trigger_reject_call(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (connection->call_state != HFP_CALL_RINGING && - connection->call_state != HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING) continue; - hfp_ag_hf_stop_ringing(connection); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); - connection->call_state = HFP_CALL_IDLE; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (hfp_connection->call_state != HFP_CALL_RINGING && + hfp_connection->call_state != HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING) continue; + hfp_ag_hf_stop_ringing(hfp_connection); + 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_IDLE; + hfp_run_for_context(hfp_connection); } } @@ -1001,15 +993,15 @@ static void hfp_ag_trigger_terminate_call(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - hfp_ag_establish_service_level_connection(connection->remote_addr); - if (connection->call_state == HFP_CALL_IDLE) continue; - connection->call_state = HFP_CALL_IDLE; - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); - connection->release_audio_connection = 1; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_ag_establish_service_level_connection(hfp_connection->remote_addr); + if (hfp_connection->call_state == HFP_CALL_IDLE) continue; + hfp_connection->call_state = HFP_CALL_IDLE; + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); + hfp_connection->release_audio_connection = 1; + hfp_run_for_context(hfp_connection); } - hfp_emit_event(hfp_callback, HFP_SUBEVENT_CALL_TERMINATED, 0); + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CALL_TERMINATED); } static void hfp_ag_set_callsetup_indicator(){ @@ -1040,10 +1032,10 @@ static void hfp_ag_stop_ringing(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (connection->call_state != HFP_CALL_RINGING && - connection->call_state != HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING) continue; - hfp_ag_hf_stop_ringing(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (hfp_connection->call_state != HFP_CALL_RINGING && + hfp_connection->call_state != HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING) continue; + hfp_ag_hf_stop_ringing(hfp_connection); } } @@ -1051,8 +1043,8 @@ static hfp_connection_t * hfp_ag_connection_for_call_state(hfp_call_state_t call linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (connection->call_state == call_state) return connection; + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (hfp_connection->call_state == call_state) return hfp_connection; } return NULL; } @@ -1061,42 +1053,42 @@ static void hfp_ag_send_response_and_hold_state(hfp_response_and_hold_state_t st linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - connection->send_response_and_hold_status = state + 1; + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_connection->send_response_and_hold_status = state + 1; } } -static int call_setup_state_machine(hfp_connection_t * connection){ +static int call_setup_state_machine(hfp_connection_t * hfp_connection){ int indicator_index; - switch (connection->call_state){ + switch (hfp_connection->call_state){ case HFP_CALL_W4_AUDIO_CONNECTION_FOR_IN_BAND_RING: - if (connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; - // we got event: audio connection established - hfp_timeout_start(connection); - connection->ag_ring = 1; - connection->ag_send_clip = hfp_gsm_clip_type() && connection->clip_enabled; - connection->call_state = HFP_CALL_RINGING; - connection->call_state = HFP_CALL_RINGING; - hfp_emit_event(hfp_callback, HFP_SUBEVENT_START_RINGINIG, 0); + if (hfp_connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; + // we got event: audio hfp_connection established + hfp_timeout_start(hfp_connection); + hfp_connection->ag_ring = 1; + hfp_connection->ag_send_clip = hfp_gsm_clip_type() && hfp_connection->clip_enabled; + hfp_connection->call_state = HFP_CALL_RINGING; + hfp_connection->call_state = HFP_CALL_RINGING; + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_START_RINGINIG); break; case HFP_CALL_W4_AUDIO_CONNECTION_FOR_ACTIVE: - if (connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; - // we got event: audio connection established - connection->call_state = HFP_CALL_ACTIVE; + if (hfp_connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; + // we got event: audio hfp_connection established + hfp_connection->call_state = HFP_CALL_ACTIVE; break; case HFP_CALL_W2_SEND_CALL_WAITING: - connection->call_state = HFP_CALL_W4_CHLD; - hfp_ag_send_call_waiting_notification(connection->rfcomm_cid); + hfp_connection->call_state = HFP_CALL_W4_CHLD; + hfp_ag_send_call_waiting_notification(hfp_connection->rfcomm_cid); indicator_index = get_ag_indicator_index_for_name("callsetup"); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, indicator_index, 1); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1); break; default: break; } return 0; } -// connection is used to identify originating HF -static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connection){ +// hfp_connection is used to identify originating HF +static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_connection){ int indicator_index; int callsetup_indicator_index = get_ag_indicator_index_for_name("callsetup"); int callheld_indicator_index = get_ag_indicator_index_for_name("callheld"); @@ -1173,7 +1165,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect hfp_gsm_handle_event(HFP_AG_HELD_CALL_JOINED_BY_AG); hfp_ag_set_callheld_indicator(); hfp_ag_transfer_callheld_state(); - hfp_emit_event(hfp_callback, HFP_SUBEVENT_CONFERENCE_CALL, 0); + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CONFERENCE_CALL); break; default: break; @@ -1192,9 +1184,9 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect hfp_gsm_handle_event(HFP_AG_INCOMING_CALL_ACCEPTED_BY_HF); hfp_ag_set_callsetup_indicator(); hfp_ag_set_call_indicator(); - hfp_ag_hf_accept_call(connection); + hfp_ag_hf_accept_call(hfp_connection); printf("HF answers call, accept call by GSM\n"); - hfp_emit_event(hfp_callback, HFP_CMD_CALL_ANSWERED, 0); + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CALL_ANSWERED); break; default: break; @@ -1241,7 +1233,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect // as with regualr call hfp_ag_set_call_indicator(); hfp_ag_set_callsetup_indicator(); - hfp_ag_hf_accept_call(connection); + hfp_ag_hf_accept_call(hfp_connection); printf("AG response and hold - hold by HF\n"); break; default: @@ -1302,7 +1294,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect hfp_gsm_handle_event(HFP_AG_TERMINATE_CALL_BY_HF); hfp_ag_set_call_indicator(); hfp_ag_transfer_call_state(); - connection->call_state = HFP_CALL_IDLE; + hfp_connection->call_state = HFP_CALL_IDLE; printf("AG terminate call\n"); break; } @@ -1372,27 +1364,27 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect case HFP_AG_OUTGOING_CALL_INITIATED: // directly reject call if number of free slots is exceeded if (!hfp_gsm_call_possible()){ - connection->send_error = 1; - hfp_run_for_context(connection); + hfp_connection->send_error = 1; + hfp_run_for_context(hfp_connection); break; } - hfp_gsm_handle_event_with_call_number(HFP_AG_OUTGOING_CALL_INITIATED, (const char *) &connection->line_buffer[3]); + hfp_gsm_handle_event_with_call_number(HFP_AG_OUTGOING_CALL_INITIATED, (const char *) &hfp_connection->line_buffer[3]); - connection->call_state = HFP_CALL_OUTGOING_INITIATED; + hfp_connection->call_state = HFP_CALL_OUTGOING_INITIATED; - hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER, (const char *) &connection->line_buffer[3]); + hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER, (const char *) &hfp_connection->line_buffer[3]); break; case HFP_AG_OUTGOING_REDIAL_INITIATED:{ // directly reject call if number of free slots is exceeded if (!hfp_gsm_call_possible()){ - connection->send_error = 1; - hfp_run_for_context(connection); + hfp_connection->send_error = 1; + hfp_run_for_context(hfp_connection); break; } hfp_gsm_handle_event(HFP_AG_OUTGOING_REDIAL_INITIATED); - connection->call_state = HFP_CALL_OUTGOING_INITIATED; + hfp_connection->call_state = HFP_CALL_OUTGOING_INITIATED; printf("\nRedial last number"); char * last_dialed_number = hfp_gsm_last_dialed_number(); @@ -1407,27 +1399,27 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect break; } case HFP_AG_OUTGOING_CALL_REJECTED: - connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_INITIATED); - if (!connection){ - log_info("hfp_ag_call_sm: did not find outgoing connection in initiated state"); + hfp_connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_INITIATED); + if (!hfp_connection){ + log_info("hfp_ag_call_sm: did not find outgoing hfp_connection in initiated state"); break; } hfp_gsm_handle_event(HFP_AG_OUTGOING_CALL_REJECTED); - connection->call_state = HFP_CALL_IDLE; - connection->send_error = 1; - hfp_run_for_context(connection); + hfp_connection->call_state = HFP_CALL_IDLE; + hfp_connection->send_error = 1; + hfp_run_for_context(hfp_connection); break; case HFP_AG_OUTGOING_CALL_ACCEPTED:{ - connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_INITIATED); - if (!connection){ - log_info("hfp_ag_call_sm: did not find outgoing connection in initiated state"); + hfp_connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_INITIATED); + if (!hfp_connection){ + log_info("hfp_ag_call_sm: did not find outgoing hfp_connection in initiated state"); break; } - connection->ok_pending = 1; - connection->call_state = HFP_CALL_OUTGOING_DIALING; + hfp_connection->ok_pending = 1; + hfp_connection->call_state = HFP_CALL_OUTGOING_DIALING; // trigger callsetup to be int put_call_on_hold = hfp_gsm_call_status() == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT; @@ -1435,47 +1427,47 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect hfp_ag_set_callsetup_indicator(); indicator_index = get_ag_indicator_index_for_name("callsetup"); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, indicator_index, 1); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1); // put current call on hold if active if (put_call_on_hold){ printf("AG putting current call on hold for new outgoing call\n"); hfp_ag_set_callheld_indicator(); indicator_index = get_ag_indicator_index_for_name("callheld"); - hfp_ag_transfer_ag_indicators_status_cmd(connection->rfcomm_cid, &hfp_ag_indicators[indicator_index]); + hfp_ag_transfer_ag_indicators_status_cmd(hfp_connection->rfcomm_cid, &hfp_ag_indicators[indicator_index]); } // start audio if needed - hfp_ag_establish_audio_connection(connection->remote_addr); + hfp_ag_establish_audio_connection(hfp_connection->remote_addr); break; } case HFP_AG_OUTGOING_CALL_RINGING: - connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_DIALING); - if (!connection){ - log_info("hfp_ag_call_sm: did not find outgoing connection in dialing state"); + hfp_connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_DIALING); + if (!hfp_connection){ + log_info("hfp_ag_call_sm: did not find outgoing hfp_connection in dialing state"); break; } hfp_gsm_handle_event(HFP_AG_OUTGOING_CALL_RINGING); - connection->call_state = HFP_CALL_OUTGOING_RINGING; + hfp_connection->call_state = HFP_CALL_OUTGOING_RINGING; hfp_ag_set_callsetup_indicator(); hfp_ag_transfer_callsetup_state(); break; case HFP_AG_OUTGOING_CALL_ESTABLISHED:{ // get outgoing call - connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_RINGING); - if (!connection){ - connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_DIALING); + hfp_connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_RINGING); + if (!hfp_connection){ + hfp_connection = hfp_ag_connection_for_call_state(HFP_CALL_OUTGOING_DIALING); } - if (!connection){ - log_info("hfp_ag_call_sm: did not find outgoing connection"); + if (!hfp_connection){ + log_info("hfp_ag_call_sm: did not find outgoing hfp_connection"); break; } int CALLHELD_STATUS_CALL_ON_HOLD_AND_NO_ACTIVE_CALLS = hfp_gsm_callheld_status() == HFP_CALLHELD_STATUS_CALL_ON_HOLD_AND_NO_ACTIVE_CALLS; hfp_gsm_handle_event(HFP_AG_OUTGOING_CALL_ESTABLISHED); - connection->call_state = HFP_CALL_ACTIVE; + hfp_connection->call_state = HFP_CALL_ACTIVE; hfp_ag_set_callsetup_indicator(); hfp_ag_set_call_indicator(); hfp_ag_transfer_call_state(); @@ -1490,8 +1482,8 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect case HFP_AG_CALL_HOLD_USER_BUSY: hfp_gsm_handle_event(HFP_AG_CALL_HOLD_USER_BUSY); hfp_ag_set_callsetup_indicator(); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); - connection->call_state = HFP_CALL_ACTIVE; + 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"); break; @@ -1501,23 +1493,23 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect // Releases all active calls (if any exist) and accepts the other (held or waiting) call. if (call_held || call_setup_in_progress){ - hfp_gsm_handle_event_with_call_index(HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, connection->call_index); + hfp_gsm_handle_event_with_call_index(HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, hfp_connection->call_index); } if (call_setup_in_progress){ printf("AG: Call Dropped, Accept new call\n"); hfp_ag_set_callsetup_indicator(); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); + 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"); } if (call_held){ hfp_ag_set_callheld_indicator(); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); } - connection->call_state = HFP_CALL_ACTIVE; + hfp_connection->call_state = HFP_CALL_ACTIVE; break; } @@ -1525,20 +1517,20 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect // Places all active calls (if any exist) on hold and accepts the other (held or waiting) call. // only update if callsetup changed int call_setup_in_progress = hfp_gsm_callsetup_status() != HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS; - hfp_gsm_handle_event_with_call_index(HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, connection->call_index); + 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"); hfp_ag_set_callsetup_indicator(); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callsetup_indicator_index, 1); + 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"); } hfp_ag_set_callheld_indicator(); // hfp_ag_set_callheld_state(HFP_CALLHELD_STATUS_CALL_ON_HOLD_OR_SWAPPED); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); - connection->call_state = HFP_CALL_ACTIVE; + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); + hfp_connection->call_state = HFP_CALL_ACTIVE; break; } @@ -1548,10 +1540,10 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect printf("AG: Join 3-way-call\n"); hfp_gsm_handle_event(HFP_AG_CALL_HOLD_ADD_HELD_CALL); hfp_ag_set_callheld_indicator(); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); - hfp_emit_event(hfp_callback, HFP_SUBEVENT_CONFERENCE_CALL, 0); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CONFERENCE_CALL); } - connection->call_state = HFP_CALL_ACTIVE; + hfp_connection->call_state = HFP_CALL_ACTIVE; break; case HFP_AG_CALL_HOLD_EXIT_AND_JOIN_CALLS: // Connects the two calls and disconnects the subscriber from both calls (Explicit Call Transfer) @@ -1559,9 +1551,9 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect printf("AG: Transfer call -> Connect two calls and disconnect\n"); hfp_ag_set_call_indicator(); hfp_ag_set_callheld_indicator(); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); - connection->call_state = HFP_CALL_IDLE; + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, call_indicator_index, 1); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1); + hfp_connection->call_state = HFP_CALL_IDLE; break; default: @@ -1572,7 +1564,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * connect } -static void hfp_ag_send_call_status(hfp_connection_t * connection, int call_index){ +static void hfp_ag_send_call_status(hfp_connection_t * hfp_connection, int call_index){ hfp_gsm_call_t * active_call = hfp_gsm_call(call_index); if (!active_call) return; @@ -1593,158 +1585,158 @@ static void hfp_ag_send_call_status(hfp_connection_t * connection, int call_inde 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, mode, mpty, type, number); - send_str_over_rfcomm(connection->rfcomm_cid, buffer); + send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); } -static void hfp_run_for_context(hfp_connection_t *context){ - if (!context) return; - if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return; +static void hfp_run_for_context(hfp_connection_t *hfp_connection){ + if (!hfp_connection) return; + if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) return; - if (context->send_status_of_current_calls){ - context->ok_pending = 0; - if (context->next_call_index < hfp_gsm_get_number_of_calls()){ - context->next_call_index++; - hfp_ag_send_call_status(context, context->next_call_index); + if (hfp_connection->send_status_of_current_calls){ + hfp_connection->ok_pending = 0; + if (hfp_connection->next_call_index < hfp_gsm_get_number_of_calls()){ + hfp_connection->next_call_index++; + hfp_ag_send_call_status(hfp_connection, hfp_connection->next_call_index); } else { - context->next_call_index = 0; - context->ok_pending = 1; - context->send_status_of_current_calls = 0; + hfp_connection->next_call_index = 0; + hfp_connection->ok_pending = 1; + hfp_connection->send_status_of_current_calls = 0; } return; } - if (context->command == HFP_CMD_UNKNOWN){ - context->ok_pending = 0; - context->send_error = 0; - context->command = HFP_CMD_NONE; - hfp_ag_error(context->rfcomm_cid); + if (hfp_connection->command == HFP_CMD_UNKNOWN){ + hfp_connection->ok_pending = 0; + hfp_connection->send_error = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_error(hfp_connection->rfcomm_cid); return; } - if (context->send_error){ - context->send_error = 0; - context->command = HFP_CMD_NONE; - hfp_ag_error(context->rfcomm_cid); + if (hfp_connection->send_error){ + hfp_connection->send_error = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_error(hfp_connection->rfcomm_cid); return; } // note: before update AG indicators and ok_pending - if (context->send_response_and_hold_status){ - int status = context->send_response_and_hold_status - 1; - context->send_response_and_hold_status = 0; - hfp_ag_set_response_and_hold(context->rfcomm_cid, status); + if (hfp_connection->send_response_and_hold_status){ + int status = hfp_connection->send_response_and_hold_status - 1; + hfp_connection->send_response_and_hold_status = 0; + hfp_ag_set_response_and_hold(hfp_connection->rfcomm_cid, status); return; } - if (context->ok_pending){ - context->ok_pending = 0; - context->command = HFP_CMD_NONE; - hfp_ag_ok(context->rfcomm_cid); + if (hfp_connection->ok_pending){ + hfp_connection->ok_pending = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_ok(hfp_connection->rfcomm_cid); return; } // update AG indicators - if (context->ag_indicators_status_update_bitmap){ + if (hfp_connection->ag_indicators_status_update_bitmap){ int i; - for (i=0;iag_indicators_nr;i++){ - if (get_bit(context->ag_indicators_status_update_bitmap, i)){ - context->ag_indicators_status_update_bitmap = store_bit(context->ag_indicators_status_update_bitmap, i, 0); - if (!context->enable_status_update_for_ag_indicators) { + for (i=0;iag_indicators_nr;i++){ + if (get_bit(hfp_connection->ag_indicators_status_update_bitmap, i)){ + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, i, 0); + if (!hfp_connection->enable_status_update_for_ag_indicators) { log_info("+CMER:3,0,0,0 - not sending update for '%s'", hfp_ag_indicators[i].name); break; } - hfp_ag_transfer_ag_indicators_status_cmd(context->rfcomm_cid, &hfp_ag_indicators[i]); + hfp_ag_transfer_ag_indicators_status_cmd(hfp_connection->rfcomm_cid, &hfp_ag_indicators[i]); return; } } } - if (context->ag_ring){ - context->ag_ring = 0; - context->command = HFP_CMD_NONE; - hfp_ag_ring(context->rfcomm_cid); + if (hfp_connection->ag_ring){ + hfp_connection->ag_ring = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_ring(hfp_connection->rfcomm_cid); return; } - if (context->ag_send_clip){ - context->ag_send_clip = 0; - context->command = HFP_CMD_NONE; - hfp_ag_send_clip(context->rfcomm_cid); + if (hfp_connection->ag_send_clip){ + hfp_connection->ag_send_clip = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_send_clip(hfp_connection->rfcomm_cid); return; } - if (context->send_phone_number_for_voice_tag){ - context->send_phone_number_for_voice_tag = 0; - context->command = HFP_CMD_NONE; - context->ok_pending = 1; - hfp_ag_send_phone_number_for_voice_tag_cmd(context->rfcomm_cid); + if (hfp_connection->send_phone_number_for_voice_tag){ + hfp_connection->send_phone_number_for_voice_tag = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->ok_pending = 1; + hfp_ag_send_phone_number_for_voice_tag_cmd(hfp_connection->rfcomm_cid); return; } - if (context->send_subscriber_number){ - if (context->next_subscriber_number_to_send < subscriber_numbers_count){ - hfp_phone_number_t phone = subscriber_numbers[context->next_subscriber_number_to_send++]; - hfp_send_subscriber_number_cmd(context->rfcomm_cid, phone.type, phone.number); + if (hfp_connection->send_subscriber_number){ + if (hfp_connection->next_subscriber_number_to_send < subscriber_numbers_count){ + hfp_phone_number_t phone = subscriber_numbers[hfp_connection->next_subscriber_number_to_send++]; + hfp_send_subscriber_number_cmd(hfp_connection->rfcomm_cid, phone.type, phone.number); } else { - context->send_subscriber_number = 0; - context->next_subscriber_number_to_send = 0; - hfp_ag_ok(context->rfcomm_cid); + hfp_connection->send_subscriber_number = 0; + hfp_connection->next_subscriber_number_to_send = 0; + hfp_ag_ok(hfp_connection->rfcomm_cid); } - context->command = HFP_CMD_NONE; + hfp_connection->command = HFP_CMD_NONE; } - if (context->send_microphone_gain){ - context->send_microphone_gain = 0; - context->command = HFP_CMD_NONE; - hfp_ag_set_microphone_gain_cmd(context->rfcomm_cid, context->microphone_gain); + if (hfp_connection->send_microphone_gain){ + hfp_connection->send_microphone_gain = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_set_microphone_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->microphone_gain); return; } - if (context->send_speaker_gain){ - context->send_speaker_gain = 0; - context->command = HFP_CMD_NONE; - hfp_ag_set_speaker_gain_cmd(context->rfcomm_cid, context->speaker_gain); + if (hfp_connection->send_speaker_gain){ + hfp_connection->send_speaker_gain = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_set_speaker_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->speaker_gain); return; } - if (context->send_ag_status_indicators){ - context->send_ag_status_indicators = 0; - hfp_ag_retrieve_indicators_status_cmd(context->rfcomm_cid); + if (hfp_connection->send_ag_status_indicators){ + hfp_connection->send_ag_status_indicators = 0; + hfp_ag_retrieve_indicators_status_cmd(hfp_connection->rfcomm_cid); return; } - int done = hfp_ag_run_for_context_service_level_connection(context); + int done = hfp_ag_run_for_context_service_level_connection(hfp_connection); if (!done){ - done = hfp_ag_run_for_context_service_level_connection_queries(context); + done = hfp_ag_run_for_context_service_level_connection_queries(hfp_connection); } if (!done){ - done = call_setup_state_machine(context); + done = call_setup_state_machine(hfp_connection); } if (!done){ - done = hfp_ag_run_for_audio_connection(context); + done = hfp_ag_run_for_audio_connection(hfp_connection); } - if (context->command == HFP_CMD_NONE && !done){ - // log_info("context->command == HFP_CMD_NONE"); - switch(context->state){ + if (hfp_connection->command == HFP_CMD_NONE && !done){ + // log_info("hfp_connection->command == HFP_CMD_NONE"); + switch(hfp_connection->state){ case HFP_W2_DISCONNECT_RFCOMM: - context->state = HFP_W4_RFCOMM_DISCONNECTED; - rfcomm_disconnect_internal(context->rfcomm_cid); + hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED; + rfcomm_disconnect_internal(hfp_connection->rfcomm_cid); break; default: break; } } if (done){ - context->command = HFP_CMD_NONE; + hfp_connection->command = HFP_CMD_NONE; } } static hfp_generic_status_indicator_t *get_hf_indicator_by_number(int number){ int i; - for (i=0;i< get_hfp_generic_status_indicators_nr();i++){ - hfp_generic_status_indicator_t * indicator = &get_hfp_generic_status_indicators()[i]; + for (i=0;i< hfp_generic_status_indicators_nr;i++){ + hfp_generic_status_indicator_t * indicator = &hfp_generic_status_indicators[i]; if (indicator->uuid == number){ return indicator; } @@ -1753,8 +1745,8 @@ static hfp_generic_status_indicator_t *get_hf_indicator_by_number(int number){ } static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ - hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel); - if (!context) return; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_rfcomm_cid(channel); + if (!hfp_connection) return; char last_char = packet[size-1]; packet[size-1] = 0; @@ -1763,55 +1755,55 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_ int pos; for (pos = 0; pos < size ; pos++){ - hfp_parse(context, packet[pos], 0); + hfp_parse(hfp_connection, packet[pos], 0); } hfp_generic_status_indicator_t * indicator; int value; - switch(context->command){ + switch(hfp_connection->command){ case HFP_CMD_RESPONSE_AND_HOLD_QUERY: if (hfp_ag_response_and_hold_active){ - context->send_response_and_hold_status = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD + 1; + hfp_connection->send_response_and_hold_status = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD + 1; } - context->ok_pending = 1; + hfp_connection->ok_pending = 1; break; case HFP_CMD_RESPONSE_AND_HOLD_COMMAND: - value = atoi((char *)&context->line_buffer[0]); + value = atoi((char *)&hfp_connection->line_buffer[0]); printf("HF Response and Hold: %u\n", 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, context); + hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_ACCEPT_INCOMING_CALL_BY_HF, hfp_connection); break; case HFP_RESPONSE_AND_HOLD_HELD_INCOMING_ACCEPTED: - hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_HF, context); + hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_HF, hfp_connection); break; case HFP_RESPONSE_AND_HOLD_HELD_INCOMING_REJECTED: - hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_HF, context); + hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_HF, hfp_connection); break; default: break; } - context->ok_pending = 1; + hfp_connection->ok_pending = 1; break; case HFP_CMD_HF_INDICATOR_STATUS: - context->command = HFP_CMD_NONE; + hfp_connection->command = HFP_CMD_NONE; // find indicator by assigned number - indicator = get_hf_indicator_by_number(context->parser_indicator_index); + indicator = get_hf_indicator_by_number(hfp_connection->parser_indicator_index); if (!indicator){ - context->send_error = 1; + hfp_connection->send_error = 1; break; } - value = atoi((char *)&context->line_buffer[0]); + value = atoi((char *)&hfp_connection->line_buffer[0]); switch (indicator->uuid){ case 1: // enhanced security if (value > 1) { - context->send_error = 1; + hfp_connection->send_error = 1; return; } printf("HF Indicator 'enhanced security' set to %u\n", value); break; case 2: // battery level if (value > 100){ - context->send_error = 1; + hfp_connection->send_error = 1; return; } printf("HF Indicator 'battery' set to %u\n", value); @@ -1820,90 +1812,90 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_ printf("HF Indicator unknown set to %u\n", value); break; } - context->ok_pending = 1; + hfp_connection->ok_pending = 1; break; case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: // expected by SLC state machine - if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) break; - context->send_ag_indicators_segment = 0; - context->send_ag_status_indicators = 1; + if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) break; + hfp_connection->send_ag_indicators_segment = 0; + hfp_connection->send_ag_status_indicators = 1; break; case HFP_CMD_LIST_CURRENT_CALLS: - context->command = HFP_CMD_NONE; - context->next_call_index = 0; - context->send_status_of_current_calls = 1; + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->next_call_index = 0; + hfp_connection->send_status_of_current_calls = 1; break; case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: if (subscriber_numbers_count == 0){ - hfp_ag_ok(context->rfcomm_cid); + hfp_ag_ok(hfp_connection->rfcomm_cid); break; } - context->next_subscriber_number_to_send = 0; - context->send_subscriber_number = 1; + hfp_connection->next_subscriber_number_to_send = 0; + hfp_connection->send_subscriber_number = 1; break; case HFP_CMD_TRANSMIT_DTMF_CODES: - context->command = HFP_CMD_NONE; - hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_TRANSMIT_DTMF_CODES, (const char *) &context->line_buffer[0]); + hfp_connection->command = HFP_CMD_NONE; + hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_TRANSMIT_DTMF_CODES, (const char *) &hfp_connection->line_buffer[0]); break; case HFP_CMD_HF_REQUEST_PHONE_NUMBER: - context->command = HFP_CMD_NONE; - hfp_emit_event(hfp_callback, HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG, 0); + hfp_connection->command = HFP_CMD_NONE; + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG); break; case HFP_CMD_TURN_OFF_EC_AND_NR: - context->command = HFP_CMD_NONE; + hfp_connection->command = HFP_CMD_NONE; if (get_bit(hfp_supported_features, HFP_AGSF_EC_NR_FUNCTION)){ - context->ok_pending = 1; - hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_EC_NR_FUNCTION, context->ag_echo_and_noise_reduction); - printf("AG: EC/NR = %u\n", context->ag_echo_and_noise_reduction); + 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); } else { - context->send_error = 1; + hfp_connection->send_error = 1; } break; case HFP_CMD_CALL_ANSWERED: - context->command = HFP_CMD_NONE; + hfp_connection->command = HFP_CMD_NONE; printf("HFP: ATA\n"); - hfp_ag_call_sm(HFP_AG_INCOMING_CALL_ACCEPTED_BY_HF, context); + hfp_ag_call_sm(HFP_AG_INCOMING_CALL_ACCEPTED_BY_HF, hfp_connection); break; case HFP_CMD_HANG_UP_CALL: - context->command = HFP_CMD_NONE; - context->ok_pending = 1; - hfp_ag_call_sm(HFP_AG_TERMINATE_CALL_BY_HF, context); + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->ok_pending = 1; + hfp_ag_call_sm(HFP_AG_TERMINATE_CALL_BY_HF, hfp_connection); break; case HFP_CMD_CALL_HOLD: { // TODO: fully implement this - log_error("HFP: unhandled call hold type %c", context->line_buffer[0]); - context->command = HFP_CMD_NONE; - context->ok_pending = 1; - context->call_index = 0; + log_error("HFP: unhandled call hold type %c", hfp_connection->line_buffer[0]); + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->ok_pending = 1; + hfp_connection->call_index = 0; - if (context->line_buffer[1] != '\0'){ - context->call_index = atoi((char *)&context->line_buffer[1]); + if (hfp_connection->line_buffer[1] != '\0'){ + hfp_connection->call_index = atoi((char *)&hfp_connection->line_buffer[1]); } - switch (context->line_buffer[0]){ + switch (hfp_connection->line_buffer[0]){ case '0': // Releases all held calls or sets User Determined User Busy (UDUB) for a waiting call. - hfp_ag_call_sm(HFP_AG_CALL_HOLD_USER_BUSY, context); + hfp_ag_call_sm(HFP_AG_CALL_HOLD_USER_BUSY, hfp_connection); break; case '1': // Releases all active calls (if any exist) and accepts the other (held or waiting) call. // Where both a held and a waiting call exist, the above procedures shall apply to the // waiting call (i.e., not to the held call) in conflicting situation. - hfp_ag_call_sm(HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, context); + hfp_ag_call_sm(HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, hfp_connection); break; case '2': // Places all active calls (if any exist) on hold and accepts the other (held or waiting) call. // Where both a held and a waiting call exist, the above procedures shall apply to the // waiting call (i.e., not to the held call) in conflicting situation. - hfp_ag_call_sm(HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, context); + hfp_ag_call_sm(HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, hfp_connection); break; case '3': // Adds a held call to the conversation. - hfp_ag_call_sm(HFP_AG_CALL_HOLD_ADD_HELD_CALL, context); + hfp_ag_call_sm(HFP_AG_CALL_HOLD_ADD_HELD_CALL, hfp_connection); break; case '4': // Connects the two calls and disconnects the subscriber from both calls (Explicit Call Transfer). - hfp_ag_call_sm(HFP_AG_CALL_HOLD_EXIT_AND_JOIN_CALLS, context); + hfp_ag_call_sm(HFP_AG_CALL_HOLD_EXIT_AND_JOIN_CALLS, hfp_connection); break; default: break; @@ -1911,34 +1903,34 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_ break; } case HFP_CMD_CALL_PHONE_NUMBER: - context->command = HFP_CMD_NONE; - hfp_ag_call_sm(HFP_AG_OUTGOING_CALL_INITIATED, context); + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_call_sm(HFP_AG_OUTGOING_CALL_INITIATED, hfp_connection); break; case HFP_CMD_REDIAL_LAST_NUMBER: - context->command = HFP_CMD_NONE; - hfp_ag_call_sm(HFP_AG_OUTGOING_REDIAL_INITIATED, context); + hfp_connection->command = HFP_CMD_NONE; + hfp_ag_call_sm(HFP_AG_OUTGOING_REDIAL_INITIATED, hfp_connection); break; case HFP_CMD_ENABLE_CLIP: - context->command = HFP_CMD_NONE; - context->clip_enabled = context->line_buffer[8] != '0'; - log_info("hfp: clip set, now: %u", context->clip_enabled); - context->ok_pending = 1; + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->clip_enabled = hfp_connection->line_buffer[8] != '0'; + log_info("hfp: clip set, now: %u", hfp_connection->clip_enabled); + hfp_connection->ok_pending = 1; break; case HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION: - context->command = HFP_CMD_NONE; - context->call_waiting_notification_enabled = context->line_buffer[8] != '0'; - log_info("hfp: call waiting notification set, now: %u", context->call_waiting_notification_enabled); - context->ok_pending = 1; + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->call_waiting_notification_enabled = hfp_connection->line_buffer[8] != '0'; + log_info("hfp: call waiting notification set, now: %u", hfp_connection->call_waiting_notification_enabled); + hfp_connection->ok_pending = 1; break; case HFP_CMD_SET_SPEAKER_GAIN: - context->command = HFP_CMD_NONE; - context->ok_pending = 1; - printf("HF speaker gain = %u\n", context->speaker_gain); + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->ok_pending = 1; + printf("HF speaker gain = %u\n", hfp_connection->speaker_gain); break; case HFP_CMD_SET_MICROPHONE_GAIN: - context->command = HFP_CMD_NONE; - context->ok_pending = 1; - printf("HF microphone gain = %u\n", context->microphone_gain); + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->ok_pending = 1; + printf("HF microphone gain = %u\n", hfp_connection->microphone_gain); break; default: break; @@ -1949,12 +1941,12 @@ static void hfp_run(void){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_run_for_context(hfp_connection); } } -static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ +static void packet_handler(void * hfp_connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet_type){ case RFCOMM_DATA_PACKET: hfp_handle_rfcomm_data(packet_type, channel, packet, size); @@ -1969,42 +1961,46 @@ static void packet_handler(void * connection, uint8_t packet_type, uint16_t chan hfp_run(); } -static void hfp_ag_set_ag_indicators(hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr){ - hfp_ag_indicators_nr = ag_indicators_nr; - memcpy(hfp_ag_indicators, ag_indicators, ag_indicators_nr * sizeof(hfp_ag_indicator_t)); -} -void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, - uint8_t * codecs, int codecs_nr, - hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr, - hfp_generic_status_indicator_t * hf_indicators, int hf_indicators_nr, - const char *call_hold_services[], int call_hold_services_nr){ +void hfp_ag_init_codecs(int codecs_nr, uint8_t * codecs){ if (codecs_nr > HFP_MAX_NUM_CODECS){ log_error("hfp_init: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS); return; } - l2cap_init(); - l2cap_register_packet_handler(packet_handler); - - rfcomm_register_packet_handler(packet_handler); - - hfp_init(rfcomm_channel_nr); - - hfp_supported_features = supported_features; - hfp_codecs_nr = codecs_nr; - int i; - for (i=0; i HFP_MAX_NUM_HF_INDICATORS) return; + hfp_generic_status_indicators_nr = hf_indicators_nr; + memcpy(hfp_generic_status_indicators, hf_indicators, hf_indicators_nr * sizeof(hfp_generic_status_indicator_t)); +} + +void hfp_ag_init_call_hold_services(int call_hold_services_nr, const char * call_hold_services[]){ hfp_ag_call_hold_services_nr = call_hold_services_nr; memcpy(hfp_ag_call_hold_services, call_hold_services, call_hold_services_nr * sizeof(char *)); +} + +void hfp_ag_init(uint16_t rfcomm_channel_nr){ + l2cap_init(); + l2cap_register_packet_handler(packet_handler); + rfcomm_register_packet_handler(packet_handler); + hfp_init(rfcomm_channel_nr); + hfp_ag_response_and_hold_active = 0; subscriber_numbers = NULL; subscriber_numbers_count = 0; @@ -2017,42 +2013,42 @@ void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr){ } void hfp_ag_release_service_level_connection(bd_addr_t bd_addr){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - hfp_release_service_level_connection(connection); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_release_service_level_connection(hfp_connection); + hfp_run_for_context(hfp_connection); } void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (!connection){ - log_error("HFP HF: connection doesn't exist."); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (!hfp_connection){ + log_error("HFP HF: hfp_connection doesn't exist."); return; } - connection->extended_audio_gateway_error = 0; - if (!connection->enable_extended_audio_gateway_error_report){ + hfp_connection->extended_audio_gateway_error = 0; + if (!hfp_connection->enable_extended_audio_gateway_error_report){ return; } - connection->extended_audio_gateway_error = error; - hfp_run_for_context(connection); + hfp_connection->extended_audio_gateway_error = error; + hfp_run_for_context(hfp_connection); } -static void hfp_ag_setup_audio_connection(hfp_connection_t * connection){ - if (connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return; - if (connection->state >= HFP_W2_DISCONNECT_SCO) return; +static void hfp_ag_setup_audio_connection(hfp_connection_t * hfp_connection){ + if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return; + if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return; - connection->establish_audio_connection = 1; + hfp_connection->establish_audio_connection = 1; - if (!has_codec_negotiation_feature(connection)){ + if (!has_codec_negotiation_feature(hfp_connection)){ log_info("hfp_ag_establish_audio_connection - no codec negotiation feature, using defaults"); - connection->codecs_state = HFP_CODECS_EXCHANGED; + hfp_connection->codecs_state = HFP_CODECS_EXCHANGED; } - switch (connection->codecs_state){ + switch (hfp_connection->codecs_state){ case HFP_CODECS_IDLE: case HFP_CODECS_RECEIVED_LIST: case HFP_CODECS_AG_RESEND_COMMON_CODEC: case HFP_CODECS_ERROR: - connection->command = HFP_CMD_AG_SEND_COMMON_CODEC; + hfp_connection->command = HFP_CMD_AG_SEND_COMMON_CODEC; break; default: break; @@ -2061,17 +2057,17 @@ static void hfp_ag_setup_audio_connection(hfp_connection_t * connection){ void hfp_ag_establish_audio_connection(bd_addr_t bd_addr){ hfp_ag_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->establish_audio_connection = 0; - hfp_ag_setup_audio_connection(connection); - hfp_run_for_context(connection); + hfp_connection->establish_audio_connection = 0; + hfp_ag_setup_audio_connection(hfp_connection); + hfp_run_for_context(hfp_connection); } void hfp_ag_release_audio_connection(bd_addr_t bd_addr){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - hfp_release_audio_connection(connection); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_release_audio_connection(hfp_connection); + hfp_run_for_context(hfp_connection); } /** @@ -2086,9 +2082,9 @@ void hfp_ag_set_use_in_band_ring_tone(int use_in_band_ring_tone){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - connection->command = HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_connection->command = HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING; + hfp_run_for_context(hfp_connection); } } @@ -2160,53 +2156,38 @@ static void hfp_ag_set_ag_indicator(const char * name, int value){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (!connection->ag_indicators[indicator_index].enabled) { + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (!hfp_connection->ag_indicators[indicator_index].enabled) { log_info("AG indicator '%s' changed to %u but not enabled", hfp_ag_indicators[indicator_index].name, value); continue; } log_info("AG indicator '%s' changed to %u, request transfer statur", hfp_ag_indicators[indicator_index].name, value); - connection->ag_indicators_status_update_bitmap = store_bit(connection->ag_indicators_status_update_bitmap, indicator_index, 1); - hfp_run_for_context(connection); + hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1); + hfp_run_for_context(hfp_connection); } } -/* - * @brief - */ void hfp_ag_set_registration_status(int status){ hfp_ag_set_ag_indicator("service", status); } -/* - * @brief - */ void hfp_ag_set_signal_strength(int strength){ hfp_ag_set_ag_indicator("signal", strength); } -/* - * @brief - */ void hfp_ag_set_roaming_status(int status){ hfp_ag_set_ag_indicator("roam", status); } -/* - * @brief - */ void hfp_ag_set_battery_level(int level){ hfp_ag_set_ag_indicator("battchg", level); } -/* - * @brief - */ void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate){ if (!get_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION)) return; - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (!get_bit(connection->remote_supported_features, HFP_HFSF_VOICE_RECOGNITION_FUNCTION)) { + if (!get_bit(hfp_connection->remote_supported_features, HFP_HFSF_VOICE_RECOGNITION_FUNCTION)) { printf("AG cannot acivate voice recognition - not supported by HF\n"); return; } @@ -2215,53 +2196,44 @@ void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate){ hfp_ag_establish_audio_connection(bd_addr); } - connection->ag_activate_voice_recognition = activate; - connection->command = HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION; - hfp_run_for_context(connection); + hfp_connection->ag_activate_voice_recognition = activate; + hfp_connection->command = HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_ag_set_microphone_gain(bd_addr_t bd_addr, int gain){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (connection->microphone_gain != gain){ - connection->command = HFP_CMD_SET_MICROPHONE_GAIN; - connection->microphone_gain = gain; - connection->send_microphone_gain = 1; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (hfp_connection->microphone_gain != gain){ + hfp_connection->command = HFP_CMD_SET_MICROPHONE_GAIN; + hfp_connection->microphone_gain = gain; + hfp_connection->send_microphone_gain = 1; } - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_ag_set_speaker_gain(bd_addr_t bd_addr, int gain){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (connection->speaker_gain != gain){ - connection->speaker_gain = gain; - connection->send_speaker_gain = 1; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (hfp_connection->speaker_gain != gain){ + hfp_connection->speaker_gain = gain; + hfp_connection->send_speaker_gain = 1; } - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_ag_send_phone_number_for_voice_tag(bd_addr_t bd_addr, const char * number){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); hfp_ag_set_clip(0, number); - connection->send_phone_number_for_voice_tag = 1; + hfp_connection->send_phone_number_for_voice_tag = 1; } void hfp_ag_reject_phone_number_for_voice_tag(bd_addr_t bd_addr){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->send_error = 1; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection->send_error = 1; } void hfp_ag_send_dtmf_code_done(bd_addr_t bd_addr){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->ok_pending = 1; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection->ok_pending = 1; } void hfp_ag_set_subcriber_number_information(hfp_phone_number_t * numbers, int numbers_count){ diff --git a/src/hfp_ag.h b/src/hfp_ag.h index b14982de9..893bf8f5c 100644 --- a/src/hfp_ag.h +++ b/src/hfp_ag.h @@ -60,26 +60,64 @@ typedef struct { /** * @brief Create HFP Audio Gateway (AG) SDP service record. + * @param service + * @param rfcomm_channel_nr + * @param name + * @param ability_to_reject_call + * @param suported_features 32-bit bitmap, see HFP_AGSF_* values in hfp.h */ void hfp_ag_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features);; /** - * @brief Intialize HFP Audio Gateway (AG) device. - * TODO: move optional params into setters + * @brief Set up HFP Audio Gateway (AG) device without additional supported features. + * @param rfcomm_channel_nr */ -void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, - uint8_t * codecs, int codecs_nr, - hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr, - hfp_generic_status_indicator_t * hf_indicators, int hf_indicators_nr, - const char *call_hold_services[], int call_hold_services_nr); +void hfp_ag_init(uint16_t rfcomm_channel_nr); + +/** + * @brief Set codecs. + * @param codecs_nr + * @param codecs + */ +void hfp_ag_init_codecs(int codecs_nr, uint8_t * codecs); + +/** + * @brief Set supported features. + * @param supported_features 32-bit bitmap, see HFP_AGSF_* values in hfp.h + */ +void hfp_ag_init_supported_features(uint32_t supported_features); + +/** + * @brief Set AG indicators. + * @param indicators_nr + * @param indicators + */ +void hfp_ag_init_ag_indicators(int ag_indicators_nr, hfp_ag_indicator_t * ag_indicators); + +/** + * @brief Set HF indicators. + * @param indicators_nr + * @param indicators + */ +void hfp_ag_init_hf_indicators(int hf_indicators_nr, hfp_generic_status_indicator_t * hf_indicators); + +/** + * @brief Set Call Hold services. + * @param indicators_nr + * @param indicators + */ +void hfp_ag_init_call_hold_services(int call_hold_services_nr, const char * call_hold_services[]); + /** * @brief Register callback for the HFP Audio Gateway (AG) client. + * @param callback */ void hfp_ag_register_packet_handler(hfp_callback_t callback); /** - * @brief Enable in-band ring tone + * @brief Enable in-band ring tone. + * @param use_in_band_ring_tone */ void hfp_ag_set_use_in_band_ring_tone(int use_in_band_ring_tone); @@ -94,72 +132,91 @@ void hfp_ag_set_use_in_band_ring_tone(int use_in_band_ring_tone); * - accept the information about available codecs in the Hands-Free (HF), if sent * - report own information describing the call hold and multiparty services, if possible * - report which HF indicators are enabled on the AG, if possible + * The status of SLC connection establishment is reported via + * HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED. + * + * @param bd_addr Bluetooth address of the HF */ void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr); /** * @brief Release the RFCOMM channel and the audio connection between the HF and the AG. - * TODO: trigger release of the audio connection ?? + * If the audio connection exists, it will be released. + * The status of releasing the SLC connection is reported via + * HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED. + * + * @param bd_addr Bluetooth address of the HF */ void hfp_ag_release_service_level_connection(bd_addr_t bd_addr); /** - * @brief + * @brief Establish audio connection. + * The status of Audio connection establishment is reported via is reported via + * HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE. + * @param bd_addr Bluetooth address of the HF */ void hfp_ag_establish_audio_connection(bd_addr_t bd_addr); /** - * @brief + * @brief Release audio connection. + * The status of releasing the Audio connection is reported via is reported via + * HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE. + * @param bd_addr Bluetooth address of the HF */ void hfp_ag_release_audio_connection(bd_addr_t bd_addr); /** - * @brief + * @brief Put the current call on hold, if it exists, and accept incoming call. */ void hfp_ag_answer_incoming_call(void); /** - * @brief + * @brief Join held call with active call. */ void hfp_ag_join_held_call(void); /** - * @brief + * @brief Reject incoming call, if exists, or terminate active call. */ void hfp_ag_terminate_call(void); /* - * @brief + * @brief Put incoming call on hold. */ void hfp_ag_hold_incoming_call(void); /* - * @brief + * @brief Accept the held incoming call. */ void hfp_ag_accept_held_incoming_call(void); /* - * @brief + * @brief Reject the held incoming call. */ void hfp_ag_reject_held_incoming_call(void); /* - * @brief + * @brief Set microphone gain. + * @param bd_addr Bluetooth address of the HF + * @param gain Valid range: [0,15] */ void hfp_ag_set_microphone_gain(bd_addr_t bd_addr, int gain); /* - * @brief + * @brief Set speaker gain. + * @param bd_addr Bluetooth address of the HF + * @param gain Valid range: [0,15] */ void hfp_ag_set_speaker_gain(bd_addr_t bd_addr, int gain); /* - * @brief + * @brief Set battery level. + * @param level Valid range: [0,5] */ void hfp_ag_set_battery_level(int level); /* - * @brief + * @brief Clear last dialed number. */ void hfp_ag_clear_last_dialed_number(void); @@ -167,17 +224,22 @@ void hfp_ag_clear_last_dialed_number(void); // Voice Recognition /* - * @brief + * @brief Activate voice recognition. + * @param bd_addr Bluetooth address of the HF + * @param activate */ void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate); /* * @brief + * @param bd_addr Bluetooth address of the HF + * @param number */ void hfp_ag_send_phone_number_for_voice_tag(bd_addr_t bd_addr, const char * number); /* * @brief + * @param bd_addr Bluetooth address of the HF */ void hfp_ag_reject_phone_number_for_voice_tag(bd_addr_t bd_addr); @@ -191,6 +253,8 @@ void hfp_ag_incoming_call(void); /** * @brief number is stored. + * @param type + * @param number */ void hfp_ag_set_clip(uint8_t type, const char * number); @@ -218,28 +282,35 @@ void hfp_ag_outgoing_call_established(void); * @brief */ void hfp_ag_call_dropped(void); + /* * @brief + * @param status */ void hfp_ag_set_registration_status(int status); /* * @brief + * @param strength */ void hfp_ag_set_signal_strength(int strength); /* * @brief + * @param status */ void hfp_ag_set_roaming_status(int status); /* * @brief + * @param numbers + * @param numbers_count */ void hfp_ag_set_subcriber_number_information(hfp_phone_number_t * numbers, int numbers_count); /* * @brief Called by cellular unit after a DTMF code was transmitted, so that the next one can be emitted + * @param bd_addr Bluetooth address of the HF */ void hfp_ag_send_dtmf_code_done(bd_addr_t bd_addr); @@ -270,6 +341,9 @@ void hfp_ag_send_dtmf_code_done(bd_addr_t bd_addr); * - +CME ERROR: 30 - no network service * - +CME ERROR: 31 - network Timeout. * - +CME ERROR: 32 - network not allowed – Emergency calls only + * + * @param bd_addr Bluetooth address of the HF + * @param error */ void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error); diff --git a/src/hfp_hf.c b/src/hfp_hf.c index fd539444c..52dce3040 100644 --- a/src/hfp_hf.c +++ b/src/hfp_hf.c @@ -91,6 +91,51 @@ void hfp_hf_register_packet_handler(hfp_callback_t callback){ hfp_callback = callback; } +static void hfp_hf_emit_subscriber_information(hfp_callback_t callback, uint8_t event_subtype, uint8_t status, uint8_t bnip_type, const char * bnip_number){ + if (!callback) return; + uint8_t event[31]; + event[0] = HCI_EVENT_HFP_META; + event[1] = sizeof(event) - 2; + event[2] = event_subtype; + event[3] = status; + event[4] = bnip_type; + int size = (strlen(bnip_number) < sizeof(event) - 6) ? strlen(bnip_number) : sizeof(event) - 6; + strncpy((char*)&event[5], bnip_number, size); + event[5 + size] = 0; + (*callback)(event, sizeof(event)); +} + +static void hfp_hf_emit_type_and_number(hfp_callback_t callback, uint8_t event_subtype, uint8_t bnip_type, const char * bnip_number){ + if (!callback) return; + uint8_t event[30]; + event[0] = HCI_EVENT_HFP_META; + event[1] = sizeof(event) - 2; + event[2] = event_subtype; + event[3] = bnip_type; + int size = (strlen(bnip_number) < sizeof(event) - 5) ? strlen(bnip_number) : sizeof(event) - 5; + strncpy((char*)&event[4], bnip_number, size); + event[4 + size] = 0; + (*callback)(event, sizeof(event)); +} + +static void hfp_hf_emit_enhanced_call_status(hfp_callback_t callback, uint8_t clcc_idx, uint8_t clcc_dir, + uint8_t clcc_status, uint8_t clcc_mpty, uint8_t bnip_type, const char * bnip_number){ + if (!callback) return; + uint8_t event[35]; + event[0] = HCI_EVENT_HFP_META; + event[1] = sizeof(event) - 2; + event[2] = HFP_SUBEVENT_ENHANCED_CALL_STATUS; + event[3] = clcc_idx; + event[4] = clcc_dir; + event[6] = clcc_status; + event[7] = clcc_mpty; + event[8] = bnip_type; + int size = (strlen(bnip_number) < sizeof(event) - 10) ? strlen(bnip_number) : sizeof(event) - 10; + strncpy((char*)&event[9], bnip_number, size); + event[9 + size] = 0; + (*callback)(event, sizeof(event)); +} + static int hfp_hf_supports_codec(uint8_t codec){ int i; for (i = 0; i < hfp_codecs_nr; i++){ @@ -98,26 +143,26 @@ static int hfp_hf_supports_codec(uint8_t codec){ } return HFP_CODEC_CVSD; } -static int has_codec_negotiation_feature(hfp_connection_t * connection){ +static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){ int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION); - int ag = get_bit(connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION); + int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION); return hf && ag; } -static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * connection){ +static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * hfp_connection){ int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING); - int ag = get_bit(connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING); + int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING); return hf && ag; } -static int has_hf_indicators_feature(hfp_connection_t * connection){ +static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){ int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS); - int ag = get_bit(connection->remote_supported_features, HFP_AGSF_HF_INDICATORS); + int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_HF_INDICATORS); return hf && ag; } -static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); +static void packet_handler(void * hfp_connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); void hfp_hf_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint32_t supported_features){ if (!name){ @@ -325,17 +370,16 @@ static int hfp_hf_send_clcc(uint16_t cid){ return send_str_over_rfcomm(cid, buffer); } -static void hfp_emit_ag_indicator_event(hfp_callback_t callback, int status, hfp_ag_indicator_t indicator){ +static void hfp_emit_ag_indicator_event(hfp_callback_t callback, hfp_ag_indicator_t indicator){ if (!callback) return; - uint8_t event[6+HFP_MAX_INDICATOR_DESC_SIZE+1]; + uint8_t event[5+HFP_MAX_INDICATOR_DESC_SIZE+1]; event[0] = HCI_EVENT_HFP_META; event[1] = sizeof(event) - 2; event[2] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED; - event[3] = status; - event[4] = indicator.index; - event[5] = indicator.status; - strncpy((char*)&event[6], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE); - event[6+HFP_MAX_INDICATOR_DESC_SIZE] = 0; + event[3] = indicator.index; + event[4] = indicator.status; + strncpy((char*)&event[5], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE); + event[5+HFP_MAX_INDICATOR_DESC_SIZE] = 0; (*callback)(event, sizeof(event)); } @@ -345,53 +389,53 @@ static void hfp_emit_network_operator_event(hfp_callback_t callback, hfp_network event[0] = HCI_EVENT_HFP_META; event[1] = sizeof(event) - 2; event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED; - event[4] = network_operator.mode; - event[5] = network_operator.format; - strcpy((char*)&event[6], network_operator.name); + event[3] = network_operator.mode; + event[4] = network_operator.format; + strcpy((char*)&event[5], network_operator.name); (*callback)(event, sizeof(event)); } -static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * context){ - if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; - if (context->ok_pending) return 0; +static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * hfp_connection){ + if (hfp_connection->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; + if (hfp_connection->ok_pending) return 0; int done = 1; - switch (context->state){ + switch (hfp_connection->state){ case HFP_EXCHANGE_SUPPORTED_FEATURES: - context->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES; - hfp_hf_cmd_exchange_supported_features(context->rfcomm_cid); + hfp_connection->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES; + hfp_hf_cmd_exchange_supported_features(hfp_connection->rfcomm_cid); break; case HFP_NOTIFY_ON_CODECS: - context->state = HFP_W4_NOTIFY_ON_CODECS; - hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); + hfp_connection->state = HFP_W4_NOTIFY_ON_CODECS; + hfp_hf_cmd_notify_on_codecs(hfp_connection->rfcomm_cid); break; case HFP_RETRIEVE_INDICATORS: - context->state = HFP_W4_RETRIEVE_INDICATORS; - hfp_hf_cmd_retrieve_indicators(context->rfcomm_cid); + hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS; + hfp_hf_cmd_retrieve_indicators(hfp_connection->rfcomm_cid); break; case HFP_RETRIEVE_INDICATORS_STATUS: - context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS; - hfp_hf_cmd_retrieve_indicators_status(context->rfcomm_cid); + hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS_STATUS; + hfp_hf_cmd_retrieve_indicators_status(hfp_connection->rfcomm_cid); break; case HFP_ENABLE_INDICATORS_STATUS_UPDATE: - context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE; - hfp_hf_cmd_activate_status_update_for_all_ag_indicators(context->rfcomm_cid, 1); + hfp_connection->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE; + hfp_hf_cmd_activate_status_update_for_all_ag_indicators(hfp_connection->rfcomm_cid, 1); break; case HFP_RETRIEVE_CAN_HOLD_CALL: - context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL; - hfp_hf_cmd_retrieve_can_hold_call(context->rfcomm_cid); + hfp_connection->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL; + hfp_hf_cmd_retrieve_can_hold_call(hfp_connection->rfcomm_cid); break; case HFP_LIST_GENERIC_STATUS_INDICATORS: - context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; - hfp_hf_cmd_list_supported_generic_status_indicators(context->rfcomm_cid); + hfp_connection->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; + hfp_hf_cmd_list_supported_generic_status_indicators(hfp_connection->rfcomm_cid); break; case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS: - context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; - hfp_hf_cmd_retrieve_supported_generic_status_indicators(context->rfcomm_cid); + hfp_connection->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; + hfp_hf_cmd_retrieve_supported_generic_status_indicators(hfp_connection->rfcomm_cid); break; case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: - context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; - hfp_hf_cmd_list_initital_supported_generic_status_indicators(context->rfcomm_cid); + hfp_connection->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; + hfp_hf_cmd_list_initital_supported_generic_status_indicators(hfp_connection->rfcomm_cid); break; default: done = 0; @@ -401,52 +445,52 @@ static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * co } -static int hfp_hf_run_for_context_service_level_connection_queries(hfp_connection_t * context){ - if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; - if (context->ok_pending) return 0; +static int hfp_hf_run_for_context_service_level_connection_queries(hfp_connection_t * hfp_connection){ + if (hfp_connection->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; + if (hfp_connection->ok_pending) return 0; int done = 0; - if (context->enable_status_update_for_ag_indicators != 0xFF){ - context->ok_pending = 1; + if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){ + hfp_connection->ok_pending = 1; done = 1; - hfp_hf_cmd_activate_status_update_for_all_ag_indicators(context->rfcomm_cid, context->enable_status_update_for_ag_indicators); + hfp_hf_cmd_activate_status_update_for_all_ag_indicators(hfp_connection->rfcomm_cid, hfp_connection->enable_status_update_for_ag_indicators); return done; }; - if (context->change_status_update_for_individual_ag_indicators){ - context->ok_pending = 1; + if (hfp_connection->change_status_update_for_individual_ag_indicators){ + hfp_connection->ok_pending = 1; done = 1; - hfp_hf_cmd_activate_status_update_for_ag_indicator(context->rfcomm_cid, - context->ag_indicators_status_update_bitmap, - context->ag_indicators_nr); + hfp_hf_cmd_activate_status_update_for_ag_indicator(hfp_connection->rfcomm_cid, + hfp_connection->ag_indicators_status_update_bitmap, + hfp_connection->ag_indicators_nr); return done; } - switch (context->hf_query_operator_state){ + switch (hfp_connection->hf_query_operator_state){ case HFP_HF_QUERY_OPERATOR_SET_FORMAT: - context->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK; - context->ok_pending = 1; - hfp_hf_cmd_query_operator_name_format(context->rfcomm_cid); + hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK; + hfp_connection->ok_pending = 1; + hfp_hf_cmd_query_operator_name_format(hfp_connection->rfcomm_cid); return 1; case HFP_HF_QUERY_OPERATOR_SEND_QUERY: - context->hf_query_operator_state = HPF_HF_QUERY_OPERATOR_W4_RESULT; - context->ok_pending = 1; - hfp_hf_cmd_query_operator_name(context->rfcomm_cid); + hfp_connection->hf_query_operator_state = HPF_HF_QUERY_OPERATOR_W4_RESULT; + hfp_connection->ok_pending = 1; + hfp_hf_cmd_query_operator_name(hfp_connection->rfcomm_cid); return 1; default: break; } - if (context->enable_extended_audio_gateway_error_report){ - context->ok_pending = 1; + if (hfp_connection->enable_extended_audio_gateway_error_report){ + hfp_connection->ok_pending = 1; done = 1; - hfp_hf_cmd_enable_extended_audio_gateway_error_report(context->rfcomm_cid, context->enable_extended_audio_gateway_error_report); + hfp_hf_cmd_enable_extended_audio_gateway_error_report(hfp_connection->rfcomm_cid, hfp_connection->enable_extended_audio_gateway_error_report); return done; } return done; } -static int codecs_exchange_state_machine(hfp_connection_t * context){ +static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){ /* events ( == commands): HFP_CMD_AVAILABLE_CODECS == received AT+BAC with list of codecs HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP: @@ -455,39 +499,39 @@ static int codecs_exchange_state_machine(hfp_connection_t * context){ HFP_CMD_HF_CONFIRMED_CODEC == received AT+BCS */ - if (context->ok_pending) return 0; + if (hfp_connection->ok_pending) return 0; - switch (context->command){ + switch (hfp_connection->command){ case HFP_CMD_AVAILABLE_CODECS: - if (context->codecs_state == HFP_CODECS_W4_AG_COMMON_CODEC) return 0; + if (hfp_connection->codecs_state == HFP_CODECS_W4_AG_COMMON_CODEC) return 0; - context->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; - context->ok_pending = 1; - hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); + hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; + hfp_connection->ok_pending = 1; + hfp_hf_cmd_notify_on_codecs(hfp_connection->rfcomm_cid); return 1; case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP: - context->codec_confirmed = 0; - context->suggested_codec = 0; - context->negotiated_codec = 0; + hfp_connection->codec_confirmed = 0; + hfp_connection->suggested_codec = 0; + hfp_connection->negotiated_codec = 0; - context->codecs_state = HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE; - context->ok_pending = 1; - hfp_hf_cmd_trigger_codec_connection_setup(context->rfcomm_cid); + hfp_connection->codecs_state = HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE; + hfp_connection->ok_pending = 1; + hfp_hf_cmd_trigger_codec_connection_setup(hfp_connection->rfcomm_cid); break; case HFP_CMD_AG_SUGGESTED_CODEC: - if (hfp_hf_supports_codec(context->suggested_codec)){ - context->codec_confirmed = context->suggested_codec; - context->ok_pending = 1; - context->codecs_state = HFP_CODECS_HF_CONFIRMED_CODEC; - hfp_hf_cmd_confirm_codec(context->rfcomm_cid, context->suggested_codec); + if (hfp_hf_supports_codec(hfp_connection->suggested_codec)){ + hfp_connection->codec_confirmed = hfp_connection->suggested_codec; + hfp_connection->ok_pending = 1; + hfp_connection->codecs_state = HFP_CODECS_HF_CONFIRMED_CODEC; + hfp_hf_cmd_confirm_codec(hfp_connection->rfcomm_cid, hfp_connection->suggested_codec); } else { - context->codec_confirmed = 0; - context->suggested_codec = 0; - context->negotiated_codec = 0; - context->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; - context->ok_pending = 1; - hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); + hfp_connection->codec_confirmed = 0; + hfp_connection->suggested_codec = 0; + hfp_connection->negotiated_codec = 0; + hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; + hfp_connection->ok_pending = 1; + hfp_hf_cmd_notify_on_codecs(hfp_connection->rfcomm_cid); } break; @@ -498,234 +542,234 @@ static int codecs_exchange_state_machine(hfp_connection_t * context){ return 0; } -static int hfp_hf_run_for_audio_connection(hfp_connection_t * context){ - if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || - context->state > HFP_W2_DISCONNECT_SCO) return 0; +static int hfp_hf_run_for_audio_connection(hfp_connection_t * hfp_connection){ + if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || + hfp_connection->state > HFP_W2_DISCONNECT_SCO) return 0; - if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED && context->release_audio_connection){ - context->state = HFP_W4_SCO_DISCONNECTED; - context->release_audio_connection = 0; - gap_disconnect(context->sco_handle); + if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED && hfp_connection->release_audio_connection){ + hfp_connection->state = HFP_W4_SCO_DISCONNECTED; + hfp_connection->release_audio_connection = 0; + gap_disconnect(hfp_connection->sco_handle); return 1; } - if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; + if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; // run codecs exchange - int done = codecs_exchange_state_machine(context); + int done = codecs_exchange_state_machine(hfp_connection); if (done) return 1; - if (context->establish_audio_connection){ - context->state = HFP_W4_SCO_CONNECTED; - context->establish_audio_connection = 0; - hfp_setup_synchronous_connection(context->con_handle, context->link_setting); + if (hfp_connection->establish_audio_connection){ + hfp_connection->state = HFP_W4_SCO_CONNECTED; + hfp_connection->establish_audio_connection = 0; + hfp_setup_synchronous_connection(hfp_connection->con_handle, hfp_connection->link_setting); return 1; } return 0; } -static int call_setup_state_machine(hfp_connection_t * context){ - if (context->hf_answer_incoming_call){ - hfp_hf_cmd_ata(context->rfcomm_cid); - context->hf_answer_incoming_call = 0; +static int call_setup_state_machine(hfp_connection_t * hfp_connection){ + if (hfp_connection->hf_answer_incoming_call){ + hfp_hf_cmd_ata(hfp_connection->rfcomm_cid); + hfp_connection->hf_answer_incoming_call = 0; return 1; } return 0; } -static void hfp_run_for_context(hfp_connection_t * context){ - if (!context) return; - if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return; +static void hfp_run_for_context(hfp_connection_t * hfp_connection){ + if (!hfp_connection) return; + if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) return; - int done = hfp_hf_run_for_context_service_level_connection(context); + int done = hfp_hf_run_for_context_service_level_connection(hfp_connection); if (!done){ - done = hfp_hf_run_for_context_service_level_connection_queries(context); + done = hfp_hf_run_for_context_service_level_connection_queries(hfp_connection); } if (!done){ - done = hfp_hf_run_for_audio_connection(context); + done = hfp_hf_run_for_audio_connection(hfp_connection); } if (!done){ - done = call_setup_state_machine(context); + done = call_setup_state_machine(hfp_connection); } - if (context->send_microphone_gain){ - context->send_microphone_gain = 0; - context->ok_pending = 1; - hfp_hf_set_microphone_gain_cmd(context->rfcomm_cid, context->microphone_gain); + if (hfp_connection->send_microphone_gain){ + hfp_connection->send_microphone_gain = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_microphone_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->microphone_gain); return; } - if (context->send_speaker_gain){ - context->send_speaker_gain = 0; - context->ok_pending = 1; - hfp_hf_set_speaker_gain_cmd(context->rfcomm_cid, context->speaker_gain); + if (hfp_connection->send_speaker_gain){ + hfp_connection->send_speaker_gain = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_speaker_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->speaker_gain); return; } - if (context->hf_deactivate_calling_line_notification){ - context->hf_deactivate_calling_line_notification = 0; - context->ok_pending = 1; - hfp_hf_set_calling_line_notification_cmd(context->rfcomm_cid, 0); + if (hfp_connection->hf_deactivate_calling_line_notification){ + hfp_connection->hf_deactivate_calling_line_notification = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_calling_line_notification_cmd(hfp_connection->rfcomm_cid, 0); return; } - if (context->hf_activate_calling_line_notification){ - context->hf_activate_calling_line_notification = 0; - context->ok_pending = 1; - hfp_hf_set_calling_line_notification_cmd(context->rfcomm_cid, 1); + if (hfp_connection->hf_activate_calling_line_notification){ + hfp_connection->hf_activate_calling_line_notification = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_calling_line_notification_cmd(hfp_connection->rfcomm_cid, 1); return; } - if (context->hf_deactivate_echo_canceling_and_noise_reduction){ - context->hf_deactivate_echo_canceling_and_noise_reduction = 0; - context->ok_pending = 1; - hfp_hf_set_echo_canceling_and_noise_reduction_cmd(context->rfcomm_cid, 0); + if (hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction){ + hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_echo_canceling_and_noise_reduction_cmd(hfp_connection->rfcomm_cid, 0); return; } - if (context->hf_activate_echo_canceling_and_noise_reduction){ - context->hf_activate_echo_canceling_and_noise_reduction = 0; - context->ok_pending = 1; - hfp_hf_set_echo_canceling_and_noise_reduction_cmd(context->rfcomm_cid, 1); + if (hfp_connection->hf_activate_echo_canceling_and_noise_reduction){ + hfp_connection->hf_activate_echo_canceling_and_noise_reduction = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_echo_canceling_and_noise_reduction_cmd(hfp_connection->rfcomm_cid, 1); return; } - if (context->hf_deactivate_voice_recognition_notification){ - context->hf_deactivate_voice_recognition_notification = 0; - context->ok_pending = 1; - hfp_hf_set_voice_recognition_notification_cmd(context->rfcomm_cid, 0); + if (hfp_connection->hf_deactivate_voice_recognition_notification){ + hfp_connection->hf_deactivate_voice_recognition_notification = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 0); return; } - if (context->hf_activate_voice_recognition_notification){ - context->hf_activate_voice_recognition_notification = 0; - context->ok_pending = 1; - hfp_hf_set_voice_recognition_notification_cmd(context->rfcomm_cid, 1); + if (hfp_connection->hf_activate_voice_recognition_notification){ + hfp_connection->hf_activate_voice_recognition_notification = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 1); return; } - if (context->hf_deactivate_call_waiting_notification){ - context->hf_deactivate_call_waiting_notification = 0; - context->ok_pending = 1; - hfp_hf_set_call_waiting_notification_cmd(context->rfcomm_cid, 0); + if (hfp_connection->hf_deactivate_call_waiting_notification){ + hfp_connection->hf_deactivate_call_waiting_notification = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_call_waiting_notification_cmd(hfp_connection->rfcomm_cid, 0); return; } - if (context->hf_activate_call_waiting_notification){ - context->hf_activate_call_waiting_notification = 0; - context->ok_pending = 1; - hfp_hf_set_call_waiting_notification_cmd(context->rfcomm_cid, 1); + if (hfp_connection->hf_activate_call_waiting_notification){ + hfp_connection->hf_activate_call_waiting_notification = 0; + hfp_connection->ok_pending = 1; + hfp_hf_set_call_waiting_notification_cmd(hfp_connection->rfcomm_cid, 1); return; } - if (context->hf_initiate_outgoing_call){ - context->hf_initiate_outgoing_call = 0; - context->ok_pending = 1; - hfp_hf_initiate_outgoing_call_cmd(context->rfcomm_cid); + if (hfp_connection->hf_initiate_outgoing_call){ + hfp_connection->hf_initiate_outgoing_call = 0; + hfp_connection->ok_pending = 1; + hfp_hf_initiate_outgoing_call_cmd(hfp_connection->rfcomm_cid); return; } - if (context->hf_initiate_memory_dialing){ - context->hf_initiate_memory_dialing = 0; - context->ok_pending = 1; - hfp_hf_send_memory_dial_cmd(context->rfcomm_cid, context->memory_id); + if (hfp_connection->hf_initiate_memory_dialing){ + hfp_connection->hf_initiate_memory_dialing = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_memory_dial_cmd(hfp_connection->rfcomm_cid, hfp_connection->memory_id); return; } - if (context->hf_initiate_redial_last_number){ - context->hf_initiate_redial_last_number = 0; - context->ok_pending = 1; - hfp_hf_send_redial_last_number_cmd(context->rfcomm_cid); + if (hfp_connection->hf_initiate_redial_last_number){ + hfp_connection->hf_initiate_redial_last_number = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_redial_last_number_cmd(hfp_connection->rfcomm_cid); return; } - if (context->hf_send_chup){ - context->hf_send_chup = 0; - context->ok_pending = 1; - hfp_hf_send_chup(context->rfcomm_cid); + if (hfp_connection->hf_send_chup){ + hfp_connection->hf_send_chup = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_chup(hfp_connection->rfcomm_cid); return; } - if (context->hf_send_chld_0){ - context->hf_send_chld_0 = 0; - context->ok_pending = 1; - hfp_hf_send_chld(context->rfcomm_cid, 0); + if (hfp_connection->hf_send_chld_0){ + hfp_connection->hf_send_chld_0 = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_chld(hfp_connection->rfcomm_cid, 0); return; } - if (context->hf_send_chld_1){ - context->hf_send_chld_1 = 0; - context->ok_pending = 1; - hfp_hf_send_chld(context->rfcomm_cid, 1); + if (hfp_connection->hf_send_chld_1){ + hfp_connection->hf_send_chld_1 = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_chld(hfp_connection->rfcomm_cid, 1); return; } - if (context->hf_send_chld_2){ - context->hf_send_chld_2 = 0; - context->ok_pending = 1; - hfp_hf_send_chld(context->rfcomm_cid, 2); + if (hfp_connection->hf_send_chld_2){ + hfp_connection->hf_send_chld_2 = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_chld(hfp_connection->rfcomm_cid, 2); return; } - if (context->hf_send_chld_3){ - context->hf_send_chld_3 = 0; - context->ok_pending = 1; - hfp_hf_send_chld(context->rfcomm_cid, 3); + if (hfp_connection->hf_send_chld_3){ + hfp_connection->hf_send_chld_3 = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_chld(hfp_connection->rfcomm_cid, 3); return; } - if (context->hf_send_chld_4){ - context->hf_send_chld_4 = 0; - context->ok_pending = 1; - hfp_hf_send_chld(context->rfcomm_cid, 4); + if (hfp_connection->hf_send_chld_4){ + hfp_connection->hf_send_chld_4 = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_chld(hfp_connection->rfcomm_cid, 4); return; } - if (context->hf_send_chld_x){ - context->hf_send_chld_x = 0; - context->ok_pending = 1; - hfp_hf_send_chld(context->rfcomm_cid, context->hf_send_chld_x_index); + if (hfp_connection->hf_send_chld_x){ + hfp_connection->hf_send_chld_x = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_chld(hfp_connection->rfcomm_cid, hfp_connection->hf_send_chld_x_index); return; } - if (context->hf_send_dtmf_code){ - char code = context->hf_send_dtmf_code; - context->hf_send_dtmf_code = 0; - context->ok_pending = 1; - hfp_hf_send_dtmf(context->rfcomm_cid, code); + if (hfp_connection->hf_send_dtmf_code){ + char code = hfp_connection->hf_send_dtmf_code; + hfp_connection->hf_send_dtmf_code = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_dtmf(hfp_connection->rfcomm_cid, code); return; } - if (context->hf_send_binp){ - context->hf_send_binp = 0; - context->ok_pending = 1; - hfp_hf_send_binp(context->rfcomm_cid); + if (hfp_connection->hf_send_binp){ + hfp_connection->hf_send_binp = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_binp(hfp_connection->rfcomm_cid); return; } - if (context->hf_send_clcc){ - context->hf_send_clcc = 0; - context->ok_pending = 1; - hfp_hf_send_clcc(context->rfcomm_cid); + if (hfp_connection->hf_send_clcc){ + hfp_connection->hf_send_clcc = 0; + hfp_connection->ok_pending = 1; + hfp_hf_send_clcc(hfp_connection->rfcomm_cid); return; } - if (context->hf_send_rrh){ - context->hf_send_rrh = 0; + if (hfp_connection->hf_send_rrh){ + hfp_connection->hf_send_rrh = 0; char buffer[20]; - switch (context->hf_send_rrh_command){ + switch (hfp_connection->hf_send_rrh_command){ case '?': sprintf(buffer, "AT%s?\r\n", HFP_RESPONSE_AND_HOLD); - send_str_over_rfcomm(context->rfcomm_cid, buffer); + send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); return; case '0': case '1': case '2': - sprintf(buffer, "AT%s=%c\r\n", HFP_RESPONSE_AND_HOLD, context->hf_send_rrh_command); - send_str_over_rfcomm(context->rfcomm_cid, buffer); + sprintf(buffer, "AT%s=%c\r\n", HFP_RESPONSE_AND_HOLD, hfp_connection->hf_send_rrh_command); + send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); return; default: break; @@ -733,25 +777,25 @@ static void hfp_run_for_context(hfp_connection_t * context){ return; } - if (context->hf_send_cnum){ - context->hf_send_cnum = 0; + if (hfp_connection->hf_send_cnum){ + hfp_connection->hf_send_cnum = 0; char buffer[20]; sprintf(buffer, "AT%s\r\n", HFP_SUBSCRIBER_NUMBER_INFORMATION); - send_str_over_rfcomm(context->rfcomm_cid, buffer); + send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); return; } // update HF indicators - if (context->generic_status_update_bitmap){ + if (hfp_connection->generic_status_update_bitmap){ int i; for (i=0;igeneric_status_update_bitmap, i)){ - if (context->generic_status_indicators[i].state){ - context->ok_pending = 1; - context->generic_status_update_bitmap = store_bit(context->generic_status_update_bitmap, i, 0); + if (get_bit(hfp_connection->generic_status_update_bitmap, i)){ + if (hfp_connection->generic_status_indicators[i].state){ + hfp_connection->ok_pending = 1; + hfp_connection->generic_status_update_bitmap = store_bit(hfp_connection->generic_status_update_bitmap, i, 0); char buffer[30]; sprintf(buffer, "AT%s=%u,%u\r\n", HFP_TRANSFER_HF_INDICATOR_STATUS, hfp_indicators[i], hfp_indicators_value[i]); - send_str_over_rfcomm(context->rfcomm_cid, buffer); + send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); } else { printf("Not sending HF indicator %u as it is disabled\n", hfp_indicators[i]); } @@ -762,10 +806,10 @@ static void hfp_run_for_context(hfp_connection_t * context){ if (done) return; // deal with disconnect - switch (context->state){ + switch (hfp_connection->state){ case HFP_W2_DISCONNECT_RFCOMM: - context->state = HFP_W4_RFCOMM_DISCONNECTED; - rfcomm_disconnect_internal(context->rfcomm_cid); + hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED; + rfcomm_disconnect_internal(hfp_connection->rfcomm_cid); break; default: @@ -773,129 +817,129 @@ static void hfp_run_for_context(hfp_connection_t * context){ } } -static void hfp_init_link_settings(hfp_connection_t * context){ +static void hfp_init_link_settings(hfp_connection_t * hfp_connection){ // determine highest possible link setting - context->link_setting = HFP_LINK_SETTINGS_D1; - if (hci_remote_eSCO_supported(context->con_handle)){ - context->link_setting = HFP_LINK_SETTINGS_S3; + hfp_connection->link_setting = HFP_LINK_SETTINGS_D1; + if (hci_remote_eSCO_supported(hfp_connection->con_handle)){ + hfp_connection->link_setting = HFP_LINK_SETTINGS_S3; if ((hfp_supported_features & (1<remote_supported_features & (1<link_setting = HFP_LINK_SETTINGS_S4; + && (hfp_connection->remote_supported_features & (1<link_setting = HFP_LINK_SETTINGS_S4; } } } -static void hfp_ag_slc_established(hfp_connection_t * context){ - context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; +static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){ + hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0); - hfp_init_link_settings(context); + hfp_init_link_settings(hfp_connection); // restore volume settings - context->speaker_gain = hfp_hf_speaker_gain; - context->send_speaker_gain = 1; + hfp_connection->speaker_gain = hfp_hf_speaker_gain; + hfp_connection->send_speaker_gain = 1; hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, hfp_hf_speaker_gain); - context->microphone_gain = hfp_hf_microphone_gain; - context->send_microphone_gain = 1; + hfp_connection->microphone_gain = hfp_hf_microphone_gain; + hfp_connection->send_microphone_gain = 1; hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain); // enable all indicators int i; for (i=0;igeneric_status_indicators[i].uuid = hfp_indicators[i]; - context->generic_status_indicators[i].state = 1; + hfp_connection->generic_status_indicators[i].uuid = hfp_indicators[i]; + hfp_connection->generic_status_indicators[i].state = 1; } } -static void hfp_hf_switch_on_ok(hfp_connection_t *context){ - context->ok_pending = 0; +static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){ + hfp_connection->ok_pending = 0; int done = 1; - switch (context->state){ + switch (hfp_connection->state){ case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: - if (has_codec_negotiation_feature(context)){ - context->state = HFP_NOTIFY_ON_CODECS; + if (has_codec_negotiation_feature(hfp_connection)){ + hfp_connection->state = HFP_NOTIFY_ON_CODECS; break; } - context->state = HFP_RETRIEVE_INDICATORS; + hfp_connection->state = HFP_RETRIEVE_INDICATORS; break; case HFP_W4_NOTIFY_ON_CODECS: - context->state = HFP_RETRIEVE_INDICATORS; + hfp_connection->state = HFP_RETRIEVE_INDICATORS; break; case HFP_W4_RETRIEVE_INDICATORS: - context->state = HFP_RETRIEVE_INDICATORS_STATUS; + hfp_connection->state = HFP_RETRIEVE_INDICATORS_STATUS; break; case HFP_W4_RETRIEVE_INDICATORS_STATUS: - context->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE; + hfp_connection->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE; break; case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE: - if (has_call_waiting_and_3way_calling_feature(context)){ - context->state = HFP_RETRIEVE_CAN_HOLD_CALL; + if (has_call_waiting_and_3way_calling_feature(hfp_connection)){ + hfp_connection->state = HFP_RETRIEVE_CAN_HOLD_CALL; break; } - if (has_hf_indicators_feature(context)){ - context->state = HFP_LIST_GENERIC_STATUS_INDICATORS; + if (has_hf_indicators_feature(hfp_connection)){ + hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS; break; } - hfp_ag_slc_established(context); + hfp_ag_slc_established(hfp_connection); break; case HFP_W4_RETRIEVE_CAN_HOLD_CALL: - if (has_hf_indicators_feature(context)){ - context->state = HFP_LIST_GENERIC_STATUS_INDICATORS; + if (has_hf_indicators_feature(hfp_connection)){ + hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS; break; } - hfp_ag_slc_established(context); + hfp_ag_slc_established(hfp_connection); break; case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: - context->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS; + hfp_connection->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS; break; case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: - context->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; + hfp_connection->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; break; case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: - hfp_ag_slc_established(context); + hfp_ag_slc_established(hfp_connection); break; case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: - if (context->enable_status_update_for_ag_indicators != 0xFF){ - context->enable_status_update_for_ag_indicators = 0xFF; + if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){ + hfp_connection->enable_status_update_for_ag_indicators = 0xFF; hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0); break; } - if (context->change_status_update_for_individual_ag_indicators == 1){ - context->change_status_update_for_individual_ag_indicators = 0; + if (hfp_connection->change_status_update_for_individual_ag_indicators == 1){ + hfp_connection->change_status_update_for_individual_ag_indicators = 0; hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0); break; } - switch (context->hf_query_operator_state){ + switch (hfp_connection->hf_query_operator_state){ case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK: printf("Format set, querying name\n"); - context->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; + hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; break; case HPF_HF_QUERY_OPERATOR_W4_RESULT: - context->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET; - hfp_emit_network_operator_event(hfp_callback, context->network_operator); + hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET; + hfp_emit_network_operator_event(hfp_callback, hfp_connection->network_operator); break; default: break; } - if (context->enable_extended_audio_gateway_error_report){ - context->enable_extended_audio_gateway_error_report = 0; + if (hfp_connection->enable_extended_audio_gateway_error_report){ + hfp_connection->enable_extended_audio_gateway_error_report = 0; break; } - switch (context->codecs_state){ + switch (hfp_connection->codecs_state){ case HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE: - context->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; + hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; break; case HFP_CODECS_HF_CONFIRMED_CODEC: - context->codecs_state = HFP_CODECS_EXCHANGED; + hfp_connection->codecs_state = HFP_CODECS_EXCHANGED; hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0); break; default: @@ -909,13 +953,13 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *context){ } // done - context->command = HFP_CMD_NONE; + hfp_connection->command = HFP_CMD_NONE; } static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ - hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel); - if (!context) return; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_rfcomm_cid(channel); + if (!hfp_connection) return; char last_char = packet[size-1]; packet[size-1] = 0; @@ -924,70 +968,83 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8 int pos, i, value; for (pos = 0; pos < size ; pos++){ - hfp_parse(context, packet[pos], 1); + hfp_parse(hfp_connection, packet[pos], 1); } - switch (context->command){ + switch (hfp_connection->command){ case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: - context->command = HFP_CMD_NONE; - printf("Subscriber Number: number %s, type %u\n", context->bnip_number, context->bnip_type); + hfp_connection->command = HFP_CMD_NONE; + // printf("Subscriber Number: number %s, type %u\n", hfp_connection->bnip_number, hfp_connection->bnip_type); + hfp_hf_emit_subscriber_information(hfp_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number); break; case HFP_CMD_RESPONSE_AND_HOLD_STATUS: - context->command = HFP_CMD_NONE; - printf("Response and Hold status: %s\n", context->line_buffer); + hfp_connection->command = HFP_CMD_NONE; + // printf("Response and Hold status: %s\n", hfp_connection->line_buffer); + hfp_emit_event(hfp_callback, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, atoi((char *)&hfp_connection->line_buffer[0])); break; case HFP_CMD_LIST_CURRENT_CALLS: - context->command = HFP_CMD_NONE; - printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n", - context->clcc_idx, context->clcc_dir, context->clcc_status, context->clcc_mpty, - context->bnip_number, context->bnip_type); + hfp_connection->command = HFP_CMD_NONE; + // printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n", + // hfp_connection->clcc_idx, hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty, + // hfp_connection->bnip_number, hfp_connection->bnip_type); + hfp_hf_emit_enhanced_call_status(hfp_callback, hfp_connection->clcc_idx, + hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty, + hfp_connection->bnip_type, hfp_connection->bnip_number); break; case HFP_CMD_SET_SPEAKER_GAIN: - context->command = HFP_CMD_NONE; - value = atoi((char*)context->line_buffer); + hfp_connection->command = HFP_CMD_NONE; + value = atoi((char*)hfp_connection->line_buffer); hfp_hf_speaker_gain = value; hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, value); break; case HFP_CMD_SET_MICROPHONE_GAIN: - context->command = HFP_CMD_NONE; - value = atoi((char*)context->line_buffer); + hfp_connection->command = HFP_CMD_NONE; + value = atoi((char*)hfp_connection->line_buffer); hfp_hf_microphone_gain = value; hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, value); break; case HFP_CMD_AG_SENT_PHONE_NUMBER: - context->command = HFP_CMD_NONE; - hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, context->bnip_number); + hfp_connection->command = HFP_CMD_NONE; + hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number); + break; + case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: + hfp_connection->command = HFP_CMD_NONE; + hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number); + break; + case HFP_CMD_AG_SENT_CLIP_INFORMATION: + hfp_connection->command = HFP_CMD_NONE; + hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALLING_LINE_INDETIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number); break; case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: - context->ok_pending = 0; - context->command = HFP_CMD_NONE; - context->extended_audio_gateway_error = 0; - hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, context->extended_audio_gateway_error_value); + hfp_connection->ok_pending = 0; + hfp_connection->command = HFP_CMD_NONE; + hfp_connection->extended_audio_gateway_error = 0; + hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value); break; case HFP_CMD_ERROR: - context->ok_pending = 0; - hfp_reset_context_flags(context); - context->command = HFP_CMD_NONE; + hfp_connection->ok_pending = 0; + hfp_reset_context_flags(hfp_connection); + hfp_connection->command = HFP_CMD_NONE; hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1); break; case HFP_CMD_OK: - hfp_hf_switch_on_ok(context); + hfp_hf_switch_on_ok(hfp_connection); break; case HFP_CMD_RING: - hfp_emit_event(hfp_callback, HFP_SUBEVENT_RING, 0); + hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_RING); break; case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: - for (i = 0; i < context->ag_indicators_nr; i++){ - if (context->ag_indicators[i].status_changed) { - if (strcmp(context->ag_indicators[i].name, "callsetup") == 0){ - hfp_callsetup_status = (hfp_callsetup_status_t) context->ag_indicators[i].status; - } else if (strcmp(context->ag_indicators[i].name, "callheld") == 0){ - hfp_callheld_status = (hfp_callheld_status_t) context->ag_indicators[i].status; - } else if (strcmp(context->ag_indicators[i].name, "call") == 0){ - hfp_call_status = (hfp_call_status_t) context->ag_indicators[i].status; + for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ + if (hfp_connection->ag_indicators[i].status_changed) { + if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){ + hfp_callsetup_status = (hfp_callsetup_status_t) hfp_connection->ag_indicators[i].status; + } else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){ + hfp_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status; + } else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){ + hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status; } - context->ag_indicators[i].status_changed = 0; - hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]); + hfp_connection->ag_indicators[i].status_changed = 0; + hfp_emit_ag_indicator_event(hfp_callback, hfp_connection->ag_indicators[i]); break; } } @@ -995,19 +1052,19 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8 default: break; } - hfp_run_for_context(context); + hfp_run_for_context(hfp_connection); } static void hfp_run(){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + hfp_run_for_context(hfp_connection); } } -static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ +static void packet_handler(void * hfp_connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet_type){ case RFCOMM_DATA_PACKET: hfp_handle_rfcomm_event(packet_type, channel, packet, size); @@ -1051,10 +1108,10 @@ void hfp_hf_init_codecs(int codecs_nr, uint8_t * codecs){ linked_list_iterator_t it; linked_list_iterator_init(&it, hfp_get_connections()); while (linked_list_iterator_has_next(&it)){ - hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); - if (!connection) continue; - connection->command = HFP_CMD_AVAILABLE_CODECS; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it); + if (!hfp_connection) continue; + hfp_connection->command = HFP_CMD_AVAILABLE_CODECS; + hfp_run_for_context(hfp_connection); } } @@ -1075,20 +1132,20 @@ void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr){ } void hfp_hf_release_service_level_connection(bd_addr_t bd_addr){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - hfp_release_service_level_connection(connection); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_release_service_level_connection(hfp_connection); + hfp_run_for_context(hfp_connection); } static void hfp_hf_set_status_update_for_all_ag_indicators(bd_addr_t bd_addr, uint8_t enable){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (!connection){ - log_error("HFP HF: connection doesn't exist."); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (!hfp_connection){ + log_error("HFP HF: hfp_connection doesn't exist."); return; } - connection->enable_status_update_for_ag_indicators = enable; - hfp_run_for_context(connection); + hfp_connection->enable_status_update_for_ag_indicators = enable; + hfp_run_for_context(hfp_connection); } void hfp_hf_enable_status_update_for_all_ag_indicators(bd_addr_t bd_addr){ @@ -1102,45 +1159,45 @@ void hfp_hf_disable_status_update_for_all_ag_indicators(bd_addr_t bd_addr){ // TODO: returned ERROR - wrong format void hfp_hf_set_status_update_for_individual_ag_indicators(bd_addr_t bd_addr, uint32_t indicators_status_bitmap){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (!connection){ - log_error("HFP HF: connection doesn't exist."); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (!hfp_connection){ + log_error("HFP HF: hfp_connection doesn't exist."); return; } - connection->change_status_update_for_individual_ag_indicators = 1; - connection->ag_indicators_status_update_bitmap = indicators_status_bitmap; - hfp_run_for_context(connection); + hfp_connection->change_status_update_for_individual_ag_indicators = 1; + hfp_connection->ag_indicators_status_update_bitmap = indicators_status_bitmap; + hfp_run_for_context(hfp_connection); } void hfp_hf_query_operator_selection(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (!connection){ - log_error("HFP HF: connection doesn't exist."); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (!hfp_connection){ + log_error("HFP HF: hfp_connection doesn't exist."); return; } - switch (connection->hf_query_operator_state){ + switch (hfp_connection->hf_query_operator_state){ case HFP_HF_QUERY_OPERATOR_FORMAT_NOT_SET: - connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SET_FORMAT; + hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SET_FORMAT; break; case HFP_HF_QUERY_OPERATOR_FORMAT_SET: - connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; + hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; break; default: break; } - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); } static void hfp_hf_set_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, uint8_t enable){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (!connection){ - log_error("HFP HF: connection doesn't exist."); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (!hfp_connection){ + log_error("HFP HF: hfp_connection doesn't exist."); return; } - connection->enable_extended_audio_gateway_error_report = enable; - hfp_run_for_context(connection); + hfp_connection->enable_extended_audio_gateway_error_report = enable; + hfp_run_for_context(hfp_connection); } @@ -1155,42 +1212,42 @@ void hfp_hf_disable_report_extended_audio_gateway_error_result_code(bd_addr_t bd void hfp_hf_establish_audio_connection(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->establish_audio_connection = 0; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection->establish_audio_connection = 0; - if (connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return; - if (connection->state >= HFP_W2_DISCONNECT_SCO) return; + if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return; + if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return; - if (!has_codec_negotiation_feature(connection)){ + if (!has_codec_negotiation_feature(hfp_connection)){ log_info("hfp_ag_establish_audio_connection - no codec negotiation feature, using defaults"); - connection->codecs_state = HFP_CODECS_EXCHANGED; - connection->establish_audio_connection = 1; + hfp_connection->codecs_state = HFP_CODECS_EXCHANGED; + hfp_connection->establish_audio_connection = 1; } else { - switch (connection->codecs_state){ + switch (hfp_connection->codecs_state){ case HFP_CODECS_W4_AG_COMMON_CODEC: break; default: - connection->command = HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP; + hfp_connection->command = HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP; break; } } - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); } void hfp_hf_release_audio_connection(bd_addr_t bd_addr){ - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - hfp_release_audio_connection(connection); - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_release_audio_connection(hfp_connection); + hfp_run_for_context(hfp_connection); } void hfp_hf_answer_incoming_call(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ - connection->hf_answer_incoming_call = 1; - hfp_run_for_context(connection); + hfp_connection->hf_answer_incoming_call = 1; + hfp_run_for_context(hfp_connection); } else { log_error("HFP HF: answering incoming call with wrong callsetup status %u", hfp_callsetup_status); } @@ -1198,338 +1255,284 @@ void hfp_hf_answer_incoming_call(bd_addr_t bd_addr){ void hfp_hf_terminate_call(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - // if (hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - connection->hf_send_chup = 1; - hfp_run_for_context(connection); - // } else { - // log_error("HFP HF: terminating incoming call with wrong call status %u", hfp_call_status); - // } + hfp_connection->hf_send_chup = 1; + hfp_run_for_context(hfp_connection); } void hfp_hf_reject_incoming_call(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ - connection->hf_send_chup = 1; - hfp_run_for_context(connection); + hfp_connection->hf_send_chup = 1; + hfp_run_for_context(hfp_connection); } } void hfp_hf_user_busy(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ - connection->hf_send_chld_0 = 1; - hfp_run_for_context(connection); + hfp_connection->hf_send_chld_0 = 1; + hfp_run_for_context(hfp_connection); } } void hfp_hf_end_active_and_accept_other(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS || hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - connection->hf_send_chld_1 = 1; - hfp_run_for_context(connection); + hfp_connection->hf_send_chld_1 = 1; + hfp_run_for_context(hfp_connection); } } void hfp_hf_swap_calls(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS || hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - connection->hf_send_chld_2 = 1; - hfp_run_for_context(connection); + hfp_connection->hf_send_chld_2 = 1; + hfp_run_for_context(hfp_connection); } } void hfp_hf_join_held_call(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS || hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - connection->hf_send_chld_3 = 1; - hfp_run_for_context(connection); + hfp_connection->hf_send_chld_3 = 1; + hfp_run_for_context(hfp_connection); } } void hfp_hf_connect_calls(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS || hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - connection->hf_send_chld_4 = 1; - hfp_run_for_context(connection); + hfp_connection->hf_send_chld_4 = 1; + hfp_run_for_context(hfp_connection); } } void hfp_hf_release_call_with_index(bd_addr_t addr, int index){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS || hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - connection->hf_send_chld_x = 1; - connection->hf_send_chld_x_index = 10 + index; - hfp_run_for_context(connection); + hfp_connection->hf_send_chld_x = 1; + hfp_connection->hf_send_chld_x_index = 10 + index; + hfp_run_for_context(hfp_connection); } } void hfp_hf_private_consultation_with_call(bd_addr_t addr, int index){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS || hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){ - connection->hf_send_chld_x = 1; - connection->hf_send_chld_x_index = 20 + index; - hfp_run_for_context(connection); + hfp_connection->hf_send_chld_x = 1; + hfp_connection->hf_send_chld_x_index = 20 + index; + hfp_run_for_context(hfp_connection); } } void hfp_hf_dial_number(bd_addr_t bd_addr, char * number){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_initiate_outgoing_call = 1; + hfp_connection->hf_initiate_outgoing_call = 1; snprintf(phone_number, sizeof(phone_number), "%s", number); - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); } void hfp_hf_dial_memory(bd_addr_t bd_addr, int memory_id){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_initiate_memory_dialing = 1; - connection->memory_id = memory_id; + hfp_connection->hf_initiate_memory_dialing = 1; + hfp_connection->memory_id = memory_id; - hfp_run_for_context(connection); + hfp_run_for_context(hfp_connection); } void hfp_hf_redial_last_number(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_initiate_redial_last_number = 1; - hfp_run_for_context(connection); + hfp_connection->hf_initiate_redial_last_number = 1; + hfp_run_for_context(hfp_connection); } void hfp_hf_activate_call_waiting_notification(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_activate_call_waiting_notification = 1; - hfp_run_for_context(connection); + hfp_connection->hf_activate_call_waiting_notification = 1; + hfp_run_for_context(hfp_connection); } void hfp_hf_deactivate_call_waiting_notification(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_deactivate_call_waiting_notification = 1; - hfp_run_for_context(connection); + hfp_connection->hf_deactivate_call_waiting_notification = 1; + hfp_run_for_context(hfp_connection); } void hfp_hf_activate_calling_line_notification(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_activate_calling_line_notification = 1; - hfp_run_for_context(connection); + hfp_connection->hf_activate_calling_line_notification = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_deactivate_calling_line_notification(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_deactivate_calling_line_notification = 1; - hfp_run_for_context(connection); + hfp_connection->hf_deactivate_calling_line_notification = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_activate_echo_canceling_and_noise_reduction(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_activate_echo_canceling_and_noise_reduction = 1; - hfp_run_for_context(connection); + hfp_connection->hf_activate_echo_canceling_and_noise_reduction = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_deactivate_echo_canceling_and_noise_reduction(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_deactivate_echo_canceling_and_noise_reduction = 1; - hfp_run_for_context(connection); + hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_activate_voice_recognition_notification(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_activate_voice_recognition_notification = 1; - hfp_run_for_context(connection); + hfp_connection->hf_activate_voice_recognition_notification = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_deactivate_voice_recognition_notification(bd_addr_t bd_addr){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); - connection->hf_deactivate_voice_recognition_notification = 1; - hfp_run_for_context(connection); + hfp_connection->hf_deactivate_voice_recognition_notification = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_set_microphone_gain(bd_addr_t bd_addr, int gain){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (connection->microphone_gain == gain) return; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (hfp_connection->microphone_gain == gain) return; if (gain < 0 || gain > 15){ log_info("Valid range for a gain is [0..15]. Currently sent: %d", gain); return; } - connection->microphone_gain = gain; - connection->send_microphone_gain = 1; - hfp_run_for_context(connection); + hfp_connection->microphone_gain = gain; + hfp_connection->send_microphone_gain = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_set_speaker_gain(bd_addr_t bd_addr, int gain){ hfp_hf_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - if (connection->speaker_gain == gain) return; + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (hfp_connection->speaker_gain == gain) return; if (gain < 0 || gain > 15){ log_info("Valid range for a gain is [0..15]. Currently sent: %d", gain); return; } - connection->speaker_gain = gain; - connection->send_speaker_gain = 1; - hfp_run_for_context(connection); + hfp_connection->speaker_gain = gain; + hfp_connection->send_speaker_gain = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_send_dtmf_code(bd_addr_t addr, char code){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); - connection->hf_send_dtmf_code = code; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection->hf_send_dtmf_code = code; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_request_phone_number_for_voice_tag(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); - connection->hf_send_binp = 1; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection->hf_send_binp = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_query_current_call_status(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); - connection->hf_send_clcc = 1; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection->hf_send_clcc = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_rrh_query_status(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); - connection->hf_send_rrh = 1; - connection->hf_send_rrh_command = '?'; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection->hf_send_rrh = 1; + hfp_connection->hf_send_rrh_command = '?'; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_rrh_hold_call(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); - connection->hf_send_rrh = 1; - connection->hf_send_rrh_command = '0'; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection->hf_send_rrh = 1; + hfp_connection->hf_send_rrh_command = '0'; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_rrh_accept_held_call(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); - connection->hf_send_rrh = 1; - connection->hf_send_rrh_command = '1'; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection->hf_send_rrh = 1; + hfp_connection->hf_send_rrh_command = '1'; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ -void hfp_hf_rrh_reject_held_call(bd_addr_t addr) -{ +void hfp_hf_rrh_reject_held_call(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); - connection->hf_send_rrh = 1; - connection->hf_send_rrh_command = '2'; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection->hf_send_rrh = 1; + hfp_connection->hf_send_rrh_command = '2'; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ -void hfp_hf_query_subscriber_number(bd_addr_t addr) -{ +void hfp_hf_query_subscriber_number(bd_addr_t addr){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); - connection->hf_send_cnum = 1; - hfp_run_for_context(connection); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection->hf_send_cnum = 1; + hfp_run_for_context(hfp_connection); } -/* - * @brief - */ void hfp_hf_set_hf_indicator(bd_addr_t addr, int assigned_number, int value){ hfp_hf_establish_service_level_connection(addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr); // find index for assigned number int i; for (i = 0; i < hfp_indicators_nr ; i++){ @@ -1537,10 +1540,10 @@ void hfp_hf_set_hf_indicator(bd_addr_t addr, int assigned_number, int value){ // set value hfp_indicators_value[i] = value; // mark for update - if (connection->state > HFP_LIST_GENERIC_STATUS_INDICATORS){ - connection->generic_status_update_bitmap |= (1<state > HFP_LIST_GENERIC_STATUS_INDICATORS){ + hfp_connection->generic_status_update_bitmap |= (1<