hfp_hf.c (1599fe578e18777a3d9adc935c69c34270df6b8a) | hfp_hf.c (a473a0097d11744933738d68d893365ee9e98f28) |
---|---|
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 --- 109 unchanged lines hidden (view full) --- 118 if (hfp_connection->local_role != HFP_ROLE_HF) continue; 119 return hfp_connection; 120 } 121 return NULL; 122} 123 124/* emit functinos */ 125 | 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 --- 109 unchanged lines hidden (view full) --- 118 if (hfp_connection->local_role != HFP_ROLE_HF) continue; 119 return hfp_connection; 120 } 121 return NULL; 122} 123 124/* emit functinos */ 125 |
126static 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){ 127 if (!callback) return; | 126static void hfp_hf_emit_subscriber_information(const hfp_connection_t * hfp_connection, uint8_t status){ 127 if (hfp_hf_callback == NULL) return; |
128 uint8_t event[31]; 129 event[0] = HCI_EVENT_HFP_META; 130 event[1] = sizeof(event) - 2; | 128 uint8_t event[31]; 129 event[0] = HCI_EVENT_HFP_META; 130 event[1] = sizeof(event) - 2; |
131 event[2] = event_subtype; | 131 event[2] = HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION; |
132 event[3] = status; | 132 event[3] = status; |
133 event[4] = bnip_type; 134 uint16_t size = btstack_min(strlen(bnip_number), sizeof(event) - 6); 135 strncpy((char*)&event[5], bnip_number, size); | 133 event[4] = hfp_connection->bnip_type; 134 uint16_t size = btstack_min(strlen(hfp_connection->bnip_number), sizeof(event) - 6); 135 strncpy((char*)&event[5], hfp_connection->bnip_number, size); |
136 event[5 + size] = 0; | 136 event[5 + size] = 0; |
137 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); | 137 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); |
138} 139 | 138} 139 |
140static void hfp_hf_emit_type_and_number(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t bnip_type, const char * bnip_number){ 141 if (!callback) return; | 140static void hfp_hf_emit_type_and_number(const hfp_connection_t * hfp_connection, uint8_t event_subtype){ 141 if (hfp_hf_callback == NULL) return; |
142 uint8_t event[30]; 143 event[0] = HCI_EVENT_HFP_META; 144 event[1] = sizeof(event) - 2; 145 event[2] = event_subtype; | 142 uint8_t event[30]; 143 event[0] = HCI_EVENT_HFP_META; 144 event[1] = sizeof(event) - 2; 145 event[2] = event_subtype; |
146 event[3] = bnip_type; 147 uint16_t size = btstack_min(strlen(bnip_number), sizeof(event) - 5); 148 strncpy((char*)&event[4], bnip_number, size); | 146 event[3] = hfp_connection->bnip_type; 147 uint16_t size = btstack_min(strlen(hfp_connection->bnip_number), sizeof(event) - 5); 148 strncpy((char*)&event[4], hfp_connection->bnip_number, size); |
149 event[4 + size] = 0; | 149 event[4 + size] = 0; |
150 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); | 150 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); |
151} 152 | 151} 152 |
153static void hfp_hf_emit_enhanced_call_status(btstack_packet_handler_t callback, hfp_connection_t * connection){ 154 if (!callback) return; | 153static void hfp_hf_emit_enhanced_call_status(const hfp_connection_t * hfp_connection){ 154 if (hfp_hf_callback == NULL) return; |
155 uint8_t event[36]; 156 int pos = 0; 157 event[pos++] = HCI_EVENT_HFP_META; 158 event[pos++] = sizeof(event) - 2; 159 event[pos++] = HFP_SUBEVENT_ENHANCED_CALL_STATUS; | 155 uint8_t event[36]; 156 int pos = 0; 157 event[pos++] = HCI_EVENT_HFP_META; 158 event[pos++] = sizeof(event) - 2; 159 event[pos++] = HFP_SUBEVENT_ENHANCED_CALL_STATUS; |
160 event[pos++] = connection->clcc_idx; 161 event[pos++] = connection->clcc_dir; 162 event[pos++] = connection->clcc_status; 163 event[pos++] = connection->clcc_mode; 164 event[pos++] = connection->clcc_mpty; 165 event[pos++] = connection->bnip_type; 166 uint16_t size = btstack_min(strlen(connection->bnip_number), sizeof(event) - pos); 167 strncpy((char*)&event[pos], connection->bnip_number, size); | 160 event[pos++] = hfp_connection->clcc_idx; 161 event[pos++] = hfp_connection->clcc_dir; 162 event[pos++] = hfp_connection->clcc_status; 163 event[pos++] = hfp_connection->clcc_mode; 164 event[pos++] = hfp_connection->clcc_mpty; 165 event[pos++] = hfp_connection->bnip_type; 166 uint16_t size = btstack_min(strlen(hfp_connection->bnip_number), sizeof(event) - pos); 167 strncpy((char*)&event[pos], hfp_connection->bnip_number, size); |
168 pos += size; 169 event[pos++] = 0; | 168 pos += size; 169 event[pos++] = 0; |
170 (*callback)(HCI_EVENT_PACKET, 0, event, pos); | 170 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, pos); |
171} 172 173 | 171} 172 173 |
174static void hfp_emit_ag_indicator_event(btstack_packet_handler_t callback, hfp_ag_indicator_t indicator){ 175 if (!callback) return; | 174static void hfp_emit_ag_indicator_event(const hfp_connection_t * hfp_connection, const hfp_ag_indicator_t * indicator){ 175 if (hfp_hf_callback == NULL) return; |
176 uint8_t event[10+HFP_MAX_INDICATOR_DESC_SIZE+1]; 177 int pos = 0; 178 event[pos++] = HCI_EVENT_HFP_META; 179 event[pos++] = sizeof(event) - 2; 180 event[pos++] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED; | 176 uint8_t event[10+HFP_MAX_INDICATOR_DESC_SIZE+1]; 177 int pos = 0; 178 event[pos++] = HCI_EVENT_HFP_META; 179 event[pos++] = sizeof(event) - 2; 180 event[pos++] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED; |
181 event[pos++] = indicator.index; 182 event[pos++] = indicator.status; 183 event[pos++] = indicator.min_range; 184 event[pos++] = indicator.max_range; 185 event[pos++] = indicator.mandatory; 186 event[pos++] = indicator.enabled; 187 event[pos++] = indicator.status_changed; 188 strncpy((char*)&event[pos], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE); | 181 event[pos++] = indicator->index; 182 event[pos++] = indicator->status; 183 event[pos++] = indicator->min_range; 184 event[pos++] = indicator->max_range; 185 event[pos++] = indicator->mandatory; 186 event[pos++] = indicator->enabled; 187 event[pos++] = indicator->status_changed; 188 strncpy((char*)&event[pos], indicator->name, HFP_MAX_INDICATOR_DESC_SIZE); |
189 pos += HFP_MAX_INDICATOR_DESC_SIZE; 190 event[pos] = 0; | 189 pos += HFP_MAX_INDICATOR_DESC_SIZE; 190 event[pos] = 0; |
191 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); | 191 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); |
192} 193 | 192} 193 |
194static void hfp_emit_network_operator_event(btstack_packet_handler_t callback, hfp_network_opearator_t network_operator){ 195 if (!callback) return; | 194static void hfp_emit_network_operator_event(const hfp_connection_t * hfp_connection){ 195 if (hfp_hf_callback == NULL) return; |
196 uint8_t event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE+1]; 197 event[0] = HCI_EVENT_HFP_META; 198 event[1] = sizeof(event) - 2; 199 event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED; | 196 uint8_t event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE+1]; 197 event[0] = HCI_EVENT_HFP_META; 198 event[1] = sizeof(event) - 2; 199 event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED; |
200 event[3] = network_operator.mode; 201 event[4] = network_operator.format; 202 strncpy((char*)&event[5], network_operator.name, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE); | 200 event[3] = hfp_connection->network_operator.mode; 201 event[4] = hfp_connection->network_operator.format; 202 strncpy((char*)&event[5], hfp_connection->network_operator.name, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE); |
203 event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE] = 0; | 203 event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE] = 0; |
204 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); | 204 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); |
205} 206 207/* send commands */ 208 209static inline int hfp_hf_send_cmd(uint16_t cid, const char * cmd){ 210 char buffer[20]; 211 snprintf(buffer, sizeof(buffer), "AT%s\r", cmd); 212 return send_str_over_rfcomm(cid, buffer); --- 794 unchanged lines hidden (view full) --- 1007 } 1008 1009 switch (hfp_connection->hf_query_operator_state){ 1010 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK: 1011 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; 1012 break; 1013 case HPF_HF_QUERY_OPERATOR_W4_RESULT: 1014 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET; | 205} 206 207/* send commands */ 208 209static inline int hfp_hf_send_cmd(uint16_t cid, const char * cmd){ 210 char buffer[20]; 211 snprintf(buffer, sizeof(buffer), "AT%s\r", cmd); 212 return send_str_over_rfcomm(cid, buffer); --- 794 unchanged lines hidden (view full) --- 1007 } 1008 1009 switch (hfp_connection->hf_query_operator_state){ 1010 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK: 1011 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; 1012 break; 1013 case HPF_HF_QUERY_OPERATOR_W4_RESULT: 1014 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET; |
1015 hfp_emit_network_operator_event(hfp_hf_callback, hfp_connection->network_operator); | 1015 hfp_emit_network_operator_event(hfp_connection); |
1016 break; 1017 default: 1018 break; 1019 } 1020 1021 if (hfp_connection->enable_extended_audio_gateway_error_report){ 1022 hfp_connection->enable_extended_audio_gateway_error_report = 0; 1023 break; --- 27 unchanged lines hidden (view full) --- 1051 } else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){ 1052 hfp_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status; 1053 // avoid set but not used warning 1054 (void) hfp_callheld_status; 1055 } else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){ 1056 hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status; 1057 } 1058 hfp_connection->ag_indicators[i].status_changed = 0; | 1016 break; 1017 default: 1018 break; 1019 } 1020 1021 if (hfp_connection->enable_extended_audio_gateway_error_report){ 1022 hfp_connection->enable_extended_audio_gateway_error_report = 0; 1023 break; --- 27 unchanged lines hidden (view full) --- 1051 } else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){ 1052 hfp_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status; 1053 // avoid set but not used warning 1054 (void) hfp_callheld_status; 1055 } else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){ 1056 hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status; 1057 } 1058 hfp_connection->ag_indicators[i].status_changed = 0; |
1059 hfp_emit_ag_indicator_event(hfp_hf_callback, hfp_connection->ag_indicators[i]); | 1059 hfp_emit_ag_indicator_event(hfp_connection, &hfp_connection->ag_indicators[i]); |
1060 break; 1061 } 1062 } 1063} 1064 1065static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){ 1066 int value; 1067 int i; 1068 switch (hfp_connection->command){ 1069 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1070 hfp_connection->command = HFP_CMD_NONE; | 1060 break; 1061 } 1062 } 1063} 1064 1065static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){ 1066 int value; 1067 int i; 1068 switch (hfp_connection->command){ 1069 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1070 hfp_connection->command = HFP_CMD_NONE; |
1071 hfp_hf_emit_subscriber_information(hfp_hf_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number); | 1071 hfp_hf_emit_subscriber_information(hfp_connection, 0); |
1072 break; 1073 case HFP_CMD_RESPONSE_AND_HOLD_STATUS: 1074 hfp_connection->command = HFP_CMD_NONE; 1075 hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0])); 1076 break; 1077 case HFP_CMD_LIST_CURRENT_CALLS: 1078 hfp_connection->command = HFP_CMD_NONE; | 1072 break; 1073 case HFP_CMD_RESPONSE_AND_HOLD_STATUS: 1074 hfp_connection->command = HFP_CMD_NONE; 1075 hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0])); 1076 break; 1077 case HFP_CMD_LIST_CURRENT_CALLS: 1078 hfp_connection->command = HFP_CMD_NONE; |
1079 hfp_hf_emit_enhanced_call_status(hfp_hf_callback, hfp_connection); | 1079 hfp_hf_emit_enhanced_call_status(hfp_connection); |
1080 break; 1081 case HFP_CMD_SET_SPEAKER_GAIN: 1082 hfp_connection->command = HFP_CMD_NONE; 1083 value = btstack_atoi((char*)hfp_connection->line_buffer); 1084 hfp_hf_speaker_gain = value; 1085 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, value); 1086 break; 1087 case HFP_CMD_SET_MICROPHONE_GAIN: 1088 hfp_connection->command = HFP_CMD_NONE; 1089 value = btstack_atoi((char*)hfp_connection->line_buffer); 1090 hfp_hf_microphone_gain = value; 1091 hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, value); 1092 break; 1093 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1094 hfp_connection->command = HFP_CMD_NONE; 1095 hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number); 1096 break; 1097 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1098 hfp_connection->command = HFP_CMD_NONE; | 1080 break; 1081 case HFP_CMD_SET_SPEAKER_GAIN: 1082 hfp_connection->command = HFP_CMD_NONE; 1083 value = btstack_atoi((char*)hfp_connection->line_buffer); 1084 hfp_hf_speaker_gain = value; 1085 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, value); 1086 break; 1087 case HFP_CMD_SET_MICROPHONE_GAIN: 1088 hfp_connection->command = HFP_CMD_NONE; 1089 value = btstack_atoi((char*)hfp_connection->line_buffer); 1090 hfp_hf_microphone_gain = value; 1091 hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, value); 1092 break; 1093 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1094 hfp_connection->command = HFP_CMD_NONE; 1095 hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number); 1096 break; 1097 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1098 hfp_connection->command = HFP_CMD_NONE; |
1099 hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number); | 1099 hfp_hf_emit_type_and_number(hfp_connection, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION); |
1100 break; 1101 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1102 hfp_connection->command = HFP_CMD_NONE; | 1100 break; 1101 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1102 hfp_connection->command = HFP_CMD_NONE; |
1103 hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number); | 1103 hfp_hf_emit_type_and_number(hfp_connection, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION); |
1104 break; 1105 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 1106 hfp_connection->command = HFP_CMD_NONE; 1107 hfp_connection->ok_pending = 0; 1108 hfp_connection->extended_audio_gateway_error = 0; 1109 hfp_emit_event(hfp_connection, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value); 1110 break; 1111 case HFP_CMD_ERROR: --- 23 unchanged lines hidden (view full) --- 1135 break; 1136 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1137 hfp_connection->command = HFP_CMD_NONE; 1138 hfp_hf_handle_transfer_ag_indicator_status(hfp_connection); 1139 break; 1140 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: 1141 hfp_connection->command = HFP_CMD_NONE; 1142 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ | 1104 break; 1105 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 1106 hfp_connection->command = HFP_CMD_NONE; 1107 hfp_connection->ok_pending = 0; 1108 hfp_connection->extended_audio_gateway_error = 0; 1109 hfp_emit_event(hfp_connection, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value); 1110 break; 1111 case HFP_CMD_ERROR: --- 23 unchanged lines hidden (view full) --- 1135 break; 1136 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1137 hfp_connection->command = HFP_CMD_NONE; 1138 hfp_hf_handle_transfer_ag_indicator_status(hfp_connection); 1139 break; 1140 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: 1141 hfp_connection->command = HFP_CMD_NONE; 1142 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ |
1143 hfp_emit_ag_indicator_event(hfp_hf_callback, hfp_connection->ag_indicators[i]); | 1143 hfp_emit_ag_indicator_event(hfp_connection, &hfp_connection->ag_indicators[i]); |
1144 } 1145 break; 1146 case HFP_CMD_AG_SUGGESTED_CODEC: 1147 hfp_connection->command = HFP_CMD_NONE; 1148 hfp_hf_handle_suggested_codec(hfp_connection); 1149 break; 1150 default: 1151 break; --- 699 unchanged lines hidden --- | 1144 } 1145 break; 1146 case HFP_CMD_AG_SUGGESTED_CODEC: 1147 hfp_connection->command = HFP_CMD_NONE; 1148 hfp_hf_handle_suggested_codec(hfp_connection); 1149 break; 1150 default: 1151 break; --- 699 unchanged lines hidden --- |