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 ---