hfp_hf.c (323d300063a7e0193cf61fbe114062cf000a3fe5) hfp_hf.c (ca59be5193cced59664efef288ea86d02eaef3a4)
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 63 unchanged lines hidden (view full) ---

72
73static uint8_t hfp_indicators_nr = 0;
74static uint8_t hfp_indicators[HFP_MAX_NUM_HF_INDICATORS];
75static uint32_t hfp_indicators_value[HFP_MAX_NUM_HF_INDICATORS];
76
77static uint8_t hfp_hf_speaker_gain = 9;
78static uint8_t hfp_hf_microphone_gain = 9;
79
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 63 unchanged lines hidden (view full) ---

72
73static uint8_t hfp_indicators_nr = 0;
74static uint8_t hfp_indicators[HFP_MAX_NUM_HF_INDICATORS];
75static uint32_t hfp_indicators_value[HFP_MAX_NUM_HF_INDICATORS];
76
77static uint8_t hfp_hf_speaker_gain = 9;
78static uint8_t hfp_hf_microphone_gain = 9;
79
80static btstack_packet_handler_t hfp_callback;
80static btstack_packet_handler_t hfp_hf_callback;
81
82static hfp_call_status_t hfp_call_status;
83static hfp_callsetup_status_t hfp_callsetup_status;
84static hfp_callheld_status_t hfp_callheld_status;
85
86static char phone_number[25];
87
88static btstack_packet_callback_registration_t hci_event_callback_registration;
89
90void hfp_hf_register_packet_handler(btstack_packet_handler_t callback){
81
82static hfp_call_status_t hfp_call_status;
83static hfp_callsetup_status_t hfp_callsetup_status;
84static hfp_callheld_status_t hfp_callheld_status;
85
86static char phone_number[25];
87
88static btstack_packet_callback_registration_t hci_event_callback_registration;
89
90void hfp_hf_register_packet_handler(btstack_packet_handler_t callback){
91 hfp_callback = callback;
92 if (callback == NULL){
93 log_error("hfp_hf_register_packet_handler called with NULL callback");
94 return;
95 }
91 if (callback == NULL){
92 log_error("hfp_hf_register_packet_handler called with NULL callback");
93 return;
94 }
96 hfp_callback = callback;
97 hfp_set_callback(callback);
95 hfp_hf_callback = callback;
96 hfp_set_hf_callback(callback);
98}
99
100static void hfp_hf_emit_subscriber_information(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t status, uint8_t bnip_type, const char * bnip_number){
101 if (!callback) return;
102 uint8_t event[31];
103 event[0] = HCI_EVENT_HFP_META;
104 event[1] = sizeof(event) - 2;
105 event[2] = event_subtype;

--- 723 unchanged lines hidden (view full) ---

829 default:
830 break;
831 }
832}
833
834static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){
835 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
836
97}
98
99static void hfp_hf_emit_subscriber_information(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t status, uint8_t bnip_type, const char * bnip_number){
100 if (!callback) return;
101 uint8_t event[31];
102 event[0] = HCI_EVENT_HFP_META;
103 event[1] = sizeof(event) - 2;
104 event[2] = event_subtype;

--- 723 unchanged lines hidden (view full) ---

828 default:
829 break;
830 }
831}
832
833static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){
834 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
835
837 hfp_emit_slc_connection_event(hfp_callback, 0, hfp_connection->acl_handle, hfp_connection->remote_addr);
836 hfp_emit_slc_connection_event(hfp_connection, 0, hfp_connection->acl_handle, hfp_connection->remote_addr);
838
839 // restore volume settings
840 hfp_connection->speaker_gain = hfp_hf_speaker_gain;
841 hfp_connection->send_speaker_gain = 1;
837
838 // restore volume settings
839 hfp_connection->speaker_gain = hfp_hf_speaker_gain;
840 hfp_connection->send_speaker_gain = 1;
842 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, hfp_hf_speaker_gain);
841 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, hfp_hf_speaker_gain);
843 hfp_connection->microphone_gain = hfp_hf_microphone_gain;
844 hfp_connection->send_microphone_gain = 1;
842 hfp_connection->microphone_gain = hfp_hf_microphone_gain;
843 hfp_connection->send_microphone_gain = 1;
845 hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain);
844 hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain);
846 // enable all indicators
847 int i;
848 for (i=0;i<hfp_indicators_nr;i++){
849 hfp_connection->generic_status_indicators[i].uuid = hfp_indicators[i];
850 hfp_connection->generic_status_indicators[i].state = 1;
851 }
852}
853

--- 49 unchanged lines hidden (view full) ---

903 break;
904
905 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
906 hfp_ag_slc_established(hfp_connection);
907 break;
908 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
909 if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){
910 hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
845 // enable all indicators
846 int i;
847 for (i=0;i<hfp_indicators_nr;i++){
848 hfp_connection->generic_status_indicators[i].uuid = hfp_indicators[i];
849 hfp_connection->generic_status_indicators[i].state = 1;
850 }
851}
852

--- 49 unchanged lines hidden (view full) ---

