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 "host/ble_uuid.h"
23 #include "nimble/ble.h"
24 #include "ble_hs_priv.h"
25
26 #include <rtthread.h>
27
28 #define console_printf rt_kprintf
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
63 static char *
ble_gatts_flags_to_str(uint16_t flags,char * buf,const char * const * names)64 ble_gatts_flags_to_str(uint16_t flags, char *buf,
65 const char * const *names)
66 {
67 int bit;
68 bool non_empty = false;
69 size_t length = 0;
70
71 buf[0] = '\0';
72 strcpy(buf, "[");
73 length += 1;
74 for (bit = 0; names[bit]; ++bit) {
75 if (flags & (1 << bit)) {
76 length += strlen(names[bit]);
77 if (length + 1 >= BLE_CHR_FLAGS_STR_LEN) {
78 return buf;
79 }
80 if (non_empty) {
81 strcat(buf, "|");
82 length += 1;
83 }
84 strcat(buf, names[bit]);
85 non_empty = true;
86 }
87 }
88 strcat(buf, "]");
89 return buf;
90 }
91
92
93 #define STRINGIFY(X) #X
94 #define FIELD_NAME_LEN STRINGIFY(12)
95 #define FIELD_INDENT STRINGIFY(2)
96
97 static void
ble_gatt_show_local_chr(const struct ble_gatt_svc_def * svc,uint16_t handle,char * uuid_buf,char * flags_buf)98 ble_gatt_show_local_chr(const struct ble_gatt_svc_def *svc,
99 uint16_t handle, char *uuid_buf, char *flags_buf)
100 {
101 const struct ble_gatt_chr_def *chr;
102 const struct ble_gatt_dsc_def *dsc;
103
104 for (chr = svc->characteristics; chr && chr->uuid; ++chr) {
105 console_printf("characteristic\n");
106 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
107 "%s\n", " ", "uuid",
108 ble_uuid_to_str(chr->uuid, uuid_buf));
109 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
110 "%d\n", " ", "def_handle", handle);
111 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
112 "%d\n", " ", "val_handle", handle+1);
113 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
114 "%d\n", " ", "min_key_size", chr->min_key_size);
115 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
116 "%s\n", " ", "flags",
117 ble_gatts_flags_to_str(chr->flags,
118 flags_buf, ble_gatt_chr_f_names));
119 handle += 2;
120 for (dsc = chr->descriptors; dsc && dsc->uuid; ++dsc) {
121 console_printf("descriptor\n");
122 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
123 "%s\n", " ", "uuid",
124 ble_uuid_to_str(dsc->uuid, uuid_buf));
125 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
126 "%d\n", " ", "handle", handle);
127 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
128 "%d\n", " ", "min_key_size", dsc->min_key_size);
129 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
130 "%s\n", " ", "flags",
131 ble_gatts_flags_to_str(dsc->att_flags,
132 flags_buf, ble_gatt_dsc_f_names));
133 handle++;
134 }
135 }
136 }
137
138 static void
ble_gatt_show_local_svc(const struct ble_gatt_svc_def * svc,uint16_t handle,uint16_t end_group_handle)139 ble_gatt_show_local_svc(const struct ble_gatt_svc_def *svc,
140 uint16_t handle, uint16_t end_group_handle)
141 {
142 char uuid_buf[BLE_UUID_STR_LEN];
143 char flags_buf[BLE_CHR_FLAGS_STR_LEN];
144
145 console_printf("%s service\n",
146 svc->type == BLE_GATT_SVC_TYPE_PRIMARY ?
147 "primary" : "secondary");
148 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
149 "%s\n", " ", "uuid",
150 ble_uuid_to_str(svc->uuid, uuid_buf));
151 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
152 "%d\n", " ", "handle",
153 handle);
154 console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
155 "%d\n", " ", "end_handle",
156 end_group_handle);
157 ble_gatt_show_local_chr(svc, handle+1,
158 uuid_buf, flags_buf);
159 }
160
161 void
ble_gatts_show_local(void)162 ble_gatts_show_local(void)
163 {
164 ble_gatts_lcl_svc_foreach(ble_gatt_show_local_svc);
165 }
166
167