summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz-von@nokia.com>2011-01-18 12:00:15 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2011-01-19 20:50:29 +0530
commit170b5be8f8a76f909dfe3e9e370dc35d9afe6d0a (patch)
tree632fa307871948c4304d2563b0f40438c73567b0
parent3c1b20edada25c1007170c3311d9096a67c3934f (diff)
downloadbluez-170b5be8f8a76f909dfe3e9e370dc35d9afe6d0a.tar.gz
Add proper tracking mechanism to NREC
NREC may change during the connections so it has to be tracked in order to signal changes to applications.
-rw-r--r--audio/headset.c62
-rw-r--r--audio/headset.h6
-rw-r--r--audio/transport.c17
3 files changed, 84 insertions, 1 deletions
diff --git a/audio/headset.c b/audio/headset.c
index 120ab23c0..01c155168 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -109,6 +109,12 @@ struct headset_state_callback {
unsigned int id;
};
+struct headset_nrec_callback {
+ unsigned int id;
+ headset_nrec_cb cb;
+ void *user_data;
+};
+
struct connect_cb {
unsigned int id;
headset_stream_cb_t cb;
@@ -137,6 +143,7 @@ struct headset_slc {
gboolean inband_ring;
gboolean nrec;
gboolean nrec_req;
+ GSList *nrec_cbs;
int sp_gain;
int mic_gain;
@@ -1096,8 +1103,17 @@ int telephony_nr_and_ec_rsp(void *telephony_device, cme_error_t err)
struct headset *hs = device->headset;
struct headset_slc *slc = hs->slc;
- if (err == CME_ERROR_NONE)
+ if (err == CME_ERROR_NONE) {
+ GSList *l;
+
+ for (l = slc->nrec_cbs; l; l = l->next) {
+ struct headset_nrec_callback *nrec_cb = l->data;
+
+ nrec_cb->cb(device, slc->nrec_req, nrec_cb->user_data);
+ }
+
slc->nrec = hs->slc->nrec_req;
+ }
return telephony_generic_rsp(telephony_device, err);
}
@@ -2105,6 +2121,9 @@ static int headset_close_rfcomm(struct audio_device *dev)
hs->rfcomm = NULL;
}
+ g_slist_foreach(hs->slc->nrec_cbs, (GFunc) g_free, NULL);
+ g_slist_free(hs->slc->nrec_cbs);
+
g_free(hs->slc);
hs->slc = NULL;
@@ -2641,6 +2660,47 @@ gboolean headset_get_nrec(struct audio_device *dev)
return hs->slc->nrec;
}
+unsigned int headset_add_nrec_cb(struct audio_device *dev,
+ headset_nrec_cb cb, void *user_data)
+{
+ struct headset *hs = dev->headset;
+ struct headset_nrec_callback *nrec_cb;
+ static unsigned int id = 0;
+
+ if (!hs->slc)
+ return 0;
+
+ nrec_cb = g_new(struct headset_nrec_callback, 1);
+ nrec_cb->cb = cb;
+ nrec_cb->user_data = user_data;
+ nrec_cb->id = ++id;
+
+ hs->slc->nrec_cbs = g_slist_prepend(hs->slc->nrec_cbs, nrec_cb);
+
+ return nrec_cb->id;
+}
+
+gboolean headset_remove_nrec_cb(struct audio_device *dev, unsigned int id)
+{
+ struct headset *hs = dev->headset;
+ GSList *l;
+
+ if (!hs->slc)
+ return FALSE;
+
+ for (l = hs->slc->nrec_cbs; l != NULL; l = l->next) {
+ struct headset_nrec_callback *cb = l->data;
+ if (cb && cb->id == id) {
+ hs->slc->nrec_cbs = g_slist_remove(hs->slc->nrec_cbs,
+ cb);
+ g_free(cb);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
gboolean headset_get_inband(struct audio_device *dev)
{
struct headset *hs = dev->headset;
diff --git a/audio/headset.h b/audio/headset.h
index 29dc02c2d..7ce88c8a5 100644
--- a/audio/headset.h
+++ b/audio/headset.h
@@ -44,6 +44,9 @@ typedef void (*headset_state_cb) (struct audio_device *dev,
headset_state_t old_state,
headset_state_t new_state,
void *user_data);
+typedef void (*headset_nrec_cb) (struct audio_device *dev,
+ gboolean nrec,
+ void *user_data);
unsigned int headset_add_state_cb(headset_state_cb cb, void *user_data);
gboolean headset_remove_state_cb(unsigned int id);
@@ -90,6 +93,9 @@ int headset_get_channel(struct audio_device *dev);
int headset_get_sco_fd(struct audio_device *dev);
gboolean headset_get_nrec(struct audio_device *dev);
+unsigned int headset_add_nrec_cb(struct audio_device *dev,
+ headset_nrec_cb cb, void *user_data);
+gboolean headset_remove_nrec_cb(struct audio_device *dev, unsigned int id);
gboolean headset_get_inband(struct audio_device *dev);
gboolean headset_get_sco_hci(struct audio_device *dev);
diff --git a/audio/transport.c b/audio/transport.c
index b5a9e4847..e2c8237fd 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -76,6 +76,7 @@ struct media_transport {
uint16_t imtu; /* Transport input mtu */
uint16_t omtu; /* Transport output mtu */
uint16_t delay; /* Transport delay (a2dp only) */
+ unsigned int nrec_id; /* Transport nrec watch (headset only) */
gboolean read_lock;
gboolean write_lock;
gboolean in_use;
@@ -685,6 +686,9 @@ static void media_transport_free(void *data)
if (transport->session)
avdtp_unref(transport->session);
+ if (transport->nrec_id)
+ headset_remove_nrec_cb(transport->device, transport->nrec_id);
+
if (transport->conn)
dbus_connection_unref(transport->conn);
@@ -693,6 +697,16 @@ static void media_transport_free(void *data)
g_free(transport);
}
+static void headset_nrec_changed(struct audio_device *dev, gboolean nrec,
+ void *user_data)
+{
+ struct media_transport *transport = user_data;
+
+ emit_property_changed(transport->conn, transport->path,
+ MEDIA_TRANSPORT_INTERFACE, "NREC",
+ DBUS_TYPE_BOOLEAN, &nrec);
+}
+
struct media_transport *media_transport_create(DBusConnection *conn,
struct media_endpoint *endpoint,
struct audio_device *device,
@@ -728,6 +742,9 @@ struct media_transport *media_transport_create(DBusConnection *conn,
transport->cancel = cancel_headset;
transport->get_properties = get_properties_headset;
transport->set_property = set_property_headset;
+ transport->nrec_id = headset_add_nrec_cb(device,
+ headset_nrec_changed,
+ transport);
} else
goto fail;