CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/lib/uuid.c
Views: 3959
1
/*
2
*
3
* BlueZ - Bluetooth protocol stack for Linux
4
*
5
* Copyright (C) 2011 Nokia Corporation
6
* Copyright (C) 2011 Marcel Holtmann <[email protected]>
7
*
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
13
*
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
*
23
*/
24
25
#ifdef HAVE_CONFIG_H
26
#include <config.h>
27
#endif
28
29
#include <string.h>
30
#include <stdlib.h>
31
#include <errno.h>
32
33
#include "uuid.h"
34
35
#if __BYTE_ORDER == __BIG_ENDIAN
36
static uint128_t bluetooth_base_uuid = {
37
.data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
38
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
39
};
40
41
#define BASE_UUID16_OFFSET 2
42
#define BASE_UUID32_OFFSET 0
43
44
#else
45
static uint128_t bluetooth_base_uuid = {
46
.data = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
47
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
48
};
49
50
#define BASE_UUID16_OFFSET 12
51
#define BASE_UUID32_OFFSET BASE_UUID16_OFFSET
52
53
#endif
54
55
static void bt_uuid16_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst)
56
{
57
dst->value.u128 = bluetooth_base_uuid;
58
dst->type = BT_UUID128;
59
60
memcpy(&dst->value.u128.data[BASE_UUID16_OFFSET],
61
&src->value.u16, sizeof(src->value.u16));
62
}
63
64
static void bt_uuid32_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst)
65
{
66
dst->value.u128 = bluetooth_base_uuid;
67
dst->type = BT_UUID128;
68
69
memcpy(&dst->value.u128.data[BASE_UUID32_OFFSET],
70
&src->value.u32, sizeof(src->value.u32));
71
}
72
73
void bt_uuid_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst)
74
{
75
switch (src->type) {
76
case BT_UUID128:
77
*dst = *src;
78
break;
79
case BT_UUID32:
80
bt_uuid32_to_uuid128(src, dst);
81
break;
82
case BT_UUID16:
83
bt_uuid16_to_uuid128(src, dst);
84
break;
85
default:
86
break;
87
}
88
}
89
90
static int bt_uuid128_cmp(const bt_uuid_t *u1, const bt_uuid_t *u2)
91
{
92
return memcmp(&u1->value.u128, &u2->value.u128, sizeof(uint128_t));
93
}
94
95
int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value)
96
{
97
memset(btuuid, 0, sizeof(bt_uuid_t));
98
btuuid->type = BT_UUID16;
99
btuuid->value.u16 = value;
100
101
return 0;
102
}
103
104
int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value)
105
{
106
memset(btuuid, 0, sizeof(bt_uuid_t));
107
btuuid->type = BT_UUID32;
108
btuuid->value.u32 = value;
109
110
return 0;
111
}
112
113
int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value)
114
{
115
memset(btuuid, 0, sizeof(bt_uuid_t));
116
btuuid->type = BT_UUID128;
117
btuuid->value.u128 = value;
118
119
return 0;
120
}
121
122
int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2)
123
{
124
bt_uuid_t u1, u2;
125
126
bt_uuid_to_uuid128(uuid1, &u1);
127
bt_uuid_to_uuid128(uuid2, &u2);
128
129
return bt_uuid128_cmp(&u1, &u2);
130
}
131
132
/*
133
* convert the UUID to string, copying a maximum of n characters.
134
*/
135
int bt_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n)
136
{
137
if (!uuid) {
138
snprintf(str, n, "NULL");
139
return -EINVAL;
140
}
141
142
switch (uuid->type) {
143
case BT_UUID16:
144
snprintf(str, n, "%.4x", uuid->value.u16);
145
break;
146
case BT_UUID32:
147
snprintf(str, n, "%.8x", uuid->value.u32);
148
break;
149
case BT_UUID128: {
150
unsigned int data0;
151
unsigned short data1;
152
unsigned short data2;
153
unsigned short data3;
154
unsigned int data4;
155
unsigned short data5;
156
157
uint128_t nvalue;
158
const uint8_t *data = (uint8_t *) &nvalue;
159
160
hton128(&uuid->value.u128, &nvalue);
161
162
memcpy(&data0, &data[0], 4);
163
memcpy(&data1, &data[4], 2);
164
memcpy(&data2, &data[6], 2);
165
memcpy(&data3, &data[8], 2);
166
memcpy(&data4, &data[10], 4);
167
memcpy(&data5, &data[14], 2);
168
169
snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
170
ntohl(data0), ntohs(data1),
171
ntohs(data2), ntohs(data3),
172
ntohl(data4), ntohs(data5));
173
}
174
break;
175
default:
176
snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
177
return -EINVAL; /* Enum type of UUID not set */
178
}
179
180
return 0;
181
}
182
183
static inline int is_uuid128(const char *string)
184
{
185
return (strlen(string) == 36 &&
186
string[8] == '-' &&
187
string[13] == '-' &&
188
string[18] == '-' &&
189
string[23] == '-');
190
}
191
192
static inline int is_uuid32(const char *string)
193
{
194
return (strlen(string) == 8 || strlen(string) == 10);
195
}
196
197
static inline int is_uuid16(const char *string)
198
{
199
return (strlen(string) == 4 || strlen(string) == 6);
200
}
201
202
static int bt_string_to_uuid16(bt_uuid_t *uuid, const char *string)
203
{
204
uint16_t u16;
205
char *endptr = NULL;
206
207
u16 = strtol(string, &endptr, 16);
208
if (endptr && *endptr == '\0') {
209
bt_uuid16_create(uuid, u16);
210
return 0;
211
}
212
213
return -EINVAL;
214
}
215
216
static int bt_string_to_uuid32(bt_uuid_t *uuid, const char *string)
217
{
218
uint32_t u32;
219
char *endptr = NULL;
220
221
u32 = strtol(string, &endptr, 16);
222
if (endptr && *endptr == '\0') {
223
bt_uuid32_create(uuid, u32);
224
return 0;
225
}
226
227
return -EINVAL;
228
}
229
230
static int bt_string_to_uuid128(bt_uuid_t *uuid, const char *string)
231
{
232
uint32_t data0, data4;
233
uint16_t data1, data2, data3, data5;
234
uint128_t n128, u128;
235
uint8_t *val = (uint8_t *) &n128;
236
237
if (sscanf(string, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
238
&data0, &data1, &data2,
239
&data3, &data4, &data5) != 6)
240
return -EINVAL;
241
242
data0 = htonl(data0);
243
data1 = htons(data1);
244
data2 = htons(data2);
245
data3 = htons(data3);
246
data4 = htonl(data4);
247
data5 = htons(data5);
248
249
memcpy(&val[0], &data0, 4);
250
memcpy(&val[4], &data1, 2);
251
memcpy(&val[6], &data2, 2);
252
memcpy(&val[8], &data3, 2);
253
memcpy(&val[10], &data4, 4);
254
memcpy(&val[14], &data5, 2);
255
256
ntoh128(&n128, &u128);
257
258
bt_uuid128_create(uuid, u128);
259
260
return 0;
261
}
262
263
int bt_string_to_uuid(bt_uuid_t *uuid, const char *string)
264
{
265
if (is_uuid128(string))
266
return bt_string_to_uuid128(uuid, string);
267
else if (is_uuid32(string))
268
return bt_string_to_uuid32(uuid, string);
269
else if (is_uuid16(string))
270
return bt_string_to_uuid16(uuid, string);
271
272
return -EINVAL;
273
}
274
275
int bt_uuid_strcmp(const void *a, const void *b)
276
{
277
return strcasecmp(a, b);
278
}
279
280