diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2004-03-31 20:37:21 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2004-03-31 20:37:21 +0000 |
commit | c787259b854f12bd827d1e05ccde53d748d22b30 (patch) | |
tree | 2cb4057b869a31329cab5db8700a204588af6cd7 /sdpd/servicedb.c | |
parent | 5a8fbb23664d5b346164f058c9f57d5b01c0a1bb (diff) |
Add sdpd server daemon
Diffstat (limited to 'sdpd/servicedb.c')
-rw-r--r-- | sdpd/servicedb.c | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c new file mode 100644 index 00000000..d0b2b85e --- /dev/null +++ b/sdpd/servicedb.c @@ -0,0 +1,209 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>, Stephen Crane <steve.crane@rococosoft.com> + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy <guruprasad.krishnamurthy@nokia.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + Service repository. + Has methods to create and clean the repository, besides + methods to add/find/modify/delete individual entries + + Fixes: + Guruprasad Krishnamurthy <guruprasad.krishnamurthy@nokia.com> + Manel Guerrero Zapata <manel.guerrero-zapata@nokia.com> +*/ + +/* + * $Id$ + */ + +#include <malloc.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/l2cap.h> +#include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h> +#include <bluetooth/sdp_internal.h> + +#include "sdpd.h" + +static sdp_list_t *service_db; + +/* + * Ordering function called when inserting a service record. + * The service repository is a linked list in sorted order + * and the service record handle is the sort key + */ +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; + + if (!rec1 || !rec2) { + SDPERR("NULL RECORD LIST FATAL\n"); + return -1; + } + return rec1->handle - rec2->handle; +} + +/* + * Reset the service repository by deleting its contents + */ +void sdp_svcdb_reset() +{ + sdp_list_free(service_db, (sdp_free_func_t)sdp_record_free); +} + +typedef struct _indexed { + int sock; + sdp_record_t *record; +} sdp_indexed_t; + +static sdp_list_t *socket_index; + +/* + * collect all services registered over this socket + */ +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; + if (item->sock == sock) { + sdp_list_t *next = p->next; + sdp_record_remove(item->record->handle); + free(item); + if (q) + q->next = next; + else + socket_index = next; + free(p); + p = next; + } else if (item->sock > sock) + return; + else { + q = p; + p = p->next; + } + } +} + +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; + if (rec == item->record) { + free(item); + if (q) + q->next = p->next; + else + socket_index = p->next; + free(p); + return; + } + } +} + +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; + 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)); + item->sock = sock; + item->record = record; + socket_index = sdp_list_insert_sorted(socket_index, item, compare_indices); +} + +/* + * Add a service record to the repository + */ +void sdp_record_add(sdp_record_t *rec) +{ +#ifdef SDP_DEBUG + SDPDBG("Adding rec : 0x%lx\n", (long)rec); + SDPDBG("with handle : 0x%lx\n", (long)rec->handle); +#endif + service_db = sdp_list_insert_sorted(service_db, rec, record_sort); +} + +static sdp_list_t *record_locate(uint32_t handle) +{ + if (service_db) { + sdp_list_t *p; + sdp_record_t r; + + r.handle = handle; + p = sdp_list_find(service_db, &r, record_sort); + return p; + } + SDPDBG("Could not find svcRec for : 0x%x\n", handle); + return 0; +} + +/* + * Given a service record handle, find the record associated with it. + */ +sdp_record_t *sdp_record_find(uint32_t handle) +{ + sdp_list_t *p = record_locate(handle); + + if (p) + return (sdp_record_t *)p->data; + SDPDBG("Couldn't find record for : 0x%x\n", handle); + return 0; +} + +/* + * Given a service record handle, remove its record from the repository + */ +int sdp_record_remove(uint32_t handle) +{ + sdp_list_t *p = record_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; + } + } + SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); + return -1; +} + +/* + * Return a pointer to the linked list containing the records in sorted order + */ +sdp_list_t *sdp_get_record_list() +{ + return service_db; +} |