WXK
2024-09-18 05e2e954bd127de378a9d1dfbb0ed95d725aad63
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
83
84
85
86
87
88
89
90
91
92
93
94
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
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
257
258
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
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
 
#ifndef H_BLE_ATT_PRIV_
#define H_BLE_ATT_PRIV_
 
#include <inttypes.h>
#include "stats/stats.h"
#include "host/ble_att.h"
#include "host/ble_uuid.h"
#include "nimble/nimble_npl.h"
 
#ifdef __cplusplus
extern "C" {
#endif
 
struct os_mbuf;
struct ble_hs_conn;
struct ble_l2cap_chan;
struct ble_att_find_info_req;
struct ble_att_error_rsp;
struct ble_att_mtu_cmd;
struct ble_att_read_req;
struct ble_att_read_blob_req;
struct ble_att_read_type_req;
struct ble_att_read_group_type_req;
struct ble_att_read_group_type_rsp;
struct ble_att_find_type_value_req;
struct ble_att_write_req;
struct ble_att_prep_write_cmd;
struct ble_att_exec_write_req;
struct ble_att_notify_req;
struct ble_att_indicate_req;
 
STATS_SECT_START(ble_att_stats)
    STATS_SECT_ENTRY(error_rsp_rx)
    STATS_SECT_ENTRY(error_rsp_tx)
    STATS_SECT_ENTRY(mtu_req_rx)
    STATS_SECT_ENTRY(mtu_req_tx)
    STATS_SECT_ENTRY(mtu_rsp_rx)
    STATS_SECT_ENTRY(mtu_rsp_tx)
    STATS_SECT_ENTRY(find_info_req_rx)
    STATS_SECT_ENTRY(find_info_req_tx)
    STATS_SECT_ENTRY(find_info_rsp_rx)
    STATS_SECT_ENTRY(find_info_rsp_tx)
    STATS_SECT_ENTRY(find_type_value_req_rx)
    STATS_SECT_ENTRY(find_type_value_req_tx)
    STATS_SECT_ENTRY(find_type_value_rsp_rx)
    STATS_SECT_ENTRY(find_type_value_rsp_tx)
    STATS_SECT_ENTRY(read_type_req_rx)
    STATS_SECT_ENTRY(read_type_req_tx)
    STATS_SECT_ENTRY(read_type_rsp_rx)
    STATS_SECT_ENTRY(read_type_rsp_tx)
    STATS_SECT_ENTRY(read_req_rx)
    STATS_SECT_ENTRY(read_req_tx)
    STATS_SECT_ENTRY(read_rsp_rx)
    STATS_SECT_ENTRY(read_rsp_tx)
    STATS_SECT_ENTRY(read_blob_req_rx)
    STATS_SECT_ENTRY(read_blob_req_tx)
    STATS_SECT_ENTRY(read_blob_rsp_rx)
    STATS_SECT_ENTRY(read_blob_rsp_tx)
    STATS_SECT_ENTRY(read_mult_req_rx)
    STATS_SECT_ENTRY(read_mult_req_tx)
    STATS_SECT_ENTRY(read_mult_rsp_rx)
    STATS_SECT_ENTRY(read_mult_rsp_tx)
    STATS_SECT_ENTRY(read_group_type_req_rx)
    STATS_SECT_ENTRY(read_group_type_req_tx)
    STATS_SECT_ENTRY(read_group_type_rsp_rx)
    STATS_SECT_ENTRY(read_group_type_rsp_tx)
    STATS_SECT_ENTRY(write_req_rx)
    STATS_SECT_ENTRY(write_req_tx)
    STATS_SECT_ENTRY(write_rsp_rx)
    STATS_SECT_ENTRY(write_rsp_tx)
    STATS_SECT_ENTRY(prep_write_req_rx)
    STATS_SECT_ENTRY(prep_write_req_tx)
    STATS_SECT_ENTRY(prep_write_rsp_rx)
    STATS_SECT_ENTRY(prep_write_rsp_tx)
    STATS_SECT_ENTRY(exec_write_req_rx)
    STATS_SECT_ENTRY(exec_write_req_tx)
    STATS_SECT_ENTRY(exec_write_rsp_rx)
    STATS_SECT_ENTRY(exec_write_rsp_tx)
    STATS_SECT_ENTRY(notify_req_rx)
    STATS_SECT_ENTRY(notify_req_tx)
    STATS_SECT_ENTRY(indicate_req_rx)
    STATS_SECT_ENTRY(indicate_req_tx)
    STATS_SECT_ENTRY(indicate_rsp_rx)
    STATS_SECT_ENTRY(indicate_rsp_tx)
    STATS_SECT_ENTRY(write_cmd_rx)
    STATS_SECT_ENTRY(write_cmd_tx)
STATS_SECT_END
extern STATS_SECT_DECL(ble_att_stats) ble_att_stats;
 
struct ble_att_prep_entry {
    SLIST_ENTRY(ble_att_prep_entry) bape_next;
    uint16_t bape_handle;
    uint16_t bape_offset;
 
    /* XXX: This is wasteful; we should use one mbuf chain for the entire
     * prepared write, and compress the data into as few mbufs as possible.
     */
    struct os_mbuf *bape_value;
};
 
SLIST_HEAD(ble_att_prep_entry_list, ble_att_prep_entry);
 
struct ble_att_svr_conn {
    /** This list is sorted by attribute handle ID. */
    struct ble_att_prep_entry_list basc_prep_list;
    ble_npl_time_t basc_prep_timeout_at;
};
 
/**
 * Handles a host attribute request.
 *
 * @param entry                 The host attribute being requested.
 * @param op                    The operation being performed on the attribute.
 * @param arg                   The request data associated with that host
 *                                  attribute.
 *
 * @return                      0 on success;
 *                              One of the BLE_ATT_ERR_[...] codes on
 *                                  failure.
 */
typedef int ble_att_svr_access_fn(uint16_t conn_handle, uint16_t attr_handle,
                                  uint8_t op, uint16_t offset,
                                  struct os_mbuf **om, void *arg);
 
int ble_att_svr_register(const ble_uuid_t *uuid, uint8_t flags,
                         uint8_t min_key_size, uint16_t *handle_id,
                         ble_att_svr_access_fn *cb, void *cb_arg);
 
struct ble_att_svr_entry {
    STAILQ_ENTRY(ble_att_svr_entry) ha_next;
 
    const ble_uuid_t *ha_uuid;
    uint8_t ha_flags;
    uint8_t ha_min_key_size;
    uint16_t ha_handle_id;
    ble_att_svr_access_fn *ha_cb;
    void *ha_cb_arg;
};
 
SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry);
 
