diff options
Diffstat (limited to 'hcid/dbus-sdp.c')
-rw-r--r-- | hcid/dbus-sdp.c | 855 |
1 files changed, 0 insertions, 855 deletions
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 */ |