902 break;
903
904 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
905 hfp_ag_slc_established(hfp_connection);
906 break;
907 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
908 if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){
909 hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
911 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
910 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 0);
912 break;
913 }
914
915 if (hfp_connection->change_status_update_for_individual_ag_indicators == 1){
916 hfp_connection->change_status_update_for_individual_ag_indicators = 0;
911 break;
912 }
913
914 if (hfp_connection->change_status_update_for_individual_ag_indicators == 1){
915 hfp_connection->change_status_update_for_individual_ag_indicators = 0;
917 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
916 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 0);
918 break;
919 }
920
921 switch (hfp_connection->hf_query_operator_state){
922 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK:
923 // printf("Format set, querying name\n");
924 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY;
925 break;
926 case HPF_HF_QUERY_OPERATOR_W4_RESULT:
927 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET;
917 break;
918 }
919
920 switch (hfp_connection->hf_query_operator_state){
921 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK:
922 // printf("Format set, querying name\n");
923 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY;
924 break;
925 case HPF_HF_QUERY_OPERATOR_W4_RESULT:
926 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET;
928 hfp_emit_network_operator_event(hfp_callback, hfp_connection->network_operator);
927 hfp_emit_network_operator_event(hfp_hf_callback, hfp_connection->network_operator);
929 break;
930 default:
931 break;
932 }
933
934 if (hfp_connection->enable_extended_audio_gateway_error_report){
935 hfp_connection->enable_extended_audio_gateway_error_report = 0;
936 break;

--- 39 unchanged lines hidden (view full) ---

976 for (pos = 0; pos < size ; pos++){
977 hfp_parse(hfp_connection, packet[pos], 1);
978 }
979
980 switch (hfp_connection->command){
981 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
982 hfp_connection->command = HFP_CMD_NONE;
983 // printf("Subscriber Number: number %s, type %u\n", hfp_connection->bnip_number, hfp_connection->bnip_type);
928 break;
929 default:
930 break;
931 }
932
933 if (hfp_connection->enable_extended_audio_gateway_error_report){
934 hfp_connection->enable_extended_audio_gateway_error_report = 0;
935 break;

--- 39 unchanged lines hidden (view full) ---

975 for (pos = 0; pos < size ; pos++){
976 hfp_parse(hfp_connection, packet[pos], 1);
977 }
978
979 switch (hfp_connection->command){
980 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
981 hfp_connection->command = HFP_CMD_NONE;
982 // printf("Subscriber Number: number %s, type %u\n", hfp_connection->bnip_number, hfp_connection->bnip_type);
984 hfp_hf_emit_subscriber_information(hfp_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number);
983 hfp_hf_emit_subscriber_information(hfp_hf_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number);
985 break;
986 case HFP_CMD_RESPONSE_AND_HOLD_STATUS:
987 hfp_connection->command = HFP_CMD_NONE;
988 // printf("Response and Hold status: %s\n", hfp_connection->line_buffer);
984 break;
985 case HFP_CMD_RESPONSE_AND_HOLD_STATUS:
986 hfp_connection->command = HFP_CMD_NONE;
987 // printf("Response and Hold status: %s\n", hfp_connection->line_buffer);
989 hfp_emit_event(hfp_callback, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0]));
988 hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0]));
990 break;
991 case HFP_CMD_LIST_CURRENT_CALLS:
992 hfp_connection->command = HFP_CMD_NONE;
993 // printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n",
994 // hfp_connection->clcc_idx, hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
995 // hfp_connection->bnip_number, hfp_connection->bnip_type);
989 break;
990 case HFP_CMD_LIST_CURRENT_CALLS:
991 hfp_connection->command = HFP_CMD_NONE;
992 // printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n",
993 // hfp_connection->clcc_idx, hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
994 // hfp_connection->bnip_number, hfp_connection->bnip_type);
996 hfp_hf_emit_enhanced_call_status(hfp_callback, hfp_connection->clcc_idx,
995 hfp_hf_emit_enhanced_call_status(hfp_hf_callback, hfp_connection->clcc_idx,
997 hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
998 hfp_connection->bnip_type, hfp_connection->bnip_number);
999 break;
1000 case HFP_CMD_SET_SPEAKER_GAIN:
1001 hfp_connection->command = HFP_CMD_NONE;
1002 value = btstack_atoi((char*)hfp_connection->line_buffer);
1003 hfp_hf_speaker_gain = value;
996 hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
997 hfp_connection->bnip_type, hfp_connection->bnip_number);
998 break;
999 case HFP_CMD_SET_SPEAKER_GAIN:
1000 hfp_connection->command = HFP_CMD_NONE;
1001 value = btstack_atoi((char*)hfp_connection->line_buffer);
1002 hfp_hf_speaker_gain = value;
1004 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, value);
1003 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, value);
1005 break;
1006 case HFP_CMD_SET_MICROPHONE_GAIN:
1007 hfp_connection->command = HFP_CMD_NONE;
1008 value = btstack_atoi((char*)hfp_connection->line_buffer);
1009 hfp_hf_microphone_gain = value;
1004 break;
1005 case HFP_CMD_SET_MICROPHONE_GAIN:
1006 hfp_connection->command = HFP_CMD_NONE;
1007 value = btstack_atoi((char*)hfp_connection->line_buffer);
1008 hfp_hf_microphone_gain = value;
1010 hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, value);
1009 hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, value);
1011 break;
1012 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1013 hfp_connection->command = HFP_CMD_NONE;
1010 break;
1011 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1012 hfp_connection->command = HFP_CMD_NONE;
1014 hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number);
1013 hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number);
1015 break;
1016 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1017 hfp_connection->command = HFP_CMD_NONE;
1014 break;
1015 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1016 hfp_connection->command = HFP_CMD_NONE;
1018 hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
1017 hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
1019 break;
1020 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1021 hfp_connection->command = HFP_CMD_NONE;
1018 break;
1019 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1020 hfp_connection->command = HFP_CMD_NONE;
1022 hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
1021 hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
1023 break;
1024 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
1025 hfp_connection->ok_pending = 0;
1026 hfp_connection->command = HFP_CMD_NONE;
1027 hfp_connection->extended_audio_gateway_error = 0;
1022 break;
1023 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
1024 hfp_connection->ok_pending = 0;
1025 hfp_connection->command = HFP_CMD_NONE;
1026 hfp_connection->extended_audio_gateway_error = 0;
1028 hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value);
1027 hfp_emit_event(hfp_connection, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value);
1029 break;
1030 case HFP_CMD_ERROR:
1031 hfp_connection->ok_pending = 0;
1032 hfp_reset_context_flags(hfp_connection);
1033 hfp_connection->command = HFP_CMD_NONE;
1028 break;
1029 case HFP_CMD_ERROR:
1030 hfp_connection->ok_pending = 0;
1031 hfp_reset_context_flags(hfp_connection);
1032 hfp_connection->command = HFP_CMD_NONE;
1034 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1);
1033 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 1);
1035 break;
1036 case HFP_CMD_OK:
1037 hfp_hf_switch_on_ok(hfp_connection);
1038 break;
1039 case HFP_CMD_RING:
1034 break;
1035 case HFP_CMD_OK:
1036 hfp_hf_switch_on_ok(hfp_connection);
1037 break;
1038 case HFP_CMD_RING:
1040 hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_RING);
1039 hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_RING);
1041 break;
1042 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1043 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){
1044 if (hfp_connection->ag_indicators[i].status_changed) {
1045 if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){
1046 hfp_callsetup_status = (hfp_callsetup_status_t) hfp_connection->ag_indicators[i].status;
1047 } else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){
1048 hfp_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status;
1049 // avoid set but not used warning
1050 (void) hfp_callheld_status;
1051 } else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){
1052 hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status;
1053 }
1054 hfp_connection->ag_indicators[i].status_changed = 0;
1040 break;
1041 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1042 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){
1043 if (hfp_connection->ag_indicators[i].status_changed) {
1044 if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){
1045 hfp_callsetup_status = (hfp_callsetup_status_t) hfp_connection->ag_indicators[i].status;
1046 } else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){
1047 hfp_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status;
1048 // avoid set but not used warning
1049 (void) hfp_callheld_status;
1050 } else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){
1051 hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status;
1052 }
1053 hfp_connection->ag_indicators[i].status_changed = 0;
1055 hfp_emit_ag_indicator_event(hfp_callback, hfp_connection->ag_indicators[i]);
1054 hfp_emit_ag_indicator_event(hfp_hf_callback, hfp_connection->ag_indicators[i]);
1056 break;
1057 }
1058 }
1059 break;
1060 default:
1061 break;
1062 }
1063 hfp_run_for_context(hfp_connection);

