summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-10-02 18:06:40 +0300
committerJohan Hedberg <johan.hedberg@nokia.com>2008-10-02 18:06:40 +0300
commit8107d29e2077d6604b0a9aad5eed13a70271efb3 (patch)
treefcd009902cc4e8e95bdcb597892be8ab833ed203
parentfab609a303259e1a62e31df7c00f8b5ed3337187 (diff)
Implement call waiting notification support
-rw-r--r--audio/headset.c68
-rw-r--r--audio/telephony.h1
2 files changed, 62 insertions, 7 deletions
diff --git a/audio/headset.c b/audio/headset.c
index 5f78cbc7..0dc4cc65 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -138,6 +138,7 @@ struct headset {
gboolean search_hfp;
gboolean cli_active;
gboolean cme_enabled;
+ gboolean cwa_enabled;
headset_state_t state;
struct pending_connect *pending;
@@ -883,6 +884,23 @@ static int extended_errors(struct audio_device *device, const char *buf)
return 0;
}
+static int call_waiting_notify(struct audio_device *device, const char *buf)
+{
+ struct headset *hs = device->headset;
+
+ if (strlen(buf) < 9)
+ return -EINVAL;
+
+ if (buf[8] == '1') {
+ hs->cwa_enabled = TRUE;
+ debug("Call waiting notifiaction enabled for headset %p", hs);
+ } else {
+ hs->cwa_enabled = FALSE;
+ debug("Call waiting notification disabled for headset %p", hs);
+ }
+
+ return 0;
+}
static struct event event_callbacks[] = {
{ "ATA", answer_call },
@@ -901,6 +919,7 @@ static struct event event_callbacks[] = {
{ "AT+CNUM", subscriber_number },
{ "AT+CLCC", list_current_calls },
{ "AT+CMEE", extended_errors },
+ { "AT+CCWA", call_waiting_notify },
{ 0 }
};
@@ -2111,7 +2130,17 @@ int headset_get_sco_fd(struct audio_device *dev)
return g_io_channel_unix_get_fd(hs->sco);
}
-static void send_foreach_headset(GSList *devices, char *format, ...)
+static int hfp_cmp(struct headset *hs)
+{
+ if (hs->hfp_active)
+ return 0;
+ else
+ return -1;
+}
+
+static void send_foreach_headset(GSList *devices,
+ int (*cmp)(struct headset *hs),
+ char *format, ...)
{
GSList *l;
va_list ap;
@@ -2121,7 +2150,7 @@ static void send_foreach_headset(GSList *devices, char *format, ...)
struct headset *hs = device->headset;
int ret;
- if (!hs->hfp_active)
+ if (cmp && cmp(hs) != 0)
continue;
va_start(ap, format);
@@ -2143,7 +2172,8 @@ int telephony_event_ind(int index)
return -EINVAL;
}
- send_foreach_headset(active_devices, "\r\n+CIEV:%d,%d\r\n", index + 1,
+ send_foreach_headset(active_devices, hfp_cmp,
+ "\r\n+CIEV:%d,%d\r\n", index + 1,
ag.indicators[index].val);
return 0;
@@ -2160,7 +2190,8 @@ int telephony_response_and_hold_ind(int rh)
if (ag.rh < 0)
return 0;
- send_foreach_headset(active_devices, "\r\n+BTRH:%d\r\n", ag.rh);
+ send_foreach_headset(active_devices, hfp_cmp, "\r\n+BTRH:%d\r\n",
+ ag.rh);
return 0;
}
@@ -2222,12 +2253,12 @@ int telephony_list_current_call_ind(int idx, int dir, int status, int mode,
return -ENODEV;
if (number)
- send_foreach_headset(active_devices,
+ send_foreach_headset(active_devices, hfp_cmp,
"\r\n+CLCC:%d,%d,%d,%d,%d,%s,%d\r\n",
idx, dir, status, mode, mprty,
number, type);
else
- send_foreach_headset(active_devices,
+ send_foreach_headset(active_devices, hfp_cmp,
"\r\n+CLCC:%d,%d,%d,%d,%d\r\n",
idx, dir, status, mode, mprty);
@@ -2239,8 +2270,31 @@ int telephony_subscriber_number_ind(const char *number, int type, int service)
if (!active_devices)
return -ENODEV;
- send_foreach_headset(active_devices, "\r\n+CNUM:,%s,%d,,%d\r\n",
+ send_foreach_headset(active_devices, hfp_cmp,
+ "\r\n+CNUM:,%s,%d,,%d\r\n",
number, type, service);
return 0;
}
+
+static int cwa_cmp(struct headset *hs)
+{
+ if (!hs->hfp_active)
+ return -1;
+
+ if (hs->cwa_enabled)
+ return 0;
+ else
+ return -1;
+}
+
+int telephony_call_waiting_ind(const char *number, int type)
+{
+ if (!active_devices)
+ return -ENODEV;
+
+ send_foreach_headset(active_devices, cwa_cmp, "\r\n+CCWA:%s,%d\r\n",
+ number, type);
+
+ return 0;
+}
diff --git a/audio/telephony.h b/audio/telephony.h
index 81ed64de..55d327b7 100644
--- a/audio/telephony.h
+++ b/audio/telephony.h
@@ -161,6 +161,7 @@ int telephony_list_current_call_ind(int idx, int dir, int status, int mode,
int type);
int telephony_subscriber_number_ind(const char *number, int type,
int service);
+int telephony_call_waiting_ind(const char *number, int type);
/* Helper function for quick indicator updates */
static inline int telephony_update_indicator(struct indicator *indicators,