diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-10-24 14:28:51 +0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-10-24 14:28:51 +0300 |
commit | 07f54e8cfaebb2a880f842206246b5af375f2ca4 (patch) | |
tree | 93f39df1de529c8b8d357fc1da4c984d4a685212 /audio/headset.c | |
parent | 4ac9e2f98a4660163b8da3a5f7041b8c703fa60d (diff) |
Ensure that SCO is up before sending RINGs for inband ringtone
Diffstat (limited to 'audio/headset.c')
-rw-r--r-- | audio/headset.c | 134 |
1 files changed, 84 insertions, 50 deletions
diff --git a/audio/headset.c b/audio/headset.c index 073d694a..dffbc924 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -144,6 +144,7 @@ struct headset { gboolean cli_active; gboolean cme_enabled; gboolean cwa_enabled; + gboolean pending_ring; headset_state_t state; struct pending_connect *pending; @@ -457,6 +458,55 @@ static unsigned int connect_cb_new(struct headset *hs, return cb->id; } +static void send_foreach_headset(GSList *devices, + int (*cmp)(struct headset *hs), + char *format, ...) +{ + GSList *l; + va_list ap; + + for (l = devices; l != NULL; l = l->next) { + struct audio_device *device = l->data; + struct headset *hs = device->headset; + int ret; + + assert(hs != NULL); + + if (cmp && cmp(hs) != 0) + continue; + + va_start(ap, format); + ret = headset_send_valist(hs, format, ap); + if (ret < 0) + error("Failed to send to headset: %s (%d)", + strerror(-ret), -ret); + va_end(ap); + } +} + +static int cli_cmp(struct headset *hs) +{ + if (!hs->hfp_active) + return -1; + + if (hs->cli_active) + return 0; + else + return -1; +} + +static gboolean ring_timer_cb(gpointer data) +{ + send_foreach_headset(active_devices, NULL, "\r\nRING\r\n"); + + if (ag.number) + send_foreach_headset(active_devices, cli_cmp, + "\r\n+CLIP:\"%s\",%d\r\n", + ag.number, ag.number_type); + + return TRUE; +} + static void sco_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, const bdaddr_t *dst, gpointer user_data) { @@ -499,6 +549,13 @@ static void sco_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, fcntl(sk, F_SETFL, 0); headset_set_state(dev, HEADSET_STATE_PLAYING); + + if (hs->pending_ring) { + ring_timer_cb(NULL); + ag.ring_timer = g_timeout_add(RING_INTERVAL, ring_timer_cb, + NULL); + hs->pending_ring = FALSE; + } } static int sco_connect(struct audio_device *dev, headset_stream_cb_t cb, @@ -538,33 +595,6 @@ static int hfp_cmp(struct headset *hs) return -1; } -static void send_foreach_headset(GSList *devices, - int (*cmp)(struct headset *hs), - char *format, ...) -{ - GSList *l; - va_list ap; - - for (l = devices; l != NULL; l = l->next) { - struct audio_device *device = l->data; - struct headset *hs = device->headset; - int ret; - - assert(hs != NULL); - - if (cmp && cmp(hs) != 0) - continue; - - va_start(ap, format); - ret = headset_send_valist(hs, format, ap); - if (ret < 0) - error("Failed to send to headset: %s (%d)", - strerror(-ret), -ret); - va_end(ap); - } -} - - static void hfp_slc_complete(struct audio_device *dev) { struct headset *hs = dev->headset; @@ -1478,29 +1508,6 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg, return NULL; } -static int cli_cmp(struct headset *hs) -{ - if (!hs->hfp_active) - return -1; - - if (hs->cli_active) - return 0; - else - return -1; -} - -static gboolean ring_timer_cb(gpointer data) -{ - send_foreach_headset(active_devices, NULL, "\r\nRING\r\n"); - - if (ag.number) - send_foreach_headset(active_devices, cli_cmp, - "\r\n+CLIP:\"%s\",%d\r\n", - ag.number, ag.number_type); - - return TRUE; -} - static DBusMessage *hs_ring(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -2167,6 +2174,13 @@ int headset_connect_sco(struct audio_device *dev, GIOChannel *io) hs->sco = io; + if (hs->pending_ring) { + ring_timer_cb(NULL); + ag.ring_timer = g_timeout_add(RING_INTERVAL, ring_timer_cb, + NULL); + hs->pending_ring = FALSE; + } + return 0; } @@ -2411,9 +2425,16 @@ int telephony_response_and_hold_ind(int rh) int telephony_incoming_call_ind(const char *number, int type) { + struct audio_device *dev; + struct headset *hs; + if (!active_devices) return -ENODEV; + /* Get the latest connected device */ + dev = active_devices->data; + hs = dev->headset; + if (ag.ring_timer) { debug("telephony_incoming_call_ind: already calling"); return -EBUSY; @@ -2423,6 +2444,19 @@ int telephony_incoming_call_ind(const char *number, int type) ag.number = g_strdup(number); ag.number_type = type; + if (ag.features & AG_FEATURE_INBAND_RINGTONE && hs->hfp_active && + hs->state != HEADSET_STATE_PLAYING) { + if (hs->state == HEADSET_STATE_CONNECTED) { + int ret; + + ret = sco_connect(dev, NULL, NULL, NULL); + if (ret < 0) + return ret; + } + + hs->pending_ring = TRUE; + } + ring_timer_cb(NULL); ag.ring_timer = g_timeout_add(RING_INTERVAL, ring_timer_cb, NULL); |