diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-09-04 14:15:20 +0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-09-04 14:15:20 +0300 |
commit | 842ed094ea0d3d591685ea3ac3423b3a57009246 (patch) | |
tree | 907bf1daef4fae6632a22ceb5e31e563505904ac /audio | |
parent | 3bb7bf627c5d0f8adb44fe8f0d9c88cc3fc8a070 (diff) |
Implement basic HFP response and hold support
Diffstat (limited to 'audio')
-rw-r--r-- | audio/headset.c | 50 | ||||
-rw-r--r-- | audio/telephony-dummy.c | 24 | ||||
-rw-r--r-- | audio/telephony.h | 8 |
3 files changed, 76 insertions, 6 deletions
diff --git a/audio/headset.c b/audio/headset.c index 34180143..8b330d5b 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -124,6 +124,7 @@ struct headset { int type; int er_mode; int er_ind; + int rh; /* Response and Hold */ headset_state_t state; struct pending_connect *pending; @@ -258,6 +259,9 @@ static int report_indicators(struct audio_device *device, const char *buf) char *str; struct indicator *indicators; + if (strlen(buf) < 8) + return -EINVAL; + indicators = telephony_indicators_req(); if (!indicators) return headset_send(hs, "\r\nERROR\r\n"); @@ -477,7 +481,7 @@ static int event_reporting(struct audio_device *dev, const char *buf) switch (hs->er_ind) { case 0: case 1: - telephony_set_event_reporting(hs->er_ind); + telephony_event_reporting_req(hs->er_ind); break; default: return -EINVAL; @@ -595,6 +599,24 @@ static int cli_notification(struct audio_device *device, const char *buf) return headset_send(hs, "\r\nOK\r\n"); } +static int response_and_hold(struct audio_device *device, const char *buf) +{ + struct headset *hs = device->headset; + + if (strlen(buf) < 8) + return -EINVAL; + + if (buf[7] == '=') { + if (telephony_response_and_hold_req(atoi(&buf[8]) < 0)) { + headset_send(hs, "\r\nERROR\r\n"); + return 0; + } + } else + headset_send(hs, "\r\n+BTRH:%d\r\n", hs->rh); + + return headset_send(hs, "\r\nOK\n\r", hs->rh); +} + static int signal_gain_setting(struct audio_device *device, const char *buf) { struct headset *hs = device->headset; @@ -650,6 +672,7 @@ static struct event event_callbacks[] = { { "AT+CHUP", terminate_call }, { "AT+CKPD", answer_call }, { "AT+CLIP", cli_notification }, + { "AT+BTRH", response_and_hold }, { 0 } }; @@ -1827,7 +1850,7 @@ void headset_set_state(struct audio_device *dev, headset_state_t state) AUDIO_HEADSET_INTERFACE, "Disconnected", DBUS_TYPE_INVALID); - telephony_set_event_reporting(0); + telephony_event_reporting_req(0); if (dev == active_telephony_device) active_telephony_device = NULL; break; @@ -1960,7 +1983,7 @@ void telephony_features_rsp(uint32_t features) ag_features = features; } -int telephony_report_event(int index, int value) +int telephony_event_ind(int index, int value) { struct headset *hs; @@ -1979,3 +2002,24 @@ int telephony_report_event(int index, int value) return headset_send(hs, "\r\n+CIEV:%d,%d\r\n", index, value); } + +int telephony_response_and_hold_ind(int rh) +{ + struct headset *hs; + + if (!active_telephony_device) + return -ENODEV; + + hs = active_telephony_device->headset; + + if (!hs->hfp_active) + return -EINVAL; + + hs->rh = rh; + + /* If we aren't in any response and hold state don't send anything */ + if (hs->rh < 0) + return 0; + + return headset_send(hs, "\r\n+BTRH:%d\r\n", hs->rh); +} diff --git a/audio/telephony-dummy.c b/audio/telephony-dummy.c index 59eacc89..73d367c1 100644 --- a/audio/telephony-dummy.c +++ b/audio/telephony-dummy.c @@ -35,6 +35,14 @@ static gboolean events_enabled = FALSE; +/* Response and hold state + * -1 = none + * 0 = incoming call is put on hold in the AG + * 1 = held incoming call is accepted in the AG + * 2 = held incoming call is rejected in the AG + */ +static int response_and_hold = -1; + static struct indicator indicators[] = { { "battchg", "0-5", 5 }, @@ -61,9 +69,23 @@ struct indicator *telephony_indicators_req(void) return indicators; } -int telephony_set_event_reporting(int ind) +int telephony_event_reporting_req(int ind) { events_enabled = ind == 1 ? TRUE : FALSE; + + if (events_enabled) + telephony_response_and_hold_ind(response_and_hold); + + return 0; +} + +int telephony_response_and_hold_req(int rh) +{ + response_and_hold = rh; + + telephony_response_and_hold_ind(response_and_hold); + + return 0; } int telephony_init(void) diff --git a/audio/telephony.h b/audio/telephony.h index 5538898a..21d5af4d 100644 --- a/audio/telephony.h +++ b/audio/telephony.h @@ -45,9 +45,13 @@ void telephony_features_rsp(uint32_t features); struct indicator *telephony_indicators_req(void); -int telephony_set_event_reporting(int ind); +int telephony_event_reporting_req(int ind); -int telephony_report_event(int index, int value); +int telephony_event_ind(int index, int value); + +int telephony_response_and_hold_req(int rh); + +int telephony_response_and_hold_ind(int rh); int telephony_init(void); void telephony_exit(void); |