hfp_hf.c (fc64f94a8301d3d0e398cde6b9b488722d71c2fc) hfp_hf.c (a0ffb263e02c613f9155d5035f68cb0ad7b80d74)
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

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

66static const char default_hfp_hf_service_name[] = "Hands-Free unit";
67static uint16_t hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
68static uint8_t hfp_codecs_nr = 0;
69static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS];
70
71static uint8_t hfp_indicators_nr = 0;
72static uint8_t hfp_indicators[HFP_MAX_NUM_HF_INDICATORS];
73static uint32_t hfp_indicators_value[HFP_MAX_NUM_HF_INDICATORS];
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

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

66static const char default_hfp_hf_service_name[] = "Hands-Free unit";
67static uint16_t hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
68static uint8_t hfp_codecs_nr = 0;
69static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS];
70
71static uint8_t hfp_indicators_nr = 0;
72static uint8_t hfp_indicators[HFP_MAX_NUM_HF_INDICATORS];
73static uint32_t hfp_indicators_value[HFP_MAX_NUM_HF_INDICATORS];
74static uint16_t hfp_indicators_status;
75
76static uint8_t hfp_hf_speaker_gain = 9;
77static uint8_t hfp_hf_microphone_gain = 9;
78
79static hfp_callback_t hfp_callback;
80
81static hfp_call_status_t hfp_call_status;
82static hfp_callsetup_status_t hfp_callsetup_status;

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

91 if (callback == NULL){
92 log_error("hfp_hf_register_packet_handler called with NULL callback");
93 return;
94 }
95 hfp_callback = callback;
96 hfp_set_callback(callback);
97}
98
74
75static uint8_t hfp_hf_speaker_gain = 9;
76static uint8_t hfp_hf_microphone_gain = 9;
77
78static hfp_callback_t hfp_callback;
79
80static hfp_call_status_t hfp_call_status;
81static hfp_callsetup_status_t hfp_callsetup_status;

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

90 if (callback == NULL){
91 log_error("hfp_hf_register_packet_handler called with NULL callback");
92 return;
93 }
94 hfp_callback = callback;
95 hfp_set_callback(callback);
96}
97
98static void hfp_hf_emit_subscriber_information(hfp_callback_t callback, uint8_t event_subtype, uint8_t status, uint8_t bnip_type, const char * bnip_number){
99 if (!callback) return;
100 uint8_t event[31];
101 event[0] = HCI_EVENT_HFP_META;
102 event[1] = sizeof(event) - 2;
103 event[2] = event_subtype;
104 event[3] = status;
105 event[4] = bnip_type;
106 int size = (strlen(bnip_number) < sizeof(event) - 6) ? strlen(bnip_number) : sizeof(event) - 6;
107 strncpy((char*)&event[5], bnip_number, size);
108 event[5 + size] = 0;
109 (*callback)(event, sizeof(event));
110}
111
112static void hfp_hf_emit_type_and_number(hfp_callback_t callback, uint8_t event_subtype, uint8_t bnip_type, const char * bnip_number){
113 if (!callback) return;
114 uint8_t event[30];
115 event[0] = HCI_EVENT_HFP_META;
116 event[1] = sizeof(event) - 2;
117 event[2] = event_subtype;
118 event[3] = bnip_type;
119 int size = (strlen(bnip_number) < sizeof(event) - 5) ? strlen(bnip_number) : sizeof(event) - 5;
120 strncpy((char*)&event[4], bnip_number, size);
121 event[4 + size] = 0;
122 (*callback)(event, sizeof(event));
123}
124
125static void hfp_hf_emit_enhanced_call_status(hfp_callback_t callback, uint8_t clcc_idx, uint8_t clcc_dir,
126 uint8_t clcc_status, uint8_t clcc_mpty, uint8_t bnip_type, const char * bnip_number){
127 if (!callback) return;
128 uint8_t event[35];
129 event[0] = HCI_EVENT_HFP_META;
130 event[1] = sizeof(event) - 2;
131 event[2] = HFP_SUBEVENT_ENHANCED_CALL_STATUS;
132 event[3] = clcc_idx;
133 event[4] = clcc_dir;
134 event[6] = clcc_status;
135 event[7] = clcc_mpty;
136 event[8] = bnip_type;
137 int size = (strlen(bnip_number) < sizeof(event) - 10) ? strlen(bnip_number) : sizeof(event) - 10;
138 strncpy((char*)&event[9], bnip_number, size);
139 event[9 + size] = 0;
140 (*callback)(event, sizeof(event));
141}
142
99static int hfp_hf_supports_codec(uint8_t codec){
100 int i;
101 for (i = 0; i < hfp_codecs_nr; i++){
102 if (hfp_codecs[i] == codec) return 1;
103 }
104 return HFP_CODEC_CVSD;
105}
143static int hfp_hf_supports_codec(uint8_t codec){
144 int i;
145 for (i = 0; i < hfp_codecs_nr; i++){
146 if (hfp_codecs[i] == codec) return 1;
147 }
148 return HFP_CODEC_CVSD;
149}
106static int has_codec_negotiation_feature(hfp_connection_t * connection){
150static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){
107 int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION);
151 int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION);
108 int ag = get_bit(connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION);
152 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION);
109 return hf && ag;
110}
111
153 return hf && ag;
154}
155
112static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * connection){
156static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * hfp_connection){
113 int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING);
157 int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING);
114 int ag = get_bit(connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING);
158 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING);
115 return hf && ag;
116}
117
118
159 return hf && ag;
160}
161
162
119static int has_hf_indicators_feature(hfp_connection_t * connection){
163static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){
120 int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS);
164 int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS);
121 int ag = get_bit(connection->remote_supported_features, HFP_AGSF_HF_INDICATORS);
165 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_HF_INDICATORS);
122 return hf && ag;
123}
124
125static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
126
127void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features){
128 if (!name){
129 name = default_hfp_hf_service_name;

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

283}
284
285static int hfp_hf_initiate_outgoing_call_cmd(uint16_t cid){
286 char buffer[40];
287 sprintf(buffer, "%s%s;\r\n", HFP_CALL_PHONE_NUMBER, phone_number);
288 return send_str_over_rfcomm(cid, buffer);
289}
290
166 return hf && ag;
167}
168
169static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
170
171void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features){
172 if (!name){
173 name = default_hfp_hf_service_name;

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

327}
328
329static int hfp_hf_initiate_outgoing_call_cmd(uint16_t cid){
330 char buffer[40];
331 sprintf(buffer, "%s%s;\r\n", HFP_CALL_PHONE_NUMBER, phone_number);
332 return send_str_over_rfcomm(cid, buffer);
333}
334
291static int hfp_hf_send_memory_dial_cmd(uint16_t cid){
335static int hfp_hf_send_memory_dial_cmd(uint16_t cid, int memory_id){
292 char buffer[40];
336 char buffer[40];
293 sprintf(buffer, "%s>%s;\r\n", HFP_CALL_PHONE_NUMBER, phone_number);
337 sprintf(buffer, "%s>%d;\r\n", HFP_CALL_PHONE_NUMBER, memory_id);
294 return send_str_over_rfcomm(cid, buffer);
295}
296
297static int hfp_hf_send_redial_last_number_cmd(uint16_t cid){
298 char buffer[20];
299 sprintf(buffer, "AT%s\r\n", HFP_REDIAL_LAST_NUMBER);
300 return send_str_over_rfcomm(cid, buffer);
301}

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

325}
326
327static int hfp_hf_send_clcc(uint16_t cid){
328 char buffer[20];
329 sprintf(buffer, "AT%s\r\n", HFP_LIST_CURRENT_CALLS);
330 return send_str_over_rfcomm(cid, buffer);
331}
332
338 return send_str_over_rfcomm(cid, buffer);
339}
340
341static int hfp_hf_send_redial_last_number_cmd(uint16_t cid){
342 char buffer[20];
343 sprintf(buffer, "AT%s\r\n", HFP_REDIAL_LAST_NUMBER);
344 return send_str_over_rfcomm(cid, buffer);
345}

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

