This commit is contained in:
Matthias Ringwald 2016-02-19 21:18:47 +01:00
commit 3de6de0559
12 changed files with 1713 additions and 1584 deletions

View File

@ -679,9 +679,8 @@ extern "C" {
#define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED 0x01
/**
* @format 11
* @format 1
* @param subevent_code
* @param status 0 == OK
*/
#define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED 0x02
@ -693,9 +692,8 @@ extern "C" {
#define HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED 0x03
/**
* @format 11
* @format 1
* @param subevent_code
* @param status 0 == OK
*/
#define HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED 0x04
@ -707,9 +705,8 @@ extern "C" {
#define HFP_SUBEVENT_COMPLETE 0x05
/**
* @format 1111T
* @format 111T
* @param subevent_code
* @param status
* @param indicator_index
* @param indicator_status
* @param indicator_name
@ -719,7 +716,6 @@ extern "C" {
/**
* @format 1111T
* @param subevent_code
* @param status
* @param network_operator_mode
* @param network_operator_format
* @param network_operator_name
@ -733,32 +729,135 @@ extern "C" {
*/
#define HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR 0x08
/**
* @format 11
* @param subevent_code
* @param status
*/
#define HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE 0x09
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_START_RINGINIG 0x0A
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_STOP_RINGINIG 0x0B
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_CALL_TERMINATED 0x0C
/**
* @format 1T
* @param subevent_code
* @param number
*/
#define HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER 0x0D
#define HFP_SUBEVENT_REDIAL_LAST_NUMBER 0x0E
#define HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 0x0F
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 0x0E
/**
* @format 1T
* @param subevent_code
* @param number
*/
#define HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG 0x0F
/**
* @format 1T
* @param subevent_code
* @param dtmf code
*/
#define HFP_SUBEVENT_TRANSMIT_DTMF_CODES 0x10
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_CALL_ANSWERED 0x11
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_CONFERENCE_CALL 0x12
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_RING 0x13
/**
* @format 111
* @param subevent_code
* @param status
* @param gain
*/
#define HFP_SUBEVENT_SPEAKER_VOLUME 0x14
/**
* @format 111
* @param subevent_code
* @param status
* @param gain
*/
#define HFP_SUBEVENT_MICROPHONE_VOLUME 0x15
/**
* @format 11T
* @param subevent_code
* @param status
* @param type
* @param number
*/
#define HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG 0x10
#define HFP_SUBEVENT_TRANSMIT_DTMF_CODES 0x11
#define HFP_SUBEVENT_TRANSMIT_STATUS_OF_CURRENT_CALL 0x12
#define HFP_SUBEVENT_CALL_ANSWERED 0x13
#define HFP_SUBEVENT_CONFERENCE_CALL 0x14
#define HFP_SUBEVENT_RING 0x15
#define HFP_SUBEVENT_SPEAKER_VOLUME 0x16
#define HFP_SUBEVENT_MICROPHONE_VOLUME 0x17
#define HFP_SUBEVENT_CALL_WAITING_NOTIFICATION 0x18
#define HFP_SUBEVENT_CALLING_LINE_INDETIFICATION_NOTIFICATION 0x19
#define HFP_SUBEVENT_ENHANCED_CALL_STATUS 0x1A
#define HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION 0x1B
#define HFP_SUBEVENT_CALL_WAITING_NOTIFICATION 0x16
/**
* @format 11T
* @param subevent_code
* @param type
* @param number
*/
#define HFP_SUBEVENT_CALLING_LINE_INDETIFICATION_NOTIFICATION 0x17
/**
* @format 111111T
* @param subevent_code
* @param clcc_idx
* @param clcc_dir
* @param clcc_status
* @param clcc_mpty
* @param bnip_type
* @param bnip_number
*/
#define HFP_SUBEVENT_ENHANCED_CALL_STATUS 0x18
/**
* @format 111T
* @param subevent_code
* @param status
* @param bnip_type
* @param bnip_number
*/
#define HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION 0x19
/**
* @format 1T
* @param subevent_code
* @param value
*/
#define HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS 0x1A
// ANCS Client
#define ANCS_CLIENT_CONNECTED 0xF0

689
src/hfp.c

File diff suppressed because it is too large Load Diff

View File

@ -159,7 +159,9 @@ typedef enum {
HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE,
HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES,
HFP_CMD_ENABLE_CLIP,
HFP_CMD_AG_SENT_CLIP_INFORMATION,
HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION,
HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE,
HFP_CMD_LIST_GENERIC_STATUS_INDICATORS,
HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS,
@ -604,7 +606,7 @@ typedef struct hfp_connection {
uint8_t clcc_mpty;
uint8_t call_index;
// also used for CLCC if set
// also used for CLCC, CCWA, CLIP if set
uint8_t bnip_type; // 0 == not set
char bnip_number[25]; //
@ -621,25 +623,22 @@ int store_bit(uint32_t bitmap, int position, uint8_t value);
void hfp_create_sdp_record(uint8_t * service, uint16_t service_uuid, int rfcomm_channel_nr, const char * name);
void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t *packet, uint16_t size);
void hfp_emit_event(hfp_callback_t callback, uint8_t event_subtype, uint8_t value);
void hfp_emit_simple_event(hfp_callback_t callback, uint8_t event_subtype);
void hfp_emit_string_event(hfp_callback_t callback, uint8_t event_subtype, const char * value);
hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid);
hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr);
hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle);
int get_hfp_generic_status_indicators_nr(void);
hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(void);
void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr);
linked_list_t * hfp_get_connections(void);
void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree);
void hfp_parse(hfp_connection_t * connection, uint8_t byte, int isHandsFree);
void hfp_init(uint16_t rfcomm_channel_nr);
void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid);
void hfp_release_service_level_connection(hfp_connection_t * connection);
void hfp_reset_context_flags(hfp_connection_t * context);
void hfp_reset_context_flags(hfp_connection_t * connection);
void hfp_release_audio_connection(hfp_connection_t * context);
void hfp_release_audio_connection(hfp_connection_t * connection);
void hfp_setup_synchronous_connection(hci_con_handle_t handle, hfp_link_setttings_t link_settings);

