dma: don't block on lock/opening the mbox file, backoff instead
[dragonfly.git] / usr.sbin / sdpd / provider.c
blobcee68ff98806d0e26abebe478d22cc8396631647
1 /* $NetBSD: provider.c,v 1.2 2007/11/09 20:08:41 plunky Exp $ */
2 /* $DragonFly: src/usr.sbin/sdpd/provider.c,v 1.1 2008/01/06 21:51:30 hasso Exp $ */
4 /*
5 * provider.c
7 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com>
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 * $Id: provider.c,v 1.2 2007/11/30 07:39:37 griffin Exp $
32 * $FreeBSD: src/usr.sbin/bluetooth/sdpd/provider.c,v 1.1 2004/01/20 20:48:26 emax Exp $
35 #include <sys/queue.h>
36 #include <bluetooth.h>
37 #include <sdp.h>
38 #include <string.h>
39 #include <stdlib.h>
40 #include "profile.h"
41 #include "provider.h"
42 #include "uuid-private.h"
44 static TAILQ_HEAD(, provider) providers = TAILQ_HEAD_INITIALIZER(providers);
45 static uint32_t change_state = 0;
46 static uint32_t next_handle = 0;
49 * Register Service Discovery provider.
50 * Should not be called more the once.
53 int32_t
54 provider_register_sd(int32_t fd)
56 extern profile_t sd_profile_descriptor;
57 extern profile_t bgd_profile_descriptor;
59 provider_p sd = calloc(1, sizeof(*sd));
60 provider_p bgd = calloc(1, sizeof(*bgd));
62 if (sd == NULL || bgd == NULL) {
63 if (sd != NULL)
64 free(sd);
66 if (bgd != NULL)
67 free(bgd);
69 return (-1);
72 sd->profile = &sd_profile_descriptor;
73 bgd->handle = 0;
74 sd->fd = fd;
75 TAILQ_INSERT_HEAD(&providers, sd, provider_next);
77 bgd->profile = &bgd_profile_descriptor;
78 bgd->handle = 1;
79 sd->fd = fd;
80 TAILQ_INSERT_AFTER(&providers, sd, bgd, provider_next);
82 change_state ++;
84 return (0);
88 * Register new provider for a given profile, bdaddr and session.
91 provider_p
92 provider_register(profile_p const profile, bdaddr_t const *bdaddr, int32_t fd,
93 uint8_t const *data, uint32_t datalen)
95 provider_p provider = calloc(1, sizeof(*provider));
97 if (provider != NULL) {
98 provider->data = malloc(datalen);
99 if (provider->data != NULL) {
100 provider->profile = profile;
101 memcpy(provider->data, data, datalen);
104 * Record handles 0x0 and 0x1 are reserved
105 * for SDP itself
108 if (++ next_handle <= 1)
109 next_handle = 2;
111 provider->handle = next_handle;
113 memcpy(&provider->bdaddr, bdaddr,
114 sizeof(provider->bdaddr));
115 provider->fd = fd;
117 TAILQ_INSERT_TAIL(&providers, provider, provider_next);
118 change_state ++;
119 } else {
120 free(provider);
121 provider = NULL;
125 return (provider);
129 * Unregister provider
132 void
133 provider_unregister(provider_p provider)
135 TAILQ_REMOVE(&providers, provider, provider_next);
136 if (provider->data != NULL)
137 free(provider->data);
138 free(provider);
139 change_state ++;
143 * Update provider data
146 int32_t
147 provider_update(provider_p provider, uint8_t const *data, uint32_t datalen)
149 uint8_t *new_data = (uint8_t *) realloc(provider->data, datalen);
151 if (new_data == NULL)
152 return (-1);
154 memcpy(new_data, data, datalen);
155 provider->data = new_data;
157 return (0);
161 * Get a provider for given record handle
164 provider_p
165 provider_by_handle(uint32_t handle)
167 provider_p provider = NULL;
169 TAILQ_FOREACH(provider, &providers, provider_next)
170 if (provider->handle == handle)
171 break;
173 return (provider);
177 * Cursor access
180 provider_p
181 provider_get_first(void)
183 return (TAILQ_FIRST(&providers));
186 provider_p
187 provider_get_next(provider_p provider)
189 return (TAILQ_NEXT(provider, provider_next));
193 * Return change state
196 uint32_t
197 provider_get_change_state(void)
199 return (change_state);
203 * Match provider to UUID list
205 * all UUIDs in list must match one of the
206 * provider UUIDs or the PublicBrowseGroup
210 provider_match_uuid(provider_p provider, uint128_t *uuid, int ucount)
212 uint128_t puuid;
213 int num, max;
215 max = provider->profile->usize / sizeof(provider->profile->uuid[0]);
217 for (; ucount-- > 0 ; uuid++) {
218 if (memcmp(uuid, &uuid_public_browse_group, sizeof(*uuid)) == 0)
219 continue;
221 for (num = 0 ; ; num++) {
222 if (num == max)
223 return 0;
225 memcpy(&puuid, &uuid_base, sizeof(puuid));
226 puuid.b[2] = provider->profile->uuid[num] >> 8;
227 puuid.b[3] = provider->profile->uuid[num];
229 if (memcmp(uuid, &puuid, sizeof(*uuid)) == 0)
230 break;
234 return 1;