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 $ */
7 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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
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>
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.
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) {
72 sd->profile = &sd_profile_descriptor;
75 TAILQ_INSERT_HEAD(&providers, sd, provider_next);
77 bgd->profile = &bgd_profile_descriptor;
80 TAILQ_INSERT_AFTER(&providers, sd, bgd, provider_next);
88 * Register new provider for a given profile, bdaddr and session.
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
108 if (++ next_handle <= 1)
111 provider->handle = next_handle;
113 memcpy(&provider->bdaddr, bdaddr,
114 sizeof(provider->bdaddr));
117 TAILQ_INSERT_TAIL(&providers, provider, provider_next);
129 * Unregister provider
133 provider_unregister(provider_p provider)
135 TAILQ_REMOVE(&providers, provider, provider_next);
136 if (provider->data != NULL)
137 free(provider->data);
143 * Update provider data
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)
154 memcpy(new_data, data, datalen);
155 provider->data = new_data;
161 * Get a provider for given record handle
165 provider_by_handle(uint32_t handle)
167 provider_p provider = NULL;
169 TAILQ_FOREACH(provider, &providers, provider_next)
170 if (provider->handle == handle)
181 provider_get_first(void)
183 return (TAILQ_FIRST(&providers));
187 provider_get_next(provider_p provider)
189 return (TAILQ_NEXT(provider, provider_next));
193 * Return change state
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)
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)
221 for (num = 0 ; ; num++) {
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)