File diff suppressed because it is too large Load Diff

View File

@ -60,26 +60,64 @@ typedef struct {
/**
* @brief Create HFP Audio Gateway (AG) SDP service record.
* @param service
* @param rfcomm_channel_nr
* @param name
* @param ability_to_reject_call
* @param suported_features 32-bit bitmap, see HFP_AGSF_* values in hfp.h
*/
void hfp_ag_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features);;
/**
* @brief Intialize HFP Audio Gateway (AG) device.
* TODO: move optional params into setters
* @brief Set up HFP Audio Gateway (AG) device without additional supported features.
* @param rfcomm_channel_nr
*/
void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features,
uint8_t * codecs, int codecs_nr,
hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr,
hfp_generic_status_indicator_t * hf_indicators, int hf_indicators_nr,
const char *call_hold_services[], int call_hold_services_nr);
void hfp_ag_init(uint16_t rfcomm_channel_nr);
/**
* @brief Set codecs.
* @param codecs_nr
* @param codecs
*/
void hfp_ag_init_codecs(int codecs_nr, uint8_t * codecs);
/**
* @brief Set supported features.
* @param supported_features 32-bit bitmap, see HFP_AGSF_* values in hfp.h
*/
void hfp_ag_init_supported_features(uint32_t supported_features);
/**
* @brief Set AG indicators.
* @param indicators_nr
* @param indicators
*/
void hfp_ag_init_ag_indicators(int ag_indicators_nr, hfp_ag_indicator_t * ag_indicators);
/**
* @brief Set HF indicators.
* @param indicators_nr
* @param indicators
*/
void hfp_ag_init_hf_indicators(int hf_indicators_nr, hfp_generic_status_indicator_t * hf_indicators);
/**
* @brief Set Call Hold services.
* @param indicators_nr
* @param indicators
*/
void hfp_ag_init_call_hold_services(int call_hold_services_nr, const char * call_hold_services[]);
/**
* @brief Register callback for the HFP Audio Gateway (AG) client.
* @param callback
*/
void hfp_ag_register_packet_handler(hfp_callback_t callback);
/**
* @brief Enable in-band ring tone
* @brief Enable in-band ring tone.
* @param use_in_band_ring_tone
*/
void hfp_ag_set_use_in_band_ring_tone(int use_in_band_ring_tone);
@ -94,72 +132,91 @@ void hfp_ag_set_use_in_band_ring_tone(int use_in_band_ring_tone);
* - accept the information about available codecs in the Hands-Free (HF), if sent
* - report own information describing the call hold and multiparty services, if possible
* - report which HF indicators are enabled on the AG, if possible
* The status of SLC connection establishment is reported via
* HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED.
*
* @param bd_addr Bluetooth address of the HF
*/
void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr);
/**
* @brief Release the RFCOMM channel and the audio connection between the HF and the AG.
* TODO: trigger release of the audio connection ??
* If the audio connection exists, it will be released.
* The status of releasing the SLC connection is reported via
* HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED.
*
* @param bd_addr Bluetooth address of the HF
*/
void hfp_ag_release_service_level_connection(bd_addr_t bd_addr);
/**
* @brief
* @brief Establish audio connection.
* The status of Audio connection establishment is reported via is reported via
* HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE.
* @param bd_addr Bluetooth address of the HF
*/
void hfp_ag_establish_audio_connection(bd_addr_t bd_addr);
/**
* @brief
* @brief Release audio connection.
* The status of releasing the Audio connection is reported via is reported via
* HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE.
* @param bd_addr Bluetooth address of the HF
*/
void hfp_ag_release_audio_connection(bd_addr_t bd_addr);
/**
* @brief
* @brief Put the current call on hold, if it exists, and accept incoming call.
*/
void hfp_ag_answer_incoming_call(void);
/**
* @brief
* @brief Join held call with active call.
*/
void hfp_ag_join_held_call(void);
/**
* @brief
* @brief Reject incoming call, if exists, or terminate active call.
*/
void hfp_ag_terminate_call(void);
/*
* @brief
* @brief Put incoming call on hold.
*/
void hfp_ag_hold_incoming_call(void);
/*
* @brief
* @brief Accept the held incoming call.
*/
void hfp_ag_accept_held_incoming_call(void);
/*
* @brief
* @brief Reject the held incoming call.
*/
void hfp_ag_reject_held_incoming_call(void);
/*
* @brief
* @brief Set microphone gain.
* @param bd_addr Bluetooth address of the HF
* @param gain Valid range: [0,15]
*/
void hfp_ag_set_microphone_gain(bd_addr_t bd_addr, int gain);
/*
* @brief
* @brief Set speaker gain.
* @param bd_addr Bluetooth address of the HF
* @param gain Valid range: [0,15]
*/
void hfp_ag_set_speaker_gain(bd_addr_t bd_addr, int gain);
/*
* @brief
* @brief Set battery level.
* @param level Valid range: [0,5]
*/
void hfp_ag_set_battery_level(int level);
/*
* @brief
* @brief Clear last dialed number.
*/
void hfp_ag_clear_last_dialed_number(void);
@ -167,17 +224,22 @@ void hfp_ag_clear_last_dialed_number(void);
// Voice Recognition
/*
* @brief
* @brief Activate voice recognition.
* @param bd_addr Bluetooth address of the HF
* @param activate
*/
void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate);
/*
* @brief
* @param bd_addr Bluetooth address of the HF
* @param number
*/
void hfp_ag_send_phone_number_for_voice_tag(bd_addr_t bd_addr, const char * number);
/*
* @brief
* @param bd_addr Bluetooth address of the HF
*/
void hfp_ag_reject_phone_number_for_voice_tag(bd_addr_t bd_addr);
@ -191,6 +253,8 @@ void hfp_ag_incoming_call(void);
/**
* @brief number is stored.
* @param type
* @param number
*/
void hfp_ag_set_clip(uint8_t type, const char * number);
@ -218,28 +282,35 @@ void hfp_ag_outgoing_call_established(void);
* @brief
*/
void hfp_ag_call_dropped(void);
/*
* @brief
* @param status
*/
void hfp_ag_set_registration_status(int status);
/*
* @brief
* @param strength
*/
void hfp_ag_set_signal_strength(int strength);
/*
* @brief
* @param status
*/
void hfp_ag_set_roaming_status(int status);
/*
* @brief
* @param numbers
* @param numbers_count
*/
void hfp_ag_set_subcriber_number_information(hfp_phone_number_t * numbers, int numbers_count);
/*
* @brief Called by cellular unit after a DTMF code was transmitted, so that the next one can be emitted
* @param bd_addr Bluetooth address of the HF
*/
void hfp_ag_send_dtmf_code_done(bd_addr_t bd_addr);
@ -270,6 +341,9 @@ void hfp_ag_send_dtmf_code_done(bd_addr_t bd_addr);
* - +CME ERROR: 30 - no network service
* - +CME ERROR: 31 - network Timeout.
* - +CME ERROR: 32 - network not allowed Emergency calls only
*
* @param bd_addr Bluetooth address of the HF
* @param error
*/
void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error);

