Move interactive code of Discover Primary to gatt.c

Initial patch to move the shared code related to Discover All Primary
Services and Discover Primary Services by UUID to gatt.c.
diff --git a/attrib/gatt.c b/attrib/gatt.c
index ae33211..7d09689 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -31,10 +31,24 @@
 #include "gattrib.h"
 #include "gatt.h"
 
-guint gatt_discover_primary(GAttrib *attrib, uint16_t start, uint16_t end,
-		uuid_t *uuid, GAttribResultFunc func, gpointer user_data)
+struct discover_primary {
+	GAttrib *attrib;
+	uuid_t uuid;
+	GSList *primaries;
+	gatt_primary_t cb;
+	void *user_data;
+};
+
+static void discover_primary_free(struct discover_primary *dp)
 {
-	uint8_t pdu[ATT_DEFAULT_MTU];
+	g_slist_free(dp->primaries);
+	g_attrib_unref(dp->attrib);
+	g_free(dp);
+}
+
+static guint16 encode_discover_primary(uint16_t start, uint16_t end,
+					uuid_t *uuid, uint8_t *pdu, size_t len)
+{
 	uuid_t prim;
 	guint16 plen;
 	uint8_t op;
@@ -42,10 +56,9 @@
 	sdp_uuid16_create(&prim, GATT_PRIM_SVC_UUID);
 
 	if (uuid == NULL) {
-
 		/* Discover all primary services */
 		op = ATT_OP_READ_BY_GROUP_REQ;
-		plen = enc_read_by_grp_req(start, end, &prim, pdu, sizeof(pdu));
+		plen = enc_read_by_grp_req(start, end, &prim, pdu, len);
 	} else {
 		const void *value;
 		int vlen;
@@ -62,13 +75,151 @@
 		}
 
 		plen = enc_find_by_type_req(start, end, &prim, value, vlen,
-							pdu, sizeof(pdu));
+								pdu, len);
 	}
 
