diff options
| -rw-r--r-- | hcid/dbus-common.c | 2 | ||||
| -rw-r--r-- | hcid/dbus-sdp.c | 855 | ||||
| -rw-r--r-- | hcid/dbus-sdp.h | 4 | 
3 files changed, 0 insertions, 861 deletions
| diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c index f40fc1d7..5d6976b5 100644 --- a/hcid/dbus-common.c +++ b/hcid/dbus-common.c @@ -232,8 +232,6 @@ DBusHandlerResult handle_method_call(DBusConnection *conn, DBusMessage *msg, voi  		return handle_test_method(conn, msg, data);  	else if (!strcmp(RFCOMM_INTERFACE, iface))  		return handle_rfcomm_method(conn, msg, data); -	else if (!strcmp(SDP_INTERFACE, iface)) -		return handle_sdp_method(conn, msg, data);  	else  		return error_unknown_method(conn, msg);  } diff --git a/hcid/dbus-sdp.c b/hcid/dbus-sdp.c index 3a2520c1..48fc6ba2 100644 --- a/hcid/dbus-sdp.c +++ b/hcid/dbus-sdp.c @@ -59,17 +59,6 @@  #define MAX_IDENTIFIER_LEN	29	/* "XX:XX:XX:XX:XX:XX/0xYYYYYYYY\0" */  #define DEFAULT_XML_BUF_SIZE	1024 -struct service_provider { -	char *owner;	/* null for remote services or unique name if local */ -	char *prov;	/* remote Bluetooth address that provides the service */ -	struct slist *lrec; -}; - -struct service_record { -	int ttl;	/* time to live */ -	sdp_record_t *record; -}; -  struct transaction_context {  	DBusConnection *conn;  	DBusMessage *rq; @@ -159,40 +148,7 @@ uint16_t sdp_str2svclass(const char *str)  	return 0;  } -/* FIXME:  move to a common file */ -const char* sdp_svclass2str(uint16_t class) -{ -	sdp_service_t *s; - -	for (s = sdp_service; s->name; s++) { -		if (s->class == class) -			return s->name; -	} - -	return NULL; -} - -/* FIXME: stub for service registration. Shared with sdptool */ -static inline sdp_record_t *sdp_service_register(const char *name, bdaddr_t *interface, -		                                   uint8_t channel, int *err) -{ -	if (err) -		*err = ENOSYS; - -	return NULL; -} - -/* FIXME: stub for service registration. Shared with sdptool */ -static inline int sdp_service_unregister(bdaddr_t *interface, sdp_record_t *rec, int *err) -{ -	if (err) -		*err = ENOSYS; - -	return -1; -} -  /* list of remote and local service records */ -static struct slist *sdp_cache = NULL;  static struct slist *pending_connects  = NULL;  static struct pending_connect *pending_connect_new(DBusConnection *conn, DBusMessage *msg, @@ -253,151 +209,6 @@ static struct pending_connect *find_pending_connect(const char *dst)  	return NULL;  } -static int str2identifier(const char *identifier, char *address, -			  uint32_t *handle) -{ -	if (!identifier || !address) -		return -1; - -	if (strlen(identifier) < 19) -		return -1; - -	memset(address, 0, 18); -	snprintf(address, 18, "%s", identifier); - -	return (sscanf(identifier + 18, "%x", handle) > 0 ? 0 : -1); -} - -static struct service_record *service_record_new(sdp_record_t *rec) -{ -	struct service_record *r; - -	r = malloc(sizeof(*r)); -	if (!r) -		return NULL; - -	memset(r, 0, sizeof(*r)); -	r->record = rec; - -	return r; -} - -static void service_record_free(void *data, void *udata) -{ -	struct service_record *r = data; - -	if (!r) -		return; - -	if (r->record) -		sdp_record_free(r->record); - -	free(r); -} - -/* - * This function doesn't check service record pattern - */ -static int service_record_cmp(const void *data, const void *udata) -{ -	const struct service_record *a = data; -	const struct service_record *b = udata; - -	if (b->record) { -		if (b->record->handle != 0xffffffff && -		    b->record->handle != a->record->handle) -			return -1; -	} - -	return 0; -} - -static void service_provider_free(void *data, void *udata) -{ -	struct service_provider *p1 = data; -	struct service_provider *p2 = udata; - -	if (!p1) -		return; - -	/* Check if the provider match */ -	if (p2) { -		if (p2->owner && strcmp(p2->owner, p1->owner)) -			return; -		if (p2->prov && strcmp(p2->prov, p1->prov)) -			return; -	} - -	if (p1->owner) -		free(p1->owner); - -	if (p1->prov) -		free(p1->prov); - -	if (p1->lrec) { -		slist_foreach(p1->lrec, service_record_free, NULL); -		slist_free(p1->lrec); -	} - -	free(p1); -} - -static struct service_provider *service_provider_new(const char *owner, const char *prov) -{ -	struct service_provider *p; - -	if (!prov) -		return NULL; - -	p = malloc(sizeof(struct service_provider)); -	if (!p) -		return NULL; - -	memset(p, 0, sizeof(*p)); -	if (owner) { -		p->owner = strdup(owner); -		if (!p->owner) -			goto fail; -	} - -	if (prov) { -		p->prov = strdup(prov); -		if (!p->prov) -			goto fail; -	} - -	return p; - -fail: -	service_provider_free(p, NULL); -	return NULL; -} - -static int service_provider_cmp(const void *data, const void *udata) -{ -	const struct service_provider *a = data; -	const struct service_provider *b = udata; -	int ret; - -	if (b->owner) { -		if (!a->owner) -			return -1; -		ret = strcmp(a->owner, b->owner); -		if (ret) -			return ret; -	} - -	if (b->prov) { -		if (!a->prov) -			return -1; -		ret = strcmp(a->prov, b->prov); -		if (ret) -			return ret; -	} - -	return 0; -} -  static const char *get_address_from_message(DBusConnection *conn, DBusMessage *msg)  {  	struct adapter *adapter; @@ -436,47 +247,6 @@ static int sdp_store_record(const char *src, const char *dst, uint32_t handle, u  	return textfile_put(filename, key, value);  } -static int sdp_cache_append(const char *owner, const char *prov, sdp_record_t *rec) -{ -	struct slist *lp, *lr; -	struct service_provider *p; -	struct service_provider psearch; -	struct service_record r, *sr; - -	if (!prov || !rec) -		return -1; - -	memset(&psearch, 0, sizeof(psearch)); -	psearch.owner = (char *) owner; -	psearch.prov = (char *) prov; - -	lp = slist_find(sdp_cache, &psearch, service_provider_cmp); -	if (!lp) { -		p = service_provider_new(owner, prov); -		sdp_cache = slist_append(sdp_cache, p); -	} else -		p = lp->data; - -	/* check if the service record already belongs to the cache */ -	r.record = sdp_record_alloc(); -	r.record->handle = rec->handle; -	lr = slist_find(p->lrec, &r, service_record_cmp); -	sdp_record_free(r.record); - -	if (lr) { -		/* overwrite the record instead of compare */ -		sr = lr->data; -		sdp_record_free(sr->record); -		sr->record = rec; -	} else { -		/* create a new entry */ -		sr = service_record_new(rec); -		p->lrec = slist_append(p->lrec, sr); -	} - -	return 0; -} -  static void transaction_context_free(void *udata)  {  	struct transaction_context *ctxt = udata; @@ -541,43 +311,6 @@ static inline void get_record_data_call_cb(get_record_data_t *d,  	d->cb(rec, d->data, err);  } -static void owner_exited(const char *owner, struct adapter *adapter) -{ -	struct slist *lp, *next, *lr; -	struct service_provider *p; -	bdaddr_t sba; -	int err = 0; -	debug("SDP provider owner %s exited", owner); - -	for (lp = sdp_cache; lp; lp = next) { - -		next = lp->next; -		p = lp->data; - -		if (!p->owner || strcmp(p->owner, owner)) -			continue; - -		/* -		 * Unregister all service records related to this owner. -		 * One owner can use multiple local adapter(provider) -		 */ -		str2ba(adapter->address, &sba); -		for (lr = p->lrec; lr; lr = lr->next) { -			struct service_record *r = lr->data; -			if (sdp_service_unregister(&sba, r->record, &err) < 0) -				error("unregister error: %s (%d)", strerror(err), err); -			else -				/* free inside the library */ -				r->record = NULL; -		} - -		/* remove from the cache */ -		sdp_cache = slist_remove(sdp_cache, p); - -		service_provider_free(p, NULL); -	} -} -  static gboolean search_process_cb(GIOChannel *chan,  				GIOCondition cond, void *udata)  { @@ -670,8 +403,6 @@ static void remote_svc_rec_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp  	sdp_store_record(src, dst, rec->handle, rsp, size); -	sdp_cache_append(NULL, dst, rec); -  	for (i = 0; i < size; i++)  		dbus_message_iter_append_basic(&array_iter,  				DBUS_TYPE_BYTE, &rsp[i]); @@ -740,8 +471,6 @@ static void remote_svc_rec_completed_xml_cb(uint8_t type, uint16_t err,  	sdp_store_record(src, dst, rec->handle, rsp, size); -	sdp_cache_append(NULL, dst, rec); -  	memset(&result, 0, sizeof(sdp_buf_t));  	convert_sdp_record_to_xml(rec, &result, append_and_grow_string); @@ -833,87 +562,6 @@ failed:  	transaction_context_free(ctxt);  } -static void search_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata) -{ -	struct transaction_context *ctxt = udata; -	char identifier[MAX_IDENTIFIER_LEN]; -	const char *ptr = identifier; -	DBusMessage *reply; -	DBusMessageIter iter, array_iter; -	const char *dst; -	uint8_t *pdata; -	int csrc, tsrc; - -	if (!ctxt) -		return; - -	if (err == 0xffff) { -		/* Check for protocol error or I/O error */ -		int sdp_err = sdp_get_error(ctxt->session); -		if (sdp_err < 0) { -			error("search failed: Invalid session!"); -			error_failed(ctxt->conn, ctxt->rq, EINVAL); -			goto failed; -		} - -		error("search failed: %s (%d)", strerror(sdp_err), sdp_err); -		error_failed(ctxt->conn, ctxt->rq, sdp_err); -		goto failed; -	} - -	if (type == SDP_ERROR_RSP) { -		error_sdp_failed(ctxt->conn, ctxt->rq, err); -		goto failed; -	} - -	/* check response PDU ID */ -	if (type != SDP_SVC_SEARCH_RSP) { -		error("SDP error: %s (%d)", strerror(EPROTO), EPROTO); -		error_failed(ctxt->conn, ctxt->rq, EPROTO); -		goto failed; -	} - -	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); - -	pdata = rsp; - -	tsrc = ntohs(bt_get_unaligned((uint16_t *) pdata)); -	if (tsrc <= 0) -		goto done; - -	pdata += sizeof(uint16_t); - -	csrc = ntohs(bt_get_unaligned((uint16_t *) pdata)); -	if (csrc <= 0) -		goto done; - -	pdata += sizeof(uint16_t); - -	do { -		uint32_t handle = ntohl(bt_get_unaligned((uint32_t*)pdata)); -		pdata += sizeof(uint32_t); - -		snprintf(identifier, MAX_IDENTIFIER_LEN, "%s/0x%x", dst, handle); - -		dbus_message_iter_append_basic(&array_iter, -				DBUS_TYPE_STRING, &ptr); -	} while (--tsrc); - -done: -	dbus_message_iter_close_container(&iter, &array_iter); -	send_message_and_unref(ctxt->conn, reply); - -failed: -	transaction_context_free(ctxt); -} -  static gboolean sdp_client_connect_cb(GIOChannel *chan,  					GIOCondition cond, void *udata)  { @@ -1185,509 +833,6 @@ DBusHandlerResult get_remote_svc_handles(DBusConnection *conn, DBusMessage *msg,  	return DBUS_HANDLER_RESULT_HANDLED;  } -static int get_identifiers_conn_cb(struct transaction_context *ctxt) -{ -	sdp_list_t *search = NULL; -	uuid_t uuid; -	int err = 0; - -	if (sdp_set_notify(ctxt->session, search_completed_cb, ctxt) < 0) { -		err = -EINVAL; -		goto fail; -	} - -	sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); -	search = sdp_list_append(0, &uuid); - -	/* Create/send the search request and set the callback to indicate the request completion */ -	if (sdp_service_search_async(ctxt->session, search, 64) < 0) { -		err = -sdp_get_error(ctxt->session); -		goto fail; -	} - -fail: -	if (search) -		sdp_list_free(search, NULL); - -	return err; -} - -static DBusHandlerResult get_identifiers(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	struct adapter *adapter = data; -	const char *dst; -	int err = 0; - -	if (!dbus_message_get_args(msg, NULL, -			DBUS_TYPE_STRING, &dst, -			DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	/* in progress is not working properly */ -	if (find_pending_connect(dst)) -		return error_service_search_in_progress(conn, msg); - -	if (!connect_request(conn, msg, adapter->dev_id, -				dst, get_identifiers_conn_cb, &err)) { -		error("Search request failed: %s (%d)", strerror(err), err); -		return error_failed(conn, msg, err); -	} - -	return DBUS_HANDLER_RESULT_HANDLED; -} - -static int get_identifiers_by_service_conn_cb(struct transaction_context *ctxt) -{ -	sdp_list_t *search = NULL; -	const char *dst, *svc; -	uuid_t uuid; -	uint16_t class; -	int err = 0; - -	if (sdp_set_notify(ctxt->session, search_completed_cb, ctxt) < 0) { -		err = -EINVAL; -		goto fail; -	} - -	dbus_message_get_args(ctxt->rq, NULL, -				DBUS_TYPE_STRING, &dst, -				DBUS_TYPE_STRING, &svc, -				DBUS_TYPE_INVALID); - -	class = sdp_str2svclass(svc); -	sdp_uuid16_create(&uuid, class); -	search = sdp_list_append(0, &uuid); - -	/* Create/send the search request and set the callback to indicate the request completion */ -	if (sdp_service_search_async(ctxt->session, search, 64) < 0) { -		err = -sdp_get_error(ctxt->session); -		goto fail; -	} - -fail: -	if (search) -		sdp_list_free(search, NULL); - -	return err; -} - -static DBusHandlerResult get_identifiers_by_service(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	struct adapter *adapter = data; -	DBusMessage *reply; -	DBusMessageIter iter, array_iter; -	struct slist *lp; -	struct slist *lr; -	struct service_provider *p; -	struct service_record *r; -	char identifier[MAX_IDENTIFIER_LEN]; -	const char *ptr = identifier; -	const char *dst, *svc; -	int err = 0, nrec = 0; -	uint32_t class; -	uuid_t uuid; - -	if (!dbus_message_get_args(msg, NULL, -			DBUS_TYPE_STRING, &dst, -			DBUS_TYPE_STRING, &svc, -			DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	class = sdp_str2svclass(svc); -	if (!class) { -		error("Invalid service class name"); -		return error_invalid_arguments(conn, msg); -	} - -	sdp_uuid16_create(&uuid, class); - -	p = service_provider_new(NULL, dst); -	if (!p) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	/* FIXME: return cache entry or query again? */ -	lp = slist_find(sdp_cache, p, service_provider_cmp); -	service_provider_free(p, NULL); - -	if (!lp) -		goto search_request; - -	reply = dbus_message_new_method_return(msg); -	dbus_message_iter_init_append(reply, &iter); -	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, -			DBUS_TYPE_STRING_AS_STRING, &array_iter); - -	p = lp->data; -	for (lr = p->lrec; lr; lr = lr->next) { -		sdp_list_t *ls; -		uuid_t *puuid; -		r = lr->data; -		/* check if the pattern match */ -		if (sdp_get_service_classes(r->record, &ls)) -			continue; - -		puuid = (uuid_t *) ls->data; - -		if (sdp_uuid16_cmp(puuid, &uuid) == 0) { -			snprintf(identifier, MAX_IDENTIFIER_LEN, "%s/0x%x", p->prov, r->record->handle); -			dbus_message_iter_append_basic(&array_iter, -					DBUS_TYPE_STRING, &ptr); -			nrec++; -		} - -		sdp_list_free(ls, free); - -	} - -	dbus_message_iter_close_container(&iter, &array_iter); - -	if (nrec > 0) -		return send_message_and_unref(conn, reply); - -	/* no record found: request search */ -	dbus_message_unref(reply); - -search_request: -	if (find_pending_connect(dst)) -		return error_service_search_in_progress(conn, msg); - -	if (!connect_request(conn, msg, adapter->dev_id, -			dst, get_identifiers_by_service_conn_cb, &err)) { -		error("Search request failed: %s (%d)", strerror(err), err); -		return error_failed(conn, msg, err); -	} - -	return DBUS_HANDLER_RESULT_HANDLED; - -} - -#if 0 -static int uuid_cmp(const void *key1, const void *key2) -{ -	uuid_t *a, *b; -	int ret_val; - -	/* converting to uuid128 */ -	a = sdp_uuid_to_uuid128((uuid_t *) key1); -	b = sdp_uuid_to_uuid128((uuid_t *) key2); - -	ret_val = sdp_uuid128_cmp(a, b); - -	bt_free(a); -	bt_free(b); - -	return ret_val; -} - -static sdp_record_t *find_record_by_uuid(const char *address, uuid_t *uuid) -{ -	struct slist *lp, *lr; -	struct service_provider *p; -	struct service_record *r; -	sdp_list_t *list = NULL; - -	for (lp = sdp_cache; lp; lp = lp->next) { -		p = lp->data; -		if (strcmp(p->prov, address)) -			continue; - -		for (lr = p->lrec; lr; lr = lr->next) { -			r = lr->data; -			/* Check whether the record has the correct uuid */ -			if (sdp_get_service_classes(r->record, &list) != 0) -				continue; - -			if (sdp_list_find(list, uuid, uuid_cmp)) -				return r->record; -		} -	} - -	return NULL; -} -#endif - -static sdp_record_t *find_record_by_handle(const char *address, -						uint32_t handle) -{ -	struct slist *lp, *lr; -	struct service_provider *p; -	struct service_record *r; - -	for (lp = sdp_cache; lp; lp = lp->next) { -		p = lp->data; -		if (strcmp(p->prov, address)) -			continue; - -		for (lr = p->lrec; lr; lr = lr->next) { -			r = lr->data; -			if (r->record->handle == handle) -				return r->record; -		} -	} - -	return NULL; -} - -static DBusHandlerResult get_uuid(DBusConnection *conn, -					 DBusMessage *msg, void *data) -{ -	char uuid_str[MAX_LEN_UUID_STR]; -	char address[18]; -	sdp_list_t *ls; -	DBusMessage *reply; -	sdp_record_t *rec; -	char *ptr = uuid_str; -	const char *identifier; -	uint32_t handle; - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &identifier, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	if (str2identifier(identifier, address, &handle) != 0) -		return error_invalid_arguments(conn, msg); - -	rec = find_record_by_handle(address, handle); -	if (!rec) -		return error_record_does_not_exist(conn, msg); - -	memset(uuid_str, 0, MAX_LEN_UUID_STR); - -	reply = dbus_message_new_method_return(msg); - -	if (sdp_get_service_classes(rec, &ls) == 0) { -		char tmp_str[MAX_LEN_UUID_STR]; -		uuid_t *uuid = (uuid_t *) ls->data; - -		if (sdp_uuid2strn(uuid, tmp_str, MAX_LEN_UUID_STR) != 0) -			error("Can't convert UUID to string!"); -		else -			snprintf(uuid_str, MAX_LEN_UUID_STR, "0x%s", tmp_str); - -		sdp_list_free(ls, free); -	} - -	dbus_message_append_args(reply, -			DBUS_TYPE_STRING, &ptr, -			DBUS_TYPE_INVALID); - -	return send_message_and_unref(conn, reply); -} - -static DBusHandlerResult get_name(DBusConnection *conn, -		DBusMessage *msg, void *data) -{ -	char address[18]; -	DBusMessage *reply; -	sdp_record_t *rec; -	sdp_list_t *ls; -	char name[] = ""; -	const char *ptr = name; -	const char *identifier; -	uuid_t *puuid; -	uint32_t handle; - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &identifier, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	if (str2identifier(identifier, address, &handle) != 0) -		return error_invalid_arguments(conn, msg); - -	rec = find_record_by_handle(address, handle); -	if (!rec) -		return error_record_does_not_exist(conn, msg); - -	if ((sdp_get_service_classes(rec, &ls)) < 0) { -		return error_failed(conn, msg, errno); -	} - -	puuid = (uuid_t *) ls->data; - -	ptr = sdp_svclass2str(puuid->value.uuid16); -	sdp_list_free(ls, free); - -	/* return empty string for non supported services */ -	if (!ptr) -		ptr = name; - -	/* FIXME: it should return the service name attribute instead of the short service name */ -	reply = dbus_message_new_method_return(msg); -	dbus_message_append_args(reply, -			DBUS_TYPE_STRING, &ptr, -			DBUS_TYPE_INVALID); - -	return send_message_and_unref(conn, reply); -} - -static DBusHandlerResult register_rfcomm(DBusConnection *conn, -		DBusMessage *msg, void *data) -{ -	struct adapter *adapter = data; -	struct service_provider psearch; -	DBusMessage *reply; -	sdp_record_t *rec; -	const char *owner, *name; -	char identifier[MAX_IDENTIFIER_LEN]; -	const char *ptr = identifier; -	bdaddr_t sba; -	int err = 0; -	uint8_t channel; - -	owner = dbus_message_get_sender(msg); - -	if (!dbus_message_get_args(msg, NULL, -			DBUS_TYPE_STRING, &name, -			DBUS_TYPE_BYTE, &channel, -			DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	str2ba(adapter->address, &sba); -	/* register service */ -	if (!(rec = sdp_service_register(name, &sba, channel, &err))) { -		dbus_message_unref(reply); -		error("service register error: %s (%d)", strerror(err), err); -		if (err == EINVAL) -			return error_invalid_arguments(conn, msg); -		else -			return error_failed(conn, msg, err); -	} - -	/* Only add a D-Bus unique name listener if there isn't one already registered */ -	memset(&psearch, 0, sizeof(psearch)); -	psearch.owner = (char *) owner; - -	if (!slist_find(sdp_cache, &psearch, service_provider_cmp)) -		name_listener_add(conn, owner, (name_cb_t) owner_exited, adapter); - -	/* add record in the cache */ -	sdp_cache_append(owner, adapter->address, rec); -	snprintf(identifier, MAX_IDENTIFIER_LEN, "%s/0x%x", adapter->address, rec->handle); -	dbus_message_append_args(reply, -			DBUS_TYPE_STRING, &ptr, -			DBUS_TYPE_INVALID); - -	return send_message_and_unref(conn, reply); -} - -static DBusHandlerResult unregister_rfcomm(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	char address[18]; -	struct adapter *adapter = data; -	struct service_provider *p, psearch; -	struct service_record rsearch, *r; -	sdp_record_t record; -	struct slist *lp, *lr; -	DBusMessage *reply; -	const char *owner, *identifier; -	bdaddr_t sba; -	int err = 0; -	uint32_t handle; - -	owner = dbus_message_get_sender(msg); - -	if (!dbus_message_get_args(msg, NULL, -			DBUS_TYPE_STRING, &identifier, -			DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	if (str2identifier(identifier, address, &handle) != 0) -		return error_invalid_arguments(conn, msg); - -	/* check if the local adapter match */ -	if (strcmp(address, adapter->address)) -		return error_not_authorized(conn, msg); - -	memset(&psearch, 0, sizeof(psearch)); - -	psearch.prov = address; -	psearch.owner = (char *) owner; - -	lp = slist_find(sdp_cache, &psearch, service_provider_cmp); -	if (!lp) -		return error_service_does_not_exist(conn, msg); - -	p = lp->data; - -	rsearch.record = &record; -	record.handle = handle; -	lr = slist_find(p->lrec, &rsearch, service_record_cmp); -	if (!lr) -		return error_service_does_not_exist(conn, msg); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	r = lr->data; -	str2ba(adapter->address, &sba); -	if (sdp_service_unregister(&sba, r->record, &err) < 0) -		error("service unregister error: %s (%d)", strerror(err), err); -	else -		r->record = NULL; - -	/* Remove the service record */ -	service_record_free(r, NULL); -	p->lrec = slist_remove(p->lrec, r); - -	/* if the service record is empty remove the provider */ -	if (!p->lrec) { -		sdp_cache = slist_remove(sdp_cache, p); -		service_provider_free(p, NULL); -	} - -	psearch.prov = NULL; - -	/* Only remove the D-Bus unique name listener if there are no more record using this name */ -	if (!slist_find(sdp_cache, &psearch, service_provider_cmp)) -		name_listener_remove(conn, owner, (name_cb_t) owner_exited, adapter); - -	return send_message_and_unref(conn, reply); -} - -static struct service_data sdp_services[] = { -	{ "GetIdentifiers",		get_identifiers			}, -	{ "GetIdentifiersByService",	get_identifiers_by_service	}, -	{ "GetUUID",			get_uuid			}, -	{ "GetName",			get_name			}, -	{ "RegisterRFCOMM",		register_rfcomm			}, -	{ "UnregisterRFCOMM",		unregister_rfcomm		}, -	{ NULL, NULL } -}; - -DBusHandlerResult handle_sdp_method(DBusConnection *conn, DBusMessage *msg, void *data) -{ -	const struct adapter *adapter = data; -	service_handler_func_t handler; - -	if (!hcid_dbus_use_experimental()) -		return error_unknown_method(conn, msg); - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	handler = find_service_handler(sdp_services, msg); - -	if (handler) -		return handler(conn, msg, data); - -	return error_unknown_method(conn, msg); -} - -void dbus_sdp_cache_free() -{ -	slist_foreach(sdp_cache, service_provider_free, NULL); -} -  /*   * Internal async get remote service record implementation   */ diff --git a/hcid/dbus-sdp.h b/hcid/dbus-sdp.h index 4760c900..b3be2091 100644 --- a/hcid/dbus-sdp.h +++ b/hcid/dbus-sdp.h @@ -28,15 +28,11 @@  #include <bluetooth/bluetooth.h>  #include <bluetooth/sdp.h> -#define SDP_INTERFACE "org.bluez.SDP" -  typedef enum {  	SDP_FORMAT_XML,  	SDP_FORMAT_BINARY  } sdp_format_t; -DBusHandlerResult handle_sdp_method(DBusConnection *conn, DBusMessage *msg, void *data); -  DBusHandlerResult get_remote_svc_handles(DBusConnection *conn, DBusMessage *msg, void *data);  DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data, sdp_format_t format); | 