File diff suppressed because it is too large Load Diff

View File

@ -65,15 +65,13 @@ extern "C" {
void hfp_hf_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint32_t supported_features);
/**
* @brief Set up HFP Hands-Free (HF) device without additional supported features
*
* @brief Set up HFP Hands-Free (HF) device without additional supported features.
* @param rfcomm_channel_nr
*/
void hfp_hf_init(uint16_t rfcomm_channel_nr);
/**
* @brief Set codecs.
*
* @param codecs_nr
* @param codecs
*/
@ -81,14 +79,12 @@ void hfp_hf_init_codecs(int codecs_nr, uint8_t * codecs);
/**
* @brief Set supported features.
*
* @param supported_features 32-bit bitmap, see HFP_HFSF_* values in hfp.h
*/
void hfp_hf_init_supported_features(uint32_t supported_features);
/**
* @brief Set HF indicators.
*
* @param indicators_nr
* @param indicators
*/
@ -97,6 +93,7 @@ void hfp_hf_init_hf_indicators(int indicators_nr, uint16_t * indicators);
/**
* @brief Register callback for the HFP Hands-Free (HF) client.
* @param callback
*/
void hfp_hf_register_packet_handler(hfp_callback_t callback);
@ -111,6 +108,7 @@ void hfp_hf_register_packet_handler(hfp_callback_t callback);
* - retrieve which HF indicators are enabled on the AG, if possible
* The status of SLC connection establishment is reported via
* HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED.
*
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr);
@ -151,7 +149,7 @@ void hfp_hf_disable_status_update_for_all_ag_indicators(bd_addr_t bd_addr);
void hfp_hf_set_status_update_for_individual_ag_indicators(bd_addr_t bd_addr, uint32_t indicators_status_bitmap);
/**
* @brief Find out the name of the currently selected Network operator by AG.
* @brief Query the name of the currently selected Network operator by AG.
*
* The name is restricted to max 16 characters. The result is reported via
* HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED subtype
@ -209,38 +207,38 @@ void hfp_hf_answer_incoming_call(bd_addr_t bd_addr);
void hfp_hf_reject_incoming_call(bd_addr_t bd_addr);
/**
* @brief Releases all held calls or sets User Determined User Busy (UDUB) for a waiting call.
* @brief Release all held calls or sets User Determined User Busy (UDUB) for a waiting call.
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_user_busy(bd_addr_t addr);
/**
* @brief Releases all active calls (if any exist) and accepts the other (held or waiting) call.
* @brief Release all active calls (if any exist) and accepts the other (held or waiting) call.
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_end_active_and_accept_other(bd_addr_t addr);
/**
* @brief Places all active calls (if any exist) on hold and accepts the other (held or waiting) call.
* @brief Place all active calls (if any exist) on hold and accepts the other (held or waiting) call.
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_swap_calls(bd_addr_t addr);
/**
* @brief Adds a held call to the conversation.
* @brief Add a held call to the conversation.
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_join_held_call(bd_addr_t addr);
/**
* @brief Connects the two calls and disconnects the subscriber from both calls (Explicit Call
* @brief Connect the two calls and disconnects the subscriber from both calls (Explicit Call
Transfer).
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_connect_calls(bd_addr_t addr);
/**
* @brief Terminates an incoming or an outgoing call.
* @brief Terminate an incoming or an outgoing call.
* HFP_SUBEVENT_CALL_TERMINATED is sent upon call termination.
* @param bd_addr Bluetooth address of the AG
*/
@ -349,15 +347,15 @@ void hfp_hf_send_dtmf_code(bd_addr_t bd_addr, char code);
/*
* @brief Read numbers from the AG for the purpose of creating
* a unique voice tag and storing the number and its linked voice
* tag in the HFs memory. The number is recived via
* HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG.
* tag in the HFs memory.
* The number is reported via HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG.
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_request_phone_number_for_voice_tag(bd_addr_t addr);
/*
* @brief Query the list of current calls in AG.
* The result is received via HFP_SUBEVENT_ENHANCED_CALL_STATUS (TODO).
* The result is received via HFP_SUBEVENT_ENHANCED_CALL_STATUS.
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_query_current_call_status(bd_addr_t addr);
@ -379,6 +377,7 @@ void hfp_hf_private_consultation_with_call(bd_addr_t addr, int index);
/*
* @brief Query the status of the Response and Hold state of the AG.
* The result is reported via HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS.
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_rrh_query_status(bd_addr_t addr);
@ -403,6 +402,7 @@ void hfp_hf_rrh_reject_held_call(bd_addr_t addr);
/*
* @brief Query the AG subscriber number.
* The result is reported via HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION.
* @param bd_addr Bluetooth address of the AG
*/
void hfp_hf_query_subscriber_number(bd_addr_t addr);