369}
370
371static int hfp_hf_send_clcc(uint16_t cid){
372 char buffer[20];
373 sprintf(buffer, "AT%s\r\n", HFP_LIST_CURRENT_CALLS);
374 return send_str_over_rfcomm(cid, buffer);
375}
376
333static void hfp_emit_ag_indicator_event(hfp_callback_t callback, int status, hfp_ag_indicator_t indicator){
377static void hfp_emit_ag_indicator_event(hfp_callback_t callback, hfp_ag_indicator_t indicator){
334 if (!callback) return;
378 if (!callback) return;
335 uint8_t event[6+HFP_MAX_INDICATOR_DESC_SIZE+1];
379 uint8_t event[5+HFP_MAX_INDICATOR_DESC_SIZE+1];
336 event[0] = HCI_EVENT_HFP_META;
337 event[1] = sizeof(event) - 2;
338 event[2] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED;
380 event[0] = HCI_EVENT_HFP_META;
381 event[1] = sizeof(event) - 2;
382 event[2] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED;
339 event[3] = status;
340 event[4] = indicator.index;
341 event[5] = indicator.status;
342 strncpy((char*)&event[6], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE);
343 event[6+HFP_MAX_INDICATOR_DESC_SIZE] = 0;
383 event[3] = indicator.index;
384 event[4] = indicator.status;
385 strncpy((char*)&event[5], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE);
386 event[5+HFP_MAX_INDICATOR_DESC_SIZE] = 0;
344 (*callback)(event, sizeof(event));
345}
346
387 (*callback)(event, sizeof(event));
388}
389
347static void hfp_emit_network_operator_event(hfp_callback_t callback, int status, hfp_network_opearator_t network_operator){
390static void hfp_emit_network_operator_event(hfp_callback_t callback, hfp_network_opearator_t network_operator){
348 if (!callback) return;
349 uint8_t event[24];
350 event[0] = HCI_EVENT_HFP_META;
351 event[1] = sizeof(event) - 2;
352 event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED;
391 if (!callback) return;
392 uint8_t event[24];
393 event[0] = HCI_EVENT_HFP_META;
394 event[1] = sizeof(event) - 2;
395 event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED;
353 event[3] = status;
354 event[4] = network_operator.mode;
355 event[5] = network_operator.format;
356 strcpy((char*)&event[6], network_operator.name);
396 event[3] = network_operator.mode;
397 event[4] = network_operator.format;
398 strcpy((char*)&event[5], network_operator.name);
357 (*callback)(event, sizeof(event));
358}
359
399 (*callback)(event, sizeof(event));
400}
401
360static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * context){
361 if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0;
362 if (context->ok_pending) return 0;
402static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * hfp_connection){
403 if (hfp_connection->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0;
404 if (hfp_connection->ok_pending) return 0;
363 int done = 1;
364
405 int done = 1;
406
365 switch (context->state){
407 switch (hfp_connection->state){
366 case HFP_EXCHANGE_SUPPORTED_FEATURES:
408 case HFP_EXCHANGE_SUPPORTED_FEATURES:
367 context->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES;
368 hfp_hf_cmd_exchange_supported_features(context->rfcomm_cid);
409 hfp_connection->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES;
410 hfp_hf_cmd_exchange_supported_features(hfp_connection->rfcomm_cid);
369 break;
370 case HFP_NOTIFY_ON_CODECS:
411 break;
412 case HFP_NOTIFY_ON_CODECS:
371 context->state = HFP_W4_NOTIFY_ON_CODECS;
372 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid);
413 hfp_connection->state = HFP_W4_NOTIFY_ON_CODECS;
414 hfp_hf_cmd_notify_on_codecs(hfp_connection->rfcomm_cid);
373 break;
374 case HFP_RETRIEVE_INDICATORS:
415 break;
416 case HFP_RETRIEVE_INDICATORS:
375 context->state = HFP_W4_RETRIEVE_INDICATORS;
376 hfp_hf_cmd_retrieve_indicators(context->rfcomm_cid);
417 hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS;
418 hfp_hf_cmd_retrieve_indicators(hfp_connection->rfcomm_cid);
377 break;
378 case HFP_RETRIEVE_INDICATORS_STATUS:
419 break;
420 case HFP_RETRIEVE_INDICATORS_STATUS:
379 context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS;
380 hfp_hf_cmd_retrieve_indicators_status(context->rfcomm_cid);
421 hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS_STATUS;
422 hfp_hf_cmd_retrieve_indicators_status(hfp_connection->rfcomm_cid);
381 break;
382 case HFP_ENABLE_INDICATORS_STATUS_UPDATE:
423 break;
424 case HFP_ENABLE_INDICATORS_STATUS_UPDATE:
383 context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE;
384 hfp_hf_cmd_activate_status_update_for_all_ag_indicators(context->rfcomm_cid, 1);
425 hfp_connection->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE;
426 hfp_hf_cmd_activate_status_update_for_all_ag_indicators(hfp_connection->rfcomm_cid, 1);
385 break;
386 case HFP_RETRIEVE_CAN_HOLD_CALL:
427 break;
428 case HFP_RETRIEVE_CAN_HOLD_CALL:
387 context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL;
388 hfp_hf_cmd_retrieve_can_hold_call(context->rfcomm_cid);
429 hfp_connection->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL;
430 hfp_hf_cmd_retrieve_can_hold_call(hfp_connection->rfcomm_cid);
389 break;
390 case HFP_LIST_GENERIC_STATUS_INDICATORS:
431 break;
432 case HFP_LIST_GENERIC_STATUS_INDICATORS:
391 context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
392 hfp_hf_cmd_list_supported_generic_status_indicators(context->rfcomm_cid);
433 hfp_connection->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
434 hfp_hf_cmd_list_supported_generic_status_indicators(hfp_connection->rfcomm_cid);
393 break;
394 case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS:
435 break;
436 case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS:
395 context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS;
396 hfp_hf_cmd_retrieve_supported_generic_status_indicators(context->rfcomm_cid);
437 hfp_connection->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS;
438 hfp_hf_cmd_retrieve_supported_generic_status_indicators(hfp_connection->rfcomm_cid);
397 break;
398 case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
439 break;
440 case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
399 context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
400 hfp_hf_cmd_list_initital_supported_generic_status_indicators(context->rfcomm_cid);
441 hfp_connection->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
442 hfp_hf_cmd_list_initital_supported_generic_status_indicators(hfp_connection->rfcomm_cid);
401 break;
402 default:
403 done = 0;
404 break;
405 }
406 return done;
407}
408
409
443 break;
444 default:
445 done = 0;
446 break;
447 }
448 return done;
449}
450
451
410static int hfp_hf_run_for_context_service_level_connection_queries(hfp_connection_t * context){
411 if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0;
412 if (context->ok_pending) return 0;
452static int hfp_hf_run_for_context_service_level_connection_queries(hfp_connection_t * hfp_connection){
453 if (hfp_connection->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0;
454 if (hfp_connection->ok_pending) return 0;
413
414 int done = 0;
455
456 int done = 0;
415 if (context->enable_status_update_for_ag_indicators != 0xFF){
416 context->ok_pending = 1;
457 if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){
458 hfp_connection->ok_pending = 1;
417 done = 1;
459 done = 1;
418 hfp_hf_cmd_activate_status_update_for_all_ag_indicators(context->rfcomm_cid, context->enable_status_update_for_ag_indicators);
460 hfp_hf_cmd_activate_status_update_for_all_ag_indicators(hfp_connection->rfcomm_cid, hfp_connection->enable_status_update_for_ag_indicators);
419 return done;
420 };
461 return done;
462 };
421 if (context->change_status_update_for_individual_ag_indicators){
422 context->ok_pending = 1;
463 if (hfp_connection->change_status_update_for_individual_ag_indicators){
464 hfp_connection->ok_pending = 1;
423 done = 1;
465 done = 1;
424 hfp_hf_cmd_activate_status_update_for_ag_indicator(context->rfcomm_cid,
425 context->ag_indicators_status_update_bitmap,
426 context->ag_indicators_nr);
466 hfp_hf_cmd_activate_status_update_for_ag_indicator(hfp_connection->rfcomm_cid,
467 hfp_connection->ag_indicators_status_update_bitmap,
468 hfp_connection->ag_indicators_nr);
427 return done;
428 }
429
469 return done;
470 }
471
430 switch (context->hf_query_operator_state){
472 switch (hfp_connection->hf_query_operator_state){
431 case HFP_HF_QUERY_OPERATOR_SET_FORMAT:
473 case HFP_HF_QUERY_OPERATOR_SET_FORMAT:
432 context->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK;
433 context->ok_pending = 1;
434 hfp_hf_cmd_query_operator_name_format(context->rfcomm_cid);
474 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK;
475 hfp_connection->ok_pending = 1;
476 hfp_hf_cmd_query_operator_name_format(hfp_connection->rfcomm_cid);
435 return 1;
436 case HFP_HF_QUERY_OPERATOR_SEND_QUERY:
477 return 1;
478 case HFP_HF_QUERY_OPERATOR_SEND_QUERY:
437 context->hf_query_operator_state = HPF_HF_QUERY_OPERATOR_W4_RESULT;
438 context->ok_pending = 1;
439 hfp_hf_cmd_query_operator_name(context->rfcomm_cid);
479 hfp_connection->hf_query_operator_state = HPF_HF_QUERY_OPERATOR_W4_RESULT;
480 hfp_connection->ok_pending = 1;
481 hfp_hf_cmd_query_operator_name(hfp_connection->rfcomm_cid);
440 return 1;
441 default:
442 break;
443 }
444
482 return 1;
483 default:
484 break;
485 }
486
445 if (context->enable_extended_audio_gateway_error_report){
446 context->ok_pending = 1;
487 if (hfp_connection->enable_extended_audio_gateway_error_report){
488 hfp_connection->ok_pending = 1;
447 done = 1;
489 done = 1;
448 hfp_hf_cmd_enable_extended_audio_gateway_error_report(context->rfcomm_cid, context->enable_extended_audio_gateway_error_report);
490 hfp_hf_cmd_enable_extended_audio_gateway_error_report(hfp_connection->rfcomm_cid, hfp_connection->enable_extended_audio_gateway_error_report);
449 return done;
450 }
451
452 return done;
453}
454
491 return done;
492 }
493
494 return done;
495}
496
455static int codecs_exchange_state_machine(hfp_connection_t * context){
497static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){
456 /* events ( == commands):
457 HFP_CMD_AVAILABLE_CODECS == received AT+BAC with list of codecs
458 HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP:
459 hf_trigger_codec_connection_setup == received BCC
460 ag_trigger_codec_connection_setup == received from AG to send BCS
461 HFP_CMD_HF_CONFIRMED_CODEC == received AT+BCS
462 */
463
498 /* events ( == commands):
499 HFP_CMD_AVAILABLE_CODECS == received AT+BAC with list of codecs
500 HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP:
501 hf_trigger_codec_connection_setup == received BCC
502 ag_trigger_codec_connection_setup == received from AG to send BCS
503 HFP_CMD_HF_CONFIRMED_CODEC == received AT+BCS
504 */
505
464 if (context->ok_pending) return 0;
506 if (hfp_connection->ok_pending) return 0;
465
507
466 switch (context->command){
508 switch (hfp_connection->command){
467 case HFP_CMD_AVAILABLE_CODECS:
509 case HFP_CMD_AVAILABLE_CODECS:
468 if (context->codecs_state == HFP_CODECS_W4_AG_COMMON_CODEC) return 0;
510 if (hfp_connection->codecs_state == HFP_CODECS_W4_AG_COMMON_CODEC) return 0;
469
511
470 context->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC;
471 context->ok_pending = 1;
472 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid);
512 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC;
513 hfp_connection->ok_pending = 1;
514 hfp_hf_cmd_notify_on_codecs(hfp_connection->rfcomm_cid);
473 return 1;
474 case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP:
515 return 1;
516 case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP:
475 context->codec_confirmed = 0;
476 context->suggested_codec = 0;
477 context->negotiated_codec = 0;
517 hfp_connection->codec_confirmed = 0;
518 hfp_connection->suggested_codec = 0;
519 hfp_connection->negotiated_codec = 0;
478
520
479 context->codecs_state = HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE;
480 context->ok_pending = 1;
481 hfp_hf_cmd_trigger_codec_connection_setup(context->rfcomm_cid);
521 hfp_connection->codecs_state = HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE;
522 hfp_connection->ok_pending = 1;
523 hfp_hf_cmd_trigger_codec_connection_setup(hfp_connection->rfcomm_cid);
482 break;
483
484 case HFP_CMD_AG_SUGGESTED_CODEC:
524 break;
525
526 case HFP_CMD_AG_SUGGESTED_CODEC:
485 if (hfp_hf_supports_codec(context->suggested_codec)){
486 context->codec_confirmed = context->suggested_codec;
487 context->ok_pending = 1;
488 context->codecs_state = HFP_CODECS_HF_CONFIRMED_CODEC;
489 hfp_hf_cmd_confirm_codec(context->rfcomm_cid, context->suggested_codec);
527 if (hfp_hf_supports_codec(hfp_connection->suggested_codec)){
528 hfp_connection->codec_confirmed = hfp_connection->suggested_codec;
529 hfp_connection->ok_pending = 1;
530 hfp_connection->codecs_state = HFP_CODECS_HF_CONFIRMED_CODEC;
531 hfp_hf_cmd_confirm_codec(hfp_connection->rfcomm_cid, hfp_connection->suggested_codec);
490 } else {
532 } else {
491 context->codec_confirmed = 0;
492 context->suggested_codec = 0;
493 context->negotiated_codec = 0;
494 context->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC;
495 context->ok_pending = 1;
496 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid);
533 hfp_connection->codec_confirmed = 0;
534 hfp_connection->suggested_codec = 0;
535 hfp_connection->negotiated_codec = 0;
536 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC;
537 hfp_connection->ok_pending = 1;
538 hfp_hf_cmd_notify_on_codecs(hfp_connection->rfcomm_cid);
497
498 }
499 break;
500
501 default:
502 break;
503 }
504 return 0;
505}
506
539
540 }
541 break;
542
543 default:
544 break;
545 }
546 return 0;
547}
548
507static int hfp_hf_run_for_audio_connection(hfp_connection_t * context){
508 if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED ||
509 context->state > HFP_W2_DISCONNECT_SCO) return 0;
549static int hfp_hf_run_for_audio_connection(hfp_connection_t * hfp_connection){
550 if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED ||
551 hfp_connection->state > HFP_W2_DISCONNECT_SCO) return 0;
510
511
552
553
512 if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED && context->release_audio_connection){
513 context->state = HFP_W4_SCO_DISCONNECTED;
514 context->release_audio_connection = 0;
515 gap_disconnect(context->sco_handle);
554 if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED && hfp_connection->release_audio_connection){
555 hfp_connection->state = HFP_W4_SCO_DISCONNECTED;
556 hfp_connection->release_audio_connection = 0;
557 gap_disconnect(hfp_connection->sco_handle);
516 return 1;
517 }
518
558 return 1;
559 }
560
519 if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0;
561 if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0;
520
521 // run codecs exchange
562
563 // run codecs exchange
522 int done = codecs_exchange_state_machine(context);
564 int done = codecs_exchange_state_machine(hfp_connection);
523 if (done) return 1;
524
565 if (done) return 1;
566
525 if (context->establish_audio_connection){
526 context->state = HFP_W4_SCO_CONNECTED;
527 context->establish_audio_connection = 0;
528 hfp_setup_synchronous_connection(context->acl_handle, context->link_setting);
567 if (hfp_connection->establish_audio_connection){
568 hfp_connection->state = HFP_W4_SCO_CONNECTED;
569 hfp_connection->establish_audio_connection = 0;
570 hfp_setup_synchronous_connection(hfp_connection->acl_handle, hfp_connection->link_setting);
529 return 1;
530 }
531
532 return 0;
533}
534
571 return 1;
572 }
573
574 return 0;
575}
576
535static int call_setup_state_machine(hfp_connection_t * context){
536 if (context->hf_answer_incoming_call){
537 hfp_hf_cmd_ata(context->rfcomm_cid);
538 context->hf_answer_incoming_call = 0;
577static int call_setup_state_machine(hfp_connection_t * hfp_connection){
578 if (hfp_connection->hf_answer_incoming_call){
579 hfp_hf_cmd_ata(hfp_connection->rfcomm_cid);
580 hfp_connection->hf_answer_incoming_call = 0;
539 return 1;
540 }
541 return 0;
542}
543
581 return 1;
582 }
583 return 0;
584}
585
544static void hfp_run_for_context(hfp_connection_t * context){
545 if (!context) return;
546 if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;
586static void hfp_run_for_context(hfp_connection_t * hfp_connection){
587 if (!hfp_connection) return;
588 if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) return;
547
589
548 int done = hfp_hf_run_for_context_service_level_connection(context);
590 int done = hfp_hf_run_for_context_service_level_connection(hfp_connection);
549 if (!done){
591 if (!done){
550 done = hfp_hf_run_for_context_service_level_connection_queries(context);
592 done = hfp_hf_run_for_context_service_level_connection_queries(hfp_connection);
551 }
552 if (!done){
593 }
594 if (!done){
553 done = hfp_hf_run_for_audio_connection(context);
595 done = hfp_hf_run_for_audio_connection(hfp_connection);
554 }
555 if (!done){
596 }
597 if (!done){
556 done = call_setup_state_machine(context);
598 done = call_setup_state_machine(hfp_connection);
557 }
558
599 }
600
559 if (context->send_microphone_gain){
560 context->send_microphone_gain = 0;
561 context->ok_pending = 1;
562 hfp_hf_set_microphone_gain_cmd(context->rfcomm_cid, context->microphone_gain);
601 if (hfp_connection->send_microphone_gain){
602 hfp_connection->send_microphone_gain = 0;
603 hfp_connection->ok_pending = 1;
604 hfp_hf_set_microphone_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->microphone_gain);
563 return;
564 }
565
605 return;
606 }
607
566 if (context->send_speaker_gain){
567 context->send_speaker_gain = 0;
568 context->ok_pending = 1;
569 hfp_hf_set_speaker_gain_cmd(context->rfcomm_cid, context->speaker_gain);
608 if (hfp_connection->send_speaker_gain){
609 hfp_connection->send_speaker_gain = 0;
610 hfp_connection->ok_pending = 1;
611 hfp_hf_set_speaker_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->speaker_gain);
570 return;
571 }
572
612 return;
613 }
614
573 if (context->hf_deactivate_calling_line_notification){
574 context->hf_deactivate_calling_line_notification = 0;
575 context->ok_pending = 1;
576 hfp_hf_set_calling_line_notification_cmd(context->rfcomm_cid, 0);
615 if (hfp_connection->hf_deactivate_calling_line_notification){
616 hfp_connection->hf_deactivate_calling_line_notification = 0;
617 hfp_connection->ok_pending = 1;
618 hfp_hf_set_calling_line_notification_cmd(hfp_connection->rfcomm_cid, 0);
577 return;
578 }
579
619 return;
620 }
621
580 if (context->hf_activate_calling_line_notification){
581 context->hf_activate_calling_line_notification = 0;
582 context->ok_pending = 1;
583 hfp_hf_set_calling_line_notification_cmd(context->rfcomm_cid, 1);
622 if (hfp_connection->hf_activate_calling_line_notification){
623 hfp_connection->hf_activate_calling_line_notification = 0;
624 hfp_connection->ok_pending = 1;
625 hfp_hf_set_calling_line_notification_cmd(hfp_connection->rfcomm_cid, 1);
584 return;
585 }
586
626 return;
627 }
628
587 if (context->hf_deactivate_echo_canceling_and_noise_reduction){
588 context->hf_deactivate_echo_canceling_and_noise_reduction = 0;
589 context->ok_pending = 1;
590 hfp_hf_set_echo_canceling_and_noise_reduction_cmd(context->rfcomm_cid, 0);
629 if (hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction){
630 hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 0;
631 hfp_connection->ok_pending = 1;
632 hfp_hf_set_echo_canceling_and_noise_reduction_cmd(hfp_connection->rfcomm_cid, 0);
591 return;
592 }
593
633 return;
634 }
635
594 if (context->hf_activate_echo_canceling_and_noise_reduction){
595 context->hf_activate_echo_canceling_and_noise_reduction = 0;
596 context->ok_pending = 1;
597 hfp_hf_set_echo_canceling_and_noise_reduction_cmd(context->rfcomm_cid, 1);
636 if (hfp_connection->hf_activate_echo_canceling_and_noise_reduction){
637 hfp_connection->hf_activate_echo_canceling_and_noise_reduction = 0;
638 hfp_connection->ok_pending = 1;
639 hfp_hf_set_echo_canceling_and_noise_reduction_cmd(hfp_connection->rfcomm_cid, 1);
598 return;
599 }
600
640 return;
641 }
642
601 if (context->hf_deactivate_voice_recognition_notification){
602 context->hf_deactivate_voice_recognition_notification = 0;
603 context->ok_pending = 1;
604 hfp_hf_set_voice_recognition_notification_cmd(context->rfcomm_cid, 0);
643 if (hfp_connection->hf_deactivate_voice_recognition_notification){
644 hfp_connection->hf_deactivate_voice_recognition_notification = 0;
645 hfp_connection->ok_pending = 1;
646 hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 0);
605 return;
606 }
607
647 return;
648 }
649
608 if (context->hf_activate_voice_recognition_notification){
609 context->hf_activate_voice_recognition_notification = 0;
610 context->ok_pending = 1;
611 hfp_hf_set_voice_recognition_notification_cmd(context->rfcomm_cid, 1);
650 if (hfp_connection->hf_activate_voice_recognition_notification){
651 hfp_connection->hf_activate_voice_recognition_notification = 0;
652 hfp_connection->ok_pending = 1;
653 hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 1);
612 return;
613 }
614
615
654 return;
655 }
656
657
616 if (context->hf_deactivate_call_waiting_notification){
617 context->hf_deactivate_call_waiting_notification = 0;
618 context->ok_pending = 1;
619 hfp_hf_set_call_waiting_notification_cmd(context->rfcomm_cid, 0);
658 if (hfp_connection->hf_deactivate_call_waiting_notification){
659 hfp_connection->hf_deactivate_call_waiting_notification = 0;
660 hfp_connection->ok_pending = 1;
661 hfp_hf_set_call_waiting_notification_cmd(hfp_connection->rfcomm_cid, 0);
620 return;
621 }
622
662 return;
663 }
664
623 if (context->hf_activate_call_waiting_notification){
624 context->hf_activate_call_waiting_notification = 0;
625 context->ok_pending = 1;
626 hfp_hf_set_call_waiting_notification_cmd(context->rfcomm_cid, 1);
665 if (hfp_connection->hf_activate_call_waiting_notification){
666 hfp_connection->hf_activate_call_waiting_notification = 0;
667 hfp_connection->ok_pending = 1;
668 hfp_hf_set_call_waiting_notification_cmd(hfp_connection->rfcomm_cid, 1);
627 return;
628 }
629
669 return;
670 }
671
630 if (context->hf_initiate_outgoing_call){
631 context->hf_initiate_outgoing_call = 0;
632 context->ok_pending = 1;
633 hfp_hf_initiate_outgoing_call_cmd(context->rfcomm_cid);
672 if (hfp_connection->hf_initiate_outgoing_call){
673 hfp_connection->hf_initiate_outgoing_call = 0;
674 hfp_connection->ok_pending = 1;
675 hfp_hf_initiate_outgoing_call_cmd(hfp_connection->rfcomm_cid);
634 return;
635 }
636
676 return;
677 }
678
637 if (context->hf_initiate_memory_dialing){
638 context->hf_initiate_memory_dialing = 0;
639 context->ok_pending = 1;
640 hfp_hf_send_memory_dial_cmd(context->rfcomm_cid);
679 if (hfp_connection->hf_initiate_memory_dialing){
680 hfp_connection->hf_initiate_memory_dialing = 0;
681 hfp_connection->ok_pending = 1;
682 hfp_hf_send_memory_dial_cmd(hfp_connection->rfcomm_cid, hfp_connection->memory_id);
641 return;
642 }
643
683 return;
684 }
685
644 if (context->hf_initiate_redial_last_number){
645 context->hf_initiate_redial_last_number = 0;
646 context->ok_pending = 1;
647 hfp_hf_send_redial_last_number_cmd(context->rfcomm_cid);
686 if (hfp_connection->hf_initiate_redial_last_number){
687 hfp_connection->hf_initiate_redial_last_number = 0;
688 hfp_connection->ok_pending = 1;
689 hfp_hf_send_redial_last_number_cmd(hfp_connection->rfcomm_cid);
648 return;
649 }
650
690 return;
691 }
692
651 if (context->hf_send_chup){
652 context->hf_send_chup = 0;
653 context->ok_pending = 1;
654 hfp_hf_send_chup(context->rfcomm_cid);
693 if (hfp_connection->hf_send_chup){
694 hfp_connection->hf_send_chup = 0;
695 hfp_connection->ok_pending = 1;
696 hfp_hf_send_chup(hfp_connection->rfcomm_cid);
655 return;
656 }
657
697 return;
698 }
699
658 if (context->hf_send_chld_0){
659 context->hf_send_chld_0 = 0;
660 context->ok_pending = 1;
661 hfp_hf_send_chld(context->rfcomm_cid, 0);
700 if (hfp_connection->hf_send_chld_0){
701 hfp_connection->hf_send_chld_0 = 0;
702 hfp_connection->ok_pending = 1;
703 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 0);
662 return;
663 }
664
704 return;
705 }
706
665 if (context->hf_send_chld_1){
666 context->hf_send_chld_1 = 0;
667 context->ok_pending = 1;
668 hfp_hf_send_chld(context->rfcomm_cid, 1);
707 if (hfp_connection->hf_send_chld_1){
708 hfp_connection->hf_send_chld_1 = 0;
709 hfp_connection->ok_pending = 1;
710 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 1);
669 return;
670 }
671
711 return;
712 }
713
672 if (context->hf_send_chld_2){
673 context->hf_send_chld_2 = 0;
674 context->ok_pending = 1;
675 hfp_hf_send_chld(context->rfcomm_cid, 2);
714 if (hfp_connection->hf_send_chld_2){
715 hfp_connection->hf_send_chld_2 = 0;
716 hfp_connection->ok_pending = 1;
717 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 2);
676 return;
677 }
678
718 return;
719 }
720
679 if (context->hf_send_chld_3){
680 context->hf_send_chld_3 = 0;
681 context->ok_pending = 1;
682 hfp_hf_send_chld(context->rfcomm_cid, 3);
721 if (hfp_connection->hf_send_chld_3){
722 hfp_connection->hf_send_chld_3 = 0;
723 hfp_connection->ok_pending = 1;
724 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 3);
683 return;
684 }
685
725 return;
726 }
727
686 if (context->hf_send_chld_4){
687 context->hf_send_chld_4 = 0;
688 context->ok_pending = 1;
689 hfp_hf_send_chld(context->rfcomm_cid, 4);
728 if (hfp_connection->hf_send_chld_4){
729 hfp_connection->hf_send_chld_4 = 0;
730 hfp_connection->ok_pending = 1;
731 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 4);
690 return;
691 }
692
732 return;
733 }
734
693 if (context->hf_send_chld_x){
694 context->hf_send_chld_x = 0;
695 context->ok_pending = 1;
696 hfp_hf_send_chld(context->rfcomm_cid, context->hf_send_chld_x_index);
735 if (hfp_connection->hf_send_chld_x){
736 hfp_connection->hf_send_chld_x = 0;
737 hfp_connection->ok_pending = 1;
738 hfp_hf_send_chld(hfp_connection->rfcomm_cid, hfp_connection->hf_send_chld_x_index);
697 return;
698 }
699
739 return;
740 }
741
700 if (context->hf_send_dtmf_code){
701 char code = context->hf_send_dtmf_code;
702 context->hf_send_dtmf_code = 0;
703 context->ok_pending = 1;
704 hfp_hf_send_dtmf(context->rfcomm_cid, code);
742 if (hfp_connection->hf_send_dtmf_code){
743 char code = hfp_connection->hf_send_dtmf_code;
744 hfp_connection->hf_send_dtmf_code = 0;
745 hfp_connection->ok_pending = 1;
746 hfp_hf_send_dtmf(hfp_connection->rfcomm_cid, code);
705 return;
706 }
707
747 return;
748 }
749
708 if (context->hf_send_binp){
709 context->hf_send_binp = 0;
710 context->ok_pending = 1;
711 hfp_hf_send_binp(context->rfcomm_cid);
750 if (hfp_connection->hf_send_binp){
751 hfp_connection->hf_send_binp = 0;
752 hfp_connection->ok_pending = 1;
753 hfp_hf_send_binp(hfp_connection->rfcomm_cid);
712 return;
713 }
714
754 return;
755 }
756
715 if (context->hf_send_clcc){
716 context->hf_send_clcc = 0;
717 context->ok_pending = 1;
718 hfp_hf_send_clcc(context->rfcomm_cid);
757 if (hfp_connection->hf_send_clcc){
758 hfp_connection->hf_send_clcc = 0;
759 hfp_connection->ok_pending = 1;
760 hfp_hf_send_clcc(hfp_connection->rfcomm_cid);
719 return;
720 }
721
761 return;
762 }
763
722 if (context->hf_send_rrh){
723 context->hf_send_rrh = 0;
764 if (hfp_connection->hf_send_rrh){
765 hfp_connection->hf_send_rrh = 0;
724 char buffer[20];
766 char buffer[20];
725 switch (context->hf_send_rrh_command){
767 switch (hfp_connection->hf_send_rrh_command){
726 case '?':
727 sprintf(buffer, "AT%s?\r\n", HFP_RESPONSE_AND_HOLD);
768 case '?':
769 sprintf(buffer, "AT%s?\r\n", HFP_RESPONSE_AND_HOLD);
728 send_str_over_rfcomm(context->rfcomm_cid, buffer);
770 send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer);
729 return;
730 case '0':
731 case '1':
732 case '2':
771 return;
772 case '0':
773 case '1':
774 case '2':
733 sprintf(buffer, "AT%s=%c\r\n", HFP_RESPONSE_AND_HOLD, context->hf_send_rrh_command);
734 send_str_over_rfcomm(context->rfcomm_cid, buffer);
775 sprintf(buffer, "AT%s=%c\r\n", HFP_RESPONSE_AND_HOLD, hfp_connection->hf_send_rrh_command);
776 send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer);
735 return;
736 default:
737 break;
738 }
739 return;
740 }
741
777 return;
778 default:
779 break;
780 }
781 return;
782 }
783
742 if (context->hf_send_cnum){
743 context->hf_send_cnum = 0;
784 if (hfp_connection->hf_send_cnum){
785 hfp_connection->hf_send_cnum = 0;
744 char buffer[20];
745 sprintf(buffer, "AT%s\r\n", HFP_SUBSCRIBER_NUMBER_INFORMATION);
786 char buffer[20];
787 sprintf(buffer, "AT%s\r\n", HFP_SUBSCRIBER_NUMBER_INFORMATION);
746 send_str_over_rfcomm(context->rfcomm_cid, buffer);
788 send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer);
747 return;
748 }
749
750 // update HF indicators
789 return;
790 }
791
792 // update HF indicators
751 if (context->generic_status_update_bitmap){
793 if (hfp_connection->generic_status_update_bitmap){
752 int i;
753 for (i=0;i<hfp_indicators_nr;i++){
794 int i;
795 for (i=0;i<hfp_indicators_nr;i++){
754 if (get_bit(context->generic_status_update_bitmap, i)){
755 if (context->generic_status_indicators[i].state){
756 context->ok_pending = 1;
757 context->generic_status_update_bitmap = store_bit(context->generic_status_update_bitmap, i, 0);
796 if (get_bit(hfp_connection->generic_status_update_bitmap, i)){
797 if (hfp_connection->generic_status_indicators[i].state){
798 hfp_connection->ok_pending = 1;
799 hfp_connection->generic_status_update_bitmap = store_bit(hfp_connection->generic_status_update_bitmap, i, 0);
758 char buffer[30];
759 sprintf(buffer, "AT%s=%u,%u\r\n", HFP_TRANSFER_HF_INDICATOR_STATUS, hfp_indicators[i], hfp_indicators_value[i]);
800 char buffer[30];
801 sprintf(buffer, "AT%s=%u,%u\r\n", HFP_TRANSFER_HF_INDICATOR_STATUS, hfp_indicators[i], hfp_indicators_value[i]);
760 send_str_over_rfcomm(context->rfcomm_cid, buffer);
802 send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer);
761 } else {
762 printf("Not sending HF indicator %u as it is disabled\n", hfp_indicators[i]);
763 }
764 return;
765 }
766 }
767 }
768
769 if (done) return;
770 // deal with disconnect
803 } else {
804 printf("Not sending HF indicator %u as it is disabled\n", hfp_indicators[i]);
805 }
806 return;
807 }
808 }
809 }
810
811 if (done) return;
812 // deal with disconnect
771 switch (context->state){
813 switch (hfp_connection->state){
772 case HFP_W2_DISCONNECT_RFCOMM:
814 case HFP_W2_DISCONNECT_RFCOMM:
773 context->state = HFP_W4_RFCOMM_DISCONNECTED;
774 rfcomm_disconnect(context->rfcomm_cid);
815 hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED;
816 rfcomm_disconnect(hfp_connection->rfcomm_cid);
775 break;
776
777 default:
778 break;
779 }
780}
781
817 break;
818
819 default:
820 break;
821 }
822}
823
782static void hfp_init_link_settings(hfp_connection_t * context){
824static void hfp_init_link_settings(hfp_connection_t * hfp_connection){
783 // determine highest possible link setting
825 // determine highest possible link setting
784 context->link_setting = HFP_LINK_SETTINGS_D1;
785 if (hci_remote_esco_supported(context->acl_handle)){
786 context->link_setting = HFP_LINK_SETTINGS_S3;
826 hfp_connection->link_setting = HFP_LINK_SETTINGS_D1;
827 if (hci_remote_esco_supported(hfp_connection->acl_handle)){
828 hfp_connection->link_setting = HFP_LINK_SETTINGS_S3;
787 if ((hfp_supported_features & (1<<HFP_HFSF_ESCO_S4))
829 if ((hfp_supported_features & (1<<HFP_HFSF_ESCO_S4))
788 && (context->remote_supported_features & (1<<HFP_AGSF_ESCO_S4))){
789 context->link_setting = HFP_LINK_SETTINGS_S4;
830 && (hfp_connection->remote_supported_features & (1<<HFP_AGSF_ESCO_S4))){
831 hfp_connection->link_setting = HFP_LINK_SETTINGS_S4;
790 }
791 }
792}
793
832 }
833 }
834}
835
794static void hfp_ag_slc_established(hfp_connection_t * context){
795 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
836static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){
837 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
796 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
838 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
797 hfp_init_link_settings(context);
839 hfp_init_link_settings(hfp_connection);
798 // restore volume settings
840 // restore volume settings
799 context->speaker_gain = hfp_hf_speaker_gain;
800 context->send_speaker_gain = 1;
841 hfp_connection->speaker_gain = hfp_hf_speaker_gain;
842 hfp_connection->send_speaker_gain = 1;
801 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, hfp_hf_speaker_gain);
843 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, hfp_hf_speaker_gain);
802 context->microphone_gain = hfp_hf_microphone_gain;
803 context->send_microphone_gain = 1;
844 hfp_connection->microphone_gain = hfp_hf_microphone_gain;
845 hfp_connection->send_microphone_gain = 1;
804 hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain);
805 // enable all indicators
806 int i;
807 for (i=0;i<hfp_indicators_nr;i++){
846 hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain);
847 // enable all indicators
848 int i;
849 for (i=0;i<hfp_indicators_nr;i++){
808 context->generic_status_indicators[i].uuid = hfp_indicators[i];
809 context->generic_status_indicators[i].state = 1;
850 hfp_connection->generic_status_indicators[i].uuid = hfp_indicators[i];
851 hfp_connection->generic_status_indicators[i].state = 1;
810 }
811}
812
852 }
853}
854
813static void hfp_hf_switch_on_ok(hfp_connection_t *context){
814 context->ok_pending = 0;
855static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){
856 hfp_connection->ok_pending = 0;
815 int done = 1;
857 int done = 1;
816 switch (context->state){
858 switch (hfp_connection->state){
817 case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
859 case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
818 if (has_codec_negotiation_feature(context)){
819 context->state = HFP_NOTIFY_ON_CODECS;
860 if (has_codec_negotiation_feature(hfp_connection)){
861 hfp_connection->state = HFP_NOTIFY_ON_CODECS;
820 break;
821 }
862 break;
863 }
822 context->state = HFP_RETRIEVE_INDICATORS;
864 hfp_connection->state = HFP_RETRIEVE_INDICATORS;
823 break;
824
825 case HFP_W4_NOTIFY_ON_CODECS:
865 break;
866
867 case HFP_W4_NOTIFY_ON_CODECS:
826 context->state = HFP_RETRIEVE_INDICATORS;
868 hfp_connection->state = HFP_RETRIEVE_INDICATORS;
827 break;
828
829 case HFP_W4_RETRIEVE_INDICATORS:
869 break;
870
871 case HFP_W4_RETRIEVE_INDICATORS:
830 context->state = HFP_RETRIEVE_INDICATORS_STATUS;
872 hfp_connection->state = HFP_RETRIEVE_INDICATORS_STATUS;
831 break;
832
833 case HFP_W4_RETRIEVE_INDICATORS_STATUS:
873 break;
874
875 case HFP_W4_RETRIEVE_INDICATORS_STATUS:
834 context->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE;
876 hfp_connection->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE;
835 break;
836
837 case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE:
877 break;
878
879 case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE:
838 if (has_call_waiting_and_3way_calling_feature(context)){
839 context->state = HFP_RETRIEVE_CAN_HOLD_CALL;
880 if (has_call_waiting_and_3way_calling_feature(hfp_connection)){
881 hfp_connection->state = HFP_RETRIEVE_CAN_HOLD_CALL;
840 break;
841 }
882 break;
883 }
842 if (has_hf_indicators_feature(context)){
843 context->state = HFP_LIST_GENERIC_STATUS_INDICATORS;
884 if (has_hf_indicators_feature(hfp_connection)){
885 hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS;
844 break;
845 }
886 break;
887 }
846 hfp_ag_slc_established(context);
888 hfp_ag_slc_established(hfp_connection);
847 break;
848
849 case HFP_W4_RETRIEVE_CAN_HOLD_CALL:
889 break;
890
891 case HFP_W4_RETRIEVE_CAN_HOLD_CALL:
850 if (has_hf_indicators_feature(context)){
851 context->state = HFP_LIST_GENERIC_STATUS_INDICATORS;
892 if (has_hf_indicators_feature(hfp_connection)){
893 hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS;
852 break;
853 }
894 break;
895 }
854 hfp_ag_slc_established(context);
896 hfp_ag_slc_established(hfp_connection);
855 break;
856
857 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
897 break;
898
899 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
858 context->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS;
900 hfp_connection->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS;
859 break;
860
861 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
901 break;
902
903 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
862 context->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
904 hfp_connection->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
863 break;
864
865 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
905 break;
906
907 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
866 hfp_ag_slc_established(context);
908 hfp_ag_slc_established(hfp_connection);
867 break;
868 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
909 break;
910 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
869 if (context->enable_status_update_for_ag_indicators != 0xFF){
870 context->enable_status_update_for_ag_indicators = 0xFF;
911 if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){
912 hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
871 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
872 break;
873 }
874
913 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
914 break;
915 }
916
875 if (context->change_status_update_for_individual_ag_indicators == 1){
876 context->change_status_update_for_individual_ag_indicators = 0;
917 if (hfp_connection->change_status_update_for_individual_ag_indicators == 1){
918 hfp_connection->change_status_update_for_individual_ag_indicators = 0;
877 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
878 break;
879 }
880
919 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
920 break;
921 }
922
881 switch (context->hf_query_operator_state){
923 switch (hfp_connection->hf_query_operator_state){
882 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK:
883 printf("Format set, querying name\n");
924 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK:
925 printf("Format set, querying name\n");
884 context->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY;
926 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY;
885 break;
886 case HPF_HF_QUERY_OPERATOR_W4_RESULT:
927 break;
928 case HPF_HF_QUERY_OPERATOR_W4_RESULT:
887 context->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET;
888 hfp_emit_network_operator_event(hfp_callback, 0, context->network_operator);
929 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET;
930 hfp_emit_network_operator_event(hfp_callback, hfp_connection->network_operator);
889 break;
890 default:
891 break;
892 }
893
931 break;
932 default:
933 break;
934 }
935
894 if (context->enable_extended_audio_gateway_error_report){
895 context->enable_extended_audio_gateway_error_report = 0;
936 if (hfp_connection->enable_extended_audio_gateway_error_report){
937 hfp_connection->enable_extended_audio_gateway_error_report = 0;
896 break;
897 }
898
938 break;
939 }
940
899 switch (context->codecs_state){
941 switch (hfp_connection->codecs_state){
900 case HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE:
942 case HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE:
901 context->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC;
943 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC;
902 break;
903 case HFP_CODECS_HF_CONFIRMED_CODEC:
944 break;
945 case HFP_CODECS_HF_CONFIRMED_CODEC:
904 context->codecs_state = HFP_CODECS_EXCHANGED;
946 hfp_connection->codecs_state = HFP_CODECS_EXCHANGED;
905 hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0);
906 break;
907 default:
908 done = 0;
909 break;
910 }
911 break;
912 default:
913 done = 0;
914 break;
915 }
916
917 // done
947 hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0);
948 break;
949 default:
950 done = 0;
951 break;
952 }
953 break;
954 default:
955 done = 0;
956 break;
957 }
958
959 // done
918 context->command = HFP_CMD_NONE;
960 hfp_connection->command = HFP_CMD_NONE;
919}
920
921
922static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
961}
962
963
964static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
923 hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel);
924 if (!context) return;
965 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_rfcomm_cid(channel);
966 if (!hfp_connection) return;
925
926 char last_char = packet[size-1];
927 packet[size-1] = 0;
928 log_info("HFP_RX %s", packet);
929 packet[size-1] = last_char;
930
931 int pos, i, value;
932 for (pos = 0; pos < size ; pos++){
967
968 char last_char = packet[size-1];
969 packet[size-1] = 0;
970 log_info("HFP_RX %s", packet);
971 packet[size-1] = last_char;
972
973 int pos, i, value;
974 for (pos = 0; pos < size ; pos++){
933 hfp_parse(context, packet[pos], 1);
975 hfp_parse(hfp_connection, packet[pos], 1);
934 }
935
976 }
977
936 switch (context->command){
978 switch (hfp_connection->command){
937 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
979 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
938 context->command = HFP_CMD_NONE;
939 printf("Subscriber Number: number %s, type %u\n", context->bnip_number, context->bnip_type);
980 hfp_connection->command = HFP_CMD_NONE;
981 // printf("Subscriber Number: number %s, type %u\n", hfp_connection->bnip_number, hfp_connection->bnip_type);
982 hfp_hf_emit_subscriber_information(hfp_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number);
940 break;
941 case HFP_CMD_RESPONSE_AND_HOLD_STATUS:
983 break;
984 case HFP_CMD_RESPONSE_AND_HOLD_STATUS:
942 context->command = HFP_CMD_NONE;
943 printf("Response and Hold status: %s\n", context->line_buffer);
985 hfp_connection->command = HFP_CMD_NONE;
986 // printf("Response and Hold status: %s\n", hfp_connection->line_buffer);
987 hfp_emit_event(hfp_callback, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, atoi((char *)&hfp_connection->line_buffer[0]));
944 break;
945 case HFP_CMD_LIST_CURRENT_CALLS:
988 break;
989 case HFP_CMD_LIST_CURRENT_CALLS:
946 context->command = HFP_CMD_NONE;
947 printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n",
948 context->clcc_idx, context->clcc_dir, context->clcc_status, context->clcc_mpty,
949 context->bnip_number, context->bnip_type);
990 hfp_connection->command = HFP_CMD_NONE;
991 // printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n",
992 // hfp_connection->clcc_idx, hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
993 // hfp_connection->bnip_number, hfp_connection->bnip_type);
994 hfp_hf_emit_enhanced_call_status(hfp_callback, hfp_connection->clcc_idx,
995 hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
996 hfp_connection->bnip_type, hfp_connection->bnip_number);
950 break;
951 case HFP_CMD_SET_SPEAKER_GAIN:
997 break;
998 case HFP_CMD_SET_SPEAKER_GAIN:
952 context->command = HFP_CMD_NONE;
953 value = atoi((char*)context->line_buffer);
999 hfp_connection->command = HFP_CMD_NONE;
1000 value = atoi((char*)hfp_connection->line_buffer);
954 hfp_hf_speaker_gain = value;
955 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, value);
956 break;
957 case HFP_CMD_SET_MICROPHONE_GAIN:
1001 hfp_hf_speaker_gain = value;
1002 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, value);
1003 break;
1004 case HFP_CMD_SET_MICROPHONE_GAIN:
958 context->command = HFP_CMD_NONE;
959 value = atoi((char*)context->line_buffer);
1005 hfp_connection->command = HFP_CMD_NONE;
1006 value = atoi((char*)hfp_connection->line_buffer);
960 hfp_hf_microphone_gain = value;
961 hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, value);
962 break;
963 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1007 hfp_hf_microphone_gain = value;
1008 hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, value);
1009 break;
1010 case HFP_CMD_AG_SENT_PHONE_NUMBER:
964 context->command = HFP_CMD_NONE;
965 hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, context->bnip_number);
1011 hfp_connection->command = HFP_CMD_NONE;
1012 hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number);
966 break;
1013 break;
1014 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1015 hfp_connection->command = HFP_CMD_NONE;
1016 hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
1017 break;
1018 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1019 hfp_connection->command = HFP_CMD_NONE;
1020 hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALLING_LINE_INDETIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
1021 break;
967 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
1022 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
968 context->ok_pending = 0;
969 context->extended_audio_gateway_error = 0;
970 context->command = HFP_CMD_NONE;
971 hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, context->extended_audio_gateway_error);
1023 hfp_connection->ok_pending = 0;
1024 hfp_connection->command = HFP_CMD_NONE;
1025 hfp_connection->extended_audio_gateway_error = 0;
1026 hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value);
972 break;
973 case HFP_CMD_ERROR:
1027 break;
1028 case HFP_CMD_ERROR:
974 context->ok_pending = 0;
975 hfp_reset_context_flags(context);
976 context->command = HFP_CMD_NONE;
1029 hfp_connection->ok_pending = 0;
1030 hfp_reset_context_flags(hfp_connection);
1031 hfp_connection->command = HFP_CMD_NONE;
977 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1);
978 break;
979 case HFP_CMD_OK:
1032 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1);
1033 break;
1034 case HFP_CMD_OK:
980 hfp_hf_switch_on_ok(context);
1035 hfp_hf_switch_on_ok(hfp_connection);
981 break;
982 case HFP_CMD_RING:
1036 break;
1037 case HFP_CMD_RING:
983 hfp_emit_event(hfp_callback, HFP_SUBEVENT_RING, 0);
1038 hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_RING);
984 break;
985 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1039 break;
1040 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
986 for (i = 0; i < context->ag_indicators_nr; i++){
987 if (context->ag_indicators[i].status_changed) {
988 if (strcmp(context->ag_indicators[i].name, "callsetup") == 0){
989 hfp_callsetup_status = (hfp_callsetup_status_t) context->ag_indicators[i].status;
990 } else if (strcmp(context->ag_indicators[i].name, "callheld") == 0){
991 hfp_callheld_status = (hfp_callheld_status_t) context->ag_indicators[i].status;
992 } else if (strcmp(context->ag_indicators[i].name, "call") == 0){
993 hfp_call_status = (hfp_call_status_t) context->ag_indicators[i].status;
1041 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){
1042 if (hfp_connection->ag_indicators[i].status_changed) {
1043 if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){
1044 hfp_callsetup_status = (hfp_callsetup_status_t) hfp_connection->ag_indicators[i].status;
1045 } else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){
1046 hfp_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status;
1047 } else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){
1048 hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status;
994 }
1049 }
995 context->ag_indicators[i].status_changed = 0;
996 hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]);
1050 hfp_connection->ag_indicators[i].status_changed = 0;
1051 hfp_emit_ag_indicator_event(hfp_callback, hfp_connection->ag_indicators[i]);
997 break;
998 }
999 }
1000 break;
1001 default:
1002 break;
1003 }
1052 break;
1053 }
1054 }
1055 break;
1056 default:
1057 break;
1058 }
1004 hfp_run_for_context(context);
1059 hfp_run_for_context(hfp_connection);
1005}
1006
1007static void hfp_run(){
1008 btstack_linked_list_iterator_t it;
1009 btstack_linked_list_iterator_init(&it, hfp_get_connections());
1010 while (btstack_linked_list_iterator_has_next(&it)){
1060}
1061
1062static void hfp_run(){
1063 btstack_linked_list_iterator_t it;
1064 btstack_linked_list_iterator_init(&it, hfp_get_connections());
1065 while (btstack_linked_list_iterator_has_next(&it)){
1011 hfp_connection_t * connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
1012 hfp_run_for_context(connection);
1066 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
1067 hfp_run_for_context(hfp_connection);
1013 }
1014}
1015
1016static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1017 switch (packet_type){
1018 case RFCOMM_DATA_PACKET:
1019 hfp_handle_rfcomm_event(packet_type, channel, packet, size);
1020 break;
1021 case HCI_EVENT_PACKET:
1022 hfp_handle_hci_event(packet_type, packet, size);
1023 default:
1024 break;
1025 }
1026 hfp_run();
1027}
1028
1068 }
1069}
1070
1071static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1072 switch (packet_type){
1073 case RFCOMM_DATA_PACKET:
1074 hfp_handle_rfcomm_event(packet_type, channel, packet, size);
1075 break;
1076 case HCI_EVENT_PACKET:
1077 hfp_handle_hci_event(packet_type, packet, size);
1078 default:
1079 break;
1080 }
1081 hfp_run();
1082}
1083
1029void hfp_hf_set_codecs(uint8_t * codecs, int codecs_nr){
1084void hfp_hf_init(uint16_t rfcomm_channel_nr){
1085 l2cap_init();
1086 l2cap_register_packet_handler(packet_handler);
1087 rfcomm_register_packet_handler(packet_handler);
1088 hfp_init(rfcomm_channel_nr);
1089
1090 hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
1091 hfp_codecs_nr = 0;
1092 hfp_indicators_nr = 0;
1093 hfp_hf_speaker_gain = 9;
1094 hfp_hf_microphone_gain = 9;
1095}
1096
1097void hfp_hf_init_codecs(int codecs_nr, uint8_t * codecs){
1030 if (codecs_nr > HFP_MAX_NUM_CODECS){
1098 if (codecs_nr > HFP_MAX_NUM_CODECS){
1031 log_error("hfp_hf_set_codecs: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS);
1099 log_error("hfp_hf_init_codecs: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS);
1032 return;
1033 }
1034
1035 hfp_codecs_nr = codecs_nr;
1036 int i;
1037 for (i=0; i<codecs_nr; i++){
1038 hfp_codecs[i] = codecs[i];
1039 }
1040
1041 char buffer[30];
1042 int offset = join(buffer, sizeof(buffer), hfp_codecs, hfp_codecs_nr);
1043 buffer[offset] = 0;
1044 btstack_linked_list_iterator_t it;
1045 btstack_linked_list_iterator_init(&it, hfp_get_connections());
1046 while (btstack_linked_list_iterator_has_next(&it)){
1100 return;
1101 }
1102
1103 hfp_codecs_nr = codecs_nr;
1104 int i;
1105 for (i=0; i<codecs_nr; i++){
1106 hfp_codecs[i] = codecs[i];
1107 }
1108
1109 char buffer[30];
1110 int offset = join(buffer, sizeof(buffer), hfp_codecs, hfp_codecs_nr);
1111 buffer[offset] = 0;
1112 btstack_linked_list_iterator_t it;
1113 btstack_linked_list_iterator_init(&it, hfp_get_connections());
1114 while (btstack_linked_list_iterator_has_next(&it)){
1047 hfp_connection_t * connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
1048 if (!connection) continue;
1049 connection->command = HFP_CMD_AVAILABLE_CODECS;
1050 hfp_run_for_context(connection);
1115 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
1116 if (! hfp_connection) continue;
1117 hfp_connection->command = HFP_CMD_AVAILABLE_CODECS;
1118 hfp_run_for_context(hfp_connection);
1051 }
1052}
1053
1119 }
1120}
1121
1054void hfp_hf_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint16_t * indicators, int indicators_nr, uint32_t indicators_status){
1055
1056 // register for HCI events
1057 hci_event_callback_registration.callback = &packet_handler;
1058 hci_add_event_handler(&hci_event_callback_registration);
1059
1060 l2cap_init();
1061 rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff);
1062
1122void hfp_hf_init_supported_features(uint32_t supported_features){
1063 hfp_supported_features = supported_features;
1123 hfp_supported_features = supported_features;
1124}
1064
1125
1126void hfp_hf_init_hf_indicators(int indicators_nr, uint16_t * indicators){
1065 hfp_indicators_nr = indicators_nr;
1127 hfp_indicators_nr = indicators_nr;
1066 hfp_indicators_status = indicators_status;
1067 int i;
1128 int i;
1068 for (i=0; i<indicators_nr; i++){
1129 for (i = 0; i < hfp_indicators_nr ; i++){
1069 hfp_indicators[i] = indicators[i];
1070 }
1071}
1072
1130 hfp_indicators[i] = indicators[i];
1131 }
1132}
1133
1073void hfp_hf_set_supported_features(uint32_t supported_features){
1074 hfp_supported_features = supported_features;
1075}
1076
1077void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr){
1078 hfp_establish_service_level_connection(bd_addr, SDP_HandsfreeAudioGateway);
1079}
1080
1081void hfp_hf_release_service_level_connection(bd_addr_t bd_addr){
1134void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr){
1135 hfp_establish_service_level_connection(bd_addr, SDP_HandsfreeAudioGateway);
1136}
1137
1138void hfp_hf_release_service_level_connection(bd_addr_t bd_addr){
1082 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1083 hfp_release_service_level_connection(connection);
1084 hfp_run_for_context(connection);
1139 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1140 hfp_release_service_level_connection(hfp_connection);
1141 hfp_run_for_context(hfp_connection);
1085}
1086
1087static void hfp_hf_set_status_update_for_all_ag_indicators(bd_addr_t bd_addr, uint8_t enable){
1088 hfp_hf_establish_service_level_connection(bd_addr);
1142}
1143
1144static void hfp_hf_set_status_update_for_all_ag_indicators(bd_addr_t bd_addr, uint8_t enable){
1145 hfp_hf_establish_service_level_connection(bd_addr);
1089 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1090 if (!connection){
1091 log_error("HFP HF: connection doesn't exist.");
1146 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1147 if (!hfp_connection){
1148 log_error("HFP HF: hfp_connection doesn't exist.");
1092 return;
1093 }
1149 return;
1150 }
1094 connection->enable_status_update_for_ag_indicators = enable;
1095 hfp_run_for_context(connection);
1151 hfp_connection->enable_status_update_for_ag_indicators = enable;
1152 hfp_run_for_context(hfp_connection);
1096}
1097
1098void hfp_hf_enable_status_update_for_all_ag_indicators(bd_addr_t bd_addr){
1099 hfp_hf_set_status_update_for_all_ag_indicators(bd_addr, 1);
1100}
1101
1102void hfp_hf_disable_status_update_for_all_ag_indicators(bd_addr_t bd_addr){
1103 hfp_hf_set_status_update_for_all_ag_indicators(bd_addr, 0);
1104}
1105
1106// TODO: returned ERROR - wrong format
1107void hfp_hf_set_status_update_for_individual_ag_indicators(bd_addr_t bd_addr, uint32_t indicators_status_bitmap){
1108 hfp_hf_establish_service_level_connection(bd_addr);
1153}
1154
1155void hfp_hf_enable_status_update_for_all_ag_indicators(bd_addr_t bd_addr){
1156 hfp_hf_set_status_update_for_all_ag_indicators(bd_addr, 1);
1157}
1158
1159void hfp_hf_disable_status_update_for_all_ag_indicators(bd_addr_t bd_addr){
1160 hfp_hf_set_status_update_for_all_ag_indicators(bd_addr, 0);
1161}
1162
1163// TODO: returned ERROR - wrong format
1164void hfp_hf_set_status_update_for_individual_ag_indicators(bd_addr_t bd_addr, uint32_t indicators_status_bitmap){
1165 hfp_hf_establish_service_level_connection(bd_addr);
1109 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1110 if (!connection){
1111 log_error("HFP HF: connection doesn't exist.");
1166 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1167 if (!hfp_connection){
1168 log_error("HFP HF: hfp_connection doesn't exist.");
1112 return;
1113 }
1169 return;
1170 }
1114 connection->change_status_update_for_individual_ag_indicators = 1;
1115 connection->ag_indicators_status_update_bitmap = indicators_status_bitmap;
1116 hfp_run_for_context(connection);
1171 hfp_connection->change_status_update_for_individual_ag_indicators = 1;
1172 hfp_connection->ag_indicators_status_update_bitmap = indicators_status_bitmap;
1173 hfp_run_for_context(hfp_connection);
1117}
1118
1119void hfp_hf_query_operator_selection(bd_addr_t bd_addr){
1120 hfp_hf_establish_service_level_connection(bd_addr);
1174}
1175
1176void hfp_hf_query_operator_selection(bd_addr_t bd_addr){
1177 hfp_hf_establish_service_level_connection(bd_addr);
1121 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1122 if (!connection){
1123 log_error("HFP HF: connection doesn't exist.");
1178 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1179 if (!hfp_connection){
1180 log_error("HFP HF: hfp_connection doesn't exist.");
1124 return;
1125 }
1181 return;
1182 }
1126 switch (connection->hf_query_operator_state){
1183 switch (hfp_connection->hf_query_operator_state){
1127 case HFP_HF_QUERY_OPERATOR_FORMAT_NOT_SET:
1184 case HFP_HF_QUERY_OPERATOR_FORMAT_NOT_SET:
1128 connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SET_FORMAT;
1185 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SET_FORMAT;
1129 break;
1130 case HFP_HF_QUERY_OPERATOR_FORMAT_SET:
1186 break;
1187 case HFP_HF_QUERY_OPERATOR_FORMAT_SET:
1131 connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY;
1188 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY;
1132 break;
1133 default:
1134 break;
1135 }
1189 break;
1190 default:
1191 break;
1192 }
1136 hfp_run_for_context(connection);
1193 hfp_run_for_context(hfp_connection);
1137}
1138
1139static void hfp_hf_set_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, uint8_t enable){
1140 hfp_hf_establish_service_level_connection(bd_addr);
1194}
1195
1196static void hfp_hf_set_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, uint8_t enable){
1197 hfp_hf_establish_service_level_connection(bd_addr);
1141 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1142 if (!connection){
1143 log_error("HFP HF: connection doesn't exist.");
1198 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1199 if (!hfp_connection){
1200 log_error("HFP HF: hfp_connection doesn't exist.");
1144 return;
1145 }
1201 return;
1202 }
1146 connection->enable_extended_audio_gateway_error_report = enable;
1147 hfp_run_for_context(connection);
1203 hfp_connection->enable_extended_audio_gateway_error_report = enable;
1204 hfp_run_for_context(hfp_connection);
1148}
1149
1150
1151void hfp_hf_enable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr){
1152 hfp_hf_set_report_extended_audio_gateway_error_result_code(bd_addr, 1);
1153}
1154
1155void hfp_hf_disable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr){
1156 hfp_hf_set_report_extended_audio_gateway_error_result_code(bd_addr, 0);
1157}
1158
1159
1160void hfp_hf_establish_audio_connection(bd_addr_t bd_addr){
1161 hfp_hf_establish_service_level_connection(bd_addr);
1205}
1206
1207
1208void hfp_hf_enable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr){
1209 hfp_hf_set_report_extended_audio_gateway_error_result_code(bd_addr, 1);
1210}
1211
1212void hfp_hf_disable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr){
1213 hfp_hf_set_report_extended_audio_gateway_error_result_code(bd_addr, 0);
1214}
1215
1216
1217void hfp_hf_establish_audio_connection(bd_addr_t bd_addr){
1218 hfp_hf_establish_service_level_connection(bd_addr);
1162 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1163 connection->establish_audio_connection = 0;
1219 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1220 hfp_connection->establish_audio_connection = 0;
1164
1221
1165 if (connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return;
1166 if (connection->state >= HFP_W2_DISCONNECT_SCO) return;
1222 if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return;
1223 if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return;
1167
1224
1168 if (!has_codec_negotiation_feature(connection)){
1225 if (!has_codec_negotiation_feature(hfp_connection)){
1169 log_info("hfp_ag_establish_audio_connection - no codec negotiation feature, using defaults");
1226 log_info("hfp_ag_establish_audio_connection - no codec negotiation feature, using defaults");
1170 connection->codecs_state = HFP_CODECS_EXCHANGED;
1171 connection->establish_audio_connection = 1;
1227 hfp_connection->codecs_state = HFP_CODECS_EXCHANGED;
1228 hfp_connection->establish_audio_connection = 1;
1172 } else {
1229 } else {
1173 switch (connection->codecs_state){
1230 switch (hfp_connection->codecs_state){
1174 case HFP_CODECS_W4_AG_COMMON_CODEC:
1175 break;
1176 default:
1231 case HFP_CODECS_W4_AG_COMMON_CODEC:
1232 break;
1233 default:
1177 connection->command = HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP;
1234 hfp_connection->command = HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP;
1178 break;
1179 }
1180 }
1181
1235 break;
1236 }
1237 }
1238
1182 hfp_run_for_context(connection);
1239 hfp_run_for_context(hfp_connection);
1183}
1184
1185void hfp_hf_release_audio_connection(bd_addr_t bd_addr){
1240}
1241
1242void hfp_hf_release_audio_connection(bd_addr_t bd_addr){
1186 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1187 hfp_release_audio_connection(connection);
1188 hfp_run_for_context(connection);
1243 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1244 hfp_release_audio_connection(hfp_connection);
1245 hfp_run_for_context(hfp_connection);
1189}
1190
1191void hfp_hf_answer_incoming_call(bd_addr_t bd_addr){
1192 hfp_hf_establish_service_level_connection(bd_addr);
1246}
1247
1248void hfp_hf_answer_incoming_call(bd_addr_t bd_addr){
1249 hfp_hf_establish_service_level_connection(bd_addr);
1193 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1250 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1194
1195 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){
1251
1252 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){
1196 connection->hf_answer_incoming_call = 1;
1197 hfp_run_for_context(connection);
1253 hfp_connection->hf_answer_incoming_call = 1;
1254 hfp_run_for_context(hfp_connection);
1198 } else {
1199 log_error("HFP HF: answering incoming call with wrong callsetup status %u", hfp_callsetup_status);
1200 }
1201}
1202
1203void hfp_hf_terminate_call(bd_addr_t bd_addr){
1204 hfp_hf_establish_service_level_connection(bd_addr);
1255 } else {
1256 log_error("HFP HF: answering incoming call with wrong callsetup status %u", hfp_callsetup_status);
1257 }
1258}
1259
1260void hfp_hf_terminate_call(bd_addr_t bd_addr){
1261 hfp_hf_establish_service_level_connection(bd_addr);
1205 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1262 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1206
1263
1207 // if (hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1208 connection->hf_send_chup = 1;
1209 hfp_run_for_context(connection);
1210 // } else {
1211 // log_error("HFP HF: terminating incoming call with wrong call status %u", hfp_call_status);
1212 // }
1264 hfp_connection->hf_send_chup = 1;
1265 hfp_run_for_context(hfp_connection);
1213}
1214
1266}
1267
1215void hfp_hf_reject_call(bd_addr_t bd_addr){
1268void hfp_hf_reject_incoming_call(bd_addr_t bd_addr){
1216 hfp_hf_establish_service_level_connection(bd_addr);
1269 hfp_hf_establish_service_level_connection(bd_addr);
1217 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1270 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1218
1219 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){
1271
1272 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){
1220 connection->hf_send_chup = 1;
1221 hfp_run_for_context(connection);
1273 hfp_connection->hf_send_chup = 1;
1274 hfp_run_for_context(hfp_connection);
1222 }
1223}
1224
1225void hfp_hf_user_busy(bd_addr_t addr){
1226 hfp_hf_establish_service_level_connection(addr);
1275 }
1276}
1277
1278void hfp_hf_user_busy(bd_addr_t addr){
1279 hfp_hf_establish_service_level_connection(addr);
1227 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1280 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1228
1229 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){
1281
1282 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){
1230 connection->hf_send_chld_0 = 1;
1231 hfp_run_for_context(connection);
1283 hfp_connection->hf_send_chld_0 = 1;
1284 hfp_run_for_context(hfp_connection);
1232 }
1233}
1234
1235void hfp_hf_end_active_and_accept_other(bd_addr_t addr){
1236 hfp_hf_establish_service_level_connection(addr);
1285 }
1286}
1287
1288void hfp_hf_end_active_and_accept_other(bd_addr_t addr){
1289 hfp_hf_establish_service_level_connection(addr);
1237 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1290 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1238
1239 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1240 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1291
1292 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1293 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1241 connection->hf_send_chld_1 = 1;
1242 hfp_run_for_context(connection);
1294 hfp_connection->hf_send_chld_1 = 1;
1295 hfp_run_for_context(hfp_connection);
1243 }
1244}
1245
1246void hfp_hf_swap_calls(bd_addr_t addr){
1247 hfp_hf_establish_service_level_connection(addr);
1296 }
1297}
1298
1299void hfp_hf_swap_calls(bd_addr_t addr){
1300 hfp_hf_establish_service_level_connection(addr);
1248 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1301 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1249
1250 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1251 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1302
1303 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1304 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1252 connection->hf_send_chld_2 = 1;
1253 hfp_run_for_context(connection);
1305 hfp_connection->hf_send_chld_2 = 1;
1306 hfp_run_for_context(hfp_connection);
1254 }
1255}
1256
1257void hfp_hf_join_held_call(bd_addr_t addr){
1258 hfp_hf_establish_service_level_connection(addr);
1307 }
1308}
1309
1310void hfp_hf_join_held_call(bd_addr_t addr){
1311 hfp_hf_establish_service_level_connection(addr);
1259 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1312 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1260
1261 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1262 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1313
1314 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1315 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1263 connection->hf_send_chld_3 = 1;
1264 hfp_run_for_context(connection);
1316 hfp_connection->hf_send_chld_3 = 1;
1317 hfp_run_for_context(hfp_connection);
1265 }
1266}
1267
1268void hfp_hf_connect_calls(bd_addr_t addr){
1269 hfp_hf_establish_service_level_connection(addr);
1318 }
1319}
1320
1321void hfp_hf_connect_calls(bd_addr_t addr){
1322 hfp_hf_establish_service_level_connection(addr);
1270 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1323 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1271
1272 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1273 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1324
1325 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1326 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1274 connection->hf_send_chld_4 = 1;
1275 hfp_run_for_context(connection);
1327 hfp_connection->hf_send_chld_4 = 1;
1328 hfp_run_for_context(hfp_connection);
1276 }
1277}
1278
1279void hfp_hf_release_call_with_index(bd_addr_t addr, int index){
1280 hfp_hf_establish_service_level_connection(addr);
1329 }
1330}
1331
1332void hfp_hf_release_call_with_index(bd_addr_t addr, int index){
1333 hfp_hf_establish_service_level_connection(addr);
1281 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1334 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1282
1283 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1284 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1335
1336 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1337 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1285 connection->hf_send_chld_x = 1;
1286 connection->hf_send_chld_x_index = 10 + index;
1287 hfp_run_for_context(connection);
1338 hfp_connection->hf_send_chld_x = 1;
1339 hfp_connection->hf_send_chld_x_index = 10 + index;
1340 hfp_run_for_context(hfp_connection);
1288 }
1289}
1290
1291void hfp_hf_private_consultation_with_call(bd_addr_t addr, int index){
1292 hfp_hf_establish_service_level_connection(addr);
1341 }
1342}
1343
1344void hfp_hf_private_consultation_with_call(bd_addr_t addr, int index){
1345 hfp_hf_establish_service_level_connection(addr);
1293 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1346 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1294
1295 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1296 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1347
1348 if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
1349 hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
1297 connection->hf_send_chld_x = 1;
1298 connection->hf_send_chld_x_index = 20 + index;
1299 hfp_run_for_context(connection);
1350 hfp_connection->hf_send_chld_x = 1;
1351 hfp_connection->hf_send_chld_x_index = 20 + index;
1352 hfp_run_for_context(hfp_connection);
1300 }
1301}
1302
1303void hfp_hf_dial_number(bd_addr_t bd_addr, char * number){
1304 hfp_hf_establish_service_level_connection(bd_addr);
1353 }
1354}
1355
1356void hfp_hf_dial_number(bd_addr_t bd_addr, char * number){
1357 hfp_hf_establish_service_level_connection(bd_addr);
1305 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1358 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1306
1359
1307 connection->hf_initiate_outgoing_call = 1;
1360 hfp_connection->hf_initiate_outgoing_call = 1;
1308 snprintf(phone_number, sizeof(phone_number), "%s", number);
1361 snprintf(phone_number, sizeof(phone_number), "%s", number);
1309 hfp_run_for_context(connection);
1362 hfp_run_for_context(hfp_connection);
1310}
1311
1363}
1364
1312void hfp_hf_dial_memory(bd_addr_t bd_addr, char * number){
1365void hfp_hf_dial_memory(bd_addr_t bd_addr, int memory_id){
1313 hfp_hf_establish_service_level_connection(bd_addr);
1366 hfp_hf_establish_service_level_connection(bd_addr);
1314 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1367 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1315
1368
1316 connection->hf_initiate_memory_dialing = 1;
1317 snprintf(phone_number, sizeof(phone_number), "%s", number);
1318 hfp_run_for_context(connection);
1369 hfp_connection->hf_initiate_memory_dialing = 1;
1370 hfp_connection->memory_id = memory_id;
1371
1372 hfp_run_for_context(hfp_connection);
1319}
1320
1321void hfp_hf_redial_last_number(bd_addr_t bd_addr){
1322 hfp_hf_establish_service_level_connection(bd_addr);
1373}
1374
1375void hfp_hf_redial_last_number(bd_addr_t bd_addr){
1376 hfp_hf_establish_service_level_connection(bd_addr);
1323 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1377 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1324
1378
1325 connection->hf_initiate_redial_last_number = 1;
1326 hfp_run_for_context(connection);
1379 hfp_connection->hf_initiate_redial_last_number = 1;
1380 hfp_run_for_context(hfp_connection);
1327}
1328
1329void hfp_hf_activate_call_waiting_notification(bd_addr_t bd_addr){
1330 hfp_hf_establish_service_level_connection(bd_addr);
1381}
1382
1383void hfp_hf_activate_call_waiting_notification(bd_addr_t bd_addr){
1384 hfp_hf_establish_service_level_connection(bd_addr);
1331 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1385 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1332
1386
1333 connection->hf_activate_call_waiting_notification = 1;
1334 hfp_run_for_context(connection);
1387 hfp_connection->hf_activate_call_waiting_notification = 1;
1388 hfp_run_for_context(hfp_connection);
1335}
1336
1337
1338void hfp_hf_deactivate_call_waiting_notification(bd_addr_t bd_addr){
1339 hfp_hf_establish_service_level_connection(bd_addr);
1389}
1390
1391
1392void hfp_hf_deactivate_call_waiting_notification(bd_addr_t bd_addr){
1393 hfp_hf_establish_service_level_connection(bd_addr);
1340 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1394 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1341
1395
1342 connection->hf_deactivate_call_waiting_notification = 1;
1343 hfp_run_for_context(connection);
1396 hfp_connection->hf_deactivate_call_waiting_notification = 1;
1397 hfp_run_for_context(hfp_connection);
1344}
1345
1346
1347void hfp_hf_activate_calling_line_notification(bd_addr_t bd_addr){
1348 hfp_hf_establish_service_level_connection(bd_addr);
1398}
1399
1400
1401void hfp_hf_activate_calling_line_notification(bd_addr_t bd_addr){
1402 hfp_hf_establish_service_level_connection(bd_addr);
1349 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1403 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1350
1404
1351 connection->hf_activate_calling_line_notification = 1;
1352 hfp_run_for_context(connection);
1405 hfp_connection->hf_activate_calling_line_notification = 1;
1406 hfp_run_for_context(hfp_connection);
1353}
1354
1407}
1408
1355/*
1356 * @brief
1357 */
1358void hfp_hf_deactivate_calling_line_notification(bd_addr_t bd_addr){
1359 hfp_hf_establish_service_level_connection(bd_addr);
1409void hfp_hf_deactivate_calling_line_notification(bd_addr_t bd_addr){
1410 hfp_hf_establish_service_level_connection(bd_addr);
1360 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1411 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1361
1412
1362 connection->hf_deactivate_calling_line_notification = 1;
1363 hfp_run_for_context(connection);
1413 hfp_connection->hf_deactivate_calling_line_notification = 1;
1414 hfp_run_for_context(hfp_connection);
1364}
1365
1366
1415}
1416
1417
1367/*
1368 * @brief
1369 */
1370void hfp_hf_activate_echo_canceling_and_noise_reduction(bd_addr_t bd_addr){
1371 hfp_hf_establish_service_level_connection(bd_addr);
1418void hfp_hf_activate_echo_canceling_and_noise_reduction(bd_addr_t bd_addr){
1419 hfp_hf_establish_service_level_connection(bd_addr);
1372 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1420 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1373
1421
1374 connection->hf_activate_echo_canceling_and_noise_reduction = 1;
1375 hfp_run_for_context(connection);
1422 hfp_connection->hf_activate_echo_canceling_and_noise_reduction = 1;
1423 hfp_run_for_context(hfp_connection);
1376}
1377
1424}
1425
1378/*
1379 * @brief
1380 */
1381void hfp_hf_deactivate_echo_canceling_and_noise_reduction(bd_addr_t bd_addr){
1382 hfp_hf_establish_service_level_connection(bd_addr);
1426void hfp_hf_deactivate_echo_canceling_and_noise_reduction(bd_addr_t bd_addr){
1427 hfp_hf_establish_service_level_connection(bd_addr);
1383 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1428 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1384
1429
1385 connection->hf_deactivate_echo_canceling_and_noise_reduction = 1;
1386 hfp_run_for_context(connection);
1430 hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 1;
1431 hfp_run_for_context(hfp_connection);
1387}
1388
1432}
1433
1389/*
1390 * @brief
1391 */
1392void hfp_hf_activate_voice_recognition_notification(bd_addr_t bd_addr){
1393 hfp_hf_establish_service_level_connection(bd_addr);
1434void hfp_hf_activate_voice_recognition_notification(bd_addr_t bd_addr){
1435 hfp_hf_establish_service_level_connection(bd_addr);
1394 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1436 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1395
1437
1396 connection->hf_activate_voice_recognition_notification = 1;
1397 hfp_run_for_context(connection);
1438 hfp_connection->hf_activate_voice_recognition_notification = 1;
1439 hfp_run_for_context(hfp_connection);
1398}
1399
1440}
1441
1400/*
1401 * @brief
1402 */
1403void hfp_hf_deactivate_voice_recognition_notification(bd_addr_t bd_addr){
1404 hfp_hf_establish_service_level_connection(bd_addr);
1442void hfp_hf_deactivate_voice_recognition_notification(bd_addr_t bd_addr){
1443 hfp_hf_establish_service_level_connection(bd_addr);
1405 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1444 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1406
1445
1407 connection->hf_deactivate_voice_recognition_notification = 1;
1408 hfp_run_for_context(connection);
1446 hfp_connection->hf_deactivate_voice_recognition_notification = 1;
1447 hfp_run_for_context(hfp_connection);
1409}
1410
1448}
1449
1411/*
1412 * @brief
1413 */
1414void hfp_hf_set_microphone_gain(bd_addr_t bd_addr, int gain){
1415 hfp_hf_establish_service_level_connection(bd_addr);
1450void hfp_hf_set_microphone_gain(bd_addr_t bd_addr, int gain){
1451 hfp_hf_establish_service_level_connection(bd_addr);
1416 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1417 if (connection->microphone_gain == gain) return;
1418
1419 connection->microphone_gain = gain;
1420 connection->send_microphone_gain = 1;
1421 hfp_run_for_context(connection);
1452 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1453 if (hfp_connection->microphone_gain == gain) return;
1454 if (gain < 0 || gain > 15){
1455 log_info("Valid range for a gain is [0..15]. Currently sent: %d", gain);
1456 return;
1457 }
1458 hfp_connection->microphone_gain = gain;
1459 hfp_connection->send_microphone_gain = 1;
1460 hfp_run_for_context(hfp_connection);
1422}
1423
1461}
1462
1424/*
1425 * @brief
1426 */
1427void hfp_hf_set_speaker_gain(bd_addr_t bd_addr, int gain){
1428 hfp_hf_establish_service_level_connection(bd_addr);
1463void hfp_hf_set_speaker_gain(bd_addr_t bd_addr, int gain){
1464 hfp_hf_establish_service_level_connection(bd_addr);
1429 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1430 if (connection->speaker_gain == gain) return;
1431
1432 connection->speaker_gain = gain;
1433 connection->send_speaker_gain = 1;
1434 hfp_run_for_context(connection);
1465 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
1466 if (hfp_connection->speaker_gain == gain) return;
1467 if (gain < 0 || gain > 15){
1468 log_info("Valid range for a gain is [0..15]. Currently sent: %d", gain);
1469 return;
1470 }
1471 hfp_connection->speaker_gain = gain;
1472 hfp_connection->send_speaker_gain = 1;
1473 hfp_run_for_context(hfp_connection);
1435}
1436
1474}
1475
1437/*
1438 * @brief
1439 */
1440void hfp_hf_send_dtmf_code(bd_addr_t addr, char code){
1441 hfp_hf_establish_service_level_connection(addr);
1476void hfp_hf_send_dtmf_code(bd_addr_t addr, char code){
1477 hfp_hf_establish_service_level_connection(addr);
1442 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1443 connection->hf_send_dtmf_code = code;
1444 hfp_run_for_context(connection);
1478 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1479 hfp_connection->hf_send_dtmf_code = code;
1480 hfp_run_for_context(hfp_connection);
1445}
1446
1481}
1482
1447/*
1448 * @brief
1449 */
1450void hfp_hf_request_phone_number_for_voice_tag(bd_addr_t addr){
1451 hfp_hf_establish_service_level_connection(addr);
1483void hfp_hf_request_phone_number_for_voice_tag(bd_addr_t addr){
1484 hfp_hf_establish_service_level_connection(addr);
1452 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1453 connection->hf_send_binp = 1;
1454 hfp_run_for_context(connection);
1485 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1486 hfp_connection->hf_send_binp = 1;
1487 hfp_run_for_context(hfp_connection);
1455}
1456
1488}
1489
1457/*
1458 * @brief
1459 */
1460void hfp_hf_query_current_call_status(bd_addr_t addr){
1461 hfp_hf_establish_service_level_connection(addr);
1490void hfp_hf_query_current_call_status(bd_addr_t addr){
1491 hfp_hf_establish_service_level_connection(addr);
1462 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1463 connection->hf_send_clcc = 1;
1464 hfp_run_for_context(connection);
1492 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1493 hfp_connection->hf_send_clcc = 1;
1494 hfp_run_for_context(hfp_connection);
1465}
1466
1467
1495}
1496
1497
1468/*
1469 * @brief
1470 */
1471void hfp_hf_rrh_query_status(bd_addr_t addr){
1472 hfp_hf_establish_service_level_connection(addr);
1498void hfp_hf_rrh_query_status(bd_addr_t addr){
1499 hfp_hf_establish_service_level_connection(addr);
1473 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1474 connection->hf_send_rrh = 1;
1475 connection->hf_send_rrh_command = '?';
1476 hfp_run_for_context(connection);
1500 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1501 hfp_connection->hf_send_rrh = 1;
1502 hfp_connection->hf_send_rrh_command = '?';
1503 hfp_run_for_context(hfp_connection);
1477}
1478
1504}
1505
1479/*
1480 * @brief
1481 */
1482void hfp_hf_rrh_hold_call(bd_addr_t addr){
1483 hfp_hf_establish_service_level_connection(addr);
1506void hfp_hf_rrh_hold_call(bd_addr_t addr){
1507 hfp_hf_establish_service_level_connection(addr);
1484 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1485 connection->hf_send_rrh = 1;
1486 connection->hf_send_rrh_command = '0';
1487 hfp_run_for_context(connection);
1508 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1509 hfp_connection->hf_send_rrh = 1;
1510 hfp_connection->hf_send_rrh_command = '0';
1511 hfp_run_for_context(hfp_connection);
1488}
1489
1512}
1513
1490/*
1491 * @brief
1492 */
1493void hfp_hf_rrh_accept_held_call(bd_addr_t addr){
1494 hfp_hf_establish_service_level_connection(addr);
1514void hfp_hf_rrh_accept_held_call(bd_addr_t addr){
1515 hfp_hf_establish_service_level_connection(addr);
1495 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1496 connection->hf_send_rrh = 1;
1497 connection->hf_send_rrh_command = '1';
1498 hfp_run_for_context(connection);
1516 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1517 hfp_connection->hf_send_rrh = 1;
1518 hfp_connection->hf_send_rrh_command = '1';
1519 hfp_run_for_context(hfp_connection);
1499}
1500
1520}
1521
1501/*
1502 * @brief
1503 */
1504void hfp_hf_rrh_reject_held_call(bd_addr_t addr)
1505{
1522void hfp_hf_rrh_reject_held_call(bd_addr_t addr){
1506 hfp_hf_establish_service_level_connection(addr);
1523 hfp_hf_establish_service_level_connection(addr);
1507 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1508 connection->hf_send_rrh = 1;
1509 connection->hf_send_rrh_command = '2';
1510 hfp_run_for_context(connection);
1524 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1525 hfp_connection->hf_send_rrh = 1;
1526 hfp_connection->hf_send_rrh_command = '2';
1527 hfp_run_for_context(hfp_connection);
1511}
1512
1528}
1529
1513/*
1514 * @brief
1515 */
1516void hfp_hf_query_subscriber_number(bd_addr_t addr)
1517{
1530void hfp_hf_query_subscriber_number(bd_addr_t addr){
1518 hfp_hf_establish_service_level_connection(addr);
1531 hfp_hf_establish_service_level_connection(addr);
1519 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1520 connection->hf_send_cnum = 1;
1521 hfp_run_for_context(connection);
1532 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1533 hfp_connection->hf_send_cnum = 1;
1534 hfp_run_for_context(hfp_connection);
1522}
1523
1535}
1536
1524/*
1525 * @brief
1526 */
1527void hfp_hf_set_hf_indicator(bd_addr_t addr, int assigned_number, int value){
1528 hfp_hf_establish_service_level_connection(addr);
1537void hfp_hf_set_hf_indicator(bd_addr_t addr, int assigned_number, int value){
1538 hfp_hf_establish_service_level_connection(addr);
1529 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
1539 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(addr);
1530 // find index for assigned number
1531 int i;
1532 for (i = 0; i < hfp_indicators_nr ; i++){
1533 if (hfp_indicators[i] == assigned_number){
1534 // set value
1535 hfp_indicators_value[i] = value;
1536 // mark for update
1540 // find index for assigned number
1541 int i;
1542 for (i = 0; i < hfp_indicators_nr ; i++){
1543 if (hfp_indicators[i] == assigned_number){
1544 // set value
1545 hfp_indicators_value[i] = value;
1546 // mark for update
1537 connection->generic_status_update_bitmap |= (1<<i);
1538 // send update
1539 hfp_run_for_context(connection);
1547 if (hfp_connection->state > HFP_LIST_GENERIC_STATUS_INDICATORS){
1548 hfp_connection->generic_status_update_bitmap |= (1<<i);
1549 // send update
1550 hfp_run_for_context(hfp_connection);
1551 }
1540 return;
1541 }
1542 }
1543}
1544
1552 return;
1553 }
1554 }
1555}
1556