diff options
author | João Paulo Rechi Vita <jprvita@openbossa.org> | 2014-09-10 11:48:26 +0200 |
---|---|---|
committer | Tanu Kaskinen <tanu.kaskinen@linux.intel.com> | 2014-09-11 14:00:15 +0300 |
commit | 374c28a40eea2a608d7bc066803588b5d843df08 (patch) | |
tree | 7048663abe85708c7473a1033534926ed177a740 | |
parent | d7a8ccce891454250a45e8ac7094cd4382aac3fa (diff) |
bluetooth: Register/Unregister Handsfree Audio Agent with oFono
Register as a HandsfreeAudioAgent with oFono during backend
initialization and unregiter during backend finalization. This commit
also adds a check when receiving method calls or signals to make sure
the sender matches with the D-Bus service we're registered with.
-rw-r--r-- | src/modules/bluetooth/backend-ofono.c | 106 |
1 files changed, 104 insertions, 2 deletions
diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index 1a4416e58..fb66fc7fa 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -28,6 +28,9 @@ #include "bluez5-util.h" +#define HFP_AUDIO_CODEC_CVSD 0x01 +#define HFP_AUDIO_CODEC_MSBC 0x02 + #define OFONO_SERVICE "org.ofono" #define HF_AUDIO_AGENT_INTERFACE OFONO_SERVICE ".HandsfreeAudioAgent" #define HF_AUDIO_MANAGER_INTERFACE OFONO_SERVICE ".HandsfreeAudioManager" @@ -58,6 +61,7 @@ struct pa_bluetooth_backend { pa_bluetooth_discovery *discovery; pa_dbus_connection *connection; pa_hashmap *cards; + char *ofono_bus_id; PA_LLIST_HEAD(pa_dbus_pending, pending); }; @@ -79,20 +83,114 @@ static pa_dbus_pending* hf_dbus_send_and_add_to_pending(pa_bluetooth_backend *ba return p; } +static void hf_audio_agent_register_reply(DBusPendingCall *pending, void *userdata) { + DBusMessage *r; + pa_dbus_pending *p; + pa_bluetooth_backend *backend; + + pa_assert_se(p = userdata); + pa_assert_se(backend = p->context_data); + pa_assert_se(r = dbus_pending_call_steal_reply(pending)); + + if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { + pa_log_error("Failed to register as a handsfree audio agent with ofono: %s: %s", + dbus_message_get_error_name(r), pa_dbus_get_error_message(r)); + goto finish; + } + + backend->ofono_bus_id = pa_xstrdup(dbus_message_get_sender(r)); + + /* TODO: List all HandsfreeAudioCard objects */ + +finish: + dbus_message_unref(r); + + PA_LLIST_REMOVE(pa_dbus_pending, backend->pending, p); + pa_dbus_pending_free(p); +} + +static void hf_audio_agent_register(pa_bluetooth_backend *hf) { + DBusMessage *m; + uint8_t codecs[2]; + const uint8_t *pcodecs = codecs; + int ncodecs = 0; + const char *path = HF_AUDIO_AGENT_PATH; + + pa_assert(hf); + + pa_assert_se(m = dbus_message_new_method_call(OFONO_SERVICE, "/", HF_AUDIO_MANAGER_INTERFACE, "Register")); + + codecs[ncodecs++] = HFP_AUDIO_CODEC_CVSD; + + pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pcodecs, ncodecs, + DBUS_TYPE_INVALID)); + + hf_dbus_send_and_add_to_pending(hf, m, hf_audio_agent_register_reply, NULL); +} + +static void hf_audio_agent_unregister(pa_bluetooth_backend *backend) { + DBusMessage *m; + const char *path = HF_AUDIO_AGENT_PATH; + + pa_assert(backend); + pa_assert(backend->connection); + + if (backend->ofono_bus_id) { + pa_assert_se(m = dbus_message_new_method_call(backend->ofono_bus_id, "/", HF_AUDIO_MANAGER_INTERFACE, "Unregister")); + pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)); + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(backend->connection), m, NULL)); + + pa_xfree(backend->ofono_bus_id); + backend->ofono_bus_id = NULL; + } +} + static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *data) { + const char *sender; + pa_bluetooth_backend *backend = data; + pa_assert(bus); pa_assert(m); + pa_assert(backend); + + sender = dbus_message_get_sender(m); + if (!pa_safe_streq(backend->ofono_bus_id, sender) && !pa_streq("org.freedesktop.DBus", sender)) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static DBusMessage *hf_audio_agent_release(DBusConnection *c, DBusMessage *m, void *data) { - DBusMessage *r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); + DBusMessage *r; + const char *sender; + pa_bluetooth_backend *backend = data; + + pa_assert(backend); + + sender = dbus_message_get_sender(m); + if (!pa_safe_streq(backend->ofono_bus_id, sender)) { + pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.NotAllowed", "Operation is not allowed by this sender")); + return r; + } + + r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); return r; } static DBusMessage *hf_audio_agent_new_connection(DBusConnection *c, DBusMessage *m, void *data) { - DBusMessage *r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); + DBusMessage *r; + const char *sender; + pa_bluetooth_backend *backend = data; + + pa_assert(backend); + + sender = dbus_message_get_sender(m); + if (!pa_safe_streq(backend->ofono_bus_id, sender)) { + pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.NotAllowed", "Operation is not allowed by this sender")); + return r; + } + + r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); return r; } @@ -180,6 +278,8 @@ pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discover pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(backend->connection), HF_AUDIO_AGENT_PATH, &vtable_hf_audio_agent, backend)); + hf_audio_agent_register(backend); + return backend; } @@ -188,6 +288,8 @@ void pa_bluetooth_backend_free(pa_bluetooth_backend *backend) { pa_dbus_free_pending_list(&backend->pending); + hf_audio_agent_unregister(backend); + dbus_connection_unregister_object_path(pa_dbus_connection_get(backend->connection), HF_AUDIO_AGENT_PATH); pa_dbus_remove_matches(pa_dbus_connection_get(backend->connection), |