diff options
| -rw-r--r-- | audio/headset.c | 74 | ||||
| -rw-r--r-- | audio/telephony-dummy.c | 12 | ||||
| -rw-r--r-- | audio/telephony.h | 27 | 
3 files changed, 111 insertions, 2 deletions
| diff --git a/audio/headset.c b/audio/headset.c index 1ce4d99b..0785df91 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -62,6 +62,9 @@  #define RING_INTERVAL 3000 +/* Number of indicator events that can be queued */ +#define EV_BUF_SIZE 4 +  #define BUF_SIZE 1024  #define HEADSET_GAIN_SPEAKER 'S' @@ -74,12 +77,19 @@ static struct {  	int er_mode;			/* Event reporting mode */  	int er_ind;			/* Event reporting for indicators */  	int rh;				/* Response and Hold state */ +	gboolean ev_buf_active;		/* Buffer indicator events */ +	struct { +		int index;		/* HFP indicator index */ +		int val;		/* new indicator value */ +	} ev_buf[EV_BUF_SIZE];		/* Indicator event buffer */  } ag = {  	.telephony_ready = FALSE,  	.features = 0,  	.er_mode = 3,  	.er_ind = 0,  	.rh = -1, +	.ev_buf_active = FALSE, +	.ev_buf = { { 0, 0 } },  };  static gboolean sco_hci = TRUE; @@ -204,6 +214,49 @@ static int headset_send(struct headset *hs, char *format, ...)  	return 0;  } +static int buffer_event(int index) +{ +	int i; + +	for (i = 0; i < EV_BUF_SIZE; i++) { +		if (ag.ev_buf[i].index == 0) { +			ag.ev_buf[i].index = index + 1; +			ag.ev_buf[i].val = ag.indicators[index].val; +			return 0; +		} +	} + +	error("No space in event buffer"); +	return -ENOSPC; +} + +static int flush_events(void) +{ +	int i; +	struct headset *hs; + +	if (!active_telephony_device) +		return -ENODEV; + +	hs = active_telephony_device->headset; + +	for (i = 0; i < EV_BUF_SIZE; i++) { +		int ret; + +		if (ag.ev_buf[i].index == 0) +			break; + +		ret = headset_send(hs, "\r\n+CIEV:%d,%d\r\n", +					ag.ev_buf[i].index, ag.ev_buf[i].val); +		if (ret < 0) +			return ret; + +		ag.ev_buf[i].index = 0; +	} + +	return 0; +} +  static int supported_features(struct audio_device *device, const char *buf)  {  	struct headset *hs = device->headset; @@ -622,6 +675,23 @@ static int response_and_hold(struct audio_device *device, const char *buf)  	return headset_send(hs, "\r\nOK\n\r", ag.rh);  } +static int last_dialed_number(struct audio_device *device, const char *buf) +{ +	struct headset *hs = device->headset; + +	ag.ev_buf_active = TRUE; + +	if (telephony_last_dialed_number() < 0) { +		headset_send(hs, "\r\nERROR\r\n"); +		return 0; +	} + +	flush_events(); +	ag.ev_buf_active = FALSE; + +	return headset_send(hs, "\r\nOK\n\r", ag.rh); +} +  static int signal_gain_setting(struct audio_device *device, const char *buf)  {  	struct headset *hs = device->headset; @@ -678,6 +748,7 @@ static struct event event_callbacks[] = {  	{ "AT+CKPD", answer_call },  	{ "AT+CLIP", cli_notification },  	{ "AT+BTRH", response_and_hold }, +	{ "AT+BLDN", last_dialed_number },  	{ 0 }  }; @@ -2013,6 +2084,9 @@ int telephony_event_ind(int index)  		return -EINVAL;  	} +	if (ag.ev_buf_active) +		return buffer_event(index); +  	return headset_send(hs, "\r\n+CIEV:%d,%d\r\n", index + 1,  				ag.indicators[index].val);  } diff --git a/audio/telephony-dummy.c b/audio/telephony-dummy.c index 6c003066..46637b95 100644 --- a/audio/telephony-dummy.c +++ b/audio/telephony-dummy.c @@ -43,7 +43,7 @@ static gboolean events_enabled = FALSE;   */  static int response_and_hold = -1; -static struct indicator indicators[] = +static struct indicator dummy_indicators[] =  {  	{ "battchg",	"0-5",	5 },  	{ "signal",	"0-5",	5 }, @@ -71,11 +71,19 @@ int telephony_response_and_hold_req(int rh)  	return 0;  } +int telephony_last_dialed_number(void) +{ +	/* Notify outgoing call set-up successfully initiated */ +	telephony_update_indicator(dummy_indicators, "callsetup", 2); + +	return 0; +} +  int telephony_init(void)  {  	uint32_t features = 0; -	telephony_ready(features, indicators, response_and_hold); +	telephony_ready(features, dummy_indicators, response_and_hold);  	return 0;  } diff --git a/audio/telephony.h b/audio/telephony.h index 4cc74ede..398f98df 100644 --- a/audio/telephony.h +++ b/audio/telephony.h @@ -23,6 +23,8 @@   */  #include <stdint.h> +#include <errno.h> +#include <glib.h>  #define AG_FEATURE_THREE_WAY_CALLING             0x0001  #define AG_FEATURE_EC_ANDOR_NR                   0x0002 @@ -48,7 +50,32 @@ int telephony_response_and_hold_req(int rh);  int telephony_response_and_hold_ind(int rh); +int telephony_last_dialed_number(void); +  int telephony_ready(uint32_t features, struct indicator *indicators, int rh); +/* Helper function for quick indicator updates */ +static inline int telephony_update_indicator(struct indicator *indicators, +						const char *desc, +						int new_val) +{ +	int i; +	struct indicator *ind = NULL; + +	for (i = 0; indicators[i].desc != NULL; i++) { +		if (g_str_equal(indicators[i].desc, desc)) { +			ind = &indicators[i]; +			break; +		} +	} + +	if (!ind) +		return -ENOENT; + +	ind->val = new_val; + +	return telephony_event_ind(i); +} +  int telephony_init(void);  void telephony_exit(void); | 
