~ubuntu-branches/ubuntu/wily/bluez/wily

« back to all changes in this revision

Viewing changes to attrib/example.c

ImportĀ upstreamĀ versionĀ 4.81

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  BlueZ - Bluetooth protocol stack for Linux
 
4
 *
 
5
 *  Copyright (C) 2010  Nokia Corporation
 
6
 *  Copyright (C) 2010  Marcel Holtmann <marcel@holtmann.org>
 
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
 
 
26
#ifdef HAVE_CONFIG_H
 
27
#include <config.h>
 
28
#endif
 
29
 
 
30
#include <arpa/inet.h>
 
31
 
 
32
#include <bluetooth/sdp.h>
 
33
#include <bluetooth/sdp_lib.h>
 
34
 
 
35
#include <glib.h>
 
36
 
 
37
#include "log.h"
 
38
#include "attrib-server.h"
 
39
 
 
40
#include "att.h"
 
41
#include "example.h"
 
42
 
 
43
/* FIXME: Not defined by SIG? UUID128? */
 
44
#define OPCODES_SUPPORTED_UUID          0xA001
 
45
#define BATTERY_STATE_SVC_UUID          0xA002
 
46
#define BATTERY_STATE_UUID              0xA003
 
47
#define THERM_HUMIDITY_SVC_UUID         0xA004
 
48
#define MANUFACTURER_SVC_UUID           0xA005
 
49
#define TEMPERATURE_UUID                0xA006
 
50
#define FMT_CELSIUS_UUID                0xA007
 
51
#define FMT_OUTSIDE_UUID                0xA008
 
52
#define RELATIVE_HUMIDITY_UUID          0xA009
 
53
#define FMT_PERCENT_UUID                0xA00A
 
54
#define BLUETOOTH_SIG_UUID              0xA00B
 
55
#define MANUFACTURER_NAME_UUID          0xA00C
 
56
#define MANUFACTURER_SERIAL_UUID        0xA00D
 
57
#define VENDOR_SPECIFIC_SVC_UUID        0xA00E
 
58
#define VENDOR_SPECIFIC_TYPE_UUID       0xA00F
 
59
#define FMT_KILOGRAM_UUID               0xA010
 
60
#define FMT_HANGING_UUID                0xA011
 
61
 
 
62
static guint timeout_id = 0;
 
63
 
 
64
static gboolean change_battery_state(gpointer user_data)
 
65
{
 
66
        static uint8_t state =  0x05;
 
67
        uuid_t uuid;
 
68
        uint8_t atval[1];
 
69
 
 
70
        /* Battery state is being increased every 10 seconds. */
 
71
        atval[0] = state++;
 
72
        sdp_uuid16_create(&uuid, BATTERY_STATE_UUID);
 
73
        attrib_db_update(0x0110, &uuid, atval, 1);
 
74
 
 
75
        return TRUE;
 
76
}
 
77
 
 
78
static int register_attributes(void)
 
