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