diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-09-05 11:38:07 +0300 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-09-05 11:38:07 +0300 | 
| commit | 1b971b060ba37714d970089e978fa720a2c9326c (patch) | |
| tree | 14b87bf835c41d3c6664d06259064c5c65769dc1 /audio/headset.c | |
| parent | a3634219a1f00b7386c55f34d6707690ff73b605 (diff) | |
Implement last number dialed (AT+BLDN) support
Diffstat (limited to 'audio/headset.c')
| -rw-r--r-- | audio/headset.c | 74 | 
1 files changed, 74 insertions, 0 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);  } | 