--- 24 unchanged lines hidden (view full) ---

1088
1089void hfp_hf_init(uint16_t rfcomm_channel_nr){
1090 // register for HCI events
1091 hci_event_callback_registration.callback = &packet_handler;
1092 hci_add_event_handler(&hci_event_callback_registration);
1093
1094 rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff);
1095
1055 break;
1056 }
1057 }
1058 break;
1059 default:
1060 break;
1061 }
1062 hfp_run_for_context(hfp_connection);

--- 24 unchanged lines hidden (view full) ---

1087
1088void hfp_hf_init(uint16_t rfcomm_channel_nr){
1089 // register for HCI events
1090 hci_event_callback_registration.callback = &packet_handler;
1091 hci_add_event_handler(&hci_event_callback_registration);
1092
1093 rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff);
1094
1096 hfp_set_packet_handler_for_rfcomm_connections(&packet_handler);
1095 hfp_set_hf_rfcomm_packet_handler(&packet_handler);
1097
1098 hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
1099 hfp_codecs_nr = 0;
1100 hfp_indicators_nr = 0;
1101 hfp_hf_speaker_gain = 9;
1102 hfp_hf_microphone_gain = 9;
1103}
1104

--- 553 unchanged lines hidden ---
1096
1097 hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
1098 hfp_codecs_nr = 0;
1099 hfp_indicators_nr = 0;
1100 hfp_hf_speaker_gain = 9;
1101 hfp_hf_microphone_gain = 9;
1102}
1103

--- 553 unchanged lines hidden ---