OSDN Git Service

android: Add support for starting and cancelling device discovery
authorJakub Tyszkowski <jakub.tyszkowski@tieto.com>
Thu, 31 Oct 2013 14:25:30 +0000 (15:25 +0100)
committerJohan Hedberg <johan.hedberg@intel.com>
Thu, 31 Oct 2013 14:46:18 +0000 (16:46 +0200)
Android will cancel ongoing discovery after some period of time so there
is no need for another timeout inside the daemon itself.

android/adapter.c

index 02f356d..a12ccb3 100644 (file)
@@ -26,8 +26,9 @@
 #include <glib.h>
 
 #include "lib/bluetooth.h"
-#include "src/shared/mgmt.h"
+#include "lib/sdp.h"
 #include "lib/mgmt.h"
+#include "src/shared/mgmt.h"
 #include "log.h"
 #include "hal-msg.h"
 #include "ipc.h"
@@ -52,6 +53,8 @@ struct bt_adapter {
 
        uint32_t supported_settings;
        uint32_t current_settings;
+
+       bool discovering;
 };
 
 static struct bt_adapter *adapter;
@@ -349,6 +352,35 @@ static void user_passkey_notify_callback(uint16_t index, uint16_t length,
                                                                ev->passkey);
 }
 
+static void mgmt_discovering_event(uint16_t index, uint16_t length,
+                                       const void *param, void *user_data)
+{
+       const struct mgmt_ev_discovering *ev = param;
+       struct hal_ev_discovery_state_changed cp;
+
+       if (length < sizeof(*ev)) {
+               error("Too small discovering event");
+               return;
+       }
+
+       DBG("hci%u type %u discovering %u", adapter->index, ev->type,
+                                                       ev->discovering);
+
+       if (adapter->discovering == !!ev->discovering)
+               return;
+
+       adapter->discovering = !!ev->discovering;
+
+       DBG("new discovering state %u", ev->discovering);
+
+       cp.state = adapter->discovering ? HAL_DISCOVERY_STATE_STARTED :
+                                               HAL_DISCOVERY_STATE_STOPPED;
+
+       ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+                                               HAL_EV_DISCOVERY_STATE_CHANGED,
+                                               sizeof(cp), &cp, -1);
+}
+
 static void register_mgmt_handlers(void)
 {
        mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
@@ -379,6 +411,10 @@ static void register_mgmt_handlers(void)
        mgmt_register(adapter->mgmt, MGMT_EV_PASSKEY_NOTIFY, adapter->index,
                                user_passkey_notify_callback, NULL, NULL);
 
+       mgmt_register(adapter->mgmt, MGMT_EV_DISCOVERING, adapter->index,
+                                                       mgmt_discovering_event,
+                                                       NULL, NULL);
+
 }
 
 static void load_link_keys_complete(uint8_t status, uint16_t length,
@@ -551,6 +587,7 @@ void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
 
        adapter->mgmt = mgmt_ref(mgmt);
        adapter->index = index;
+       adapter->discovering = false;
        adapter->ready = cb;
 
        if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
@@ -624,6 +661,46 @@ static bool get_property(void *buf, uint16_t len)
        }
 }
 
+static bool start_discovery(void)
+{
+       struct mgmt_cp_start_discovery cp;
+       uint8_t type = 1 << BDADDR_BREDR;
+
+       if (adapter->current_settings & type)
+               cp.type = type;
+       else
+               cp.type = 0;
+
+       DBG("type=0x%x", type);
+
+       if (mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY, adapter->index,
+                       sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+               return true;
+
+       error("Failed to start discovery");
+       return false;
+}
+
+static bool stop_discovery(void)
+{
+       struct mgmt_cp_stop_discovery cp;
+       uint8_t type = 1 << BDADDR_BREDR;
+
+       if (adapter->current_settings & type)
+               cp.type = type;
+       else
+               cp.type = 0;
+
+       DBG("type=0x%x", type);
+
+       if (mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY, adapter->index,
+                       sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+               return true;
+
+       error("Failed to start discovery");
+       return false;
+}
+
 static uint8_t set_scan_mode(void *buf, uint16_t len)
 {
        uint8_t *mode = buf;
@@ -987,6 +1064,35 @@ void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
                status = ssp_reply(buf, len);
                if (status != HAL_STATUS_SUCCESS)
                        goto error;
+               break;
+       case HAL_OP_START_DISCOVERY:
+               if (adapter->discovering) {
+                       status = HAL_STATUS_DONE;
+                       goto error;
+               }
+
+               if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+                       status = HAL_STATUS_NOT_READY;
+                       goto error;
+               }
+
+               if (!start_discovery())
+                       goto error;
+
+               break;
+       case HAL_OP_CANCEL_DISCOVERY:
+               if (!adapter->discovering) {
+                       status = HAL_STATUS_DONE;
+                       goto error;
+               }
+
+               if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+                       status = HAL_STATUS_NOT_READY;
+                       goto error;
+               }
+
+               if (!stop_discovery())
+                       goto error;
 
                break;
        default: