diff options
Diffstat (limited to 'sdpd')
-rw-r--r-- | sdpd/main.c | 2 | ||||
-rw-r--r-- | sdpd/sdpd.h | 4 | ||||
-rw-r--r-- | sdpd/server.c | 18 | ||||
-rw-r--r-- | sdpd/service.c | 63 |
4 files changed, 82 insertions, 5 deletions
diff --git a/sdpd/main.c b/sdpd/main.c index 4027ae96..856c6cb3 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -139,7 +139,7 @@ int main(int argc, char *argv[]) event_loop = g_main_loop_new(NULL, FALSE); - if (start_sdp_server(mtu, flags) < 0) { + if (start_sdp_server(mtu, NULL, flags) < 0) { g_main_loop_unref(event_loop); exit(1); } diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 8ec47b1a..13aa2c74 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -46,6 +46,8 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp); void register_public_browse_group(int public); void register_server_service(int public); +void register_device_id(const uint16_t vendor, const uint16_t product, + const uint16_t version); typedef struct { uint32_t timestamp; @@ -80,7 +82,7 @@ uint32_t sdp_get_time(); #define SDP_SERVER_MASTER (1 << 1) #define SDP_SERVER_PUBLIC (1 << 2) -int start_sdp_server(uint16_t mtu, uint32_t flags); +int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags); void stop_sdp_server(void); int add_record_to_server(sdp_record_t *rec); diff --git a/sdpd/server.c b/sdpd/server.c index 2abcc6bc..fab17f00 100644 --- a/sdpd/server.c +++ b/sdpd/server.c @@ -31,6 +31,7 @@ #include <stdio.h> #include <errno.h> #include <unistd.h> +#include <stdlib.h> #include <sys/stat.h> #include <sys/socket.h> @@ -215,7 +216,7 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da return TRUE; } -int start_sdp_server(uint16_t mtu, uint32_t flags) +int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags) { int compat = flags & SDP_SERVER_COMPAT; int master = flags & SDP_SERVER_MASTER; @@ -228,6 +229,21 @@ int start_sdp_server(uint16_t mtu, uint32_t flags) return -1; } + if (did && strlen(did) > 0) { + const char *ptr = did; + uint16_t vid = 0x0000, pid = 0x0000, ver = 0x0000; + + vid = (uint16_t) strtol(ptr, NULL, 16); + ptr = strchr(ptr, ':'); + if (ptr) { + pid = (uint16_t) strtol(ptr + 1, NULL, 16); + ptr = strchr(ptr + 1, ':'); + if (ptr) + ver = (uint16_t) strtol(ptr + 1, NULL, 16); + register_device_id(vid, pid, ver); + } + } + l2cap_io = g_io_channel_unix_new(l2cap_sock); g_io_channel_set_close_on_unref(l2cap_io, TRUE); diff --git a/sdpd/service.c b/sdpd/service.c index 69c5242b..8c8c3a73 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -102,7 +102,8 @@ void register_public_browse_group(int public) sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); add_lang_attr(browse); - sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", "Root of public browse hierarchy"); + sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", + "Root of public browse hierarchy"); sdp_uuid16_create(&bgscid, BROWSE_GRP_DESC_SVCLASS_ID); browselist = sdp_list_append(0, &bgscid); @@ -140,7 +141,8 @@ void register_server_service(int public) server->handle = SDP_SERVER_RECORD_HANDLE; sdp_record_add(BDADDR_ANY, server); - sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); + sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, + sdp_data_alloc(SDP_UINT32, &server->handle)); /* * Add all attributes to service record. (No need to commit since we @@ -207,6 +209,63 @@ void register_server_service(int public) update_db_timestamp(); } +void register_device_id(const uint16_t vendor, const uint16_t product, + const uint16_t version) +{ + const uint16_t spec = 0x0102, source = 0x0002; + const uint8_t primary = 1; + sdp_list_t *class_list, *group_list, *profile_list; + uuid_t class_uuid, group_uuid; + sdp_data_t *sdp_data, *primary_data, *source_data; + sdp_data_t *spec_data, *vendor_data, *product_data, *version_data; + sdp_profile_desc_t profile; + sdp_record_t *record = sdp_record_alloc(); + + info("Adding device id record for %04x:%04x", vendor, product); + + record->handle = sdp_next_handle(); + + sdp_record_add(BDADDR_ANY, record); + sdp_data = sdp_data_alloc(SDP_UINT32, &record->handle); + sdp_attr_add(record, SDP_ATTR_RECORD_HANDLE, sdp_data); + + sdp_uuid16_create(&class_uuid, PNP_INFO_SVCLASS_ID); + class_list = sdp_list_append(0, &class_uuid); + sdp_set_service_classes(record, class_list); + sdp_list_free(class_list, NULL); + + sdp_uuid16_create(&group_uuid, PUBLIC_BROWSE_GROUP); + group_list = sdp_list_append(NULL, &group_uuid); + sdp_set_browse_groups(record, group_list); + sdp_list_free(group_list, NULL); + + sdp_uuid16_create(&profile.uuid, PNP_INFO_PROFILE_ID); + profile.version = spec; + profile_list = sdp_list_append(NULL, &profile); + sdp_set_profile_descs(record, profile_list); + sdp_list_free(profile_list, NULL); + + spec_data = sdp_data_alloc(SDP_UINT16, &spec); + sdp_attr_add(record, 0x0200, spec_data); + + vendor_data = sdp_data_alloc(SDP_UINT16, &vendor); + sdp_attr_add(record, 0x0201, vendor_data); + + product_data = sdp_data_alloc(SDP_UINT16, &product); + sdp_attr_add(record, 0x0202, product_data); + + version_data = sdp_data_alloc(SDP_UINT16, &version); + sdp_attr_add(record, 0x0203, version_data); + + primary_data = sdp_data_alloc(SDP_BOOL, &primary); + sdp_attr_add(record, 0x0204, primary_data); + + source_data = sdp_data_alloc(SDP_UINT16, &source); + sdp_attr_add(record, 0x0205, source_data); + + update_db_timestamp(); +} + int add_record_to_server(sdp_record_t *rec) { sdp_data_t *data; |