hfp: handle multiple commands/responses in single rfcomm data packet

This commit is contained in:
Matthias Ringwald 2018-11-29 16:24:43 +01:00
parent eb1deedd3b
commit 0cef86faed
2 changed files with 252 additions and 257 deletions

View File

@ -1841,185 +1841,185 @@ static void hfp_ag_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uin
int pos;
for (pos = 0; pos < size ; pos++){
hfp_parse(hfp_connection, packet[pos], 0);
}
int value;
hfp_generic_status_indicator_t * indicator;
switch(hfp_connection->command){
case HFP_CMD_RESPONSE_AND_HOLD_QUERY:
if (hfp_ag_response_and_hold_active){
hfp_connection->send_response_and_hold_status = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD + 1;
}
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_RESPONSE_AND_HOLD_COMMAND:
value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
log_info("HF Response and Hold: %u", value);
switch(value){
case HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD:
hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_ACCEPT_INCOMING_CALL_BY_HF, hfp_connection);
break;
case HFP_RESPONSE_AND_HOLD_HELD_INCOMING_ACCEPTED:
hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_HF, hfp_connection);
break;
case HFP_RESPONSE_AND_HOLD_HELD_INCOMING_REJECTED:
hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_HF, hfp_connection);
break;
default:
break;
}
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_HF_INDICATOR_STATUS:
hfp_connection->command = HFP_CMD_NONE;
// find indicator by assigned number
indicator = get_hf_indicator_by_number(hfp_connection->parser_indicator_index);
if (!indicator){
hfp_connection->send_error = 1;
break;
}
value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
switch (indicator->uuid){
case 1: // enhanced security
if (value > 1) {
hfp_connection->send_error = 1;
return;
}
log_info("HF Indicator 'enhanced security' set to %u", value);
break;
case 2: // battery level
if (value > 100){
hfp_connection->send_error = 1;
return;
}
log_info("HF Indicator 'battery' set to %u", value);
break;
default:
log_info("HF Indicator unknown set to %u", value);
break;
}
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS:
// expected by SLC state machine
if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) break;
hfp_connection->send_ag_indicators_segment = 0;
hfp_connection->send_ag_status_indicators = 1;
break;
case HFP_CMD_LIST_CURRENT_CALLS:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->next_call_index = 0;
hfp_connection->send_status_of_current_calls = 1;
break;
case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
if (subscriber_numbers_count == 0){
hfp_ag_send_ok(hfp_connection->rfcomm_cid);
break;
}
hfp_connection->next_subscriber_number_to_send = 0;
hfp_connection->send_subscriber_number = 1;
break;
case HFP_CMD_TRANSMIT_DTMF_CODES:
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_TRANSMIT_DTMF_CODES, (const char *) &hfp_connection->line_buffer[0]);
break;
case HFP_CMD_HF_REQUEST_PHONE_NUMBER:
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG);
break;
case HFP_CMD_TURN_OFF_EC_AND_NR:
hfp_connection->command = HFP_CMD_NONE;
if (get_bit(hfp_supported_features, HFP_AGSF_EC_NR_FUNCTION)){
int value;
hfp_generic_status_indicator_t * indicator;
switch(hfp_connection->command){
case HFP_CMD_RESPONSE_AND_HOLD_QUERY:
if (hfp_ag_response_and_hold_active){
hfp_connection->send_response_and_hold_status = HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD + 1;
}
hfp_connection->ok_pending = 1;
hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_EC_NR_FUNCTION, hfp_connection->ag_echo_and_noise_reduction);
log_info("AG: EC/NR = %u", hfp_connection->ag_echo_and_noise_reduction);
} else {
hfp_connection->send_error = 1;
}
break;
case HFP_CMD_CALL_ANSWERED:
hfp_connection->command = HFP_CMD_NONE;
log_info("HFP: ATA");
hfp_ag_call_sm(HFP_AG_INCOMING_CALL_ACCEPTED_BY_HF, hfp_connection);
break;
case HFP_CMD_HANG_UP_CALL:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->ok_pending = 1;
hfp_ag_call_sm(HFP_AG_TERMINATE_CALL_BY_HF, hfp_connection);
break;
case HFP_CMD_CALL_HOLD: {
// TODO: fully implement this
log_error("HFP: unhandled call hold type %c", hfp_connection->line_buffer[0]);
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->ok_pending = 1;
hfp_connection->call_index = 0;
if (hfp_connection->line_buffer[1] != '\0'){
hfp_connection->call_index = btstack_atoi((char *)&hfp_connection->line_buffer[1]);
}
break;
case HFP_CMD_RESPONSE_AND_HOLD_COMMAND:
value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
log_info("HF Response and Hold: %u", value);
switch(value){
case HFP_RESPONSE_AND_HOLD_INCOMING_ON_HOLD:
hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_ACCEPT_INCOMING_CALL_BY_HF, hfp_connection);
break;
case HFP_RESPONSE_AND_HOLD_HELD_INCOMING_ACCEPTED:
hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_ACCEPT_HELD_CALL_BY_HF, hfp_connection);
break;
case HFP_RESPONSE_AND_HOLD_HELD_INCOMING_REJECTED:
hfp_ag_call_sm(HFP_AG_RESPONSE_AND_HOLD_REJECT_HELD_CALL_BY_HF, hfp_connection);
break;
default:
break;
}
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_HF_INDICATOR_STATUS:
hfp_connection->command = HFP_CMD_NONE;
// find indicator by assigned number
indicator = get_hf_indicator_by_number(hfp_connection->parser_indicator_index);
if (!indicator){
hfp_connection->send_error = 1;
break;
}
value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
switch (indicator->uuid){
case 1: // enhanced security
if (value > 1) {
hfp_connection->send_error = 1;
return;
}
log_info("HF Indicator 'enhanced security' set to %u", value);
break;
case 2: // battery level
if (value > 100){
hfp_connection->send_error = 1;
return;
}
log_info("HF Indicator 'battery' set to %u", value);
break;
default:
log_info("HF Indicator unknown set to %u", value);
break;
}
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS:
// expected by SLC state machine
if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) break;
hfp_connection->send_ag_indicators_segment = 0;
hfp_connection->send_ag_status_indicators = 1;
break;
case HFP_CMD_LIST_CURRENT_CALLS:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->next_call_index = 0;
hfp_connection->send_status_of_current_calls = 1;
break;
case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
if (subscriber_numbers_count == 0){
hfp_ag_send_ok(hfp_connection->rfcomm_cid);
break;
}
hfp_connection->next_subscriber_number_to_send = 0;
hfp_connection->send_subscriber_number = 1;
break;
case HFP_CMD_TRANSMIT_DTMF_CODES:
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_TRANSMIT_DTMF_CODES, (const char *) &hfp_connection->line_buffer[0]);
break;
case HFP_CMD_HF_REQUEST_PHONE_NUMBER:
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG);
break;
case HFP_CMD_TURN_OFF_EC_AND_NR:
hfp_connection->command = HFP_CMD_NONE;
if (get_bit(hfp_supported_features, HFP_AGSF_EC_NR_FUNCTION)){
hfp_connection->ok_pending = 1;
hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_EC_NR_FUNCTION, hfp_connection->ag_echo_and_noise_reduction);
log_info("AG: EC/NR = %u", hfp_connection->ag_echo_and_noise_reduction);
} else {
hfp_connection->send_error = 1;
}
break;
case HFP_CMD_CALL_ANSWERED:
hfp_connection->command = HFP_CMD_NONE;
log_info("HFP: ATA");
hfp_ag_call_sm(HFP_AG_INCOMING_CALL_ACCEPTED_BY_HF, hfp_connection);
break;
case HFP_CMD_HANG_UP_CALL:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->ok_pending = 1;
hfp_ag_call_sm(HFP_AG_TERMINATE_CALL_BY_HF, hfp_connection);
break;
case HFP_CMD_CALL_HOLD: {
// TODO: fully implement this
log_error("HFP: unhandled call hold type %c", hfp_connection->line_buffer[0]);
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->ok_pending = 1;
hfp_connection->call_index = 0;
if (hfp_connection->line_buffer[1] != '\0'){
hfp_connection->call_index = btstack_atoi((char *)&hfp_connection->line_buffer[1]);
}
switch (hfp_connection->line_buffer[0]){
case '0':
// Releases all held calls or sets User Determined User Busy (UDUB) for a waiting call.
hfp_ag_call_sm(HFP_AG_CALL_HOLD_USER_BUSY, hfp_connection);
break;
case '1':
// Releases all active calls (if any exist) and accepts the other (held or waiting) call.
// Where both a held and a waiting call exist, the above procedures shall apply to the
// waiting call (i.e., not to the held call) in conflicting situation.
hfp_ag_call_sm(HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, hfp_connection);
break;
case '2':
// Places all active calls (if any exist) on hold and accepts the other (held or waiting) call.
// Where both a held and a waiting call exist, the above procedures shall apply to the
// waiting call (i.e., not to the held call) in conflicting situation.
hfp_ag_call_sm(HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, hfp_connection);
break;
case '3':
// Adds a held call to the conversation.
hfp_ag_call_sm(HFP_AG_CALL_HOLD_ADD_HELD_CALL, hfp_connection);
break;
case '4':
// Connects the two calls and disconnects the subscriber from both calls (Explicit Call Transfer).
hfp_ag_call_sm(HFP_AG_CALL_HOLD_EXIT_AND_JOIN_CALLS, hfp_connection);
break;
default:
break;
switch (hfp_connection->line_buffer[0]){
case '0':
// Releases all held calls or sets User Determined User Busy (UDUB) for a waiting call.
hfp_ag_call_sm(HFP_AG_CALL_HOLD_USER_BUSY, hfp_connection);
break;
case '1':
// Releases all active calls (if any exist) and accepts the other (held or waiting) call.
// Where both a held and a waiting call exist, the above procedures shall apply to the
// waiting call (i.e., not to the held call) in conflicting situation.
hfp_ag_call_sm(HFP_AG_CALL_HOLD_RELEASE_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, hfp_connection);
break;
case '2':
// Places all active calls (if any exist) on hold and accepts the other (held or waiting) call.
// Where both a held and a waiting call exist, the above procedures shall apply to the
// waiting call (i.e., not to the held call) in conflicting situation.
hfp_ag_call_sm(HFP_AG_CALL_HOLD_PARK_ACTIVE_ACCEPT_HELD_OR_WAITING_CALL, hfp_connection);
break;
case '3':
// Adds a held call to the conversation.
hfp_ag_call_sm(HFP_AG_CALL_HOLD_ADD_HELD_CALL, hfp_connection);
break;
case '4':
// Connects the two calls and disconnects the subscriber from both calls (Explicit Call Transfer).
hfp_ag_call_sm(HFP_AG_CALL_HOLD_EXIT_AND_JOIN_CALLS, hfp_connection);
break;
default:
break;
}
break;
}
break;
case HFP_CMD_CALL_PHONE_NUMBER:
hfp_connection->command = HFP_CMD_NONE;
hfp_ag_call_sm(HFP_AG_OUTGOING_CALL_INITIATED, hfp_connection);
break;
case HFP_CMD_REDIAL_LAST_NUMBER:
hfp_connection->command = HFP_CMD_NONE;
hfp_ag_call_sm(HFP_AG_OUTGOING_REDIAL_INITIATED, hfp_connection);
break;
case HFP_CMD_ENABLE_CLIP:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->clip_enabled = hfp_connection->line_buffer[8] != '0';
log_info("hfp: clip set, now: %u", hfp_connection->clip_enabled);
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->call_waiting_notification_enabled = hfp_connection->line_buffer[8] != '0';
log_info("hfp: call waiting notification set, now: %u", hfp_connection->call_waiting_notification_enabled);
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_SET_SPEAKER_GAIN:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->ok_pending = 1;
log_info("HF speaker gain = %u", hfp_connection->speaker_gain);
break;
case HFP_CMD_SET_MICROPHONE_GAIN:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->ok_pending = 1;
log_info("HF microphone gain = %u", hfp_connection->microphone_gain);
break;
default:
break;
}
case HFP_CMD_CALL_PHONE_NUMBER:
hfp_connection->command = HFP_CMD_NONE;
hfp_ag_call_sm(HFP_AG_OUTGOING_CALL_INITIATED, hfp_connection);
break;
case HFP_CMD_REDIAL_LAST_NUMBER:
hfp_connection->command = HFP_CMD_NONE;
hfp_ag_call_sm(HFP_AG_OUTGOING_REDIAL_INITIATED, hfp_connection);
break;
case HFP_CMD_ENABLE_CLIP:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->clip_enabled = hfp_connection->line_buffer[8] != '0';
log_info("hfp: clip set, now: %u", hfp_connection->clip_enabled);
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->call_waiting_notification_enabled = hfp_connection->line_buffer[8] != '0';
log_info("hfp: call waiting notification set, now: %u", hfp_connection->call_waiting_notification_enabled);
hfp_connection->ok_pending = 1;
break;
case HFP_CMD_SET_SPEAKER_GAIN:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->ok_pending = 1;
log_info("HF speaker gain = %u", hfp_connection->speaker_gain);
break;
case HFP_CMD_SET_MICROPHONE_GAIN:
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->ok_pending = 1;
log_info("HF microphone gain = %u", hfp_connection->microphone_gain);
break;
default:
break;
}
}