+	return plen;
+}
+
+static void primary_by_uuid_cb(guint8 status, const guint8 *ipdu,
+					guint16 iplen, gpointer user_data)
+
+{
+	struct discover_primary *dp = user_data;
+	GSList *ranges, *last;
+	struct att_range *range;
+	uint8_t opdu[ATT_DEFAULT_MTU];
+	guint16 oplen;
+	int err = 0;
+
+	if (status) {
+		err = status == ATT_ECODE_ATTR_NOT_FOUND ? 0 : status;
+		goto done;
+	}
+
+	ranges = dec_find_by_type_resp(ipdu, iplen);
+	if (ranges == NULL)
+		goto done;
+
+	dp->primaries = g_slist_concat(dp->primaries, ranges);
+
+	last = g_slist_last(ranges);
+	g_slist_free(ranges);
+	range = last->data;
+
+	if (range->end == 0xffff)
+		goto done;
+
+	oplen = encode_discover_primary(range->end + 1, 0xffff, &dp->uuid,
+							opdu, sizeof(opdu));
+
+	if (oplen == 0)
+		goto done;
+
+	g_attrib_send(dp->attrib, 0, opdu[0], opdu, oplen, primary_by_uuid_cb,
+								dp, NULL);
+	return;
+
+done:
+	dp->cb(dp->primaries, err, dp->user_data);
+	discover_primary_free(dp);
+}
+
+static void primary_all_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
+							gpointer user_data)
+{
+	struct discover_primary *dp = user_data;
+	struct att_data_list *list;
+	unsigned int i, err;
+	uint16_t start, end;
+
+	if (status) {
+		err = status == ATT_ECODE_ATTR_NOT_FOUND ? 0 : status;
+		goto done;
+	}
+
+	list = dec_read_by_grp_resp(ipdu, iplen);
+	if (list == NULL) {
+		err = ATT_ECODE_IO;
+		goto done;
+	}
+
+	for (i = 0, end = 0; i < list->num; i++) {
+		const uint8_t *data = list->data[i];
+		struct att_primary *primary;
+		uuid_t u128, u16;
+
+		start = att_get_u16(&data[0]);
+		end = att_get_u16(&data[2]);
+
+		if (list->len == 6) {
+			sdp_uuid16_create(&u16,
+					att_get_u16(&data[4]));
+			sdp_uuid16_to_uuid128(&u128, &u16);
+
+		} else if (list->len == 20)
+			sdp_uuid128_create(&u128, &data[4]);
+		else
+			/* Skipping invalid data */
+			continue;
+
+		primary = g_try_new0(struct att_primary, 1);
+		if (!primary) {
+			err = ATT_ECODE_INSUFF_RESOURCES;
+			goto done;
+		}
+		primary->start = start;
+		primary->end = end;
+		sdp_uuid2strn(&u128, primary->uuid, sizeof(primary->uuid));
+		dp->primaries = g_slist_append(dp->primaries, primary);
+	}
+
+	att_data_list_free(list);
+	err = 0;
+
+	if (end != 0xffff) {
+		uint8_t opdu[ATT_DEFAULT_MTU];
+		guint16 oplen = encode_discover_primary(end + 1, 0xffff, NULL,
+							opdu, sizeof(opdu));
+
+		g_attrib_send(dp->attrib, 0, opdu[0], opdu, oplen,
+						primary_all_cb, dp, NULL);
+
+		return;
+	}
+
+done:
+	dp->cb(dp->primaries, err, dp->user_data);
+	discover_primary_free(dp);
+}
+
+guint gatt_discover_primary(GAttrib *attrib, uuid_t *uuid, gatt_primary_t func,
+							gpointer user_data)
+{
+	struct discover_primary *dp;
+	uint8_t pdu[ATT_DEFAULT_MTU];
+	GAttribResultFunc cb;
+	guint16 plen;
+
+	plen = encode_discover_primary(0x0001, 0xffff, uuid, pdu, sizeof(pdu));
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, op, pdu, plen, func, user_data, NULL);
+	dp = g_try_new0(struct discover_primary, 1);
+	if (dp == NULL)
+		return 0;
+
+	dp->attrib = g_attrib_ref(attrib);
+	dp->cb = func;
+	dp->user_data = user_data;
+
+	if (uuid) {
+		memcpy(&dp->uuid, uuid, sizeof(uuid_t));
+		cb = primary_by_uuid_cb;
+	} else
+		cb = primary_all_cb;
+
+	return g_attrib_send(attrib, 0, pdu[0], pdu, plen, cb, dp, NULL);
 }
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 1e1e628..936c592 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -24,8 +24,10 @@
 
 #define GATT_CID 4
 
-guint gatt_discover_primary(GAttrib *attrib, uint16_t start, uint16_t end,
-		uuid_t *uuid, GAttribResultFunc func, gpointer user_data);
+typedef void (*gatt_primary_t) (GSList *l, guint8 status, gpointer user_data);
+
+guint gatt_discover_primary(GAttrib *attrib, uuid_t *uuid, gatt_primary_t func,
+							gpointer user_data);
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 				GAttribResultFunc func, gpointer user_data);
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index a6f92db..ad0216b 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -145,76 +145,30 @@
 	return chan;
 }
 
