hfp_hf.c (6ba83b5e65b7df1008f59d6cd59fdde205cd3987) | hfp_hf.c (e2c3b58d3fd5175f415b313f803fc22e5bd181f7) |
---|---|
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 --- 354 unchanged lines hidden (view full) --- 363static int hfp_hf_set_speaker_gain_cmd(uint16_t cid, int gain){ 364 return hfp_hf_send_cmd_with_int(cid, HFP_SET_SPEAKER_GAIN, gain); 365} 366 367static int hfp_hf_set_calling_line_notification_cmd(uint16_t cid, uint8_t activate){ 368 return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_CLIP, activate); 369} 370 | 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 --- 354 unchanged lines hidden (view full) --- 363static int hfp_hf_set_speaker_gain_cmd(uint16_t cid, int gain){ 364 return hfp_hf_send_cmd_with_int(cid, HFP_SET_SPEAKER_GAIN, gain); 365} 366 367static int hfp_hf_set_calling_line_notification_cmd(uint16_t cid, uint8_t activate){ 368 return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_CLIP, activate); 369} 370 |
371static int hfp_hf_set_echo_canceling_and_noise_reduction_cmd(uint16_t cid, uint8_t activate){ 372 return hfp_hf_send_cmd_with_int(cid, HFP_TURN_OFF_EC_AND_NR, activate); 373} 374 | |
375static int hfp_hf_set_voice_recognition_notification_cmd(uint16_t cid, uint8_t activate){ 376 return hfp_hf_send_cmd_with_int(cid, HFP_ACTIVATE_VOICE_RECOGNITION, activate); 377} 378 379static int hfp_hf_set_call_waiting_notification_cmd(uint16_t cid, uint8_t activate){ 380 return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_CALL_WAITING_NOTIFICATION, activate); 381} 382 --- 392 unchanged lines hidden (view full) --- 775 } 776 if (!done){ 777 done = hfp_hf_voice_recognition_state_machine(hfp_connection); 778 } 779 if (!done){ 780 done = call_setup_state_machine(hfp_connection); 781 } 782 | 371static int hfp_hf_set_voice_recognition_notification_cmd(uint16_t cid, uint8_t activate){ 372 return hfp_hf_send_cmd_with_int(cid, HFP_ACTIVATE_VOICE_RECOGNITION, activate); 373} 374 375static int hfp_hf_set_call_waiting_notification_cmd(uint16_t cid, uint8_t activate){ 376 return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_CALL_WAITING_NOTIFICATION, activate); 377} 378 --- 392 unchanged lines hidden (view full) --- 771 } 772 if (!done){ 773 done = hfp_hf_voice_recognition_state_machine(hfp_connection); 774 } 775 if (!done){ 776 done = call_setup_state_machine(hfp_connection); 777 } 778 |
783 // don't send a new command while ok still pending 784 if (hfp_connection->ok_pending) return; 785 | 779 // don't send a new command while ok still pending or SLC is not established 780 if (hfp_connection->ok_pending || (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED)){ 781 return; 782 } 783 |
786 if (hfp_connection->send_microphone_gain){ 787 hfp_connection->send_microphone_gain = 0; 788 hfp_connection->ok_pending = 1; 789 hfp_hf_set_microphone_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->microphone_gain); 790 return; 791 } 792 793 if (hfp_connection->send_speaker_gain){ --- 14 unchanged lines hidden (view full) --- 808 hfp_connection->hf_activate_calling_line_notification = 0; 809 hfp_connection->ok_pending = 1; 810 hfp_hf_set_calling_line_notification_cmd(hfp_connection->rfcomm_cid, 1); 811 return; 812 } 813 814 if (hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction){ 815 hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 0; | 784 if (hfp_connection->send_microphone_gain){ 785 hfp_connection->send_microphone_gain = 0; 786 hfp_connection->ok_pending = 1; 787 hfp_hf_set_microphone_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->microphone_gain); 788 return; 789 } 790 791 if (hfp_connection->send_speaker_gain){ --- 14 unchanged lines hidden (view full) --- 806 hfp_connection->hf_activate_calling_line_notification = 0; 807 hfp_connection->ok_pending = 1; 808 hfp_hf_set_calling_line_notification_cmd(hfp_connection->rfcomm_cid, 1); 809 return; 810 } 811 812 if (hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction){ 813 hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 0; |
814 hfp_connection->hf_ok_pending_for_command = HFP_CMD_TURN_OFF_EC_AND_NR; |
|
816 hfp_connection->ok_pending = 1; | 815 hfp_connection->ok_pending = 1; |
817 hfp_hf_set_echo_canceling_and_noise_reduction_cmd(hfp_connection->rfcomm_cid, 0); | 816 hfp_hf_send_cmd_with_int(hfp_connection->rfcomm_cid, HFP_TURN_OFF_EC_AND_NR, 0); |
818 return; 819 } 820 | 817 return; 818 } 819 |
821 if (hfp_connection->hf_activate_echo_canceling_and_noise_reduction){ 822 hfp_connection->hf_activate_echo_canceling_and_noise_reduction = 0; 823 hfp_connection->ok_pending = 1; 824 hfp_hf_set_echo_canceling_and_noise_reduction_cmd(hfp_connection->rfcomm_cid, 1); 825 return; 826 } 827 | |
828 if (hfp_connection->hf_deactivate_call_waiting_notification){ 829 hfp_connection->hf_deactivate_call_waiting_notification = 0; 830 hfp_connection->ok_pending = 1; 831 hfp_hf_set_call_waiting_notification_cmd(hfp_connection->rfcomm_cid, 0); 832 return; 833 } 834 835 if (hfp_connection->hf_activate_call_waiting_notification){ --- 201 unchanged lines hidden (view full) --- 1037 hfp_connection->suggested_codec = 0; 1038 hfp_connection->negotiated_codec = 0; 1039 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; 1040 1041 hfp_connection->hf_send_supported_codecs = true; 1042 } 1043} 1044 | 820 if (hfp_connection->hf_deactivate_call_waiting_notification){ 821 hfp_connection->hf_deactivate_call_waiting_notification = 0; 822 hfp_connection->ok_pending = 1; 823 hfp_hf_set_call_waiting_notification_cmd(hfp_connection->rfcomm_cid, 0); 824 return; 825 } 826 827 if (hfp_connection->hf_activate_call_waiting_notification){ --- 201 unchanged lines hidden (view full) --- 1029 hfp_connection->suggested_codec = 0; 1030 hfp_connection->negotiated_codec = 0; 1031 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; 1032 1033 hfp_connection->hf_send_supported_codecs = true; 1034 } 1035} 1036 |
1045static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){ 1046 switch (hfp_connection->state){ 1047 case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: 1048 if (has_codec_negotiation_feature(hfp_connection)){ 1049 hfp_connection->state = HFP_NOTIFY_ON_CODECS; 1050 break; 1051 } 1052 hfp_connection->state = HFP_RETRIEVE_INDICATORS; 1053 break; | 1037static bool hfp_hf_switch_on_ok_pending(hfp_connection_t *hfp_connection, uint8_t status){ 1038 bool event_emited = true; |
1054 | 1039 |
1055 case HFP_W4_NOTIFY_ON_CODECS: 1056 hfp_connection->state = HFP_RETRIEVE_INDICATORS; 1057 break; 1058 1059 case HFP_W4_RETRIEVE_INDICATORS: 1060 hfp_connection->state = HFP_RETRIEVE_INDICATORS_STATUS; | 1040 switch (hfp_connection->hf_ok_pending_for_command){ 1041 case HFP_CMD_TURN_OFF_EC_AND_NR: 1042 hfp_emit_event(hfp_connection, HFP_SUBEVENT_ECHO_CANCELING_AND_NOISE_REDUCTION_DEACTIVATE, status); |
1061 break; | 1043 break; |
1062 1063 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 1064 hfp_connection->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE; 1065 break; 1066 1067 case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE: 1068 if (has_call_waiting_and_3way_calling_feature(hfp_connection)){ 1069 hfp_connection->state = HFP_RETRIEVE_CAN_HOLD_CALL; 1070 break; 1071 } 1072 if (has_hf_indicators_feature(hfp_connection)){ 1073 hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS; 1074 break; 1075 } 1076 hfp_ag_slc_established(hfp_connection); 1077 break; 1078 1079 case HFP_W4_RETRIEVE_CAN_HOLD_CALL: 1080 if (has_hf_indicators_feature(hfp_connection)){ 1081 hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS; 1082 break; 1083 } 1084 hfp_ag_slc_established(hfp_connection); 1085 break; 1086 1087 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: 1088 hfp_connection->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS; 1089 break; | 1044 default: 1045 event_emited = false; 1046 1047 switch (hfp_connection->state){ 1048 case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: 1049 if (has_codec_negotiation_feature(hfp_connection)){ 1050 hfp_connection->state = HFP_NOTIFY_ON_CODECS; 1051 break; 1052 } 1053 hfp_connection->state = HFP_RETRIEVE_INDICATORS; 1054 break; |
1090 | 1055 |
1091 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: 1092 hfp_connection->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; 1093 break; | 1056 case HFP_W4_NOTIFY_ON_CODECS: 1057 hfp_connection->state = HFP_RETRIEVE_INDICATORS; 1058 break; 1059 1060 case HFP_W4_RETRIEVE_INDICATORS: 1061 hfp_connection->state = HFP_RETRIEVE_INDICATORS_STATUS; 1062 break; 1063 1064 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 1065 hfp_connection->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE; 1066 break; |
1094 | 1067 |
1095 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 1096 hfp_ag_slc_established(hfp_connection); 1097 break; 1098 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 1099 if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){ 1100 hfp_connection->enable_status_update_for_ag_indicators = 0xFF; 1101 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 0); 1102 break; 1103 } 1104 1105 if (hfp_connection->change_status_update_for_individual_ag_indicators == 1){ 1106 hfp_connection->change_status_update_for_individual_ag_indicators = 0; 1107 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 0); 1108 break; 1109 } 1110 1111 switch (hfp_connection->hf_query_operator_state){ 1112 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK: 1113 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; | 1068 case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE: 1069 if (has_call_waiting_and_3way_calling_feature(hfp_connection)){ 1070 hfp_connection->state = HFP_RETRIEVE_CAN_HOLD_CALL; 1071 break; 1072 } 1073 if (has_hf_indicators_feature(hfp_connection)){ 1074 hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS; 1075 break; 1076 } 1077 hfp_ag_slc_established(hfp_connection); |
1114 break; | 1078 break; |
1115 case HPF_HF_QUERY_OPERATOR_W4_RESULT: 1116 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET; 1117 hfp_emit_network_operator_event(hfp_connection); | 1079 1080 case HFP_W4_RETRIEVE_CAN_HOLD_CALL: 1081 if (has_hf_indicators_feature(hfp_connection)){ 1082 hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS; 1083 break; 1084 } 1085 hfp_ag_slc_established(hfp_connection); |
1118 break; | 1086 break; |
1119 default: | 1087 1088 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: 1089 hfp_connection->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS; |
1120 break; | 1090 break; |
1121 } | |
1122 | 1091 |
1123 if (hfp_connection->enable_extended_audio_gateway_error_report){ 1124 hfp_connection->enable_extended_audio_gateway_error_report = 0; 1125 break; 1126 } 1127 1128 switch (hfp_connection->codecs_state){ 1129 case HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE: 1130 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; | 1092 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: 1093 hfp_connection->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; |
1131 break; | 1094 break; |
1132 case HFP_CODECS_HF_CONFIRMED_CODEC: 1133 hfp_connection->codecs_state = HFP_CODECS_EXCHANGED; | 1095 1096 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 1097 hfp_ag_slc_established(hfp_connection); |
1134 break; | 1098 break; |
1099 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 1100 if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){ 1101 hfp_connection->enable_status_update_for_ag_indicators = 0xFF; 1102 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 0); 1103 break; 1104 } 1105 1106 if (hfp_connection->change_status_update_for_individual_ag_indicators == 1){ 1107 hfp_connection->change_status_update_for_individual_ag_indicators = 0; 1108 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 0); 1109 break; 1110 } 1111 1112 switch (hfp_connection->hf_query_operator_state){ 1113 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK: 1114 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; 1115 break; 1116 case HPF_HF_QUERY_OPERATOR_W4_RESULT: 1117 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET; 1118 hfp_emit_network_operator_event(hfp_connection); 1119 break; 1120 default: 1121 break; 1122 } 1123 1124 if (hfp_connection->enable_extended_audio_gateway_error_report){ 1125 hfp_connection->enable_extended_audio_gateway_error_report = 0; 1126 break; 1127 } 1128 1129 switch (hfp_connection->codecs_state){ 1130 case HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE: 1131 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; 1132 break; 1133 case HFP_CODECS_HF_CONFIRMED_CODEC: 1134 hfp_connection->codecs_state = HFP_CODECS_EXCHANGED; 1135 break; 1136 default: 1137 break; 1138 } 1139 hfp_hf_voice_recognition_state_machine(hfp_connection); 1140 break; 1141 case HFP_AUDIO_CONNECTION_ESTABLISHED: 1142 hfp_hf_voice_recognition_state_machine(hfp_connection); 1143 break; |
|
1135 default: 1136 break; 1137 } | 1144 default: 1145 break; 1146 } |
1138 hfp_hf_voice_recognition_state_machine(hfp_connection); | |
1139 break; | 1147 break; |
1140 case HFP_AUDIO_CONNECTION_ESTABLISHED: 1141 hfp_hf_voice_recognition_state_machine(hfp_connection); 1142 break; 1143 default: 1144 break; | |
1145 } 1146 1147 // done | 1148 } 1149 1150 // done |
1151 hfp_connection->hf_ok_pending_for_command = HFP_CMD_NONE; |
|
1148 hfp_connection->ok_pending = 0; 1149 hfp_connection->command = HFP_CMD_NONE; | 1152 hfp_connection->ok_pending = 0; 1153 hfp_connection->command = HFP_CMD_NONE; |
1154 return event_emited; |
|
1150} 1151 1152 1153static void hfp_hf_handle_transfer_ag_indicator_status(hfp_connection_t * hfp_connection) { 1154 uint16_t i; 1155 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ 1156 if (hfp_connection->ag_indicators[i].status_changed) { 1157 if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){ --- 10 unchanged lines hidden (view full) --- 1168 break; 1169 } 1170 } 1171} 1172 1173static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){ 1174 int value; 1175 int i; | 1155} 1156 1157 1158static void hfp_hf_handle_transfer_ag_indicator_status(hfp_connection_t * hfp_connection) { 1159 uint16_t i; 1160 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ 1161 if (hfp_connection->ag_indicators[i].status_changed) { 1162 if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){ --- 10 unchanged lines hidden (view full) --- 1173 break; 1174 } 1175 } 1176} 1177 1178static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){ 1179 int value; 1180 int i; |
1181 bool event_emited; 1182 |
|
1176 switch (hfp_connection->command){ 1177 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1178 hfp_connection->command = HFP_CMD_NONE; 1179 hfp_hf_emit_subscriber_information(hfp_connection, 0); 1180 break; 1181 case HFP_CMD_RESPONSE_AND_HOLD_STATUS: 1182 hfp_connection->command = HFP_CMD_NONE; 1183 hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0])); --- 44 unchanged lines hidden (view full) --- 1228 return; 1229 default: 1230 break; 1231 } 1232 break; 1233 default: 1234 break; 1235 } | 1183 switch (hfp_connection->command){ 1184 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1185 hfp_connection->command = HFP_CMD_NONE; 1186 hfp_hf_emit_subscriber_information(hfp_connection, 0); 1187 break; 1188 case HFP_CMD_RESPONSE_AND_HOLD_STATUS: 1189 hfp_connection->command = HFP_CMD_NONE; 1190 hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0])); --- 44 unchanged lines hidden (view full) --- 1235 return; 1236 default: 1237 break; 1238 } 1239 break; 1240 default: 1241 break; 1242 } |
1243 |
|
1236 // handle error response for voice activation (HF initiated) 1237 switch(hfp_connection->vra_state_requested){ 1238 case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 1239 hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); 1240 break; 1241 default: | 1244 // handle error response for voice activation (HF initiated) 1245 switch(hfp_connection->vra_state_requested){ 1246 case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 1247 hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); 1248 break; 1249 default: |
1250 if (hfp_connection->vra_state_requested == hfp_connection->vra_state){ 1251 break; 1252 } |
|
1242 hfp_connection->vra_state_requested = hfp_connection->vra_state; 1243 hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); 1244 hfp_reset_context_flags(hfp_connection); 1245 return; 1246 } | 1253 hfp_connection->vra_state_requested = hfp_connection->vra_state; 1254 hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); 1255 hfp_reset_context_flags(hfp_connection); 1256 return; 1257 } |
1247 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 1); | 1258 event_emited = hfp_hf_switch_on_ok_pending(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); 1259 if (!event_emited){ 1260 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 1); 1261 } |
1248 hfp_reset_context_flags(hfp_connection); 1249 break; 1250 1251 case HFP_CMD_OK: | 1262 hfp_reset_context_flags(hfp_connection); 1263 break; 1264 1265 case HFP_CMD_OK: |
1252 hfp_hf_switch_on_ok(hfp_connection); 1253 break; | 1266 hfp_hf_switch_on_ok_pending(hfp_connection, ERROR_CODE_SUCCESS); 1267 break; |
1254 case HFP_CMD_RING: 1255 hfp_connection->command = HFP_CMD_NONE; 1256 hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_RING); 1257 break; 1258 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1259 hfp_connection->command = HFP_CMD_NONE; 1260 hfp_hf_handle_transfer_ag_indicator_status(hfp_connection); 1261 break; --- 839 unchanged lines hidden --- | 1268 case HFP_CMD_RING: 1269 hfp_connection->command = HFP_CMD_NONE; 1270 hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_RING); 1271 break; 1272 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1273 hfp_connection->command = HFP_CMD_NONE; 1274 hfp_hf_handle_transfer_ag_indicator_status(hfp_connection); 1275 break; --- 839 unchanged lines hidden --- |