Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bluetooth/sdpd/provider.c
103499 views
1
/*-
2
* provider.c
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
*
6
* Copyright (c) 2004 Maksim Yevmenkin <[email protected]>
7
* All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
* SUCH DAMAGE.
29
*
30
* $Id: provider.c,v 1.5 2004/01/13 01:54:39 max Exp $
31
*/
32
33
#include <sys/queue.h>
34
#define L2CAP_SOCKET_CHECKED
35
#include <bluetooth.h>
36
#include <string.h>
37
#include <stdlib.h>
38
#include "profile.h"
39
#include "provider.h"
40
41
static TAILQ_HEAD(, provider) providers = TAILQ_HEAD_INITIALIZER(providers);
42
static uint32_t change_state = 0;
43
static uint32_t handle = 0;
44
45
/*
46
* Register Service Discovery provider.
47
* Should not be called more the once.
48
*/
49
50
int32_t
51
provider_register_sd(int32_t fd)
52
{
53
extern profile_t sd_profile_descriptor;
54
extern profile_t bgd_profile_descriptor;
55
56
provider_p sd = calloc(1, sizeof(*sd));
57
provider_p bgd = calloc(1, sizeof(*bgd));
58
59
if (sd == NULL || bgd == NULL) {
60
if (sd != NULL)
61
free(sd);
62
63
if (bgd != NULL)
64
free(bgd);
65
66
return (-1);
67
}
68
69
sd->profile = &sd_profile_descriptor;
70
bgd->handle = 0;
71
sd->fd = fd;
72
TAILQ_INSERT_HEAD(&providers, sd, provider_next);
73
74
bgd->profile = &bgd_profile_descriptor;
75
bgd->handle = 1;
76
sd->fd = fd;
77
TAILQ_INSERT_AFTER(&providers, sd, bgd, provider_next);
78
79
change_state ++;
80
81
return (0);
82
}
83
84
/*
85
* Register new provider for a given profile, bdaddr and session.
86
*/
87
88
provider_p
89
provider_register(profile_p const profile, bdaddr_p const bdaddr, int32_t fd,
90
uint8_t const *data, uint32_t datalen)
91
{
92
provider_p provider = calloc(1, sizeof(*provider));
93
94
if (provider != NULL) {
95
provider->data = malloc(datalen);
96
if (provider->data != NULL) {
97
provider->profile = profile;
98
memcpy(provider->data, data, datalen);
99
100
/*
101
* Record handles 0x0 and 0x1 are reserved
102
* for SDP itself
103
*/
104
105
if (++ handle <= 1)
106
handle = 2;
107
108
provider->handle = handle;
109
110
memcpy(&provider->bdaddr, bdaddr,
111
sizeof(provider->bdaddr));
112
provider->fd = fd;
113
114
TAILQ_INSERT_TAIL(&providers, provider, provider_next);
115
change_state ++;
116
} else {
117
free(provider);
118
provider = NULL;
119
}
120
}
121
122
return (provider);
123
}
124
125
/*
126
* Unregister provider
127
*/
128
129
void
130
provider_unregister(provider_p provider)
131
{
132
TAILQ_REMOVE(&providers, provider, provider_next);
133
if (provider->data != NULL)
134
free(provider->data);
135
free(provider);
136
change_state ++;
137
}
138
139
/*
140
* Update provider data
141
*/
142
143
int32_t
144
provider_update(provider_p provider, uint8_t const *data, uint32_t datalen)
145
{
146
uint8_t *new_data = (uint8_t *) realloc(provider->data, datalen);
147
148
if (new_data == NULL)
149
return (-1);
150
151
memcpy(new_data, data, datalen);
152
provider->data = new_data;
153
154
return (0);
155
}
156
157
/*
158
* Get a provider for given record handle
159
*/
160
161
provider_p
162
provider_by_handle(uint32_t handle)
163
{
164
provider_p provider = NULL;
165
166
TAILQ_FOREACH(provider, &providers, provider_next)
167
if (provider->handle == handle)
168
break;
169
170
return (provider);
171
}
172
173
/*
174
* Cursor access
175
*/
176
177
provider_p
178
provider_get_first(void)
179
{
180
return (TAILQ_FIRST(&providers));
181
}
182
183
provider_p
184
provider_get_next(provider_p provider)
185
{
186
return (TAILQ_NEXT(provider, provider_next));
187
}
188
189
/*
190
* Return change state
191
*/
192
193
uint32_t
194
provider_get_change_state(void)
195
{
196
return (change_state);
197
}
198
199
200