summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2007-06-18 17:56:29 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2007-06-18 17:56:29 +0000
commit8b82bd82b15db30f805c755aa783f6c98f0be73e (patch)
tree3e7979d7e0a1e50cb081c8e680c4d6f847ac88b6
parent7318cfb762eab445b8181ddc279fe2e73c6c2e6e (diff)
GetRemoteServiceIdentifiers: Request the DeviceID if it was not returned previouly by browse or L2CAP
-rw-r--r--hcid/dbus-sdp.c136
1 files changed, 62 insertions, 74 deletions
diff --git a/hcid/dbus-sdp.c b/hcid/dbus-sdp.c
index f812dd9c..17e2d284 100644
--- a/hcid/dbus-sdp.c
+++ b/hcid/dbus-sdp.c
@@ -79,6 +79,7 @@ struct transaction_context {
GIOChannel *io;
guint io_id;
uuid_t uuid;
+ GSList *identifiers;
/* Used for internal async get remote service record implementation */
get_record_data_t *call;
@@ -421,6 +422,11 @@ static void transaction_context_free(void *udata, gboolean cache)
g_io_channel_unref(ctxt->io);
}
+ if (ctxt->identifiers) {
+ g_slist_foreach(ctxt->identifiers, (GFunc) g_free, NULL);
+ g_slist_free(ctxt->identifiers);
+ }
+
g_free(ctxt);
}
@@ -731,17 +737,43 @@ static const char *extract_service_class(sdp_data_t *d)
if (uuid->type != SDP_UUID16)
return NULL;
- sprintf(uuid_str, "0000%04X-0000-1000-8000-00805F9B34FB",
+ sprintf(uuid_str, "0000%04x-0000-1000-8000-00805f9b34fb",
uuid->value.uuid16);
return uuid_str;
}
+static int service_search_attr(struct transaction_context *ctxt, uint16_t uuid)
+{
+ sdp_list_t *attrids, *search;
+ uint32_t range = 0x0000ffff;
+ int ret = 0;
+
+ sdp_uuid16_create(&ctxt->uuid, uuid);
+
+ search = sdp_list_append(0, &ctxt->uuid);
+ attrids = sdp_list_append(NULL, &range);
+
+ /*
+ * Create/send the search request and set the
+ * callback to indicate the request completion
+ */
+ if (sdp_service_search_attr_async(ctxt->session, search,
+ SDP_ATTR_REQ_RANGE, attrids) < 0)
+ ret = -sdp_get_error(ctxt->session);
+
+ sdp_list_free(search, NULL);
+ sdp_list_free(attrids, NULL);
+
+ return ret;
+}
+
static void remote_svc_identifiers_completed_cb(uint8_t type, uint16_t err,
uint8_t *rsp, size_t size, void *udata)
{
struct transaction_context *ctxt = udata;
- const char *src, *dst;
+ const char *src, *dst, *puuid;
+ const char *devid_uuid = "00001200-0000-1000-8000-00805f9b34fb";
DBusMessage *reply;
GSList *l = NULL;
DBusMessageIter iter, array_iter;
@@ -777,56 +809,15 @@ static void remote_svc_identifiers_completed_cb(uint8_t type, uint16_t err,
goto failed;
}
- scanned = sdp_extract_seqtype(rsp, &dtd, &len);
-
- /* When the sequence is empty: check for L2CAP/DeviceID */
- if (!len && ctxt->uuid.type == SDP_UUID16) {
- uint32_t range = 0x0000ffff;
- sdp_list_t *attrids, *search;
-
- switch(ctxt->uuid.value.uuid16) {
- case PUBLIC_BROWSE_GROUP:
- sdp_uuid16_create(&ctxt->uuid, L2CAP_UUID);
- break;
- case L2CAP_UUID:
- sdp_uuid16_create(&ctxt->uuid, PNP_INFO_SVCLASS_ID);
- break;
- default: /* Reply an empty array */
- goto done;
- }
-
- search = sdp_list_append(0, &ctxt->uuid);
- attrids = sdp_list_append(NULL, &range);
-
- if (sdp_service_search_attr_async(ctxt->session, search,
- SDP_ATTR_REQ_RANGE, attrids) < 0) {
- sdp_list_free(search, NULL);
- sdp_list_free(attrids, NULL);
- goto done;
- }
-
- sdp_list_free(search, NULL);
- sdp_list_free(attrids, NULL);
-
- /* Wait the L2CAP/DeviceID query */
- return;
- }
-
-done:
src = get_address_from_message(ctxt->conn, ctxt->rq);
dbus_message_get_args(ctxt->rq, NULL,
DBUS_TYPE_STRING, &dst,
DBUS_TYPE_INVALID);
- reply = dbus_message_new_method_return(ctxt->rq);
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_STRING_AS_STRING, &array_iter);
-
+ scanned = sdp_extract_seqtype(rsp, &dtd, &len);
rsp += scanned;
for (; extracted < len; rsp += recsize, extracted += recsize) {
sdp_record_t *rec;
- const char *puuid;
sdp_data_t *d;
recsize = 0;
@@ -847,22 +838,41 @@ done:
if (!puuid)
continue;
- l = g_slist_find_custom(l, puuid, (GCompareFunc) strcmp);
+ /* Ignore repeated identifiers */
+ l = g_slist_find_custom(ctxt->identifiers,
+ puuid, (GCompareFunc) strcmp);
if (l)
continue;
+ ctxt->identifiers = g_slist_append(ctxt->identifiers,
+ g_strdup(puuid));
+ }
+
+ /* If public browse response is empty: search for L2CAP */
+ if (!ctxt->identifiers && ctxt->uuid.value.uuid16 == PUBLIC_BROWSE_GROUP)
+ if (service_search_attr(ctxt, L2CAP_UUID) == 0)
+ return; /* Wait the response */
+
+ /* Request DeviceID if it was not returned previously */
+ l = g_slist_find_custom(ctxt->identifiers,
+ devid_uuid, (GCompareFunc) strcmp);
+ if (!l && ctxt->uuid.value.uuid16 != PNP_INFO_SVCLASS_ID)
+ if (service_search_attr(ctxt, PNP_INFO_SVCLASS_ID) == 0)
+ return; /* Wait the response */
+
+ reply = dbus_message_new_method_return(ctxt->rq);
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array_iter);
+
+ for (l = ctxt->identifiers; l; l = l->next) {
+ puuid = l->data;
dbus_message_iter_append_basic(&array_iter,
DBUS_TYPE_STRING, &puuid);
- l = g_slist_append(l, g_strdup(puuid));
}
dbus_message_iter_close_container(&iter, &array_iter);
send_message_and_unref(ctxt->conn, reply);
-
- if (l) {
- g_slist_foreach(l, (GFunc) g_free, NULL);
- g_slist_free(l);
- }
failed:
transaction_context_free(ctxt, TRUE);
}
@@ -1100,33 +1110,11 @@ static int remote_svc_handles_conn_cb(struct transaction_context *ctxt)
static int remote_svc_identifiers_conn_cb(struct transaction_context *ctxt)
{
- sdp_list_t *attrids, *search;
- uint32_t range = 0x0000ffff;
-
if (sdp_set_notify(ctxt->session,
remote_svc_identifiers_completed_cb, ctxt) < 0)
return -EINVAL;
- sdp_uuid16_create(&ctxt->uuid, PUBLIC_BROWSE_GROUP);
- search = sdp_list_append(0, &ctxt->uuid);
-
- attrids = sdp_list_append(NULL, &range);
-
- /*
- * Create/send the search request and set the
- * callback to indicate the request completion
- */
- if (sdp_service_search_attr_async(ctxt->session, search,
- SDP_ATTR_REQ_RANGE, attrids) < 0) {
- sdp_list_free(search, NULL);
- sdp_list_free(attrids, NULL);
- return -sdp_get_error(ctxt->session);
- }
-
- sdp_list_free(search, NULL);
- sdp_list_free(attrids, NULL);
-
- return 0;
+ return service_search_attr(ctxt, PUBLIC_BROWSE_GROUP);
}
DBusHandlerResult get_remote_svc_handles(DBusConnection *conn, DBusMessage *msg, void *data)