summaryrefslogtreecommitdiffstats
path: root/sdpd
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-08-05 02:59:23 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-08-05 02:59:23 +0000
commit028619a565a8dd60da011170f8ce326de78a1e47 (patch)
tree5688c11481f50ae3f16194dba8f3dbbffc46450e /sdpd
parentb0ba2fc57a3da851aa0bb7ff6bbf78347c838221 (diff)
Add support for device specific SDP records
Diffstat (limited to 'sdpd')
-rw-r--r--sdpd/main.c16
-rw-r--r--sdpd/request.c10
-rw-r--r--sdpd/sdpd.h4
-rw-r--r--sdpd/servicedb.c138
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;