79
{
 
80
        const char *devname = "Example Device";
 
81
        const char *desc_out_temp = "Outside Temperature";
 
82
        const char *desc_out_hum = "Outside Relative Humidity";
 
83
        const char *desc_weight = "Rucksack Weight";
 
84
        const char *manufacturer_name1 = "ACME Temperature Sensor";
 
85
        const char *manufacturer_name2 = "ACME Weighing Scales";
 
86
        const char *serial1 = "237495-3282-A";
 
87
        const char *serial2 = "11267-2327A00239";
 
88
        const unsigned char char_weight_uuid[] = { 0x80, 0x88, 0xF2, 0x18, 0x90,
 
89
                0x2C, 0x45, 0x0B, 0xB6, 0xC4, 0x62, 0x89, 0x1E, 0x8C, 0x25,
 
90
                0xE9 };
 
91
        const unsigned char prim_weight_uuid[] = { 0x4F, 0x0A, 0xC0, 0x96, 0x35,
 
92
                0xD4, 0x49, 0x11, 0x96, 0x31, 0xDE, 0xA8, 0xDC, 0x74, 0xEE,
 
93
                0xFE };
 
94
        uint8_t atval[256];
 
95
        uuid_t uuid;
 
96
        int len;
 
97
        uint16_t u16;
 
98
 
 
99
        /* GAP service: primary service definition */
 
100
        sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 
101
        u16 = htons(GENERIC_ACCESS_PROFILE_ID);
 
102
        atval[0] = u16 >> 8;
 
103
        atval[1] = u16;
 
104
        attrib_db_add(0x0001, &uuid, atval, 2);
 
105
 
 
106
        /* GAP service: device name characteristic */
 
107
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
108
        u16 = htons(GATT_CHARAC_DEVICE_NAME);
 
109
        atval[0] = ATT_CHAR_PROPER_READ;
 
110
        atval[1] = 0x06;
 
111
        atval[2] = 0x00;
 
112
        atval[3] = u16 >> 8;
 
113
        atval[4] = u16;
 
114
        attrib_db_add(0x0004, &uuid, atval, 5);
 
115
 
 
116
        /* GAP service: device name attribute */
 
117
        sdp_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
 
118
        len = strlen(devname);
 
119
        strncpy((char *) atval, devname, len);
 
120
        attrib_db_add(0x0006, &uuid, atval, len);
 
121
 
 
122
        /* GATT service: primary service definition */
 
123
        sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 
124
        u16 = htons(GENERIC_ATTRIB_PROFILE_ID);
 
125
        atval[0] = u16 >> 8;
 
126
        atval[1] = u16;
 
127
        attrib_db_add(0x0010, &uuid, atval, 2);
 
128
 
 
129
        /* GATT service: attributes opcodes characteristic */
 
130
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
131
        u16 = htons(OPCODES_SUPPORTED_UUID);
 
132
        atval[0] = ATT_CHAR_PROPER_READ;
 
133
        atval[1] = 0x12;
 
134
        atval[2] = 0x00;
 
135
        atval[3] = u16 >> 8;
 
136
        atval[4] = u16;
 
137
        attrib_db_add(0x0011, &uuid, atval, 5);
 
138
 
 
139
        /* GATT service: attribute opcodes supported */
 
140
        sdp_uuid16_create(&uuid, OPCODES_SUPPORTED_UUID);
 
141
        atval[0] = 0xFF;
 
142
        atval[1] = 0x01;
 
143
        attrib_db_add(0x0012, &uuid, atval, 2);
 
144
 
 
145
        /* Battery state service: primary service definition */
 
146
        sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 
147
        u16 = htons(BATTERY_STATE_SVC_UUID);
 
148
        atval[0] = u16 >> 8;
 
149
        atval[1] = u16;
 
150
        attrib_db_add(0x0100, &uuid, atval, 2);
 
151
 
 
152
        /* Battery: battery state characteristic */
 
153
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
154
        u16 = htons(BATTERY_STATE_UUID);
 
155
        atval[0] = ATT_CHAR_PROPER_READ;
 
156
        atval[1] = 0x10;
 
157
        atval[2] = 0x01;
 
158
        atval[3] = u16 >> 8;
 
159
        atval[4] = u16;
 
160
        attrib_db_add(0x0106, &uuid, atval, 5);
 
161
 
 
162
        /* Battery: battery state attribute */
 
163
        sdp_uuid16_create(&uuid, BATTERY_STATE_UUID);
 
164
        atval[0] = 0x04;
 
165
        attrib_db_add(0x0110, &uuid, atval, 1);
 
166
 
 
167
        /* Battery: Client Characteristic Configuration */
 
168
        sdp_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
 
169
        atval[0] = 0x00;
 
170
        atval[1] = 0x00;
 
171
        attrib_db_add(0x0111, &uuid, atval, 2);
 
172
 
 
173
        timeout_id = g_timeout_add_seconds(10, change_battery_state, NULL);
 
174
 
 
175
        /* Thermometer: primary service definition */
 
176
        sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 
177
        u16 = htons(THERM_HUMIDITY_SVC_UUID);
 
178
        atval[0] = u16 >> 8;
 
179
        atval[1] = u16;
 
180
        attrib_db_add(0x0200, &uuid, atval, 2);
 
181
 
 
182
        /* Thermometer: Include */
 
183
        sdp_uuid16_create(&uuid, GATT_INCLUDE_UUID);
 
184
        u16 = htons(MANUFACTURER_SVC_UUID);
 
185
        atval[0] = 0x00;
 
186
        atval[1] = 0x05;
 
187
        atval[2] = 0x04;
 
188
        atval[3] = 0x05;
 
189
        atval[4] = u16 >> 8;
 
190
        atval[5] = u16;
 
191
        attrib_db_add(0x0201, &uuid, atval, 6);
 
192
 
 
193
        /* Thermometer: Include */
 
194
        atval[0] = 0x50;
 
195
        atval[1] = 0x05;
 
196
        atval[2] = 0x68;
 
197
        atval[3] = 0x05;
 
198
        attrib_db_add(0x0202, &uuid, atval, 4);
 
199
 
 
200
        /* Thermometer: temperature characteristic */
 
201
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
202
        u16 = htons(TEMPERATURE_UUID);
 
203
        atval[0] = ATT_CHAR_PROPER_READ;
 
204
        atval[1] = 0x04;
 
205
        atval[2] = 0x02;
 
206
        atval[3] = u16 >> 8;
 
207
        atval[4] = u16;
 
208
        attrib_db_add(0x0203, &uuid, atval, 5);
 
209
 
 
210
        /* Thermometer: temperature characteristic value */
 
211
        sdp_uuid16_create(&uuid, TEMPERATURE_UUID);
 
212
        atval[0] = 0x8A;
 
213
        atval[1] = 0x02;
 
214
        attrib_db_add(0x0204, &uuid, atval, 2);
 
215
 
 
216
        /* Thermometer: temperature characteristic format */
 
217
        sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
 
218
        u16 = htons(FMT_CELSIUS_UUID);
 
219
        atval[0] = 0x0E;
 
220
        atval[1] = 0xFE;
 
221
        atval[2] = u16 >> 8;
 
222
        atval[3] = u16;
 
223
        atval[4] = 0x01;
 
224
        u16 = htons(FMT_OUTSIDE_UUID);
 
225
        atval[5] = u16 >> 8;
 
226
        atval[6] = u16;
 
227
        attrib_db_add(0x0205, &uuid, atval, 7);
 
228
 
 
229
        /* Thermometer: characteristic user description */
 
230
        sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
 
231
        len = strlen(desc_out_temp);
 
232
        strncpy((char *) atval, desc_out_temp, len);
 
233
        attrib_db_add(0x0206, &uuid, atval, len);
 
234
 
 
235
        /* Thermometer: relative humidity characteristic */
 
236
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
237
        u16 = htons(RELATIVE_HUMIDITY_UUID);
 
238
        atval[0] = ATT_CHAR_PROPER_READ;
 
239
        atval[1] = 0x12;
 
240
        atval[2] = 0x02;
 
241
        atval[3] = u16 >> 8;
 
242
        atval[4] = u16;
 
243
        attrib_db_add(0x0210, &uuid, atval, 5);
 
244
 
 
245
        /* Thermometer: relative humidity value */
 
246
        sdp_uuid16_create(&uuid, RELATIVE_HUMIDITY_UUID);
 
247
        atval[0] = 0x27;
 
248
        attrib_db_add(0x0212, &uuid, atval, 1);
 
249
 
 
250
        /* Thermometer: relative humidity characteristic format */
 
251
        sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
 
252
        u16 = htons(FMT_PERCENT_UUID);
 
253
        atval[0] = 0x04;
 
254
        atval[1] = 0x00;
 
255
        atval[2] = u16 >> 8;
 
256
        atval[3] = u16;
 
257
        u16 = htons(BLUETOOTH_SIG_UUID);
 
258
        atval[4] = u16 >> 8;
 
259
        atval[5] = u16;
 
260
        u16 = htons(FMT_OUTSIDE_UUID);
 
261
        atval[6] = u16 >> 8;
 
262
        atval[7] = u16;
 
263
        attrib_db_add(0x0213, &uuid, atval, 8);
 
264
 
 
265
        /* Thermometer: characteristic user description */
 
266
        sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
 
267
        len = strlen(desc_out_hum);
 
268
        strncpy((char *) atval, desc_out_hum, len);
 
269
        attrib_db_add(0x0214, &uuid, atval, len);
 
270
 
 
271
        /* Secondary Service: Manufacturer Service */
 
272
        sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
 
273
        u16 = htons(MANUFACTURER_SVC_UUID);
 
274
        atval[0] = u16 >> 8;
 
275
        atval[1] = u16;
 
276
        attrib_db_add(0x0500, &uuid, atval, 2);
 
277
 
 
278
        /* Manufacturer name characteristic definition */
 
279
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
280
        u16 = htons(MANUFACTURER_NAME_UUID);
 
281
        atval[0] = ATT_CHAR_PROPER_READ;
 
282
        atval[1] = 0x02;
 
283
        atval[2] = 0x05;
 
284
        atval[3] = u16 >> 8;
 
285
        atval[4] = u16;
 
286
        attrib_db_add(0x0501, &uuid, atval, 5);
 
287
 
 
288
        /* Manufacturer name characteristic value */
 
289
        sdp_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
 
290
        len = strlen(manufacturer_name1);
 
291
        strncpy((char *) atval, manufacturer_name1, len);
 
292
        attrib_db_add(0x0502, &uuid, atval, len);
 
293
 
 
294
        /* Manufacturer serial number characteristic */
 
295
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
296
        u16 = htons(MANUFACTURER_SERIAL_UUID);
 
297
        atval[0] = ATT_CHAR_PROPER_READ;
 
298
        atval[1] = 0x04;
 
299
        atval[2] = 0x05;
 
300
        atval[3] = u16 >> 8;
 
301
        atval[4] = u16;
 
302
        attrib_db_add(0x0503, &uuid, atval, 5);
 
303
 
 
304
        /* Manufacturer serial number characteristic value */
 
305
        sdp_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
 
306
        len = strlen(serial1);
 
307
        strncpy((char *) atval, serial1, len);
 
308
        attrib_db_add(0x0504, &uuid, atval, len);
 
309
 
 
310
        /* Secondary Service: Manufacturer Service */
 
311
        sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
 
312
        u16 = htons(MANUFACTURER_SVC_UUID);
 
313
        atval[0] = u16 >> 8;
 
314
        atval[1] = u16;
 
315
        attrib_db_add(0x0505, &uuid, atval, 2);
 
316
 
 
317
        /* Manufacturer name characteristic definition */
 
318
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
319
        u16 = htons(MANUFACTURER_NAME_UUID);
 
320
        atval[0] = ATT_CHAR_PROPER_READ;
 
321
        atval[1] = 0x07;
 
322
        atval[2] = 0x05;
 
323
        atval[3] = u16 >> 8;
 
324
        atval[4] = u16;
 
325
        attrib_db_add(0x0506, &uuid, atval, 5);
 
326
 
 
327
        /* Secondary Service: Vendor Specific Service */
 
328
        sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
 
329
        u16 = htons(VENDOR_SPECIFIC_SVC_UUID);
 
330
        atval[0] = u16 >> 8;
 
331
        atval[1] = u16;
 
332
        attrib_db_add(0x0550, &uuid, atval, 2);
 
333
 
 
334
        /* Vendor Specific Type characteristic definition */
 
335
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
336
        u16 = htons(VENDOR_SPECIFIC_TYPE_UUID);
 
337
        atval[0] = ATT_CHAR_PROPER_READ;
 
338
        atval[1] = 0x68;
 
339
        atval[2] = 0x05;
 
340
        atval[3] = u16 >> 8;
 
341
        atval[4] = u16;
 
342
        attrib_db_add(0x0560, &uuid, atval, 5);
 
343
 
 
344
        /* Vendor Specific Type characteristic value */
 
345
        sdp_uuid16_create(&uuid, VENDOR_SPECIFIC_TYPE_UUID);
 
346
        atval[0] = 0x56;
 
347
        atval[1] = 0x65;
 
348
        atval[2] = 0x6E;
 
349
        atval[3] = 0x64;
 
350
        atval[4] = 0x6F;
 
351
        atval[5] = 0x72;
 
352
        attrib_db_add(0x0568, &uuid, atval, 6);
 
353
 
 
354
        /* Manufacturer name attribute */
 
355
        sdp_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
 
356
        len = strlen(manufacturer_name2);
 
357
        strncpy((char *) atval, manufacturer_name2, len);
 
358
        attrib_db_add(0x0507, &uuid, atval, len);
 
359
 
 
360
        /* Characteristic: serial number */
 
361
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
362
        u16 = htons(MANUFACTURER_SERIAL_UUID);
 
363
        atval[0] = ATT_CHAR_PROPER_READ;
 
364
        atval[1] = 0x09;
 
365
        atval[2] = 0x05;
 
366
        atval[3] = u16 >> 8;
 
367
        atval[4] = u16;
 
368
        attrib_db_add(0x0508, &uuid, atval, 5);
 
369
 
 
370
        /* Serial number characteristic value */
 
371
        sdp_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
 
372
        len = strlen(serial2);
 
373
        strncpy((char *) atval, serial2, len);
 
374
        attrib_db_add(0x0509, &uuid, atval, len);
 
375
 
 
376
        /* Weight service: primary service definition */
 
377
        sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 
378
        memcpy(atval, prim_weight_uuid, 16);
 
379
        attrib_db_add(0x0680, &uuid, atval, 16);
 
380
 
 
381
        /* Weight: include */
 
382
        sdp_uuid16_create(&uuid, GATT_INCLUDE_UUID);
 
383
        u16 = htons(MANUFACTURER_SVC_UUID);
 
384
        atval[0] = 0x05;
 
385
        atval[1] = 0x05;
 
386
        atval[2] = 0x09;
 
387
        atval[3] = 0x05;
 
388
        atval[4] = u16 >> 8;
 
389
        atval[5] = u16;
 
390
        attrib_db_add(0x0681, &uuid, atval, 6);
 
391
 
 
392
        /* Weight: characteristic */
 
393
        sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
394
        atval[0] = ATT_CHAR_PROPER_READ;
 
395
        atval[1] = 0x83;
 
396
        atval[2] = 0x06;
 
397
        memcpy(atval + 3, char_weight_uuid, 16);
 
398
        attrib_db_add(0x0682, &uuid, atval, 19);
 
399
 
 
400
        /* Weight: characteristic value */
 
401
        sdp_uuid128_create(&uuid, char_weight_uuid);
 
402
        atval[0] = 0x82;
 
403
        atval[1] = 0x55;
 
404
        atval[2] = 0x00;
 
405
        atval[3] = 0x00;
 
406
        attrib_db_add(0x0683, &uuid, atval, 4);
 
407
 
 
408
        /* Weight: characteristic format */
 
409
        sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
 
410
        u16 = htons(FMT_KILOGRAM_UUID);
 
411
        atval[0] = 0x08;
 
412
        atval[1] = 0xFD;
 
413
        atval[2] = u16 >> 8;
 
414
        atval[3] = u16;
 
415
        u16 = htons(BLUETOOTH_SIG_UUID);
 
416
        atval[4] = u16 >> 8;
 
417
        atval[5] = u16;
 
418
        u16 = htons(FMT_HANGING_UUID);
 
419
        atval[6] = u16 >> 8;
 
420
        atval[7] = u16;
 
421
        attrib_db_add(0x0684, &uuid, atval, 8);
 
422
 
 
423
        /* Weight: characteristic user description */
 
424
        sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
 
425
        len = strlen(desc_weight);
 
426
        strncpy((char *) atval, desc_weight, len);
 
427
        attrib_db_add(0x0685, &uuid, atval, len);
 
428
 
 
429
        return 0;
 
430
}
 
431
 
 
432
int server_example_init(void)
 
433
{
 
434
        return register_attributes();
 
435
}
 
436
 
 
437
void server_example_exit(void)
 
438
{
 
439
        g_source_remove(timeout_id);
 
440
}