diff --git a/android/adapter.c b/android/adapter.c
index 074fc68..40fb89d 100644
--- a/android/adapter.c
+++ b/android/adapter.c
#include "src/shared/mgmt.h"
#include "src/glib-helper.h"
#include "src/eir.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "lib/uuid.h"
+#include "src/sdp-client.h"
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
#define DEFAULT_IO_CAPABILITY 0x01
static GIOChannel *notification_io = NULL;
+/* This list contains addresses which are asked for records */
+static GSList *browse_reqs;
struct bt_adapter {
uint16_t index;
bool discovering;
};
+struct browse_req {
+ bdaddr_t bdaddr;
+ GSList *uuids;
+ int search_uuid;
+ int reconnect_attempt;
+};
+
+static const uint16_t uuid_list[] = {
+ L2CAP_UUID,
+ PNP_INFO_SVCLASS_ID,
+ PUBLIC_BROWSE_GROUP,
+ 0
+};
+
static struct bt_adapter *adapter;
static GSList *found_devices = NULL;
HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev, -1);
}
+static void browse_req_free(struct browse_req *req)
+{
+ g_slist_free_full(req->uuids, g_free);
+ g_free(req);
+}
+
+static void update_records(struct browse_req *req, sdp_list_t *recs)
+{
+ /* TODO cache found uuids */
+}
+
+static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
+{
+ struct browse_req *req = user_data;
+ uuid_t uuid;
+
+ /* If we have a valid response and req->search_uuid == 2, then L2CAP
+ * UUID & PNP searching was successful -- we are done */
+ if (err < 0 || req->search_uuid == 2) {
+ if (err == -ECONNRESET && req->reconnect_attempt < 1) {
+ req->search_uuid--;
+ req->reconnect_attempt++;
+ } else {
+ goto done;
+ }
+ }
+
+ update_records(req, recs);
+
+ /* Search for mandatory uuids */
+ if (uuid_list[req->search_uuid]) {
+ sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
+ bt_search_service(&adapter->bdaddr, &req->bdaddr, &uuid,
+ browse_cb, user_data, NULL);
+ return;
+ }
+
+done:
+ browse_reqs = g_slist_remove(browse_reqs, req);
+ browse_req_free(req);
+}
+
+static int req_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct browse_req *req = a;
+ const bdaddr_t *bdaddr = b;
+
+ return bacmp(&req->bdaddr, bdaddr);
+}
+
+static uint8_t browse_remote_sdp(const bdaddr_t *addr)
+{
+ struct browse_req *req;
+ uuid_t uuid;
+
+ if (g_slist_find_custom(browse_reqs, addr, req_cmp))
+ return HAL_STATUS_DONE;
+
+ req = g_new0(struct browse_req, 1);
+ bacpy(&req->bdaddr, addr);
+ sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
+
+ if (bt_search_service(&adapter->bdaddr,
+ &req->bdaddr, &uuid, browse_cb, req, NULL) < 0) {
+ browse_req_free(req);
+ return false;
+ }
+
+ browse_reqs = g_slist_append(browse_reqs, req);
+
+ return HAL_STATUS_SUCCESS;
+}
+
static void new_link_key_callback(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
static uint8_t get_remote_services(void *buf, uint16_t len)
{
- return HAL_STATUS_UNSUPPORTED;
+ struct hal_cmd_get_remote_services *cmd = buf;
+ bdaddr_t addr;
+
+ android2bdaddr(&cmd->bdaddr, &addr);
+
+ return browse_remote_sdp(&addr);
}
void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,