@@ -2008,7 +2008,7 @@ bool bt_health_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
mcl_connected, mcl_reconnected,
mcl_disconnected, mcl_uncached,
NULL, /* CSP is not used right now */
- NULL, &err);
+ NULL, NULL, &err);
if (!mcap) {
error("health: MCAP instance creation failed %s", err->message);
g_error_free(err);
@@ -1347,6 +1347,7 @@ static gboolean update_adapter(struct hdp_adapter *hdp_adapter)
mcl_connected, mcl_reconnected,
mcl_disconnected, mcl_uncached,
NULL, /* CSP is not used by now */
+ btd_request_authorization,
hdp_adapter, &err);
if (hdp_adapter->mi == NULL) {
error("Error creating the MCAP instance: %s", err->message);
@@ -14,6 +14,7 @@
#endif
#define _GNU_SOURCE
+#include <dbus/dbus.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
@@ -23,6 +24,7 @@
#include <glib.h>
#include "lib/bluetooth.h"
+#include "lib/uuid.h"
#include "bluetooth/l2cap.h"
#include "btio/btio.h"
#include "src/log.h"
@@ -1980,7 +1982,6 @@ static void set_mcl_conf(GIOChannel *chan, struct mcap_mcl *mcl)
mcl->state = MCL_CONNECTED;
mcl->role = MCL_ACCEPTOR;
mcl->req = MCL_AVAILABLE;
- mcl->cc = g_io_channel_ref(chan);
mcl->ctrl |= MCAP_CTRL_STD_OP;
mcap_sync_init(mcl);
@@ -2005,19 +2006,38 @@ static void set_mcl_conf(GIOChannel *chan, struct mcap_mcl *mcl)
mcl->mi->mcl_connected_cb(mcl, mcl->mi->user_data);
}
+static void auth_callback(DBusError *derr, void *user_data)
+{
+ struct mcap_mcl *mcl = user_data;
+
+ if (derr) {
+ error("Access denied: %s", derr->message);
+ goto reject;
+ }
+
+ set_mcl_conf(mcl->cc, mcl);
+ return;
+
+reject:
+ g_io_channel_shutdown(mcl->cc, TRUE, NULL);
+ g_io_channel_unref(mcl->cc);
+}
+
static void connect_mcl_event_cb(GIOChannel *chan, GError *gerr,
gpointer user_data)
{
struct mcap_instance *mi = user_data;
struct mcap_mcl *mcl;
- bdaddr_t dst;
+ bdaddr_t src, dst;
char address[18], srcstr[18];
GError *err = NULL;
+ guint ret;
if (gerr)
return;
bt_io_get(chan, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &src,
BT_IO_OPT_DEST_BDADDR, &dst,
BT_IO_OPT_DEST, address,
BT_IO_OPT_INVALID);
@@ -2044,6 +2064,18 @@ static void connect_mcl_event_cb(GIOChannel *chan, GError *gerr,
mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
}
+ mcl->cc = g_io_channel_ref(chan);
+ if (mi->authorize_cb) {
+ ret = mi->authorize_cb(&src, &dst, HDP_UUID, auth_callback,
+ mcl);
+ if (ret != 0)
+ return;
+
+ error("HDP: authorization for device %s failed", address);
+ g_io_channel_unref(mcl->cc);
+ goto drop;
+ }
+
set_mcl_conf(chan, mcl);
return;
@@ -2060,6 +2092,7 @@ struct mcap_instance *mcap_create_instance(const bdaddr_t *src,
mcap_mcl_event_cb mcl_disconnected,
mcap_mcl_event_cb mcl_uncached,
mcap_info_ind_event_cb mcl_sync_info_ind,
+ mcap_authorize_cb authorize_cb,
gpointer user_data,
GError **gerr)
{
@@ -2089,6 +2122,7 @@ struct mcap_instance *mcap_create_instance(const bdaddr_t *src,
mi->mcl_disconnected_cb = mcl_disconnected;
mi->mcl_uncached_cb = mcl_uncached;
mi->mcl_sync_infoind_cb = mcl_sync_info_ind;
+ mi->authorize_cb = authorize_cb;
mi->user_data = user_data;
mi->csp_enabled = FALSE;
@@ -9,6 +9,8 @@
*
*/
+#include <dbus/dbus.h>
+
#define MCAP_VERSION 0x0100 /* current version 01.00 */
/* bytes to get MCAP Supported Procedures */
@@ -249,6 +251,11 @@ typedef void (* mcap_sync_set_cb) (struct mcap_mcl *mcl,
GError *err,
gpointer data);
+typedef void mcap_auth_cb(DBusError *derr, void *user_data);
+typedef guint (* mcap_authorize_cb) (const bdaddr_t *src, const bdaddr_t *dst,
+ const char *uuid, mcap_auth_cb cb,
+ void *user_data);
+
struct mcap_mdl_cb {
mcap_mdl_event_cb mdl_connected; /* Remote device has created a MDL */
mcap_mdl_event_cb mdl_closed; /* Remote device has closed a MDL */
@@ -271,6 +278,7 @@ struct mcap_instance {
mcap_mcl_event_cb mcl_disconnected_cb; /* MCL disconnected */
mcap_mcl_event_cb mcl_uncached_cb; /* MCL has been removed from MCAP cache */
mcap_info_ind_event_cb mcl_sync_infoind_cb; /* (CSP Master) Received info indication */
+ mcap_authorize_cb authorize_cb; /* Method to request authorization */
gpointer user_data; /* Data to be provided in callbacks */
int ref; /* Reference counter */
@@ -404,6 +412,7 @@ struct mcap_instance *mcap_create_instance(const bdaddr_t *src,
mcap_mcl_event_cb mcl_disconnected,
mcap_mcl_event_cb mcl_uncached,
mcap_info_ind_event_cb mcl_sync_info_ind,
+ mcap_authorize_cb authorize_cb,
gpointer user_data,
GError **gerr);
void mcap_release_instance(struct mcap_instance *mi);
@@ -434,7 +434,7 @@ int main(int argc, char *argv[])
mcl_connected, mcl_reconnected,
mcl_disconnected, mcl_uncached,
NULL, /* CSP is not used right now */
- NULL, &err);
+ NULL, NULL, &err);
if (!mcap) {
printf("MCAP instance creation failed %s\n", err->message);
From: Yun-Hao Chung <howardchung@chromium.org> Currently mcap is the only profile that doesn't request adatper authorization. This patch adds a argument when creating the mcap instance to set authorize method. The reason why we don't use btd_request_authorization directly like all other profiles is because tools/mcaptest includes the profile/health/mcap.h. If we add dependency to adapter.h in mcap.h, it will make mcaptest depend on adapter and be not able to build independently. --- (no changes since v1) android/health.c | 2 +- profiles/health/hdp.c | 1 + profiles/health/mcap.c | 38 ++++++++++++++++++++++++++++++++++++-- profiles/health/mcap.h | 9 +++++++++ tools/mcaptest.c | 2 +- 5 files changed, 48 insertions(+), 4 deletions(-)