Newer
Older
/*************************************************************************************************/
/*!
* \file
*
* \brief Example GATT and GAP service implementations.
*
* Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
/* card10:
* copied from lib/sdk/Libraries/BTLE/stack/ble-profiles/sources/services/svc_core.c
*/
#include "wsf_types.h"
#include "att_api.h"
#include "att_uuid.h"
#include "util/bstream.h"
#include "svc_core.h"
#include "svc_ch.h"
#include "svc_cfg.h"
#include "wsf_assert.h"
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! Characteristic read permissions */
#ifndef CORE_SEC_PERMIT_READ
#define CORE_SEC_PERMIT_READ SVC_SEC_PERMIT_READ
#endif
/*! Characteristic write permissions */
#ifndef CORE_SEC_PERMIT_WRITE
#define CORE_SEC_PERMIT_WRITE SVC_SEC_PERMIT_WRITE
#endif
/*! Default device name */
#define CORE_DEFAULT_DEV_NAME "card10"
/*! Length of default device name */
#define CORE_DEFAULT_DEV_NAME_LEN 6
/**************************************************************************************************
GAP group
**************************************************************************************************/
/* service */
static const uint8_t gapValSvc[] = {UINT16_TO_BYTES(ATT_UUID_GAP_SERVICE)};
static const uint16_t gapLenSvc = sizeof(gapValSvc);
/* device name characteristic */
static const uint8_t gapValDnCh[] = {ATT_PROP_READ, UINT16_TO_BYTES(GAP_DN_HDL), UINT16_TO_BYTES(ATT_UUID_DEVICE_NAME)};
static const uint16_t gapLenDnCh = sizeof(gapValDnCh);
/* device name */
static uint8_t gapValDn[ATT_DEFAULT_PAYLOAD_LEN] = CORE_DEFAULT_DEV_NAME;
static uint16_t gapLenDn = CORE_DEFAULT_DEV_NAME_LEN;
/* appearance characteristic */
static const uint8_t gapValApCh[] = {ATT_PROP_READ, UINT16_TO_BYTES(GAP_AP_HDL), UINT16_TO_BYTES(ATT_UUID_APPEARANCE)};
static const uint16_t gapLenApCh = sizeof(gapValApCh);
/* appearance */
static uint8_t gapValAp[] = {UINT16_TO_BYTES(CH_APPEAR_UNKNOWN)};
static const uint16_t gapLenAp = sizeof(gapValAp);
/* central address resolution characteristic */
static const uint8_t gapValCarCh[] = {ATT_PROP_READ, UINT16_TO_BYTES(GAP_CAR_HDL), UINT16_TO_BYTES(ATT_UUID_CAR)};
static const uint16_t gapLenCarCh = sizeof(gapValCarCh);
/* central address resolution */
static uint8_t gapValCar[] = {FALSE};
static const uint16_t gapLenCar = sizeof(gapValCar);
#if 0
/* TODO card10:
* Enable these if "privacy" is enabled. See svc_core.h lien 38 */
/* resolvable private address only characteristic */
static const uint8_t gapValRpaoCh[] = {ATT_PROP_READ, UINT16_TO_BYTES(GAP_RPAO_HDL), UINT16_TO_BYTES(ATT_UUID_RPAO)};
static const uint16_t gapLenRpaoCh = sizeof(gapValRpaoCh);
/* resolvable private address only */
static uint8_t gapValRpao[] = {0};
static const uint16_t gapLenRpao = sizeof(gapValRpao);
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* Attribute list for GAP group */
static const attsAttr_t gapList[] =
{
{
attPrimSvcUuid,
(uint8_t *) gapValSvc,
(uint16_t *) &gapLenSvc,
sizeof(gapValSvc),
0,
ATTS_PERMIT_READ
},
{
attChUuid,
(uint8_t *) gapValDnCh,
(uint16_t *) &gapLenDnCh,
sizeof(gapValDnCh),
0,
ATTS_PERMIT_READ
},
{
attDnChUuid,
gapValDn,
&gapLenDn,
sizeof(gapValDn),
(ATTS_SET_VARIABLE_LEN | ATTS_SET_WRITE_CBACK),
(ATTS_PERMIT_READ | CORE_SEC_PERMIT_WRITE)
},
{
attChUuid,
(uint8_t *) gapValApCh,
(uint16_t *) &gapLenApCh,
sizeof(gapValApCh),
0,
ATTS_PERMIT_READ
},
{
attApChUuid,
gapValAp,
(uint16_t *) &gapLenAp,
sizeof(gapValAp),
0,
ATTS_PERMIT_READ
},
{
attChUuid,
(uint8_t *) gapValCarCh,
(uint16_t *) &gapLenCarCh,
sizeof(gapValCarCh),
0,
ATTS_PERMIT_READ
},
{
attCarChUuid,
gapValCar,
(uint16_t *) &gapLenCar,
sizeof(gapValCar),
0,
ATTS_PERMIT_READ
},
#if 0
/* TODO card10:
* Enable these if "privacy" is enabled. See svc_core.h lien 38 */
{
attChUuid,
(uint8_t *) gapValRpaoCh,
(uint16_t *) &gapLenRpaoCh,
sizeof(gapValRpaoCh),
0,
ATTS_PERMIT_READ
},
{
attRpaoChUuid,
gapValRpao,
(uint16_t *) &gapLenRpao,
sizeof(gapValRpao),
0,
ATTS_PERMIT_READ
}
};
/* GAP group structure */
static attsGroup_t svcGapGroup =
{
NULL,
(attsAttr_t *) gapList,
NULL,
NULL,
GAP_START_HDL,
GAP_END_HDL
};
WSF_CT_ASSERT(((sizeof(gapList) / sizeof(gapList[0])) == GAP_END_HDL - GAP_START_HDL + 1));
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/**************************************************************************************************
GATT group
**************************************************************************************************/
/* service */
static const uint8_t gattValSvc[] = {UINT16_TO_BYTES(ATT_UUID_GATT_SERVICE)};
static const uint16_t gattLenSvc = sizeof(gattValSvc);
/* service changed characteristic */
static const uint8_t gattValScCh[] = {ATT_PROP_INDICATE, UINT16_TO_BYTES(GATT_SC_HDL), UINT16_TO_BYTES(ATT_UUID_SERVICE_CHANGED)};
static const uint16_t gattLenScCh = sizeof(gattValScCh);
/* service changed */
static const uint8_t gattValSc[] = {UINT16_TO_BYTES(0x0001), UINT16_TO_BYTES(0xFFFF)};
static const uint16_t gattLenSc = sizeof(gattValSc);
/* service changed client characteristic configuration */
static uint8_t gattValScChCcc[] = {UINT16_TO_BYTES(0x0000)};
static const uint16_t gattLenScChCcc = sizeof(gattValScChCcc);
/* Attribute list for GATT group */
static const attsAttr_t gattList[] =
{
{
attPrimSvcUuid,
(uint8_t *) gattValSvc,
(uint16_t *) &gattLenSvc,
sizeof(gattValSvc),
0,
ATTS_PERMIT_READ
},
{
attChUuid,
(uint8_t *) gattValScCh,
(uint16_t *) &gattLenScCh,
sizeof(gattValScCh),
0,
ATTS_PERMIT_READ
},
{
attScChUuid,
(uint8_t *) gattValSc,
(uint16_t *) &gattLenSc,
sizeof(gattValSc),
0,
0
},
{
attCliChCfgUuid,
gattValScChCcc,
(uint16_t *) &gattLenScChCcc,
sizeof(gattValScChCcc),
ATTS_SET_CCC,
(ATTS_PERMIT_READ | CORE_SEC_PERMIT_WRITE)
},
};
/* GATT group structure */
static attsGroup_t svcGattGroup =
{
NULL,
(attsAttr_t *) gattList,
NULL,
NULL,
GATT_START_HDL,
GATT_END_HDL
};
WSF_CT_ASSERT(((sizeof(gattList) / sizeof(gattList[0])) == GATT_END_HDL - GATT_START_HDL + 1));
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/*************************************************************************************************/
/*!
* \brief Add the services to the attribute server.
*
* \return None.
*/
/*************************************************************************************************/
void SvcCoreAddGroup(void)
{
AttsAddGroup(&svcGapGroup);
AttsAddGroup(&svcGattGroup);
}
/*************************************************************************************************/
/*!
* \brief Remove the services from the attribute server.
*
* \return None.
*/
/*************************************************************************************************/
void SvcCoreRemoveGroup(void)
{
AttsRemoveGroup(GAP_START_HDL);
AttsRemoveGroup(GATT_START_HDL);
}
/*************************************************************************************************/
/*!
* \brief Register callbacks for the service.
*
* \param readCback Read callback function.
* \param writeCback Write callback function.
*
* \return None.
*/
/*************************************************************************************************/
void SvcCoreGapCbackRegister(attsReadCback_t readCback, attsWriteCback_t writeCback)
{
svcGapGroup.readCback = readCback;
svcGapGroup.writeCback = writeCback;
}
/*************************************************************************************************/
/*!
* \brief Register callbacks for the service.
*
* \param readCback Read callback function.
* \param writeCback Write callback function.
*
* \return None.
*/
/*************************************************************************************************/
void SvcCoreGattCbackRegister(attsReadCback_t readCback, attsWriteCback_t writeCback)
{
svcGattGroup.readCback = readCback;
svcGattGroup.writeCback = writeCback;
}
/*************************************************************************************************/
/*!
* \brief Update the central address resolution attribute value.
*
* \param value New value.
*
* \return None.
*/
/*************************************************************************************************/
void SvcCoreGapCentAddrResUpdate(bool_t value)
{
gapValCar[0] = value;
}
/*************************************************************************************************/
/*!
* \brief Add the Resolvable Private Address Only (RPAO) characteristic to the GAP service.
* The RPAO characteristic should be added only when DM Privacy is enabled.
*
* \return None.
*/
/*************************************************************************************************/
void SvcCoreGapAddRpaoCh(void)
{
/* if RPAO characteristic not already in GAP service */
if (svcGapGroup.endHandle < GAP_RPAO_HDL)
{
svcGapGroup.endHandle = GAP_RPAO_HDL;
}
}