/*** @gen */
 
struct ble_l2cap_chan *ble_att_create_chan(uint16_t conn_handle);
int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
                           struct ble_l2cap_chan **out_chan);
void ble_att_inc_tx_stat(uint8_t att_op);
void ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan,
                             struct os_mbuf *txom);
void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan);
int ble_att_init(void);
 
/*** @svr */
 
int ble_att_svr_start(void);
 
struct ble_att_svr_entry *
ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at,
                         const ble_uuid_t *uuid,
                         uint16_t end_handle);
uint16_t ble_att_svr_prev_handle(void);
int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom);
struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id);
int32_t ble_att_svr_ticks_until_tmo(const struct ble_att_svr_conn *svr,
                                    ble_npl_time_t now);
int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_svr_rx_find_type_value(uint16_t conn_handle,
                                   struct os_mbuf **rxom);
int ble_att_svr_rx_read_type(uint16_t conn_handle,
                             struct os_mbuf **rxom);
int ble_att_svr_rx_read_group_type(uint16_t conn_handle,
                                   struct os_mbuf **rxom);
int ble_att_svr_rx_read(uint16_t conn_handle,
                        struct os_mbuf **rxom);
int ble_att_svr_rx_read_blob(uint16_t conn_handle,
                             struct os_mbuf **rxom);
int ble_att_svr_rx_read_mult(uint16_t conn_handle,
                             struct os_mbuf **rxom);
int ble_att_svr_rx_write(uint16_t conn_handle,
                         struct os_mbuf **rxom);
int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_svr_rx_prep_write(uint16_t conn_handle,
                              struct os_mbuf **rxom);
int ble_att_svr_rx_exec_write(uint16_t conn_handle,
                              struct os_mbuf **rxom);
int ble_att_svr_rx_notify(uint16_t conn_handle,
                          struct os_mbuf **rxom);
int ble_att_svr_rx_indicate(uint16_t conn_handle,
                            struct os_mbuf **rxom);
void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list);
int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle,
                            uint16_t offset, struct os_mbuf *om,
                            uint8_t *out_att_err);
void ble_att_svr_reset(void);
int ble_att_svr_init(void);
 
void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle);
void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle);
 
int ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom,
                             uint8_t req_op, uint16_t handle,
                             uint8_t error_code);
/*** $clt */
 
/** An information-data entry in a find information response. */
struct ble_att_find_info_idata {
    uint16_t attr_handle;
    ble_uuid_any_t uuid;
};
 
/** A handles-information entry in a find by type value response. */
struct ble_att_find_type_value_hinfo {
    uint16_t attr_handle;
    uint16_t group_end_handle;
};
 
/** An attribute-data entry in a read by type response. */
struct ble_att_read_type_adata {
    uint16_t att_handle;
    int value_len;
    uint8_t *value;
 
};
 
/** An attribute-data entry in a read by group type response. */
struct ble_att_read_group_type_adata {
    uint16_t att_handle;
    uint16_t end_group_handle;
    int value_len;
    uint8_t *value;
};
 
int ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu);
int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle);
int ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle,
                             uint16_t offset);
int ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_read_mult(uint16_t conn_handle,
                             const uint16_t *handles, int num_handles);
int ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle,
                             uint16_t end_handle, const ble_uuid_t *uuid);
int ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_read_group_type(uint16_t conn_handle,
                                   uint16_t start_handle, uint16_t end_handle,
                                   const ble_uuid_t *uuid128);
int ble_att_clt_rx_read_group_type(uint16_t conn_handle,
                                   struct os_mbuf **rxom);
int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle,
                             uint16_t end_handle);
int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle,
                                   uint16_t end_handle, uint16_t attribute_type,
                                   const void *attribute_value, int value_len);
int ble_att_clt_rx_find_type_value(uint16_t conn_handle,
                                   struct os_mbuf **rxom);
int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle,
                             struct os_mbuf *txom);
int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle,
                             struct os_mbuf *txom);
int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle,
                              uint16_t offset, struct os_mbuf *txom);
int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags);
int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
                          struct os_mbuf *txom);
int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle,
                            struct os_mbuf *txom);
int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom);
 
#ifdef __cplusplus
}
#endif
 
#endif