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)