• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stddef.h>
21 #include <string.h>
22 #include "securec.h"
23 #include "host/ble_uuid.h"
24 #include "nimble/ble.h"
25 #include "ble_hs_priv.h"
26 
27 static const ble_uuid_t *uuid_ccc =
28                 BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16);
29 
30 static const char *const ble_gatt_chr_f_names[] = {
31     "BROADCAST",
32     "READ",
33     "WRITE_NO_RSP",
34     "WRITE",
35     "NOTIFY",
36     "INDICATE",
37     "AUTH_SIGN_WRITE",
38     "RELIABLE_WRITE",
39     "AUX_WRITE",
40     "READ_ENC",
41     "READ_AUTHEN",
42     "READ_AUTHOR",
43     "WRITE_ENC",
44     "WRITE_AUTHEN",
45     "WRITE_AUTHOR",
46     NULL
47 };
48 
49 static const char *const ble_gatt_dsc_f_names[] = {
50     "READ",
51     "WRITE",
52     "READ_ENC",
53     "READ_AUTHEN",
54     "READ_AUTHOR",
55     "WRITE_ENC",
56     "WRITE_AUTHEN",
57     "WRITE_AUTHOR",
58     NULL
59 };
60 
61 #define BLE_CHR_FLAGS_STR_LEN 180
62 
ble_gatts_flags_to_str(uint16_t flags,char * buf,const char * const * names)63 static char *ble_gatts_flags_to_str(uint16_t flags, char *buf, const char *const *names)
64 {
65     int bit;
66     bool non_empty = false;
67     size_t length = 0;
68     buf[0] = '\0';
69     strcpy_s(buf, sizeof(buf), "[");
70     length += 1;
71 
72     for (bit = 0; names[bit]; ++bit) {
73         if (flags & (1 << bit)) {
74             length += strlen(names[bit]);
75             if (length + 1 >= BLE_CHR_FLAGS_STR_LEN) {
76                 return buf;
77             }
78 
79             if (non_empty) {
80                 strcat_s(buf, sizeof(buf), "|");
81                 length += 1;
82             }
83 
84             strcat_s(buf,  sizeof(buf), names[bit]);
85             non_empty = true;
86         }
87     }
88 
89     strcat_s(buf, sizeof(buf), "]");
90     return buf;
91 }
92 
93 #define STRINGIFY(X) #X
94 #define FIELD_NAME_LEN STRINGIFY(12)
95 #define FIELD_INDENT STRINGIFY(2)
96 
ble_gatt_show_local_chr(const struct ble_gatt_svc_def * svc,uint16_t handle,char * uuid_buf,char * flags_buf)97 static void ble_gatt_show_local_chr(const struct ble_gatt_svc_def *svc,
98                                     uint16_t handle, char *uuid_buf, char *flags_buf)
99 {
100     const struct ble_gatt_chr_def *chr;
101     const struct ble_gatt_dsc_def *dsc;
102 
103     for (chr = svc->characteristics; chr && chr->uuid; ++chr) {
104         printf("characteristic\n");
105         printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
106                "%s\n", " ", "uuid",
107                ble_uuid_to_str(chr->uuid, uuid_buf));
108         printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
109                "%d\n", " ", "def_handle", handle);
110         printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
111                "%d\n", " ", "val_handle", handle + 1);
112         printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
113                "%d\n", " ", "min_key_size", chr->min_key_size);
114         printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
115                "%s\n", " ", "flags",
116                ble_gatts_flags_to_str(chr->flags,
117                                       flags_buf, ble_gatt_chr_f_names));
118         handle += 2;
119 
120         if ((chr->flags & BLE_GATT_CHR_F_NOTIFY) ||
121                 (chr->flags & BLE_GATT_CHR_F_INDICATE)) {
122             printf("ccc descriptor\n");
123             printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
124                    "%s\n", " ", "uuid",
125                    ble_uuid_to_str(uuid_ccc, uuid_buf));
126             printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
127                    "%d\n", " ", "handle", handle);
128             printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
129                    "%d\n", " ", "min_key_size", 0);
130             printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
131                    "%s\n", " ", "flags",
132                    ble_gatts_flags_to_str(BLE_ATT_F_READ | BLE_ATT_F_WRITE,
133                                           flags_buf, ble_gatt_dsc_f_names));
134             handle++;
135         }
136 
137         for (dsc = chr->descriptors; dsc && dsc->uuid; ++dsc) {
138             printf("descriptor\n");
139             printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
140                    "%s\n", " ", "uuid",
141                    ble_uuid_to_str(dsc->uuid, uuid_buf));
142             printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
143                    "%d\n", " ", "handle", handle);
144             printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
145                    "%d\n", " ", "min_key_size", dsc->min_key_size);
146             printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
147                    "%s\n", " ", "flags",
148                    ble_gatts_flags_to_str(dsc->att_flags,
149                                           flags_buf, ble_gatt_dsc_f_names));
150             handle++;
151         }
152     }
153 }
154 
ble_gatt_show_local_inc_svc(const struct ble_gatt_svc_def * svc,uint16_t handle,char * uuid_buf)155 static int ble_gatt_show_local_inc_svc(const struct ble_gatt_svc_def *svc,
156                                        uint16_t handle, char *uuid_buf)
157 {
158     const struct ble_gatt_svc_def **includes;
159     int num = 0;
160 
161     for (includes = &svc->includes[0]; *includes != NULL; ++includes) {
162         printf("included service\n");
163         printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
164                "%s\n", " ", "uuid",
165                ble_uuid_to_str((*includes)->uuid, uuid_buf));
166         printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
167                "%d\n", " ", "attr handle", handle);
168         ++num;
169     }
170 
171     return num;
172 }
173 
ble_gatt_show_local_svc(const struct ble_gatt_svc_def * svc,uint16_t handle,uint16_t end_group_handle,void * arg)174 static void ble_gatt_show_local_svc(const struct ble_gatt_svc_def *svc,
175                                     uint16_t handle, uint16_t end_group_handle,
176                                     void *arg)
177 {
178     uint16_t handle_tmp = handle;
179     char uuid_buf[BLE_UUID_STR_LEN];
180     char flags_buf[BLE_CHR_FLAGS_STR_LEN];
181     printf("%s service\n",
182            svc->type == BLE_GATT_SVC_TYPE_PRIMARY ?
183            "primary" : "secondary");
184     printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
185            "%s\n", " ", "uuid",
186            ble_uuid_to_str(svc->uuid, uuid_buf));
187     printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
188            "%d\n", " ", "handle",
189            handle_tmp);
190     printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
191            "%d\n", " ", "end_handle",
192            end_group_handle);
193     handle_tmp++;
194 
195     if (svc->includes) {
196         handle_tmp += ble_gatt_show_local_inc_svc(svc, handle_tmp, uuid_buf);
197     }
198 
199     ble_gatt_show_local_chr(svc, handle_tmp,
200                             uuid_buf, flags_buf);
201 }
202 
ble_gatts_show_local(void)203 void ble_gatts_show_local(void)
204 {
205     ble_gatts_lcl_svc_foreach(ble_gatt_show_local_svc, NULL);
206 }