View File

@ -362,8 +362,7 @@ void packet_handler(uint8_t * event, uint16_t event_size){
if (event[3]
&& event[2] != HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER
&& event[2] != HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG
&& event[2] != HFP_SUBEVENT_TRANSMIT_DTMF_CODES
&& event[2] != HFP_SUBEVENT_TRANSMIT_STATUS_OF_CURRENT_CALL){
&& event[2] != HFP_SUBEVENT_TRANSMIT_DTMF_CODES){
printf("ERROR, status: %u\n", event[3]);
return;
}
@ -418,11 +417,12 @@ void packet_handler(uint8_t * event, uint16_t event_size){
TEST_GROUP(HFPClient){
void setup(void){
hfp_ag_init(rfcomm_channel_nr, supported_features_with_codec_negotiation,
codecs, sizeof(codecs),
ag_indicators, ag_indicators_nr,
hf_indicators, hf_indicators_nr,
call_hold_services, call_hold_services_nr);
hfp_ag_init(rfcomm_channel_nr);
hfp_ag_init_supported_features(supported_features_with_codec_negotiation);
hfp_ag_init_codecs(sizeof(codecs), codecs);
hfp_ag_init_ag_indicators(ag_indicators_nr, ag_indicators);
hfp_ag_init_hf_indicators(hf_indicators_nr, hf_indicators);
hfp_ag_init_call_hold_services(call_hold_services_nr, call_hold_services);
}
void teardown(void){

View File

@ -45,14 +45,11 @@
#include "CppUTest/CommandLineTestRunner.h"
#include "hfp.h"
#include "hfp_ag.h"
void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree);
hfp_generic_status_indicator_t * get_hfp_generic_status_indicators();
void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr);
hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context);
int get_hfp_ag_indicators_nr(hfp_connection_t * context);
void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr);
hfp_ag_indicator_t * hfp_ag_get_ag_indicators(hfp_connection_t * hfp_connection);
// static int hf_indicators_nr = 3;
// static hfp_generic_status_indicator_t hf_indicators[] = {
@ -139,13 +136,13 @@ TEST(HFPParser, HFP_AG_ENABLE_INDICATOR_STATUS_UPDATE){
TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE){
set_hfp_ag_indicators((hfp_ag_indicator_t *)&hfp_ag_indicators, hfp_ag_indicators_nr);
hfp_ag_init_ag_indicators(hfp_ag_indicators_nr, (hfp_ag_indicator_t *)&hfp_ag_indicators);
context.ag_indicators_nr = hfp_ag_indicators_nr;
memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
for (pos = 0; pos < hfp_ag_indicators_nr; pos++){
CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].index, hfp_ag_indicators[pos].index);
CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, hfp_ag_indicators[pos].enabled);
CHECK_EQUAL(hfp_ag_get_ag_indicators(&context)[pos].index, hfp_ag_indicators[pos].index);
CHECK_EQUAL(hfp_ag_get_ag_indicators(&context)[pos].enabled, hfp_ag_indicators[pos].enabled);
CHECK_EQUAL(context.ag_indicators[pos].index, hfp_ag_indicators[pos].index);
CHECK_EQUAL(context.ag_indicators[pos].enabled, hfp_ag_indicators[pos].enabled);
}
@ -158,18 +155,18 @@ TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE){
CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command);
for (pos = 0; pos < hfp_ag_indicators_nr; pos++){
if (get_hfp_ag_indicators(&context)[pos].mandatory){
CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, 1);
if (hfp_ag_get_ag_indicators(&context)[pos].mandatory){
CHECK_EQUAL(hfp_ag_get_ag_indicators(&context)[pos].enabled, 1);
CHECK_EQUAL(context.ag_indicators[pos].enabled, 1);
} else {
CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, 0);
CHECK_EQUAL(hfp_ag_get_ag_indicators(&context)[pos].enabled, 0);
CHECK_EQUAL(context.ag_indicators[pos].enabled, 0);
}
}
}
TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES3){
set_hfp_ag_indicators((hfp_ag_indicator_t *)&hfp_ag_indicators, hfp_ag_indicators_nr);
hfp_ag_init_ag_indicators(hfp_ag_indicators_nr, (hfp_ag_indicator_t *)&hfp_ag_indicators);
context.ag_indicators_nr = hfp_ag_indicators_nr;
memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
@ -182,15 +179,15 @@ TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES3){
CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command);
for (pos = 0; pos < hfp_ag_indicators_nr; pos++){
CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].index, hfp_ag_indicators[pos].index);
CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, hfp_ag_indicators[pos].enabled);
CHECK_EQUAL(hfp_ag_get_ag_indicators(&context)[pos].index, hfp_ag_indicators[pos].index);
CHECK_EQUAL(hfp_ag_get_ag_indicators(&context)[pos].enabled, hfp_ag_indicators[pos].enabled);
CHECK_EQUAL(context.ag_indicators[pos].index, hfp_ag_indicators[pos].index);
CHECK_EQUAL(context.ag_indicators[pos].enabled, hfp_ag_indicators[pos].enabled);
}
}
TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES2){
set_hfp_ag_indicators((hfp_ag_indicator_t *)&hfp_ag_indicators, hfp_ag_indicators_nr);
hfp_ag_init_ag_indicators(hfp_ag_indicators_nr, (hfp_ag_indicator_t *)&hfp_ag_indicators);
context.ag_indicators_nr = hfp_ag_indicators_nr;
memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
@ -203,13 +200,13 @@ TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES2){
CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command);
for (pos = 0; pos < hfp_ag_indicators_nr; pos++){
CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, 1);
CHECK_EQUAL(hfp_ag_get_ag_indicators(&context)[pos].enabled, 1);
CHECK_EQUAL(context.ag_indicators[pos].enabled, 1);
}
}
TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES1){
set_hfp_ag_indicators((hfp_ag_indicator_t *)&hfp_ag_indicators, hfp_ag_indicators_nr);
hfp_ag_init_ag_indicators(hfp_ag_indicators_nr, (hfp_ag_indicator_t *)&hfp_ag_indicators);
context.ag_indicators_nr = hfp_ag_indicators_nr;
memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
@ -222,7 +219,7 @@ TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES1){
CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command);
for (pos = 0; pos < hfp_ag_indicators_nr; pos++){
CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, 1);
CHECK_EQUAL(hfp_ag_get_ag_indicators(&context)[pos].enabled, 1);
CHECK_EQUAL(context.ag_indicators[pos].enabled, 1);
}
}