-static void primary_all_cb(guint8 status, const guint8 *pdu, guint16 plen,
-							gpointer user_data)
+static void primary_all_cb(GSList *services, guint8 status, gpointer user_data)
 {
-	GAttrib *attrib = user_data;
-	struct att_data_list *list;
-	unsigned int i;
-	uint16_t end;
+	GSList *l;
 
-	if (status == ATT_ECODE_ATTR_NOT_FOUND)
-		goto done;
-
-	if (status != 0) {
+	if (status) {
 		g_printerr("Discover all primary services failed: %s\n",
 							att_ecode2str(status));
 		goto done;
 	}
 
-	list = dec_read_by_grp_resp(pdu, plen);
-	if (list == NULL)
-		goto done;
-
-	for (i = 0, end = 0; i < list->num; i++) {
-		char uuidstr[MAX_LEN_UUID_STR];
-		uint8_t *value = list->data[i];
-		uint8_t length;
-		uint16_t start;
-		uuid_t uuid;
-
-		/* Each element contains: attribute handle, end group handle
-		 * and attribute value */
-		length = list->len - 2 * sizeof(uint16_t);
-		start = att_get_u16(value);
-		end = att_get_u16(&value[2]);
-
-		g_print("attr handle = 0x%04x, end grp handle = 0x%04x, ",
-								start, end);
-		if (length == 2)
-			sdp_uuid16_create(&uuid, att_get_u16(&value[4]));
-		else
-			sdp_uuid128_create(&uuid, value + 4);
-
-		sdp_uuid2strn(&uuid, uuidstr, MAX_LEN_UUID_STR);
-		g_print("attr value (UUID) = %s\n", uuidstr);
+	for (l = services; l; l = l->next) {
+		struct att_primary *prim = l->data;
+		g_print("attr handle = 0x%04x, end grp handle = 0x%04x "
+			"uuid: %s\n", prim->start, prim->end, prim->uuid);
 	}
 
-	att_data_list_free(list);
-
-	/* Don't go beyond the maximum handle value */
-	if (end == 0xffff)
-		goto done;
-
-	/*
-	 * Discover all primary services sub-procedure shall send another
-	 * Read by Group Type Request until Error Response is received and
-	 * the Error Code is set to Attribute Not Found.
-	 */
-
-	gatt_discover_primary(attrib, end + 1, opt_end, NULL, primary_all_cb,
-								attrib);
-	return;
-
 done:
-	if (opt_listen == FALSE)
-		g_main_loop_quit(event_loop);
+	g_main_loop_quit(event_loop);
 }
 
-static void primary_by_uuid_cb(guint8 status, const guint8 *pdu, guint16 plen,
+static void primary_by_uuid_cb(GSList *ranges, guint8 status,
 							gpointer user_data)
 {
-	GSList *ranges, *l;
+	GSList *l;
 
 	if (status != 0) {
 		g_printerr("Discover primary services by UUID failed: %s\n",
@@ -222,21 +176,12 @@
 		goto done;
 	}
 
-	ranges = dec_find_by_type_resp(pdu, plen);
-	if (ranges == NULL) {
-		g_printerr("Protocol error!\n");
-		goto done;
-	}
-
 	for (l = ranges; l; l = l->next) {
 		struct att_range *range = l->data;
 		g_print("Starting handle: %04x Ending handle: %04x\n",
 						range->start, range->end);
 	}
 
-	g_slist_foreach(ranges, (GFunc) g_free, NULL);
-	g_slist_free(ranges);
-
 done:
 	g_main_loop_quit(event_loop);
 }
@@ -292,11 +237,10 @@
 	GAttrib *attrib = user_data;
 
 	if (opt_uuid)
-		gatt_discover_primary(attrib, opt_start, opt_end, opt_uuid,
-						primary_by_uuid_cb, attrib);
+		gatt_discover_primary(attrib, opt_uuid, primary_by_uuid_cb,
+									NULL);
 	else
-		gatt_discover_primary(attrib, opt_start, opt_end, NULL,
-						primary_all_cb, attrib);
+		gatt_discover_primary(attrib, NULL, primary_all_cb, NULL);
 
 	return FALSE;
 }
diff --git a/src/device.c b/src/device.c
index 4d53228..b7b9a98 100644
--- a/src/device.c
+++ b/src/device.c
@@ -53,6 +53,8 @@
 #include "event.h"
 #include "error.h"
 #include "glib-helper.h"
+#include "gattrib.h"
+#include "gatt.h"
 #include "agent.h"
 #include "sdp-xml.h"
 #include "storage.h"
@@ -95,6 +97,8 @@
 struct browse_req {
 	DBusConnection *conn;
 	DBusMessage *msg;
+	GAttrib *attrib;
+	GIOChannel *io;
 	struct btd_device *device;
 	GSList *match_uuids;
 	GSList *profiles_added;
@@ -170,6 +174,13 @@
 	g_slist_free(req->profiles_removed);
 	if (req->records)
 		sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
+
+	if (req->io) {
+		g_attrib_unref(req->attrib);
+		g_io_channel_unref(req->io);
+		g_io_channel_shutdown(req->io, FALSE, NULL);
+	}
+
 	g_free(req);
 }
 
@@ -1559,7 +1570,7 @@
 	return g_string_free(services, FALSE);
 }
 
-static void primary_cb(GSList *services, int err, gpointer user_data)
+static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 {
 	struct browse_req *req = user_data;
 	struct btd_device *device = req->device;
@@ -1568,9 +1579,9 @@
 	bdaddr_t dba, sba;
 	char *str;
 
-	if (err) {
+	if (status) {
 		DBusMessage *reply;
-		reply = btd_error_failed(req->msg, strerror(-err));
+		reply = btd_error_failed(req->msg, att_ecode2str(status));
 		g_dbus_send_message(req->conn, reply);
 		goto done;
 	}
@@ -1603,13 +1614,36 @@
 	browse_request_free(req);
 }
 
+static void gatt_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
+{
+	struct browse_req *req = user_data;
+	struct btd_device *device = req->device;
+
+	if (gerr) {
+		DBusMessage *reply;
+
+		DBG("%s", gerr->message);
+
+		reply = btd_error_failed(req->msg, gerr->message);
+		g_dbus_send_message(req->conn, reply);
+
+		device->browse = NULL;
+		browse_request_free(req);
+
+		return;
+	}
+
+	req->attrib = g_attrib_new(io);
+	gatt_discover_primary(req->attrib, NULL, primary_cb, req);
+}
+
 int device_browse_primary(struct btd_device *device, DBusConnection *conn,
 				DBusMessage *msg, gboolean secure)
 {
 	struct btd_adapter *adapter = device->adapter;
 	struct browse_req *req;
+	BtIOSecLevel sec_level;
 	bdaddr_t src;
-	int err;
 
 	if (device->browse)
 		return -EBUSY;
@@ -1619,11 +1653,18 @@
 
 	adapter_get_address(adapter, &src);
 
-	err = bt_discover_primary(&src, &device->bdaddr, -1, primary_cb, req,
-							secure, NULL);
-	if (err < 0) {
+	sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW;
+
+	req->io = bt_io_connect(BT_IO_L2CAP, gatt_connect_cb, req, NULL, NULL,
+				BT_IO_OPT_SOURCE_BDADDR, &src,
+				BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
+				BT_IO_OPT_CID, GATT_CID,
+				BT_IO_OPT_SEC_LEVEL, sec_level,
+				BT_IO_OPT_INVALID);
+
+	if (req->io == NULL ) {
 		browse_request_free(req);
-		return err;
+		return -EIO;
 	}
 
 	if (conn == NULL)
@@ -1644,7 +1685,7 @@
 						req, NULL);
 	}
 
-	return err;
+	return 0;
 }
 
 int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
diff --git a/src/glib-helper.c b/src/glib-helper.c
index b5f038d..22c14e7 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -38,28 +38,12 @@
 #include <glib.h>
 
 #include "btio.h"
-#include "gattrib.h"
-#include "att.h"
-#include "gatt.h"
 #include "sdpd.h"
 #include "glib-helper.h"
 
 /* Number of seconds to keep a sdp_session_t in the cache */
 #define CACHE_TIMEOUT 2
 
-struct gattrib_context {
-	bdaddr_t src;
-	bdaddr_t dst;
-	GAttrib *attrib;
-	GIOChannel *io;
-	bt_primary_t cb;
-	bt_destroy_t destroy;
-	gpointer user_data;
-	GSList *primaries;
-};
-
-static GSList *gattrib_list = NULL;
-
 struct cached_sdp_session {
 	bdaddr_t src;
 	bdaddr_t dst;
@@ -69,22 +53,6 @@
 
 static GSList *cached_sdp_sessions = NULL;
 
-static void gattrib_context_free(struct gattrib_context *ctxt)
-{
-	gattrib_list = g_slist_remove(gattrib_list, ctxt);
-	if (ctxt->destroy)
-		ctxt->destroy(ctxt->user_data);
-
-	g_slist_free(ctxt->primaries);
-	g_attrib_unref(ctxt->attrib);
-	if (ctxt->io) {
-		g_io_channel_unref(ctxt->io);
-		g_io_channel_shutdown(ctxt->io, FALSE, NULL);
-	}
-
-	g_free(ctxt);
-}
-
 static gboolean cached_session_expired(gpointer user_data)
 {
 	struct cached_sdp_session *cached = user_data;
@@ -370,16 +338,22 @@
 					bacmp(&ctxt->src, &search->src));
 }
 
-static gint gattrib_find_by_bdaddr(gconstpointer data, gconstpointer user_data)
+int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
 {
-	const struct gattrib_context *ctxt = data, *search = user_data;
+	struct search_context match, *ctxt;
+	GSList *l;
 
-	return (bacmp(&ctxt->dst, &search->dst) &&
-					bacmp(&ctxt->src, &search->src));
-}
+	memset(&match, 0, sizeof(match));
+	bacpy(&match.src, src);
+	bacpy(&match.dst, dst);
 
-static int cancel_sdp(struct search_context *ctxt)
-{
+	/* Ongoing SDP Discovery */
+	l = g_slist_find_custom(context_list, &match, find_by_bdaddr);
+	if (l == NULL)
+		return -ENOENT;
+
+	ctxt = l->data;
+
 	if (!ctxt->session)
 		return -ENOTCONN;
 
@@ -394,178 +368,6 @@
 	return 0;
 }
 
-static int cancel_gattrib(struct gattrib_context *ctxt)
-{
-	if (ctxt->attrib)
-		g_attrib_cancel_all(ctxt->attrib);
-
-	gattrib_context_free(ctxt);
-
-	return 0;
-}
-
-int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
-{
-	struct search_context sdp_ctxt;
-	struct gattrib_context gatt_ctxt;
-	GSList *match;
-
-	memset(&sdp_ctxt, 0, sizeof(sdp_ctxt));
-	bacpy(&sdp_ctxt.src, src);
-	bacpy(&sdp_ctxt.dst, dst);
-
-	/* Ongoing SDP Discovery */
-	match = g_slist_find_custom(context_list, &sdp_ctxt, find_by_bdaddr);
-	if (match)
-		return cancel_sdp(match->data);
-
-	memset(&gatt_ctxt, 0, sizeof(gatt_ctxt));
-	bacpy(&gatt_ctxt.src, src);
-	bacpy(&gatt_ctxt.dst, dst);
-
-	/* Ongoing Discover All Primary Services */
-	match = g_slist_find_custom(gattrib_list, &gatt_ctxt,
-						gattrib_find_by_bdaddr);
-	if (match == NULL)
-		return -ENOTCONN;
-
-	return cancel_gattrib(match->data);
-}
-
-static void primary_cb(guint8 status, const guint8 *pdu, guint16 plen,
-							gpointer user_data)
-{
-	struct gattrib_context *ctxt = user_data;
-	struct att_data_list *list;
-	unsigned int i, err;
-	uint16_t start, end;
-
-	if (status == ATT_ECODE_ATTR_NOT_FOUND) {
-		err = 0;
-		goto done;
-	}
-
-	if (status != 0) {
-		err = -EIO;
-		goto done;
-	}
-
-	list = dec_read_by_grp_resp(pdu, plen);
-	if (list == NULL) {
-		err = -EPROTO;
-		goto done;
-	}
-
-	for (i = 0, end = 0; i < list->num; i++) {
-		const uint8_t *data = list->data[i];
-		struct att_primary *primary;
-		uuid_t u128, u16;
-
-		start = att_get_u16(&data[0]);
-		end = att_get_u16(&data[2]);
-
-		if (list->len == 6) {
-			sdp_uuid16_create(&u16,
-					att_get_u16(&data[4]));
-			sdp_uuid16_to_uuid128(&u128, &u16);
-
-		} else if (list->len == 20)
-			sdp_uuid128_create(&u128, &data[4]);
-		else
-			/* Skipping invalid data */
-			continue;
-
-		primary = g_try_new0(struct att_primary, 1);
-		if (!primary) {
-			err = -ENOMEM;
-			goto done;
-		}
-		primary->start = start;
-		primary->end = end;
-		sdp_uuid2strn(&u128, primary->uuid, sizeof(primary->uuid));
-		ctxt->primaries = g_slist_append(ctxt->primaries, primary);
-	}
-
-	att_data_list_free(list);
-	err = 0;
-
-	if (end != 0xffff) {
-		gatt_discover_primary(ctxt->attrib, end + 1, 0xffff, NULL,
-							primary_cb, ctxt);
-		return;
-	}
-
-done:
-	ctxt->cb(ctxt->primaries, err, ctxt->user_data);
-	gattrib_context_free(ctxt);
-}
-
-static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
-{
-	struct gattrib_context *ctxt = user_data;
-
-	if (gerr) {
-		ctxt->cb(NULL, -EIO, ctxt->user_data);
-		gattrib_context_free(ctxt);
-		return;
-	}
-
-	ctxt->attrib = g_attrib_new(io);
-	gatt_discover_primary(ctxt->attrib, 0x0001, 0xffff, NULL, primary_cb,
-									ctxt);
-}
-
-int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
-					bt_primary_t cb, void *user_data,
-					gboolean secure,
-					bt_destroy_t destroy)
-{
-	struct gattrib_context *ctxt;
-	BtIOSecLevel sec_level;
-	GIOChannel *io;
-
-	ctxt = g_try_new0(struct gattrib_context, 1);
-	if (ctxt == NULL)
-		return -ENOMEM;
-
-	bacpy(&ctxt->src, src);
-	bacpy(&ctxt->dst, dst);
-	ctxt->user_data = user_data;
-	ctxt->cb = cb;
-	ctxt->destroy = destroy;
-
-	if (secure == TRUE)
-		sec_level = BT_IO_SEC_HIGH;
-	else
-		sec_level = BT_IO_SEC_LOW;
-
-	if (psm < 0)
-		io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, NULL,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_DEST_BDADDR, dst,
-				BT_IO_OPT_CID, GATT_CID,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-	else
-		io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, NULL,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_DEST_BDADDR, dst,
-				BT_IO_OPT_PSM, psm,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-
-	if (io == NULL) {
-		gattrib_context_free(ctxt);
-		return -EIO;
-	}
-
-	ctxt->io = io;
-
-	gattrib_list = g_slist_append(gattrib_list, ctxt);
-
-	return 0;
-}
-
 char *bt_uuid2string(uuid_t *uuid)
 {
 	gchar *str;
diff --git a/src/glib-helper.h b/src/glib-helper.h
index 25fe276..c83f5e2 100644
--- a/src/glib-helper.h
+++ b/src/glib-helper.h
@@ -22,7 +22,6 @@
  */
 
 typedef void (*bt_callback_t) (sdp_list_t *recs, int err, gpointer user_data);
-typedef void (*bt_primary_t) (GSList *l, int err, gpointer user_data);
 typedef void (*bt_destroy_t) (gpointer user_data);
 
 int bt_search_service(const bdaddr_t *src, const bdaddr_t *dst,
@@ -30,11 +29,6 @@
 			bt_destroy_t destroy);
 int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst);
 
-int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
-					bt_primary_t cb, void *user_data,
-					gboolean secure,
-					bt_destroy_t destroy);
-
 gchar *bt_uuid2string(uuid_t *uuid);
 char *bt_name2string(const char *string);
 int bt_string2uuid(uuid_t *uuid, const char *string);