summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-09-04 14:15:20 +0300
committerJohan Hedberg <johan.hedberg@nokia.com>2008-09-04 14:15:20 +0300
commit842ed094ea0d3d591685ea3ac3423b3a57009246 (patch)
tree907bf1daef4fae6632a22ceb5e31e563505904ac /audio
parent3bb7bf627c5d0f8adb44fe8f0d9c88cc3fc8a070 (diff)
Implement basic HFP response and hold support
Diffstat (limited to 'audio')
-rw-r--r--audio/headset.c50
-rw-r--r--audio/telephony-dummy.c24
-rw-r--r--audio/telephony.h8
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);