xref: /nrf52832-nimble/packages/NimBLE-latest/apps/blehr/src/gatt_svr.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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 <stdio.h>
22 #include <string.h>
23 #include "host/ble_hs.h"
24 #include "host/ble_uuid.h"
25 #include "blehr_sens.h"
26 
27 static const char *manuf_name = "Apache Mynewt";
28 static const char *model_num = "Mynewt HR Sensor";
29 uint16_t hrs_hrm_handle;
30 
31 static int
32 gatt_svr_chr_access_heart_rate(uint16_t conn_handle, uint16_t attr_handle,
33                                struct ble_gatt_access_ctxt *ctxt, void *arg);
34 
35 static int
36 gatt_svr_chr_access_device_info(uint16_t conn_handle, uint16_t attr_handle,
37                                 struct ble_gatt_access_ctxt *ctxt, void *arg);
38 
39 static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
40     {
41         /* Service: Heart-rate */
42         .type = BLE_GATT_SVC_TYPE_PRIMARY,
43         .uuid = BLE_UUID16_DECLARE(GATT_HRS_UUID),
44         .characteristics = (struct ble_gatt_chr_def[]) { {
45             /* Characteristic: Heart-rate measurement */
46             .uuid = BLE_UUID16_DECLARE(GATT_HRS_MEASUREMENT_UUID),
47             .access_cb = gatt_svr_chr_access_heart_rate,
48             .val_handle = &hrs_hrm_handle,
49             .flags = BLE_GATT_CHR_F_NOTIFY,
50         }, {
51             /* Characteristic: Body sensor location */
52             .uuid = BLE_UUID16_DECLARE(GATT_HRS_BODY_SENSOR_LOC_UUID),
53             .access_cb = gatt_svr_chr_access_heart_rate,
54             .flags = BLE_GATT_CHR_F_READ,
55         }, {
56             0, /* No more characteristics in this service */
57         }, }
58     },
59 
60     {
61         /* Service: Device Information */
62         .type = BLE_GATT_SVC_TYPE_PRIMARY,
63         .uuid = BLE_UUID16_DECLARE(GATT_DEVICE_INFO_UUID),
64         .characteristics = (struct ble_gatt_chr_def[]) { {
65             /* Characteristic: * Manufacturer name */
66             .uuid = BLE_UUID16_DECLARE(GATT_MANUFACTURER_NAME_UUID),
67             .access_cb = gatt_svr_chr_access_device_info,
68             .flags = BLE_GATT_CHR_F_READ,
69         }, {
70             /* Characteristic: Model number string */
71             .uuid = BLE_UUID16_DECLARE(GATT_MODEL_NUMBER_UUID),
72             .access_cb = gatt_svr_chr_access_device_info,
73             .flags = BLE_GATT_CHR_F_READ,
74         }, {
75             0, /* No more characteristics in this service */
76         }, }
77     },
78 
79         {
80             0, /* No more services */
81         },
82 };
83 
84 static int
gatt_svr_chr_access_heart_rate(uint16_t conn_handle,uint16_t attr_handle,struct ble_gatt_access_ctxt * ctxt,void * arg)85 gatt_svr_chr_access_heart_rate(uint16_t conn_handle, uint16_t attr_handle,
86                                struct ble_gatt_access_ctxt *ctxt, void *arg)
87 {
88     /* Sensor location, set to "Chest" */
89     static uint8_t body_sens_loc = 0x01;
90     uint16_t uuid;
91     int rc;
92 
93     uuid = ble_uuid_u16(ctxt->chr->uuid);
94 
95     if (uuid == GATT_HRS_BODY_SENSOR_LOC_UUID) {
96         rc = os_mbuf_append(ctxt->om, &body_sens_loc, sizeof(body_sens_loc));
97 
98         return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
99     }
100 
101     assert(0);
102     return BLE_ATT_ERR_UNLIKELY;
103 }
104 
105 static int
gatt_svr_chr_access_device_info(uint16_t conn_handle,uint16_t attr_handle,struct ble_gatt_access_ctxt * ctxt,void * arg)106 gatt_svr_chr_access_device_info(uint16_t conn_handle, uint16_t attr_handle,
107                                 struct ble_gatt_access_ctxt *ctxt, void *arg)
108 {
109     uint16_t uuid;
110     int rc;
111 
112     uuid = ble_uuid_u16(ctxt->chr->uuid);
113 
114     if (uuid == GATT_MODEL_NUMBER_UUID) {
115         rc = os_mbuf_append(ctxt->om, model_num, strlen(model_num));
116         return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
117     }
118 
119     if (uuid == GATT_MANUFACTURER_NAME_UUID) {
120         rc = os_mbuf_append(ctxt->om, manuf_name, strlen(manuf_name));
121         return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
122     }
123 
124     assert(0);
125     return BLE_ATT_ERR_UNLIKELY;
126 }
127 
128 void
gatt_svr_register_cb(struct ble_gatt_register_ctxt * ctxt,void * arg)129 gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
130 {
131     char buf[BLE_UUID_STR_LEN];
132 
133     switch (ctxt->op) {
134     case BLE_GATT_REGISTER_OP_SVC:
135         MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
136                     ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
137                     ctxt->svc.handle);
138         break;
139 
140     case BLE_GATT_REGISTER_OP_CHR:
141         MODLOG_DFLT(DEBUG, "registering characteristic %s with "
142                            "def_handle=%d val_handle=%d\n",
143                     ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
144                     ctxt->chr.def_handle,
145                     ctxt->chr.val_handle);
146         break;
147 
148     case BLE_GATT_REGISTER_OP_DSC:
149         MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
150                     ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
151                     ctxt->dsc.handle);
152         break;
153 
154     default:
155         assert(0);
156         break;
157     }
158 }
159 
160 int
gatt_svr_init(void)161 gatt_svr_init(void)
162 {
163     int rc;
164 
165     rc = ble_gatts_count_cfg(gatt_svr_svcs);
166     if (rc != 0) {
167         return rc;
168     }
169 
170     rc = ble_gatts_add_svcs(gatt_svr_svcs);
171     if (rc != 0) {
172         return rc;
173     }
174 
175     return 0;
176 }
177 
178