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); } |