summaryrefslogtreecommitdiffstats
path: root/sdpd/servicedb.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2004-03-31 20:37:21 +0000
committerMarcel Holtmann <marcel@holtmann.org>2004-03-31 20:37:21 +0000
commitc787259b854f12bd827d1e05ccde53d748d22b30 (patch)
tree2cb4057b869a31329cab5db8700a204588af6cd7 /sdpd/servicedb.c
parent5a8fbb23664d5b346164f058c9f57d5b01c0a1bb (diff)
Add sdpd server daemon
Diffstat (limited to 'sdpd/servicedb.c')
-rw-r--r--sdpd/servicedb.c209
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;
+}