View File

@ -998,92 +998,87 @@ static void hfp_hf_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, ui
int pos;
for (pos = 0; pos < size ; pos++){
hfp_parse(hfp_connection, packet[pos], 1);
}
int value;
int i;
switch (hfp_connection->command){
case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
hfp_connection->command = HFP_CMD_NONE;
// printf("Subscriber Number: number %s, type %u\n", hfp_connection->bnip_number, hfp_connection->bnip_type);
hfp_hf_emit_subscriber_information(hfp_hf_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number);
break;
case HFP_CMD_RESPONSE_AND_HOLD_STATUS:
hfp_connection->command = HFP_CMD_NONE;
// printf("Response and Hold status: %s\n", hfp_connection->line_buffer);
hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0]));
break;
case HFP_CMD_LIST_CURRENT_CALLS:
hfp_connection->command = HFP_CMD_NONE;
// printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n",
// hfp_connection->clcc_idx, hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
// hfp_connection->bnip_number, hfp_connection->bnip_type);
hfp_hf_emit_enhanced_call_status(hfp_hf_callback, hfp_connection->clcc_idx,
hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
hfp_connection->bnip_type, hfp_connection->bnip_number);
break;
case HFP_CMD_SET_SPEAKER_GAIN:
hfp_connection->command = HFP_CMD_NONE;
value = btstack_atoi((char*)hfp_connection->line_buffer);
hfp_hf_speaker_gain = value;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, value);
break;
case HFP_CMD_SET_MICROPHONE_GAIN:
hfp_connection->command = HFP_CMD_NONE;
value = btstack_atoi((char*)hfp_connection->line_buffer);
hfp_hf_microphone_gain = value;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, value);
break;
case HFP_CMD_AG_SENT_PHONE_NUMBER:
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number);
break;
case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
hfp_connection->command = HFP_CMD_NONE;
hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
break;
case HFP_CMD_AG_SENT_CLIP_INFORMATION:
hfp_connection->command = HFP_CMD_NONE;
hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
break;
case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
hfp_connection->ok_pending = 0;
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->extended_audio_gateway_error = 0;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value);
break;
case HFP_CMD_ERROR:
hfp_connection->ok_pending = 0;
hfp_reset_context_flags(hfp_connection);
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 1);
break;
case HFP_CMD_OK:
hfp_hf_switch_on_ok(hfp_connection);
break;
case HFP_CMD_RING:
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_RING);
break;
case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
for (i = 0; i < hfp_connection->ag_indicators_nr; i++){
if (hfp_connection->ag_indicators[i].status_changed) {
if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){
hfp_callsetup_status = (hfp_callsetup_status_t) hfp_connection->ag_indicators[i].status;
} else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){
hfp_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status;
// avoid set but not used warning
(void) hfp_callheld_status;
} else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){
hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status;
int value;
int i;
switch (hfp_connection->command){
case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
hfp_connection->command = HFP_CMD_NONE;
hfp_hf_emit_subscriber_information(hfp_hf_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number);
break;
case HFP_CMD_RESPONSE_AND_HOLD_STATUS:
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0]));
break;
case HFP_CMD_LIST_CURRENT_CALLS:
hfp_connection->command = HFP_CMD_NONE;
hfp_hf_emit_enhanced_call_status(hfp_hf_callback, hfp_connection->clcc_idx,
hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
hfp_connection->bnip_type, hfp_connection->bnip_number);
break;
case HFP_CMD_SET_SPEAKER_GAIN:
hfp_connection->command = HFP_CMD_NONE;
value = btstack_atoi((char*)hfp_connection->line_buffer);
hfp_hf_speaker_gain = value;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, value);
break;
case HFP_CMD_SET_MICROPHONE_GAIN:
hfp_connection->command = HFP_CMD_NONE;
value = btstack_atoi((char*)hfp_connection->line_buffer);
hfp_hf_microphone_gain = value;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, value);
break;
case HFP_CMD_AG_SENT_PHONE_NUMBER:
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number);
break;
case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
hfp_connection->command = HFP_CMD_NONE;
hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
break;
case HFP_CMD_AG_SENT_CLIP_INFORMATION:
hfp_connection->command = HFP_CMD_NONE;
hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
break;
case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
hfp_connection->ok_pending = 0;
hfp_connection->command = HFP_CMD_NONE;
hfp_connection->extended_audio_gateway_error = 0;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value);
break;
case HFP_CMD_ERROR:
hfp_connection->ok_pending = 0;
hfp_reset_context_flags(hfp_connection);
hfp_connection->command = HFP_CMD_NONE;
hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 1);
break;
case HFP_CMD_OK:
hfp_hf_switch_on_ok(hfp_connection);
break;
case HFP_CMD_RING:
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_RING);
break;
case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
for (i = 0; i < hfp_connection->ag_indicators_nr; i++){
if (hfp_connection->ag_indicators[i].status_changed) {
if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){
hfp_callsetup_status = (hfp_callsetup_status_t) hfp_connection->ag_indicators[i].status;
} else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){
hfp_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status;
// avoid set but not used warning
(void) hfp_callheld_status;
} else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){
hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status;
}
hfp_connection->ag_indicators[i].status_changed = 0;
hfp_emit_ag_indicator_event(hfp_hf_callback, hfp_connection->ag_indicators[i]);
break;
}
hfp_connection->ag_indicators[i].status_changed = 0;
hfp_emit_ag_indicator_event(hfp_hf_callback, hfp_connection->ag_indicators[i]);
break;
}
}
break;
default:
break;
break;
default:
break;
}
}
hfp_run_for_context(hfp_connection);
}