1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <assert.h>
21 #include <string.h>
22 #include "sysinit/sysinit.h"
23 #include "host/ble_hs.h"
24 #include "services/dis/ble_svc_dis.h"
25
26 /* Device information */
27 struct ble_svc_dis_data ble_svc_dis_data = {
28 .model_number = MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_DEFAULT),
29 .serial_number = MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT),
30 .firmware_revision = MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT),
31 .hardware_revision = MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT),
32 .software_revision = MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT),
33 .manufacturer_name = MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT),
34 };
35
36 /* Access function */
37 #if (MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM) >= 0) || \
38 (MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM) >= 0) || \
39 (MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM) >= 0) || \
40 (MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM) >= 0) || \
41 (MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM) >= 0) || \
42 (MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM) >= 0)
43 static int
44 ble_svc_dis_access(uint16_t conn_handle, uint16_t attr_handle,
45 struct ble_gatt_access_ctxt *ctxt, void *arg);
46 #endif
47
48 static const struct ble_gatt_svc_def ble_svc_dis_defs[] = {
49 { /*** Service: Device Information Service (DIS). */
50 .type = BLE_GATT_SVC_TYPE_PRIMARY,
51 .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_UUID16),
52 .characteristics = (struct ble_gatt_chr_def[]) { {
53 #if (MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM) >= 0)
54 /*** Characteristic: Model Number String */
55 .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_MODEL_NUMBER),
56 .access_cb = ble_svc_dis_access,
57 .flags = BLE_GATT_CHR_F_READ |
58 MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM),
59 }, {
60 #endif
61 #if (MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM) >= 0)
62 /*** Characteristic: Serial Number String */
63 .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_SERIAL_NUMBER),
64 .access_cb = ble_svc_dis_access,
65 .flags = BLE_GATT_CHR_F_READ |
66 MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM),
67 }, {
68 #endif
69 #if (MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM) >= 0)
70 /*** Characteristic: Hardware Revision String */
71 .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_HARDWARE_REVISION),
72 .access_cb = ble_svc_dis_access,
73 .flags = BLE_GATT_CHR_F_READ |
74 MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM),
75 }, {
76 #endif
77 #if (MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM) >= 0)
78 /*** Characteristic: Firmware Revision String */
79 .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_FIRMWARE_REVISION),
80 .access_cb = ble_svc_dis_access,
81 .flags = BLE_GATT_CHR_F_READ |
82 MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM),
83 }, {
84 #endif
85 #if (MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM) >= 0)
86 /*** Characteristic: Software Revision String */
87 .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_SOFTWARE_REVISION),
88 .access_cb = ble_svc_dis_access,
89 .flags = BLE_GATT_CHR_F_READ |
90 MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM),
91 }, {
92 #endif
93 #if (MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM) >= 0)
94 /*** Characteristic: Manufacturer Name */
95 .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_MANUFACTURER_NAME),
96 .access_cb = ble_svc_dis_access,
97 .flags = BLE_GATT_CHR_F_READ |
98 MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM),
99 }, {
100 #endif
101 0, /* No more characteristics in this service */
102 }, }
103 },
104
105 {
106 0, /* No more services. */
107 },
108 };
109
110 /**
111 * Simple read access callback for the device information service
112 * characteristic.
113 */
114 #if (MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM) >= 0) || \
115 (MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM) >= 0) || \
116 (MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM) >= 0) || \
117 (MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM) >= 0) || \
118 (MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM) >= 0) || \
119 (MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM) >= 0)
120 static int
ble_svc_dis_access(uint16_t conn_handle,uint16_t attr_handle,struct ble_gatt_access_ctxt * ctxt,void * arg)121 ble_svc_dis_access(uint16_t conn_handle, uint16_t attr_handle,
122 struct ble_gatt_access_ctxt *ctxt, void *arg)
123 {
124 uint16_t uuid = ble_uuid_u16(ctxt->chr->uuid);
125 const char *info = NULL;
126
127 switch(uuid) {
128 #if (MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM) >= 0)
129 case BLE_SVC_DIS_CHR_UUID16_MODEL_NUMBER:
130 info = ble_svc_dis_data.model_number;
131 #ifdef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_NAME_DEFAULT
132 if (info == NULL) {
133 info = MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_DEFAULT);
134 }
135 #endif
136 break;
137 #endif
138 #if (MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM) >= 0)
139 case BLE_SVC_DIS_CHR_UUID16_SERIAL_NUMBER:
140 info = ble_svc_dis_data.serial_number;
141 #ifdef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT
142 if (info == NULL) {
143 info = MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT);
144 }
145 #endif
146 break;
147 #endif
148 #if (MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM) >= 0)
149 case BLE_SVC_DIS_CHR_UUID16_FIRMWARE_REVISION:
150 info = ble_svc_dis_data.firmware_revision;
151 #ifdef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT
152 if (info == NULL) {
153 info = MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT);
154 }
155 #endif
156 break;
157 #endif
158 #if (MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM) >= 0)
159 case BLE_SVC_DIS_CHR_UUID16_HARDWARE_REVISION:
160 info = ble_svc_dis_data.hardware_revision;
161 #ifdef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT
162 if (info == NULL) {
163 info = MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT);
164 }
165 #endif
166 break;
167 #endif
168 #if (MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM) >= 0)
169 case BLE_SVC_DIS_CHR_UUID16_SOFTWARE_REVISION:
170 info = ble_svc_dis_data.software_revision;
171 #ifdef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT
172 if (info == NULL) {
173 info = MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT);
174 }
175 #endif
176 break;
177 #endif
178 #if (MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM) >= 0)
179 case BLE_SVC_DIS_CHR_UUID16_MANUFACTURER_NAME:
180 info = ble_svc_dis_data.manufacturer_name;
181 #ifdef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT
182 if (info == NULL) {
183 info = MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT);
184 }
185 #endif
186 break;
187 #endif
188 default:
189 assert(0);
190 return BLE_ATT_ERR_UNLIKELY;
191 }
192
193 if (info != NULL) {
194 int rc = os_mbuf_append(ctxt->om, info, strlen(info));
195 return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
196 }
197
198 return 0;
199 }
200 #endif
201
202 const char *
ble_svc_dis_model_number(void)203 ble_svc_dis_model_number(void)
204 {
205 return ble_svc_dis_data.model_number;
206 }
207
208 int
ble_svc_dis_model_number_set(const char * value)209 ble_svc_dis_model_number_set(const char *value)
210 {
211 ble_svc_dis_data.model_number = value;
212 return 0;
213 }
214
215 const char *
ble_svc_dis_serial_number(void)216 ble_svc_dis_serial_number(void)
217 {
218 return ble_svc_dis_data.serial_number;
219 }
220
221 int
ble_svc_dis_serial_number_set(const char * value)222 ble_svc_dis_serial_number_set(const char *value)
223 {
224 ble_svc_dis_data.serial_number = value;
225 return 0;
226 }
227
228 const char *
ble_svc_dis_firmware_revision(void)229 ble_svc_dis_firmware_revision(void)
230 {
231 return ble_svc_dis_data.firmware_revision;
232 }
233
234 int
ble_svc_dis_firmware_revision_set(const char * value)235 ble_svc_dis_firmware_revision_set(const char *value)
236 {
237 ble_svc_dis_data.firmware_revision = value;
238 return 0;
239 }
240
241 const char *
ble_svc_dis_hardware_revision(void)242 ble_svc_dis_hardware_revision(void)
243 {
244 return ble_svc_dis_data.hardware_revision;
245 }
246
247 int
ble_svc_dis_hardware_revision_set(const char * value)248 ble_svc_dis_hardware_revision_set(const char *value)
249 {
250 ble_svc_dis_data.hardware_revision = value;
251 return 0;
252 }
253
254 const char *
ble_svc_dis_software_revision(void)255 ble_svc_dis_software_revision(void)
256 {
257 return ble_svc_dis_data.software_revision;
258 }
259
260 int
ble_svc_dis_software_revision_set(const char * value)261 ble_svc_dis_software_revision_set(const char *value)
262 {
263 ble_svc_dis_data.software_revision = value;
264 return 0;
265 }
266
267 const char *
ble_svc_dis_manufacturer_name(void)268 ble_svc_dis_manufacturer_name(void)
269 {
270 return ble_svc_dis_data.manufacturer_name;
271 }
272
273 int
ble_svc_dis_manufacturer_name_set(const char * value)274 ble_svc_dis_manufacturer_name_set(const char *value)
275 {
276 ble_svc_dis_data.manufacturer_name = value;
277 return 0;
278 }
279
280 /**
281 * Initialize the DIS package.
282 */
283 void
ble_svc_dis_init(void)284 ble_svc_dis_init(void)
285 {
286 int rc;
287
288 /* Ensure this function only gets called by sysinit. */
289 SYSINIT_ASSERT_ACTIVE();
290
291 rc = ble_gatts_count_cfg(ble_svc_dis_defs);
292 SYSINIT_PANIC_ASSERT(rc == 0);
293
294 rc = ble_gatts_add_svcs(ble_svc_dis_defs);
295 SYSINIT_PANIC_ASSERT(rc == 0);
296 }
297