hfp: enhanced call status, fix event and parsing, extend demo

This commit is contained in:
Milanka Ringwald 2019-01-25 16:28:41 +01:00
parent 8a5282fd8d
commit 0aee97eff3
6 changed files with 103 additions and 23 deletions

View File

@ -67,7 +67,8 @@ const uint8_t rfcomm_channel_nr = 1;
const char hfp_hf_service_name[] = "HFP HF Demo"; const char hfp_hf_service_name[] = "HFP HF Demo";
#ifdef HAVE_BTSTACK_STDIN #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 #endif
static bd_addr_t device_addr; 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: case HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION:
printf("Caller ID, number %s\n", hfp_subevent_calling_line_identification_notification_get_number(event)); printf("Caller ID, number %s\n", hfp_subevent_calling_line_identification_notification_get_number(event));
break; 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: default:
printf("event not handled %u\n", event[2]); printf("event not handled %u\n", event[2]);
break; break;

View File

@ -1273,11 +1273,12 @@ typedef uint8_t sm_key_t[16];
#define HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION 0x17 #define HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION 0x17
/** /**
* @format 111111T * @format 1111111T
* @param subevent_code * @param subevent_code
* @param clcc_idx * @param clcc_idx
* @param clcc_dir * @param clcc_dir
* @param clcc_status * @param clcc_status
* @param clcc_mode
* @param clcc_mpty * @param clcc_mpty
* @param bnip_type * @param bnip_type
* @param bnip_number * @param bnip_number

View File

@ -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){ static inline uint8_t hfp_subevent_enhanced_call_status_get_clcc_status(const uint8_t * event){
return event[5]; 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 * @brief Get field clcc_mpty from event HFP_SUBEVENT_ENHANCED_CALL_STATUS
* @param event packet * @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 * @note: btstack_type 1
*/ */
static inline uint8_t hfp_subevent_enhanced_call_status_get_clcc_mpty(const uint8_t * event){ 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 * @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 * @note: btstack_type 1
*/ */
static inline uint8_t hfp_subevent_enhanced_call_status_get_bnip_type(const uint8_t * event){ 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 * @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 * @note: btstack_type T
*/ */
static inline const char * hfp_subevent_enhanced_call_status_get_bnip_number(const uint8_t * event){ 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];
} }
/** /**

View File

@ -97,6 +97,52 @@ static const char * hfp_ag_features[] = {
"Reserved for future definition" "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 void parse_sequence(hfp_connection_t * context);
static btstack_linked_list_t hfp_connections = NULL; static btstack_linked_list_t hfp_connections = NULL;
@ -1263,13 +1309,17 @@ static void parse_sequence(hfp_connection_t * hfp_connection){
break; break;
case 3: case 3:
value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
hfp_connection->clcc_mpty = value; hfp_connection->clcc_mode = value;
break; break;
case 4: 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)); 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; hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0;
break; break;
case 5: case 6:
value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
hfp_connection->bnip_type = value; hfp_connection->bnip_type = value;
break; break;

View File

@ -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); 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 #if defined __cplusplus
} }
#endif #endif

View File

@ -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, 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; if (!callback) return;
uint8_t event[35]; printf("hfp_hf_emit_enhanced_call_status: %s \n", bnip_number);
event[0] = HCI_EVENT_HFP_META; uint8_t event[36];
event[1] = sizeof(event) - 2; int pos = 0;
event[2] = HFP_SUBEVENT_ENHANCED_CALL_STATUS; event[pos++] = HCI_EVENT_HFP_META;
event[3] = clcc_idx; event[pos++] = sizeof(event) - 2;
event[4] = clcc_dir; event[pos++] = HFP_SUBEVENT_ENHANCED_CALL_STATUS;
event[6] = clcc_status; event[pos++] = clcc_idx;
event[7] = clcc_mpty; event[pos++] = clcc_dir;
event[8] = bnip_type; event[pos++] = clcc_status;
int size = (strlen(bnip_number) < sizeof(event) - 10) ? (int) strlen(bnip_number) : (int) sizeof(event) - 10; event[pos++] = clcc_mode;
strncpy((char*)&event[9], bnip_number, size); event[pos++] = clcc_mpty;
event[9 + size] = 0; event[pos++] = bnip_type;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 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){ 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: case HFP_CMD_LIST_CURRENT_CALLS:
hfp_connection->command = HFP_CMD_NONE; hfp_connection->command = HFP_CMD_NONE;
hfp_hf_emit_enhanced_call_status(hfp_hf_callback, hfp_connection->clcc_idx, 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->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mode,
hfp_connection->bnip_type, hfp_connection->bnip_number); hfp_connection->clcc_mpty, hfp_connection->bnip_type, hfp_connection->bnip_number);
break; break;
case HFP_CMD_SET_SPEAKER_GAIN: case HFP_CMD_SET_SPEAKER_GAIN:
hfp_connection->command = HFP_CMD_NONE; hfp_connection->command = HFP_CMD_NONE;