diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2005-08-05 02:59:23 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2005-08-05 02:59:23 +0000 |
commit | 028619a565a8dd60da011170f8ce326de78a1e47 (patch) | |
tree | 5688c11481f50ae3f16194dba8f3dbbffc46450e /sdpd | |
parent | b0ba2fc57a3da851aa0bb7ff6bbf78347c838221 (diff) |
Add support for device specific SDP records
Diffstat (limited to 'sdpd')
-rw-r--r-- | sdpd/main.c | 16 | ||||
-rw-r--r-- | sdpd/request.c | 10 | ||||
-rw-r--r-- | sdpd/sdpd.h | 4 | ||||
-rw-r--r-- | sdpd/servicedb.c | 138 |
4 files changed, 131 insertions, 37 deletions
diff --git a/sdpd/main.c b/sdpd/main.c index 734b8bda..27d2f800 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -328,18 +328,18 @@ static inline void handle_request(int sk, uint8_t *data, int len) memset(&lo, 0, sizeof(lo)); size = sizeof(lo); getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); - req.bdaddr = sa.l2_bdaddr; - req.mtu = lo.omtu; - req.local = 0; + bacpy(&req.bdaddr, &sa.l2_bdaddr); + req.mtu = lo.omtu; + req.local = 0; memset(&sa, 0, sizeof(sa)); size = sizeof(sa); getsockname(sk, (struct sockaddr *) &sa, &size); - req.device = sa.l2_bdaddr; + bacpy(&req.device, &sa.l2_bdaddr); } else { - req.device = *BDADDR_ANY; - req.bdaddr = *BDADDR_LOCAL; - req.mtu = 2048; - req.local = 1; + bacpy(&req.device, BDADDR_ANY); + bacpy(&req.bdaddr, BDADDR_LOCAL); + req.mtu = 2048; + req.local = 1; } req.sock = sk; req.buf = data; diff --git a/sdpd/request.c b/sdpd/request.c index 356ce1d8..07051f9f 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -298,11 +298,12 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) handleSize = 0; for (; list && rsp_count < expected; list = list->next) { - sdp_record_t *rec = (sdp_record_t *)list->data; + sdp_record_t *rec = (sdp_record_t *) list->data; SDPDBG("Checking svcRec : 0x%x\n", rec->handle); - if (sdp_match_uuid(pattern, rec->pattern) > 0) { + if (sdp_match_uuid(pattern, rec->pattern) > 0 && + sdp_check_access(rec->handle, &req->device)) { rsp_count++; sdp_put_unaligned(htonl(rec->handle), (uint32_t *)pdata); pdata += sizeof(uint32_t); @@ -672,8 +673,9 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) /* no continuation state -> create new response */ sdp_list_t *p; for (p = svcList; p; p = p->next) { - sdp_record_t *rec = (sdp_record_t *)p->data; - if (sdp_match_uuid(pattern, rec->pattern) > 0) { + sdp_record_t *rec = (sdp_record_t *) p->data; + if (sdp_match_uuid(pattern, rec->pattern) > 0 && + sdp_check_access(rec->handle, &req->device)) { rsp_count++; status = extract_attrs(rec, seq, dtd, &tmpbuf); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 0bca315f..af028a4f 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -83,7 +83,9 @@ void sdp_svcdb_collect(sdp_record_t *rec); sdp_record_t *sdp_record_find(uint32_t handle); void sdp_record_add(bdaddr_t *device, sdp_record_t *rec); int sdp_record_remove(uint32_t handle); -sdp_list_t *sdp_get_record_list(); +sdp_list_t *sdp_get_record_list(void); +sdp_list_t *sdp_get_access_list(void); +int sdp_check_access(uint32_t handle, bdaddr_t *device); uint32_t sdp_next_handle(void); uint32_t sdp_get_time(); diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index c977bc81..6a1e2279 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -46,6 +46,12 @@ #include "sdpd.h" static sdp_list_t *service_db; +static sdp_list_t *access_db; + +typedef struct { + uint32_t handle; + bdaddr_t device; +} sdp_access_t; /* * Ordering function called when inserting a service record. @@ -54,22 +60,42 @@ static sdp_list_t *service_db; */ static int record_sort(const void *r1, const void *r2) { - const sdp_record_t *rec1 = (const sdp_record_t *)r1; - const sdp_record_t *rec2 = (const sdp_record_t *)r2; + const sdp_record_t *rec1 = (const sdp_record_t *) r1; + const sdp_record_t *rec2 = (const sdp_record_t *) r2; if (!rec1 || !rec2) { SDPERR("NULL RECORD LIST FATAL\n"); return -1; } + return rec1->handle - rec2->handle; } +static int access_sort(const void *r1, const void *r2) +{ + const sdp_access_t *rec1 = (const sdp_access_t *) r1; + const sdp_access_t *rec2 = (const sdp_access_t *) r2; + + if (!rec1 || !rec2) { + SDPERR("NULL RECORD LIST FATAL\n"); + return -1; + } + + return rec1->handle - rec2->handle; +} + +static void access_free(void *p) +{ + free(p); +} + /* * Reset the service repository by deleting its contents */ void sdp_svcdb_reset() { - sdp_list_free(service_db, (sdp_free_func_t)sdp_record_free); + sdp_list_free(service_db, (sdp_free_func_t) sdp_record_free); + sdp_list_free(access_db, access_free); } typedef struct _indexed { @@ -86,8 +112,8 @@ void sdp_svcdb_collect_all(int sock) { sdp_list_t *p, *q; - for (p=socket_index, q=0; p; ) { - sdp_indexed_t *item = (sdp_indexed_t *)p->data; + for (p = socket_index, q = 0; p; ) { + sdp_indexed_t *item = (sdp_indexed_t *) p->data; if (item->sock == sock) { sdp_list_t *next = p->next; sdp_record_remove(item->record->handle); @@ -111,8 +137,8 @@ void sdp_svcdb_collect(sdp_record_t *rec) { sdp_list_t *p, *q; - for (p=socket_index, q=0; p; q=p, p=p->next) { - sdp_indexed_t *item = (sdp_indexed_t *)p->data; + for (p = socket_index, q = 0; p; q = p, p = p->next) { + sdp_indexed_t *item = (sdp_indexed_t *) p->data; if (rec == item->record) { free(item); if (q) @@ -127,14 +153,14 @@ void sdp_svcdb_collect(sdp_record_t *rec) static int compare_indices(const void *i1, const void *i2) { - const sdp_indexed_t *s1 = (const sdp_indexed_t *)i1; - const sdp_indexed_t *s2 = (const sdp_indexed_t *)i2; + const sdp_indexed_t *s1 = (const sdp_indexed_t *) i1; + const sdp_indexed_t *s2 = (const sdp_indexed_t *) i2; return s1->sock - s2->sock; } void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) { - sdp_indexed_t *item = (sdp_indexed_t *)malloc(sizeof(sdp_indexed_t)); + sdp_indexed_t *item = malloc(sizeof(sdp_indexed_t)); item->sock = sock; item->record = record; socket_index = sdp_list_insert_sorted(socket_index, item, compare_indices); @@ -145,11 +171,22 @@ void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) */ void sdp_record_add(bdaddr_t *device, sdp_record_t *rec) { + sdp_access_t *dev; + #ifdef SDP_DEBUG SDPDBG("Adding rec : 0x%lx\n", (long) rec); SDPDBG("with handle : 0x%x\n", rec->handle); #endif service_db = sdp_list_insert_sorted(service_db, rec, record_sort); + + dev = malloc(sizeof(*dev)); + if (!dev) + return; + + bacpy(&dev->device, device); + dev->handle = rec->handle; + + access_db = sdp_list_insert_sorted(access_db, dev, access_sort); } static sdp_list_t *record_locate(uint32_t handle) @@ -162,8 +199,24 @@ static sdp_list_t *record_locate(uint32_t handle) p = sdp_list_find(service_db, &r, record_sort); return p; } + SDPDBG("Could not find svcRec for : 0x%x\n", handle); - return 0; + return NULL; +} + +static sdp_list_t *access_locate(uint32_t handle) +{ + if (access_db) { + sdp_list_t *p; + sdp_access_t a; + + a.handle = handle; + p = sdp_list_find(access_db, &a, access_sort); + return p; + } + + SDPDBG("Could not find access data for : 0x%x\n", handle); + return NULL; } /* @@ -171,12 +224,14 @@ static sdp_list_t *record_locate(uint32_t handle) */ sdp_record_t *sdp_record_find(uint32_t handle) { - sdp_list_t *p = record_locate(handle); + sdp_list_t *p = record_locate(handle); + + if (!p) { + SDPDBG("Couldn't find record for : 0x%x\n", handle); + return 0; + } - if (p) - return (sdp_record_t *)p->data; - SDPDBG("Couldn't find record for : 0x%x\n", handle); - return 0; + return (sdp_record_t *) p->data; } /* @@ -185,26 +240,61 @@ sdp_record_t *sdp_record_find(uint32_t handle) int sdp_record_remove(uint32_t handle) { sdp_list_t *p = record_locate(handle); + sdp_record_t *r; + sdp_access_t *a; + + if (!p) { + SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); + return -1; + } + + r = (sdp_record_t *) p->data; + if (r) + service_db = sdp_list_remove(service_db, r); + p = access_locate(handle); if (p) { - sdp_record_t *r = (sdp_record_t *)p->data; - if (r) { - service_db = sdp_list_remove(service_db, r); - return 0; - } + a = (sdp_access_t *) p->data; + if (a) + access_db = sdp_list_remove(access_db, a); } - SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); - return -1; + + return 0; } /* * Return a pointer to the linked list containing the records in sorted order */ -sdp_list_t *sdp_get_record_list() +sdp_list_t *sdp_get_record_list(void) { return service_db; } +sdp_list_t *sdp_get_access_list(void) +{ + return access_db; +} + +int sdp_check_access(uint32_t handle, bdaddr_t *device) +{ + sdp_list_t *p = access_locate(handle); + sdp_access_t *a; + + if (!p) + return 1; + + a = (sdp_access_t *) p->data; + if (!a) + return 1; + + if (bacmp(&a->device, device) && + bacmp(&a->device, BDADDR_ANY) && + bacmp(device, BDADDR_ANY)) + return 0; + + return 1; +} + uint32_t sdp_next_handle(void) { uint32_t handle = 0x10000; |