View File

@ -394,14 +394,6 @@ void simulate_test_sequence(hfp_test_item_t * test_item){
void packet_handler(uint8_t * event, uint16_t event_size){
if (event[0] != HCI_EVENT_HFP_META) return;
if (event[3]
&& event[2] != HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR
&& event[2] != HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG
&& event[2] != HFP_SUBEVENT_SPEAKER_VOLUME
&& event[2] != HFP_SUBEVENT_MICROPHONE_VOLUME){
printf("ERROR, status: %u\n", event[3]);
return;
}
switch (event[2]) {
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
@ -443,10 +435,10 @@ void packet_handler(uint8_t * event, uint16_t event_size){
printf("HFP AG HFP_SUBEVENT_COMPLETE.\n");
break;
case HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED:
printf("AG_INDICATOR_STATUS_CHANGED, AG indicator '%s' (index: %d) to: %d\n", (const char*) &event[6], event[4], event[5]);
printf("AG_INDICATOR_STATUS_CHANGED, AG indicator '%s' (index: %d) to: %d\n", (const char*) &event[5], event[3], event[4]);
break;
case HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED:
printf("NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[4], event[5], (char *) &event[6]);
printf("NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[3], event[4], (char *) &event[5]);
break;
case HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR:
if (event[4])

View File

@ -599,8 +599,7 @@ static void packet_handler(uint8_t * event, uint16_t event_size){
if (event[3]
&& event[2] != HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER
&& event[2] != HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG
&& event[2] != HFP_SUBEVENT_TRANSMIT_DTMF_CODES
&& event[2] != HFP_SUBEVENT_TRANSMIT_STATUS_OF_CURRENT_CALL){
&& event[2] != HFP_SUBEVENT_TRANSMIT_DTMF_CODES){
printf("ERROR, status: %u\n", event[3]);
return;
}
@ -665,10 +664,13 @@ int btstack_main(int argc, const char * argv[]){
l2cap_init();
rfcomm_init();
hfp_ag_init(rfcomm_channel_nr, 0x3ef | (1<<HFP_AGSF_HF_INDICATORS) | (1<<HFP_AGSF_ESCO_S4), codecs, sizeof(codecs),
ag_indicators, ag_indicators_nr,
hf_indicators, hf_indicators_nr,
call_hold_services, call_hold_services_nr);
hfp_ag_init(rfcomm_channel_nr);
hfp_ag_init_supported_features(0x3ef | (1<<HFP_AGSF_HF_INDICATORS) | (1<<HFP_AGSF_ESCO_S4));
hfp_ag_init_codecs(sizeof(codecs), codecs);
hfp_ag_init_ag_indicators(ag_indicators_nr, ag_indicators);
hfp_ag_init_hf_indicators(hf_indicators_nr, hf_indicators);
hfp_ag_init_call_hold_services(call_hold_services_nr, call_hold_services);
hfp_ag_set_subcriber_number_information(&subscriber_number, 1);
hfp_ag_register_packet_handler(packet_handler);

View File

@ -467,14 +467,7 @@ static void packet_handler(uint8_t * event, uint16_t event_size){
return;
}
if (event[0] != HCI_EVENT_HFP_META) return;
if (event[3]
&& event[2] != HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR
&& event[2] != HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG
&& event[2] != HFP_SUBEVENT_SPEAKER_VOLUME
&& event[2] != HFP_SUBEVENT_MICROPHONE_VOLUME){
printf("ERROR, status: %u\n", event[3]);
return;
}
switch (event[2]) {
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
printf("Service level connection established.\n\n");
@ -500,10 +493,10 @@ static void packet_handler(uint8_t * event, uint16_t event_size){
}
break;
case HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED:
printf("AG_INDICATOR_STATUS_CHANGED, AG indicator '%s' (index: %d) to: %d\n", (const char*) &event[6], event[4], event[5]);
printf("AG_INDICATOR_STATUS_CHANGED, AG indicator '%s' (index: %d) to: %d\n", (const char*) &event[5], event[3], event[4]);
break;
case HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED:
printf("NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[4], event[5], (char *) &event[6]);
printf("NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[3], event[4], (char *) &event[5]);
break;
case HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR:
if (event[4])
@ -536,9 +529,8 @@ int btstack_main(int argc, const char * argv[]){
// hfp_hf_init(rfcomm_channel_nr, HFP_DEFAULT_HF_SUPPORTED_FEATURES, codecs, sizeof(codecs), indicators, sizeof(indicators)/sizeof(uint16_t), 1);
hfp_hf_init(rfcomm_channel_nr);
hfp_hf_init_supported_features(438 | (1<<HFP_HFSF_ESCO_S4) | (1<<HFP_HFSF_EC_NR_FUNCTION));
hfp_hf_init_hf_indicators(sizeof(indicators)/sizeof(uint16_t), indicators, hf_indicators_values);
hfp_hf_init_hf_indicators(sizeof(indicators)/sizeof(uint16_t), indicators);
hfp_hf_init_codecs(sizeof(codecs), codecs);
hfp_hf_set_indicators_status(1);
hfp_hf_register_packet_handler(packet_handler);