From 0aee97eff3e77a1a29b856d1782b8523c8efe833 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 25 Jan 2019 16:28:41 +0100 Subject: [PATCH] hfp: enhanced call status, fix event and parsing, extend demo --- example/hfp_hf_demo.c | 13 ++++++++++- src/btstack_defines.h | 3 ++- src/btstack_event.h | 15 +++++++++--- src/classic/hfp.c | 54 +++++++++++++++++++++++++++++++++++++++++-- src/classic/hfp.h | 5 ++++ src/classic/hfp_hf.c | 36 ++++++++++++++++------------- 6 files changed, 103 insertions(+), 23 deletions(-) diff --git a/example/hfp_hf_demo.c b/example/hfp_hf_demo.c index 8335faf65..083268925 100644 --- a/example/hfp_hf_demo.c +++ b/example/hfp_hf_demo.c @@ -67,7 +67,8 @@ const uint8_t rfcomm_channel_nr = 1; const char hfp_hf_service_name[] = "HFP HF Demo"; #ifdef HAVE_BTSTACK_STDIN -static const char * device_addr_string = "6C:72:E7:10:22:EE"; +// static const char * device_addr_string = "6C:72:E7:10:22:EE"; +static const char * device_addr_string = "54:E4:3A:26:A2:39"; #endif static bd_addr_t device_addr; @@ -545,6 +546,16 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even case HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION: printf("Caller ID, number %s\n", hfp_subevent_calling_line_identification_notification_get_number(event)); break; + case HFP_SUBEVENT_ENHANCED_CALL_STATUS: + printf("Enhanced call status:\n"); + printf(" - call index: %d \n", hfp_subevent_enhanced_call_status_get_clcc_idx(event)); + printf(" - direction : %s \n", hfp_enhanced_call_dir2str(hfp_subevent_enhanced_call_status_get_clcc_dir(event))); + printf(" - status : %s \n", hfp_enhanced_call_status2str(hfp_subevent_enhanced_call_status_get_clcc_status(event))); + printf(" - mode : %s \n", hfp_enhanced_call_mode2str(hfp_subevent_enhanced_call_status_get_clcc_mode(event))); + printf(" - multipart : %s \n", hfp_enhanced_call_mpty2str(hfp_subevent_enhanced_call_status_get_clcc_mpty(event))); + printf(" - type : %d \n", hfp_subevent_enhanced_call_status_get_bnip_type(event)); + printf(" - number : %s \n", hfp_subevent_enhanced_call_status_get_bnip_number(event)); + break; default: printf("event not handled %u\n", event[2]); break; diff --git a/src/btstack_defines.h b/src/btstack_defines.h index 32985af7b..5a0f354e2 100644 --- a/src/btstack_defines.h +++ b/src/btstack_defines.h @@ -1273,11 +1273,12 @@ typedef uint8_t sm_key_t[16]; #define HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION 0x17 /** - * @format 111111T + * @format 1111111T * @param subevent_code * @param clcc_idx * @param clcc_dir * @param clcc_status + * @param clcc_mode * @param clcc_mpty * @param bnip_type * @param bnip_number diff --git a/src/btstack_event.h b/src/btstack_event.h index 878560832..2910d3095 100644 --- a/src/btstack_event.h +++ b/src/btstack_event.h @@ -4008,6 +4008,15 @@ static inline uint8_t hfp_subevent_enhanced_call_status_get_clcc_dir(const uint8 static inline uint8_t hfp_subevent_enhanced_call_status_get_clcc_status(const uint8_t * event){ return event[5]; } +/** + * @brief Get field clcc_mode from event HFP_SUBEVENT_ENHANCED_CALL_STATUS + * @param event packet + * @return clcc_mode + * @note: btstack_type 1 + */ +static inline uint8_t hfp_subevent_enhanced_call_status_get_clcc_mode(const uint8_t * event){ + return event[6]; +} /** * @brief Get field clcc_mpty from event HFP_SUBEVENT_ENHANCED_CALL_STATUS * @param event packet @@ -4015,7 +4024,7 @@ static inline uint8_t hfp_subevent_enhanced_call_status_get_clcc_status(const ui * @note: btstack_type 1 */ static inline uint8_t hfp_subevent_enhanced_call_status_get_clcc_mpty(const uint8_t * event){ - return event[6]; + return event[7]; } /** * @brief Get field bnip_type from event HFP_SUBEVENT_ENHANCED_CALL_STATUS @@ -4024,7 +4033,7 @@ static inline uint8_t hfp_subevent_enhanced_call_status_get_clcc_mpty(const uint * @note: btstack_type 1 */ static inline uint8_t hfp_subevent_enhanced_call_status_get_bnip_type(const uint8_t * event){ - return event[7]; + return event[8]; } /** * @brief Get field bnip_number from event HFP_SUBEVENT_ENHANCED_CALL_STATUS @@ -4033,7 +4042,7 @@ static inline uint8_t hfp_subevent_enhanced_call_status_get_bnip_type(const uint * @note: btstack_type T */ static inline const char * hfp_subevent_enhanced_call_status_get_bnip_number(const uint8_t * event){ - return (const char *) &event[8]; + return (const char *) &event[9]; } /** diff --git a/src/classic/hfp.c b/src/classic/hfp.c index 8c10246af..0e44a3466 100644 --- a/src/classic/hfp.c +++ b/src/classic/hfp.c @@ -97,6 +97,52 @@ static const char * hfp_ag_features[] = { "Reserved for future definition" }; +static const char * hfp_enhanced_call_dir[] = { + "outgoing", + "incoming" +}; + +static const char * hfp_enhanced_call_status[] = { + "active", + "held", + "outgoing dialing", + "outgoing alerting", + "incoming", + "incoming waiting", + "call held by response and hold" +}; + +static const char * hfp_enhanced_call_mode[] = { + "voice", + "data", + "fax" +}; + +static const char * hfp_enhanced_call_mpty[] = { + "not a conference call", + "conference call" +}; + +const char * hfp_enhanced_call_dir2str(uint16_t index){ + if (index <= HFP_ENHANCED_CALL_DIR_INCOMING) return hfp_enhanced_call_dir[index]; + return "not defined"; +} + +const char * hfp_enhanced_call_status2str(uint16_t index){ + if (index <= HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD) return hfp_enhanced_call_status[index]; + return "not defined"; +} + +const char * hfp_enhanced_call_mode2str(uint16_t index){ + if (index <= HFP_ENHANCED_CALL_MODE_FAX) return hfp_enhanced_call_mode[index]; + return "not defined"; +} + +const char * hfp_enhanced_call_mpty2str(uint16_t index){ + if (index <= HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL) return hfp_enhanced_call_mpty[index]; + return "not defined"; +} + static void parse_sequence(hfp_connection_t * context); static btstack_linked_list_t hfp_connections = NULL; @@ -1263,13 +1309,17 @@ static void parse_sequence(hfp_connection_t * hfp_connection){ break; case 3: value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); - hfp_connection->clcc_mpty = value; + hfp_connection->clcc_mode = value; break; case 4: + value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); + hfp_connection->clcc_mpty = value; + break; + case 5: strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; break; - case 5: + case 6: value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); hfp_connection->bnip_type = value; break; diff --git a/src/classic/hfp.h b/src/classic/hfp.h index e5764b4c5..eb067db82 100644 --- a/src/classic/hfp.h +++ b/src/classic/hfp.h @@ -683,6 +683,11 @@ const char * hfp_ag_feature(int index); void hfp_log_rfcomm_message(const char * tag, uint8_t * packet, uint16_t size); +const char * hfp_enhanced_call_dir2str(uint16_t index); +const char * hfp_enhanced_call_status2str(uint16_t index); +const char * hfp_enhanced_call_mode2str(uint16_t index); +const char * hfp_enhanced_call_mpty2str(uint16_t index); + #if defined __cplusplus } #endif diff --git a/src/classic/hfp_hf.c b/src/classic/hfp_hf.c index 215d9c36d..abcb3e62d 100644 --- a/src/classic/hfp_hf.c +++ b/src/classic/hfp_hf.c @@ -137,21 +137,25 @@ static void hfp_hf_emit_type_and_number(btstack_packet_handler_t callback, uint8 } static void hfp_hf_emit_enhanced_call_status(btstack_packet_handler_t callback, uint8_t clcc_idx, uint8_t clcc_dir, - uint8_t clcc_status, uint8_t clcc_mpty, uint8_t bnip_type, const char * bnip_number){ + uint8_t clcc_status, uint8_t clcc_mode, uint8_t clcc_mpty, uint8_t bnip_type, const char * bnip_number){ if (!callback) return; - uint8_t event[35]; - event[0] = HCI_EVENT_HFP_META; - event[1] = sizeof(event) - 2; - event[2] = HFP_SUBEVENT_ENHANCED_CALL_STATUS; - event[3] = clcc_idx; - event[4] = clcc_dir; - event[6] = clcc_status; - event[7] = clcc_mpty; - event[8] = bnip_type; - int size = (strlen(bnip_number) < sizeof(event) - 10) ? (int) strlen(bnip_number) : (int) sizeof(event) - 10; - strncpy((char*)&event[9], bnip_number, size); - event[9 + size] = 0; - (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); + printf("hfp_hf_emit_enhanced_call_status: %s \n", bnip_number); + uint8_t event[36]; + int pos = 0; + event[pos++] = HCI_EVENT_HFP_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = HFP_SUBEVENT_ENHANCED_CALL_STATUS; + event[pos++] = clcc_idx; + event[pos++] = clcc_dir; + event[pos++] = clcc_status; + event[pos++] = clcc_mode; + event[pos++] = clcc_mpty; + event[pos++] = bnip_type; + int size = (strlen(bnip_number) < sizeof(event) - pos) ? (int) strlen(bnip_number) : (int) sizeof(event) - pos; + strncpy((char*)&event[pos], bnip_number, size); + pos += size; + event[pos++] = 0; + (*callback)(HCI_EVENT_PACKET, 0, event, pos); } static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){ @@ -1026,8 +1030,8 @@ static void hfp_hf_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, ui 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); + hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mode, + 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;