mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-17 11:42:34 +00:00
hfp ag: update docu
This commit is contained in:
parent
dd5c93ea6b
commit
e86127dffc
18
src/hfp.c
18
src/hfp.c
@ -97,24 +97,9 @@ static const char * hfp_ag_features[] = {
|
||||
"Reserved for future definition"
|
||||
};
|
||||
|
||||
static int hfp_generic_status_indicators_nr = 0;
|
||||
static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_HF_INDICATORS];
|
||||
|
||||
static linked_list_t hfp_connections = NULL;
|
||||
static void parse_sequence(hfp_connection_t * hfp_connection);
|
||||
|
||||
hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(void){
|
||||
return (hfp_generic_status_indicator_t *) &hfp_generic_status_indicators;
|
||||
}
|
||||
int get_hfp_generic_status_indicators_nr(void){
|
||||
return hfp_generic_status_indicators_nr;
|
||||
}
|
||||
void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr){
|
||||
if (indicator_nr > HFP_MAX_NUM_HF_INDICATORS) return;
|
||||
hfp_generic_status_indicators_nr = indicator_nr;
|
||||
memcpy(hfp_generic_status_indicators, indicators, indicator_nr * sizeof(hfp_generic_status_indicator_t));
|
||||
}
|
||||
|
||||
const char * hfp_hf_feature(int index){
|
||||
if (index > HFP_HF_FEATURES_SIZE){
|
||||
return hfp_hf_features[HFP_HF_FEATURES_SIZE];
|
||||
@ -315,9 +300,6 @@ static hfp_connection_t * create_hfp_connection_context(){
|
||||
|
||||
hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
|
||||
|
||||
hfp_connection->generic_status_indicators_nr = hfp_generic_status_indicators_nr;
|
||||
memcpy(hfp_connection->generic_status_indicators, hfp_generic_status_indicators, hfp_generic_status_indicators_nr * sizeof(hfp_generic_status_indicator_t));
|
||||
|
||||
linked_list_add(&hfp_connections, (linked_item_t*)hfp_connection);
|
||||
return hfp_connection;
|
||||
}
|
||||
|
@ -630,10 +630,6 @@ 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 * connection, uint8_t byte, int isHandsFree);
|
||||
|
||||
|
140
src/hfp_ag.c
140
src/hfp_ag.c
@ -72,6 +72,9 @@ static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS];
|
||||
static int hfp_ag_indicators_nr = 0;
|
||||
static hfp_ag_indicator_t hfp_ag_indicators[HFP_MAX_NUM_AG_INDICATORS];
|
||||
|
||||
static int hfp_generic_status_indicators_nr = 0;
|
||||
static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_HF_INDICATORS];
|
||||
|
||||
static int hfp_ag_call_hold_services_nr = 0;
|
||||
static char *hfp_ag_call_hold_services[6];
|
||||
static hfp_callback_t hfp_callback;
|
||||
@ -88,14 +91,16 @@ static void hfp_run_for_context(hfp_connection_t *hfp_connection);
|
||||
static void hfp_ag_setup_audio_connection(hfp_connection_t * hfp_connection);
|
||||
static void hfp_ag_hf_start_ringing(hfp_connection_t * hfp_connection);
|
||||
|
||||
hfp_generic_status_indicator_t * get_hfp_generic_status_indicators();
|
||||
int get_hfp_generic_status_indicators_nr();
|
||||
void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr);
|
||||
void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr);
|
||||
int get_hfp_ag_indicators_nr(hfp_connection_t * hfp_connection);
|
||||
hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * hfp_connection);
|
||||
|
||||
hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * hfp_connection){
|
||||
static int hfp_ag_get_ag_indicators_nr(hfp_connection_t * hfp_connection){
|
||||
if (hfp_connection->ag_indicators_nr != hfp_ag_indicators_nr){
|
||||
hfp_connection->ag_indicators_nr = hfp_ag_indicators_nr;
|
||||
memcpy(hfp_connection->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
|
||||
}
|
||||
return hfp_connection->ag_indicators_nr;
|
||||
}
|
||||
|
||||
hfp_ag_indicator_t * hfp_ag_get_ag_indicators(hfp_connection_t * hfp_connection){
|
||||
// TODO: save only value, and value changed in the hfp_connection?
|
||||
if (hfp_connection->ag_indicators_nr != hfp_ag_indicators_nr){
|
||||
hfp_connection->ag_indicators_nr = hfp_ag_indicators_nr;
|
||||
@ -124,19 +129,6 @@ static int get_ag_indicator_index_for_name(const char * name){
|
||||
return -1;
|
||||
}
|
||||
|
||||
void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr){
|
||||
memcpy(hfp_ag_indicators, indicators, indicator_nr * sizeof(hfp_ag_indicator_t));
|
||||
hfp_ag_indicators_nr = indicator_nr;
|
||||
}
|
||||
|
||||
int get_hfp_ag_indicators_nr(hfp_connection_t * hfp_connection){
|
||||
if (hfp_connection->ag_indicators_nr != hfp_ag_indicators_nr){
|
||||
hfp_connection->ag_indicators_nr = hfp_ag_indicators_nr;
|
||||
memcpy(hfp_connection->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
|
||||
}
|
||||
return hfp_connection->ag_indicators_nr;
|
||||
}
|
||||
|
||||
|
||||
void hfp_ag_register_packet_handler(hfp_callback_t callback){
|
||||
if (callback == NULL){
|
||||
@ -260,22 +252,22 @@ static int string_len_for_uint32(uint32_t i){
|
||||
// get size for indicator string
|
||||
static int hfp_ag_indicators_string_size(hfp_connection_t * hfp_connection, int i){
|
||||
// template: ("$NAME",($MIN,$MAX))
|
||||
return 8 + strlen(get_hfp_ag_indicators(hfp_connection)[i].name)
|
||||
+ string_len_for_uint32(get_hfp_ag_indicators(hfp_connection)[i].min_range)
|
||||
+ string_len_for_uint32(get_hfp_ag_indicators(hfp_connection)[i].min_range);
|
||||
return 8 + strlen(hfp_ag_get_ag_indicators(hfp_connection)[i].name)
|
||||
+ string_len_for_uint32(hfp_ag_get_ag_indicators(hfp_connection)[i].min_range)
|
||||
+ string_len_for_uint32(hfp_ag_get_ag_indicators(hfp_connection)[i].min_range);
|
||||
}
|
||||
|
||||
// store indicator
|
||||
static void hfp_ag_indicators_string_store(hfp_connection_t * hfp_connection, int i, uint8_t * buffer){
|
||||
sprintf((char *) buffer, "(\"%s\",(%d,%d)),",
|
||||
get_hfp_ag_indicators(hfp_connection)[i].name,
|
||||
get_hfp_ag_indicators(hfp_connection)[i].min_range,
|
||||
get_hfp_ag_indicators(hfp_connection)[i].max_range);
|
||||
hfp_ag_get_ag_indicators(hfp_connection)[i].name,
|
||||
hfp_ag_get_ag_indicators(hfp_connection)[i].min_range,
|
||||
hfp_ag_get_ag_indicators(hfp_connection)[i].max_range);
|
||||
}
|
||||
|
||||
// structure: header [indicator [comma indicator]] footer
|
||||
static int hfp_ag_indicators_cmd_generator_num_segments(hfp_connection_t * hfp_connection){
|
||||
int num_indicators = get_hfp_ag_indicators_nr(hfp_connection);
|
||||
int num_indicators = hfp_ag_get_ag_indicators_nr(hfp_connection);
|
||||
if (!num_indicators) return 2;
|
||||
return 3 + (num_indicators-1) * 2;
|
||||
}
|
||||
@ -286,7 +278,7 @@ static int hfp_ag_indicators_cmd_generator_get_segment_len(hfp_connection_t * hf
|
||||
return strlen(HFP_INDICATOR) + 3; // "\n\r%s:""
|
||||
}
|
||||
index--;
|
||||
int num_indicators = get_hfp_ag_indicators_nr(hfp_connection);
|
||||
int num_indicators = hfp_ag_get_ag_indicators_nr(hfp_connection);
|
||||
int indicator_index = index >> 1;
|
||||
if ((index & 1) == 0){
|
||||
return hfp_ag_indicators_string_size(hfp_connection, indicator_index);
|
||||
@ -308,7 +300,7 @@ static void hgp_ag_indicators_cmd_generator_store_segment(hfp_connection_t * hfp
|
||||
return;
|
||||
}
|
||||
index--;
|
||||
int num_indicators = get_hfp_ag_indicators_nr(hfp_connection);
|
||||
int num_indicators = hfp_ag_get_ag_indicators_nr(hfp_connection);
|
||||
int indicator_index = index >> 1;
|
||||
if ((index & 1) == 0){
|
||||
hfp_ag_indicators_string_store(hfp_connection, indicator_index, buffer);
|
||||
@ -325,21 +317,21 @@ static int hfp_hf_indicators_join(char * buffer, int buffer_size){
|
||||
if (buffer_size < hfp_ag_indicators_nr * 3) return 0;
|
||||
int i;
|
||||
int offset = 0;
|
||||
for (i = 0; i < get_hfp_generic_status_indicators_nr()-1; i++) {
|
||||
offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_hfp_generic_status_indicators()[i].uuid);
|
||||
for (i = 0; i < hfp_generic_status_indicators_nr-1; i++) {
|
||||
offset += snprintf(buffer+offset, buffer_size-offset, "%d,", hfp_generic_status_indicators[i].uuid);
|
||||
}
|
||||
if (i < get_hfp_generic_status_indicators_nr()){
|
||||
offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_hfp_generic_status_indicators()[i].uuid);
|
||||
if (i < hfp_generic_status_indicators_nr){
|
||||
offset += snprintf(buffer+offset, buffer_size-offset, "%d,", hfp_generic_status_indicators[i].uuid);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int hfp_hf_indicators_initial_status_join(char * buffer, int buffer_size){
|
||||
if (buffer_size < get_hfp_generic_status_indicators_nr() * 3) return 0;
|
||||
if (buffer_size < hfp_generic_status_indicators_nr * 3) return 0;
|
||||
int i;
|
||||
int offset = 0;
|
||||
for (i = 0; i < get_hfp_generic_status_indicators_nr(); i++) {
|
||||
offset += snprintf(buffer+offset, buffer_size-offset, "\r\n%s:%d,%d\r\n", HFP_GENERIC_STATUS_INDICATOR, get_hfp_generic_status_indicators()[i].uuid, get_hfp_generic_status_indicators()[i].state);
|
||||
for (i = 0; i < hfp_generic_status_indicators_nr; i++) {
|
||||
offset += snprintf(buffer+offset, buffer_size-offset, "\r\n%s:%d,%d\r\n", HFP_GENERIC_STATUS_INDICATOR, hfp_generic_status_indicators[i].uuid, hfp_generic_status_indicators[i].state);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
@ -1743,8 +1735,8 @@ static void hfp_run_for_context(hfp_connection_t *hfp_connection){
|
||||
}
|
||||
static hfp_generic_status_indicator_t *get_hf_indicator_by_number(int number){
|
||||
int i;
|
||||
for (i=0;i< get_hfp_generic_status_indicators_nr();i++){
|
||||
hfp_generic_status_indicator_t * indicator = &get_hfp_generic_status_indicators()[i];
|
||||
for (i=0;i< hfp_generic_status_indicators_nr;i++){
|
||||
hfp_generic_status_indicator_t * indicator = &hfp_generic_status_indicators[i];
|
||||
if (indicator->uuid == number){
|
||||
return indicator;
|
||||
}
|
||||
@ -1969,42 +1961,46 @@ static void packet_handler(void * hfp_connection, uint8_t packet_type, uint16_t
|
||||
hfp_run();
|
||||
}
|
||||
|
||||
static void hfp_ag_set_ag_indicators(hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr){
|
||||
hfp_ag_indicators_nr = ag_indicators_nr;
|
||||
memcpy(hfp_ag_indicators, ag_indicators, ag_indicators_nr * sizeof(hfp_ag_indicator_t));
|
||||
}
|
||||
|
||||
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_codecs(int codecs_nr, uint8_t * codecs){
|
||||
if (codecs_nr > HFP_MAX_NUM_CODECS){
|
||||
log_error("hfp_init: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS);
|
||||
return;
|
||||
}
|
||||
l2cap_init();
|
||||
l2cap_register_packet_handler(packet_handler);
|
||||
|
||||
rfcomm_register_packet_handler(packet_handler);
|
||||
|
||||
hfp_init(rfcomm_channel_nr);
|
||||
|
||||
hfp_supported_features = supported_features;
|
||||
hfp_codecs_nr = codecs_nr;
|
||||
|
||||
int i;
|
||||
for (i=0; i<codecs_nr; i++){
|
||||
hfp_codecs_nr = codecs_nr;
|
||||
for (i=0; i < codecs_nr; i++){
|
||||
hfp_codecs[i] = codecs[i];
|
||||
}
|
||||
}
|
||||
|
||||
hfp_ag_set_ag_indicators(ag_indicators, ag_indicators_nr);
|
||||
void hfp_ag_init_supported_features(uint32_t supported_features){
|
||||
hfp_supported_features = supported_features;
|
||||
}
|
||||
|
||||
set_hfp_generic_status_indicators(hf_indicators, hf_indicators_nr);
|
||||
void hfp_ag_init_ag_indicators(int ag_indicators_nr, hfp_ag_indicator_t * ag_indicators){
|
||||
hfp_ag_indicators_nr = ag_indicators_nr;
|
||||
memcpy(hfp_ag_indicators, ag_indicators, ag_indicators_nr * sizeof(hfp_ag_indicator_t));
|
||||
}
|
||||
|
||||
void hfp_ag_init_hf_indicators(int hf_indicators_nr, hfp_generic_status_indicator_t * hf_indicators){
|
||||
if (hf_indicators_nr > HFP_MAX_NUM_HF_INDICATORS) return;
|
||||
hfp_generic_status_indicators_nr = hf_indicators_nr;
|
||||
memcpy(hfp_generic_status_indicators, hf_indicators, hf_indicators_nr * sizeof(hfp_generic_status_indicator_t));
|
||||
}
|
||||
|
||||
void hfp_ag_init_call_hold_services(int call_hold_services_nr, const char * call_hold_services[]){
|
||||
hfp_ag_call_hold_services_nr = call_hold_services_nr;
|
||||
memcpy(hfp_ag_call_hold_services, call_hold_services, call_hold_services_nr * sizeof(char *));
|
||||
}
|
||||
|
||||
|
||||
void hfp_ag_init(uint16_t rfcomm_channel_nr){
|
||||
l2cap_init();
|
||||
l2cap_register_packet_handler(packet_handler);
|
||||
rfcomm_register_packet_handler(packet_handler);
|
||||
hfp_init(rfcomm_channel_nr);
|
||||
|
||||
hfp_ag_response_and_hold_active = 0;
|
||||
subscriber_numbers = NULL;
|
||||
subscriber_numbers_count = 0;
|
||||
@ -2171,37 +2167,22 @@ static void hfp_ag_set_ag_indicator(const char * name, int value){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
*/
|
||||
void hfp_ag_set_registration_status(int status){
|
||||
hfp_ag_set_ag_indicator("service", status);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
*/
|
||||
void hfp_ag_set_signal_strength(int strength){
|
||||
hfp_ag_set_ag_indicator("signal", strength);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
*/
|
||||
void hfp_ag_set_roaming_status(int status){
|
||||
hfp_ag_set_ag_indicator("roam", status);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
*/
|
||||
void hfp_ag_set_battery_level(int level){
|
||||
hfp_ag_set_ag_indicator("battchg", level);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
*/
|
||||
void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate){
|
||||
if (!get_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION)) return;
|
||||
hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||
@ -2220,9 +2201,6 @@ void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate){
|
||||
hfp_run_for_context(hfp_connection);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
*/
|
||||
void hfp_ag_set_microphone_gain(bd_addr_t bd_addr, int gain){
|
||||
hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||
if (hfp_connection->microphone_gain != gain){
|
||||
@ -2233,9 +2211,6 @@ void hfp_ag_set_microphone_gain(bd_addr_t bd_addr, int gain){
|
||||
hfp_run_for_context(hfp_connection);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
*/
|
||||
void hfp_ag_set_speaker_gain(bd_addr_t bd_addr, int gain){
|
||||
hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||
if (hfp_connection->speaker_gain != gain){
|
||||
@ -2245,9 +2220,6 @@ void hfp_ag_set_speaker_gain(bd_addr_t bd_addr, int gain){
|
||||
hfp_run_for_context(hfp_connection);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
*/
|
||||
void hfp_ag_send_phone_number_for_voice_tag(bd_addr_t bd_addr, const char * number){
|
||||
hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||
hfp_ag_set_clip(0, number);
|
||||
|
85
src/hfp_ag.h
85
src/hfp_ag.h
@ -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,22 +132,27 @@ 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
|
||||
*
|
||||
* @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 ??
|
||||
* @param bd_addr Bluetooth address of the HF
|
||||
*/
|
||||
void hfp_ag_release_service_level_connection(bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param bd_addr Bluetooth address of the HF
|
||||
*/
|
||||
void hfp_ag_establish_audio_connection(bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param bd_addr Bluetooth address of the HF
|
||||
*/
|
||||
void hfp_ag_release_audio_connection(bd_addr_t bd_addr);
|
||||
|
||||
@ -144,17 +187,22 @@ void hfp_ag_accept_held_incoming_call(void);
|
||||
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
|
||||
* @param level
|
||||
*/
|
||||
void hfp_ag_set_battery_level(int level);
|
||||
|
||||
@ -168,16 +216,21 @@ void hfp_ag_clear_last_dialed_number(void);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* @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 +244,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 +273,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 +332,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);
|
||||
|
||||
|
@ -66,14 +66,12 @@ void hfp_hf_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const ch
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
|
@ -417,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){
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -664,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);
|
||||
|
||||
|
@ -496,7 +496,7 @@ static void packet_handler(uint8_t * event, uint16_t event_size){
|
||||
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[3], event[4]], (char *) &event[5]);
|
||||
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])
|
||||
|
Loading…
x
Reference in New Issue
Block a user