GCC Code Coverage Report


Directory: main/
File: bluetooth/att_cfg.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 0 483 0.0%
Functions: 0 21 0.0%
Branches: 0 135 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2019-2023, Jacques Gagnon
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <stdio.h>
7 #include <dirent.h>
8 #include <esp_ota_ops.h>
9 #include <esp_system.h>
10 #include "host.h"
11 #include "hci.h"
12 #include "att.h"
13 #include "att_cfg.h"
14 #include "zephyr/uuid.h"
15 #include "zephyr/att.h"
16 #include "zephyr/gatt.h"
17 #include "adapter/config.h"
18 #include "adapter/memory_card.h"
19 #include "adapter/gameid.h"
20 #include "system/manager.h"
21 #include "system/fs.h"
22
23 #define ATT_MAX_LEN 512
24 #define BR_ABI_VER 2
25
26 #define CFG_CMD_GET_ABI_VER 0x01
27 #define CFG_CMD_GET_FW_VER 0x02
28 #define CFG_CMD_GET_BDADDR 0x03
29 #define CFG_CMD_GET_GAMEID 0x04
30 #define CFG_CMD_GET_CFG_SRC 0x05
31 #define CFG_CMD_GET_FILE 0x06
32 #define CFG_CMD_GET_FW_NAME 0x07
33 #define CFG_CMD_SET_DEFAULT_CFG 0x10
34 #define CFG_CMD_SET_GAMEID_CFG 0x11
35 #define CFG_CMD_OPEN_DIR 0x12
36 #define CFG_CMD_CLOSE_DIR 0x13
37 #define CFG_CMD_DEL_FILE 0x14
38 #define CFG_CMD_SYS_DEEP_SLEEP 0x37
39 #define CFG_CMD_SYS_RESET 0x38
40 #define CFG_CMD_SYS_FACTORY 0x39
41 #define CFG_CMD_OTA_END 0x5A
42 #define CFG_CMD_OTA_START 0xA5
43 #define CFG_CMD_OTA_ABORT 0xDE
44
45 enum {
46 GATT_GRP_HDL = 0x0001,
47 GATT_SRVC_CH_ATT_HDL,
48 GATT_SRVC_CH_CHRC_HDL,
49 GAP_GRP_HDL = 0x0014,
50 GAP_DEV_NAME_ATT_HDL,
51 GAP_DEV_NAME_CHRC_HDL,
52 GAP_APP_ATT_HDL,
53 GAP_APP_CHRC_HDL,
54 GAP_PPCP_ATT_HDL,
55 GAP_PPCP_CHRC_HDL,
56 BR_GRP_HDL = 0x0040,
57 BR_GLBL_CFG_ATT_HDL,
58 BR_GLBL_CFG_CHRC_HDL,
59 BR_OUT_CFG_CTRL_ATT_HDL,
60 BR_OUT_CFG_CTRL_CHRC_HDL,
61 BR_OUT_CFG_DATA_ATT_HDL,
62 BR_OUT_CFG_DATA_CHRC_HDL,
63 BR_IN_CFG_CTRL_ATT_HDL,
64 BR_IN_CFG_CTRL_CHRC_HDL,
65 BR_IN_CFG_DATA_ATT_HDL,
66 BR_IN_CFG_DATA_CHRC_HDL,
67 BR_ABI_VER_ATT_HDL,
68 BR_ABI_VER_CHRC_HDL, /* Deprecated, use BR_CFG_CMD_CHRC_HDL */
69 BR_CFG_CMD_ATT_HDL,
70 BR_CFG_CMD_CHRC_HDL,
71 BR_OTA_FW_DATA_ATT_HDL,
72 BR_OTA_FW_DATA_CHRC_HDL,
73 BR_FW_VER_ATT_HDL,
74 BR_FW_VER_CHRC_HDL, /* Deprecated, use BR_CFG_CMD_CHRC_HDL */
75 BR_MC_CTRL_ATT_HDL,
76 BR_MC_CTRL_CHRC_HDL,
77 BR_MC_DATA_ATT_HDL,
78 BR_MC_DATA_CHRC_HDL,
79 BR_BD_ADDR_ATT_HDL,
80 BR_BD_ADDR_CHRC_HDL, /* Deprecated, use BR_CFG_CMD_CHRC_HDL */
81 LAST_HDL = BR_BD_ADDR_CHRC_HDL,
82 MAX_HDL,
83 };
84
85 static uint8_t br_grp_base_uuid[] = {0x00, 0x9a, 0x79, 0x76, 0xa1, 0x2f, 0x4b, 0x31, 0xb0, 0xfa, 0x80, 0x51, 0x56, 0x0f, 0x83, 0x56};
86
87 static uint16_t mtu = 23;
88 static esp_ota_handle_t ota_hdl = 0;
89 static const esp_partition_t *update_partition = NULL;
90 static uint16_t out_cfg_id = 0;
91 static uint16_t in_cfg_offset = 0;
92 static uint16_t in_cfg_id = 0;
93 static uint32_t mc_offset = 0;
94 static uint8_t cfg_cmd = 0;
95 static DIR *d = NULL;
96 static struct dirent *dir = NULL;
97
98 static void bt_att_cmd_gatt_char_read_type_rsp(uint16_t handle) {
99 struct bt_att_read_type_rsp *rd_type_rsp = (struct bt_att_read_type_rsp *)bt_hci_pkt_tmp.att_data;
100 uint8_t *data = rd_type_rsp->data->value;
101
102 printf("# %s\n", __FUNCTION__);
103
104 rd_type_rsp->len = 7;
105
106 rd_type_rsp->data->handle = GATT_SRVC_CH_ATT_HDL;
107 *data = BT_GATT_CHRC_INDICATE;
108 data++;
109 *(uint16_t *)data = GATT_SRVC_CH_CHRC_HDL;
110 data += 2;
111 *(uint16_t *)data = BT_UUID_GATT_SC;
112
113 bt_att_cmd(handle, BT_ATT_OP_READ_TYPE_RSP, sizeof(rd_type_rsp->len) + rd_type_rsp->len);
114 }
115
116 static void bt_att_cmd_gap_char_read_type_rsp(uint16_t handle) {
117 struct bt_att_read_type_rsp *rd_type_rsp = (struct bt_att_read_type_rsp *)bt_hci_pkt_tmp.att_data;
118 struct bt_att_data *name_data = (struct bt_att_data *)((uint8_t *)rd_type_rsp->data + 0);
119 struct bt_att_data *app_data = (struct bt_att_data *)((uint8_t *)rd_type_rsp->data + 7);
120 struct bt_att_data *ppcp_data = (struct bt_att_data *)((uint8_t *)rd_type_rsp->data + 14);
121 uint8_t *data;
122
123 printf("# %s\n", __FUNCTION__);
124
125 rd_type_rsp->len = 7;
126
127 name_data->handle = GAP_DEV_NAME_ATT_HDL;
128 data = name_data->value;
129 *data = BT_GATT_CHRC_READ;
130 data++;
131 *(uint16_t *)data = GAP_DEV_NAME_CHRC_HDL;
132 data += 2;
133 *(uint16_t *)data = BT_UUID_GAP_DEVICE_NAME;
134
135 app_data->handle = GAP_APP_ATT_HDL;
136 data = app_data->value;
137 *data = BT_GATT_CHRC_READ;
138 data++;
139 *(uint16_t *)data = GAP_APP_CHRC_HDL;
140 data += 2;
141 *(uint16_t *)data = BT_UUID_GAP_APPEARANCE;
142
143 ppcp_data->handle = GAP_PPCP_ATT_HDL;
144 data = ppcp_data->value;
145 *data = BT_GATT_CHRC_READ;
146 data++;
147 *(uint16_t *)data = GAP_PPCP_CHRC_HDL;
148 data += 2;
149 *(uint16_t *)data = BT_UUID_GAP_PPCP;
150
151 bt_att_cmd(handle, BT_ATT_OP_READ_TYPE_RSP, sizeof(rd_type_rsp->len) + rd_type_rsp->len * 3);
152 }
153
154 static void bt_att_cmd_blueretro_char_read_type_rsp(uint16_t handle, uint16_t start) {
155 struct bt_att_read_type_rsp *rd_type_rsp = (struct bt_att_read_type_rsp *)bt_hci_pkt_tmp.att_data;
156 uint8_t *data = rd_type_rsp->data->value;
157
158 printf("# %s\n", __FUNCTION__);
159
160 rd_type_rsp->len = 21;
161
162 if (!(start & 0x01)) {
163 rd_type_rsp->data->handle = start + 1;
164 }
165 else {
166 rd_type_rsp->data->handle = start;
167 }
168
169 switch (rd_type_rsp->data->handle + 1) {
170 case BR_ABI_VER_CHRC_HDL:
171 case BR_FW_VER_CHRC_HDL:
172 case BR_BD_ADDR_CHRC_HDL:
173 *data++ = BT_GATT_CHRC_READ;
174 break;
175 case BR_OUT_CFG_CTRL_CHRC_HDL:
176 case BR_IN_CFG_CTRL_CHRC_HDL:
177 case BR_OTA_FW_DATA_CHRC_HDL:
178 case BR_MC_CTRL_CHRC_HDL:
179 *data++ = BT_GATT_CHRC_WRITE;
180 break;
181 default:
182 *data++ = BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE;
183 break;
184 }
185
186 *(uint16_t *)data = rd_type_rsp->data->handle + 1;
187 data += 2;
188 memcpy(data, br_grp_base_uuid, sizeof(br_grp_base_uuid));
189 *data = (rd_type_rsp->data->handle - BR_GLBL_CFG_ATT_HDL)/2 + 1;
190
191 bt_att_cmd(handle, BT_ATT_OP_READ_TYPE_RSP, sizeof(rd_type_rsp->len) + rd_type_rsp->len);
192 }
193
194 static void bt_att_cmd_dev_name_rd_rsp(uint16_t handle) {
195 const char *str = bt_hci_get_device_name();
196 printf("# %s\n", __FUNCTION__);
197
198 memcpy(bt_hci_pkt_tmp.att_data, str, strlen(str));
199
200 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, strlen(str));
201 }
202
203 static void bt_att_cmd_app_rd_rsp(uint16_t handle) {
204 printf("# %s\n", __FUNCTION__);
205
206 *(uint16_t *)bt_hci_pkt_tmp.att_data = 964; /* HID Gamepad */
207
208 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, sizeof(uint16_t));
209 }
210
211 static void bt_att_cmd_ppcp_rd_rsp(uint16_t handle) {
212 struct bt_l2cap_conn_param_req *conn_param =
213 (struct bt_l2cap_conn_param_req *)bt_hci_pkt_tmp.att_data;
214
215 printf("# %s\n", __FUNCTION__);
216
217 conn_param->min_interval = 6;
218 conn_param->max_interval = 12;
219 conn_param->latency = 0;
220 conn_param->timeout = 960;
221
222 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, sizeof(struct bt_l2cap_conn_param_req));
223 }
224
225 static void bt_att_cmd_global_cfg_rd_rsp(uint16_t handle, uint16_t offset) {
226 uint32_t len = 0;
227 printf("# %s\n", __FUNCTION__);
228
229 len = sizeof(config.global_cfg);
230 memcpy(bt_hci_pkt_tmp.att_data, (void *)&config.global_cfg, len);
231
232 bt_att_cmd(handle, offset ? BT_ATT_OP_READ_BLOB_RSP : BT_ATT_OP_READ_RSP, len);
233 }
234
235 static void bt_att_cmd_out_cfg_rd_rsp(uint16_t handle, uint16_t offset) {
236 uint32_t len = 0;
237 printf("# %s\n", __FUNCTION__);
238
239 if (offset > sizeof(config.out_cfg[0])) {
240 len = 0;
241 }
242 else {
243 len = sizeof(config.out_cfg[0]) - offset;
244
245 if (len > (mtu - 1)) {
246 len = mtu - 1;
247 }
248
249 memcpy(bt_hci_pkt_tmp.att_data, (void *)&config.out_cfg[out_cfg_id] + offset, len);
250 }
251
252 bt_att_cmd(handle, offset ? BT_ATT_OP_READ_BLOB_RSP : BT_ATT_OP_READ_RSP, len);
253 }
254
255 static void bt_att_cmd_in_cfg_rd_rsp(uint16_t handle, uint16_t offset) {
256 uint32_t len = 0;
257 uint32_t cfg_len = (sizeof(config.in_cfg[0]) - (ADAPTER_MAPPING_MAX * sizeof(config.in_cfg[0].map_cfg[0]) - config.in_cfg[in_cfg_id].map_size * sizeof(config.in_cfg[0].map_cfg[0])));
258 uint32_t sum_offset = in_cfg_offset + offset;
259
260 printf("# %s\n", __FUNCTION__);
261
262 if (sum_offset > cfg_len || offset > ATT_MAX_LEN) {
263 len = 0;
264 }
265 else {
266 len = cfg_len - sum_offset;
267
268 if (len > (mtu - 1)) {
269 len = mtu - 1;
270 }
271
272 if ((offset + len) > ATT_MAX_LEN) {
273 len = ATT_MAX_LEN - offset;
274 }
275
276 memcpy(bt_hci_pkt_tmp.att_data, (void *)&config.in_cfg[in_cfg_id] + sum_offset, len);
277 }
278
279 bt_att_cmd(handle, offset ? BT_ATT_OP_READ_BLOB_RSP : BT_ATT_OP_READ_RSP, len);
280 }
281
282 static void bt_att_cmd_mc_rd_rsp(uint16_t handle, uint8_t blob) {
283 uint32_t len = 0;
284 uint32_t block = mc_offset / 4096 + 1;
285 printf("# %s\n", __FUNCTION__);
286
287 len = (block * 4096) - mc_offset;
288
289 if (len > (mtu - 2)) {
290 len = mtu - 2;
291 len &= 0xFFFFFFFC;
292 }
293
294 mc_read(mc_offset, bt_hci_pkt_tmp.att_data, len);
295
296 bt_att_cmd(handle, (blob) ? BT_ATT_OP_READ_BLOB_RSP : BT_ATT_OP_READ_RSP, len);
297
298 mc_offset += len;
299 }
300
301 static void bt_att_cfg_cmd_abi_ver_rsp(uint16_t handle) {
302 printf("# ABI version: %d\n", BR_ABI_VER);
303
304 bt_hci_pkt_tmp.att_data[0] = BR_ABI_VER;
305
306 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, 1);
307 }
308
309 static void bt_att_cfg_cmd_fw_ver_rsp(uint16_t handle) {
310 const esp_app_desc_t *app_desc = esp_app_get_description();
311
312 memcpy(bt_hci_pkt_tmp.att_data, app_desc->version, 23);
313 bt_hci_pkt_tmp.att_data[23] = 0;
314 printf("# %s %s\n", __FUNCTION__, bt_hci_pkt_tmp.att_data);
315
316 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, 23);
317 }
318
319 static void bt_att_cfg_cmd_fw_name_rsp(uint16_t handle) {
320 const esp_app_desc_t *app_desc = esp_app_get_description();
321
322 memcpy(bt_hci_pkt_tmp.att_data, app_desc->project_name, 23);
323 bt_hci_pkt_tmp.att_data[23] = 0;
324 printf("# %s %s\n", __FUNCTION__, bt_hci_pkt_tmp.att_data);
325
326 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, 23);
327 }
328
329 static void bt_att_cfg_cmd_bdaddr_rsp(uint16_t handle) {
330 bt_addr_le_t bdaddr;
331
332 bt_hci_get_le_local_addr(&bdaddr);
333
334 memcpy(bt_hci_pkt_tmp.att_data, bdaddr.a.val, sizeof(bdaddr.a.val));
335
336 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, 6);
337 }
338
339 static void bt_att_cfg_cmd_gameid_rsp(uint16_t handle) {
340 const char *gameid = gid_get();
341 uint32_t len = strlen(gameid);
342
343 if (len > 23) {
344 len = 23;
345 }
346
347 memcpy(bt_hci_pkt_tmp.att_data, gameid, len);
348
349 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, len);
350 }
351
352 static void bt_att_cfg_cmd_cfg_src_rsp(uint16_t handle) {
353 bt_hci_pkt_tmp.att_data[0] = config_get_src();
354 printf("# %s %s\n", __FUNCTION__, bt_hci_pkt_tmp.att_data);
355
356 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, 1);
357 }
358
359 static void bt_att_cfg_cmd_file_rsp(uint16_t handle) {
360 uint32_t len;
361
362 dir = readdir(d);
363
364 if (dir == NULL) {
365 len = 0;
366 }
367 else {
368 len = strlen(dir->d_name);
369 }
370
371 if (len > 23) {
372 len = 23;
373 }
374
375 memcpy(bt_hci_pkt_tmp.att_data, dir->d_name, len);
376
377 bt_att_cmd(handle, BT_ATT_OP_READ_RSP, len);
378 }
379
380 static void bt_att_cmd_read_group_rsp(uint16_t handle, uint16_t start, uint16_t end) {
381 struct bt_att_read_group_rsp *rd_grp_rsp = (struct bt_att_read_group_rsp *)bt_hci_pkt_tmp.att_data;
382 struct bt_att_group_data *gatt_data = (struct bt_att_group_data *)((uint8_t *)rd_grp_rsp->data + 0);
383 struct bt_att_group_data *gap_data = (struct bt_att_group_data *)((uint8_t *)rd_grp_rsp->data + 6);
384 uint32_t len = sizeof(*rd_grp_rsp) - sizeof(rd_grp_rsp->data);
385
386 printf("# %s\n", __FUNCTION__);
387
388 if (start <= GAP_PPCP_CHRC_HDL) {
389 rd_grp_rsp->len = 6;
390
391 if (start <= GATT_GRP_HDL && end >= GATT_SRVC_CH_CHRC_HDL) {
392 gatt_data->start_handle = GATT_GRP_HDL;
393 gatt_data->end_handle = GATT_SRVC_CH_CHRC_HDL;
394 *(uint16_t *)gatt_data->value = BT_UUID_GATT;
395 len += rd_grp_rsp->len;
396 }
397
398 if (start <= GAP_GRP_HDL && end >= GAP_PPCP_CHRC_HDL) {
399 gap_data->start_handle = GAP_GRP_HDL;
400 gap_data->end_handle = GAP_PPCP_CHRC_HDL;
401 *(uint16_t *)gap_data->value = BT_UUID_GAP;
402 len += rd_grp_rsp->len;
403 }
404 }
405 else {
406 rd_grp_rsp->len = 20;
407
408 if (start <= BR_GRP_HDL && end >= LAST_HDL) {
409 gatt_data->start_handle = BR_GRP_HDL;
410 gatt_data->end_handle = LAST_HDL;
411 memcpy(gatt_data->value, br_grp_base_uuid, sizeof(br_grp_base_uuid));
412 len += rd_grp_rsp->len;
413 }
414 }
415
416 bt_att_cmd(handle, BT_ATT_OP_READ_GROUP_RSP, len);
417 }
418
419 static void bt_att_cfg_cmd_rd_hdlr(uint16_t handle) {
420 switch (cfg_cmd) {
421 case CFG_CMD_GET_ABI_VER:
422 bt_att_cfg_cmd_abi_ver_rsp(handle);
423 break;
424 case CFG_CMD_GET_FW_VER:
425 bt_att_cfg_cmd_fw_ver_rsp(handle);
426 break;
427 case CFG_CMD_GET_BDADDR:
428 bt_att_cfg_cmd_bdaddr_rsp(handle);
429 break;
430 case CFG_CMD_GET_GAMEID:
431 bt_att_cfg_cmd_gameid_rsp(handle);
432 break;
433 case CFG_CMD_GET_CFG_SRC:
434 bt_att_cfg_cmd_cfg_src_rsp(handle);
435 break;
436 case CFG_CMD_GET_FILE:
437 bt_att_cfg_cmd_file_rsp(handle);
438 break;
439 case CFG_CMD_GET_FW_NAME:
440 bt_att_cfg_cmd_fw_name_rsp(handle);
441 break;
442 default:
443 printf("# Invalid read cfg cmd: %02X\n", cfg_cmd);
444 bt_att_cfg_cmd_abi_ver_rsp(handle);
445 break;
446 }
447 }
448
449 static void bt_att_cfg_cmd_wr_hdlr(struct bt_dev *device, uint8_t *data, uint32_t len) {
450 cfg_cmd = data[0];
451
452 switch (cfg_cmd) {
453 case CFG_CMD_SET_DEFAULT_CFG:
454 {
455 char tmp_str[32] = "/fs/";
456 config_init(DEFAULT_CFG);
457 strcat(tmp_str, gid_get());
458 remove(tmp_str);
459 break;
460 }
461 case CFG_CMD_SET_GAMEID_CFG:
462 config_update(GAMEID_CFG);
463 break;
464 case CFG_CMD_OTA_START:
465 update_partition = esp_ota_get_next_update_partition(NULL);
466 if (esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &ota_hdl) == 0) {
467 printf("# OTA FW Update started...\n");
468 }
469 else {
470 esp_ota_abort(ota_hdl);
471 ota_hdl = 0;
472 printf("# OTA FW Update start fail\n");
473 }
474 break;
475 case CFG_CMD_OTA_END:
476 if (esp_ota_end(ota_hdl) == 0) {
477 if (esp_ota_set_boot_partition(update_partition) == 0) {
478 ota_hdl = 0;
479 sys_mgr_cmd(SYS_MGR_CMD_ADAPTER_RST);
480 printf("# OTA FW Update sucessfull! Restarting...\n");
481 }
482 else {
483 printf("# OTA FW Update set partition fail\n");
484 }
485 }
486 else {
487 printf("# OTA FW Update end fail\n");
488 }
489 break;
490 case CFG_CMD_SYS_DEEP_SLEEP:
491 printf("# ESP32 going in deep sleep\n");
492 sys_mgr_cmd(SYS_MGR_CMD_DEEP_SLEEP);
493 break;
494 case CFG_CMD_SYS_RESET:
495 {
496 printf("# Reset ESP32\n");
497 sys_mgr_cmd(SYS_MGR_CMD_ADAPTER_RST);
498 break;
499 }
500 case CFG_CMD_SYS_FACTORY:
501 {
502 sys_mgr_cmd(SYS_MGR_CMD_FACTORY_RST);
503 break;
504 }
505 case CFG_CMD_OTA_ABORT:
506 if (ota_hdl) {
507 esp_ota_abort(ota_hdl);
508 ota_hdl = 0;
509 printf("# OTA FW Update abort from WebUI\n");
510 }
511 break;
512 case CFG_CMD_OPEN_DIR:
513 if (d) {
514 closedir(d);
515 }
516 d = opendir(ROOT);
517 break;
518 case CFG_CMD_CLOSE_DIR:
519 if (d) {
520 closedir(d);
521 }
522 break;
523 case CFG_CMD_DEL_FILE:
524 {
525 char tmp_str[32] = "/fs/";
526 memcpy(&tmp_str[4], &data[1], len - 1);
527 tmp_str[4 + len - 1] = 0;
528 printf("# delete file: %s\n", tmp_str);
529 if (strncmp(&tmp_str[4], gid_get(), len) == 0) {
530 printf("# Deleting current cfg, switch to default\n");
531 config_init(DEFAULT_CFG);
532 }
533 remove(tmp_str);
534 break;
535 }
536 default:
537 break;
538 }
539 bt_att_cmd_wr_rsp(device->acl_handle);
540 }
541
542 void bt_att_cfg_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint32_t len) {
543 switch (bt_hci_acl_pkt->att_hdr.code) {
544 case BT_ATT_OP_MTU_REQ:
545 {
546 struct bt_att_exchange_mtu_req *mtu_req = (struct bt_att_exchange_mtu_req *)bt_hci_acl_pkt->att_data;
547 uint16_t max_mtu = bt_att_get_le_max_mtu();
548 printf("# BT_ATT_OP_MTU_REQ\n");
549 if (mtu_req->mtu < max_mtu) {
550 mtu = mtu_req->mtu;
551 }
552 else {
553 mtu = max_mtu;
554 }
555 printf("# Set mtu %d\n", mtu);
556 bt_att_cmd_mtu_rsp(device->acl_handle, mtu);
557 break;
558 }
559 case BT_ATT_OP_FIND_INFO_REQ:
560 {
561 struct bt_att_find_info_req *find_info_req = (struct bt_att_find_info_req *)bt_hci_acl_pkt->att_data;
562 printf("# BT_ATT_OP_FIND_INFO_REQ %04X %04X\n", find_info_req->start_handle, find_info_req->end_handle);
563 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_FIND_INFO_REQ, find_info_req->start_handle, BT_ATT_ERR_NOT_SUPPORTED);
564 break;
565 }
566 case BT_ATT_OP_FIND_TYPE_REQ:
567 {
568 struct bt_att_find_type_req *fd_type_req = (struct bt_att_find_type_req *)bt_hci_acl_pkt->att_data;
569 printf("# BT_ATT_OP_FIND_TYPE_REQ %04X %04X\n", fd_type_req->start_handle, fd_type_req->end_handle);
570 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_FIND_TYPE_REQ, fd_type_req->start_handle, BT_ATT_ERR_NOT_SUPPORTED);
571 break;
572 }
573 case BT_ATT_OP_READ_TYPE_REQ:
574 {
575 struct bt_att_read_type_req *rd_type_req = (struct bt_att_read_type_req *)bt_hci_acl_pkt->att_data;
576 printf("# BT_ATT_OP_READ_TYPE_REQ\n");
577 uint16_t start = rd_type_req->start_handle;
578 uint16_t end = rd_type_req->end_handle;
579
580 if (*(uint16_t *)rd_type_req->uuid == BT_UUID_GATT_CHRC) {
581 /* GATT */
582 if (start >= GATT_GRP_HDL && start < GATT_SRVC_CH_CHRC_HDL && end >= GATT_SRVC_CH_CHRC_HDL) {
583 bt_att_cmd_gatt_char_read_type_rsp(device->acl_handle);
584 }
585 /* GAP */
586 else if (start >= GATT_SRVC_CH_CHRC_HDL && start < GAP_PPCP_CHRC_HDL && end >= GAP_PPCP_CHRC_HDL) {
587 bt_att_cmd_gap_char_read_type_rsp(device->acl_handle);
588 }
589 /* BLUERETRO */
590 else if (start >= GAP_PPCP_CHRC_HDL && start < LAST_HDL && end >= LAST_HDL) {
591 bt_att_cmd_blueretro_char_read_type_rsp(device->acl_handle, start);
592 }
593 else {
594 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_READ_TYPE_REQ, rd_type_req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
595 }
596 }
597 else {
598 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_READ_TYPE_REQ, rd_type_req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
599 }
600 break;
601 }
602 case BT_ATT_OP_READ_REQ:
603 {
604 struct bt_att_read_req *rd_req = (struct bt_att_read_req *)bt_hci_acl_pkt->att_data;
605 printf("# BT_ATT_OP_READ_REQ\n");
606
607 switch (rd_req->handle) {
608 case GAP_DEV_NAME_CHRC_HDL:
609 bt_att_cmd_dev_name_rd_rsp(device->acl_handle);
610 break;
611 case GAP_APP_CHRC_HDL:
612 bt_att_cmd_app_rd_rsp(device->acl_handle);
613 break;
614 case GAP_PPCP_CHRC_HDL:
615 bt_att_cmd_ppcp_rd_rsp(device->acl_handle);
616 break;
617 case BR_GLBL_CFG_CHRC_HDL:
618 bt_att_cmd_global_cfg_rd_rsp(device->acl_handle, 0);
619 break;
620 case BR_OUT_CFG_DATA_CHRC_HDL:
621 bt_att_cmd_out_cfg_rd_rsp(device->acl_handle, 0);
622 break;
623 case BR_IN_CFG_DATA_CHRC_HDL:
624 bt_att_cmd_in_cfg_rd_rsp(device->acl_handle, 0);
625 break;
626 case BR_ABI_VER_CHRC_HDL:
627 bt_att_cfg_cmd_abi_ver_rsp(device->acl_handle);
628 break;
629 case BR_FW_VER_CHRC_HDL:
630 bt_att_cfg_cmd_fw_ver_rsp(device->acl_handle);
631 break;
632 case BR_MC_DATA_CHRC_HDL:
633 bt_att_cmd_mc_rd_rsp(device->acl_handle, 0);
634 break;
635 case BR_BD_ADDR_CHRC_HDL:
636 bt_att_cfg_cmd_bdaddr_rsp(device->acl_handle);
637 break;
638 case BR_CFG_CMD_CHRC_HDL:
639 if (!atomic_test_bit(&device->flags, BT_DEV_PPCP_DONE)) {
640 struct hci_cp_le_conn_update le_conn_update = {
641 .conn_interval_min = 6,
642 .conn_interval_max = 12,
643 .conn_latency = 0,
644 .supervision_timeout = 960,
645 .min_ce_len = 0,
646 .max_ce_len = 0,
647 };
648
649 le_conn_update.handle = device->acl_handle;
650
651 bt_hci_le_conn_update(&le_conn_update);
652 atomic_set_bit(&device->flags, BT_DEV_PPCP_DONE);
653 }
654 bt_att_cfg_cmd_rd_hdlr(device->acl_handle);
655 break;
656 default:
657 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_READ_REQ, rd_req->handle, BT_ATT_ERR_INVALID_HANDLE);
658 break;
659 }
660 break;
661 }
662 case BT_ATT_OP_READ_BLOB_REQ:
663 {
664 struct bt_att_read_blob_req *rd_blob_req = (struct bt_att_read_blob_req *)bt_hci_acl_pkt->att_data;
665 printf("# BT_ATT_OP_READ_BLOB_RSP\n");
666
667 switch (rd_blob_req->handle) {
668 case BR_GLBL_CFG_CHRC_HDL:
669 bt_att_cmd_global_cfg_rd_rsp(device->acl_handle, rd_blob_req->offset);
670 break;
671 case BR_OUT_CFG_DATA_CHRC_HDL:
672 bt_att_cmd_out_cfg_rd_rsp(device->acl_handle, rd_blob_req->offset);
673 break;
674 case BR_IN_CFG_DATA_CHRC_HDL:
675 bt_att_cmd_in_cfg_rd_rsp(device->acl_handle, rd_blob_req->offset);
676 break;
677 case BR_MC_DATA_CHRC_HDL:
678 bt_att_cmd_mc_rd_rsp(device->acl_handle, 1);
679 break;
680 default:
681 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_READ_BLOB_REQ, rd_blob_req->handle, BT_ATT_ERR_INVALID_HANDLE);
682 break;
683 }
684 break;
685 }
686 case BT_ATT_OP_READ_GROUP_REQ:
687 {
688 struct bt_att_read_group_req *rd_grp_req = (struct bt_att_read_group_req *)bt_hci_acl_pkt->att_data;
689 printf("# BT_ATT_OP_READ_GROUP_REQ\n");
690 if (rd_grp_req->start_handle < MAX_HDL && *(uint16_t *)rd_grp_req->uuid == BT_UUID_GATT_PRIMARY) {
691 bt_att_cmd_read_group_rsp(device->acl_handle, rd_grp_req->start_handle, rd_grp_req->end_handle);
692 }
693 else {
694 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_READ_GROUP_REQ, rd_grp_req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
695 }
696 break;
697 }
698 case BT_ATT_OP_WRITE_REQ:
699 {
700 struct bt_att_write_req *wr_req = (struct bt_att_write_req *)bt_hci_acl_pkt->att_data;
701 uint16_t *data = (uint16_t *)wr_req->value;
702 uint32_t att_len = len - (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE + sizeof(struct bt_l2cap_hdr) + sizeof(struct bt_att_hdr));
703 uint32_t data_len = att_len - sizeof(wr_req->handle);
704
705 /* Disable debug tracing */
706 if (config.global_cfg.banksel == CONFIG_BANKSEL_DBG) {
707 config.global_cfg.banksel = 0xFF;
708 }
709
710 printf("# BT_ATT_OP_WRITE_REQ len: %ld\n", data_len);
711 switch (wr_req->handle) {
712 case BR_GLBL_CFG_CHRC_HDL:
713 printf("# BR_GLBL_CFG_CHRC_HDL %04X\n", wr_req->handle);
714 memcpy((void *)&config.global_cfg, wr_req->value, sizeof(config.global_cfg));
715 config_update(config_get_src());
716 bt_att_cmd_wr_rsp(device->acl_handle);
717 break;
718 case BR_OUT_CFG_DATA_CHRC_HDL:
719 memcpy((void *)&config.out_cfg[out_cfg_id], wr_req->value, sizeof(config.out_cfg[0]));
720 config_update(config_get_src());
721 bt_att_cmd_wr_rsp(device->acl_handle);
722 break;
723 case BR_IN_CFG_DATA_CHRC_HDL:
724 memcpy((void *)&config.in_cfg[in_cfg_id] + in_cfg_offset, wr_req->value, data_len);
725 config_update(config_get_src());
726 bt_att_cmd_wr_rsp(device->acl_handle);
727 break;
728 case BR_OUT_CFG_CTRL_CHRC_HDL:
729 out_cfg_id = *data;
730 bt_att_cmd_wr_rsp(device->acl_handle);
731 break;
732 case BR_IN_CFG_CTRL_CHRC_HDL:
733 in_cfg_id = *data++;
734 in_cfg_offset = *data;
735 bt_att_cmd_wr_rsp(device->acl_handle);
736 break;
737 case BR_CFG_CMD_CHRC_HDL:
738 bt_att_cfg_cmd_wr_hdlr(device, wr_req->value, data_len);
739 break;
740 case BR_OTA_FW_DATA_CHRC_HDL:
741 esp_ota_write(ota_hdl, wr_req->value, data_len);
742 bt_att_cmd_wr_rsp(device->acl_handle);
743 break;
744 case BR_MC_CTRL_CHRC_HDL:
745 mc_offset = *(uint32_t *)wr_req->value;
746 bt_att_cmd_wr_rsp(device->acl_handle);
747 break;
748 case BR_MC_DATA_CHRC_HDL:
749 mc_write(mc_offset, wr_req->value, data_len);
750 mc_offset += data_len;
751 bt_att_cmd_wr_rsp(device->acl_handle);
752 break;
753 default:
754 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_WRITE_REQ, wr_req->handle, BT_ATT_ERR_INVALID_HANDLE);
755 break;
756 }
757 break;
758 }
759 case BT_ATT_OP_PREPARE_WRITE_REQ:
760 {
761 struct bt_att_prepare_write_req *prep_wr_req = (struct bt_att_prepare_write_req *)bt_hci_acl_pkt->att_data;
762 uint32_t att_len = len - (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE + sizeof(struct bt_l2cap_hdr) + sizeof(struct bt_att_hdr));
763 uint32_t data_len = att_len - (sizeof(prep_wr_req->handle) + sizeof(prep_wr_req->offset));
764 printf("# BT_ATT_OP_PREPARE_WRITE_REQ len: %ld offset: %d\n", data_len, prep_wr_req->offset);
765 switch (prep_wr_req->handle) {
766 case BR_IN_CFG_DATA_CHRC_HDL:
767 memcpy((void *)&config.in_cfg[in_cfg_id] + in_cfg_offset + prep_wr_req->offset, prep_wr_req->value, data_len);
768 bt_att_cmd_prep_wr_rsp(device->acl_handle, bt_hci_acl_pkt->att_data, att_len);
769 break;
770 case BR_OTA_FW_DATA_CHRC_HDL:
771 esp_ota_write(ota_hdl, prep_wr_req->value, data_len);
772 bt_att_cmd_prep_wr_rsp(device->acl_handle, bt_hci_acl_pkt->att_data, att_len);
773 break;
774 case BR_MC_DATA_CHRC_HDL:
775 mc_write(mc_offset, prep_wr_req->value, data_len);
776 mc_offset += data_len;
777 bt_att_cmd_prep_wr_rsp(device->acl_handle, bt_hci_acl_pkt->att_data, att_len);
778 break;
779 default:
780 bt_att_cmd_error_rsp(device->acl_handle, BT_ATT_OP_PREPARE_WRITE_REQ, prep_wr_req->handle, BT_ATT_ERR_INVALID_HANDLE);
781 break;
782 }
783 break;
784 }
785 case BT_ATT_OP_EXEC_WRITE_REQ:
786 {
787 struct bt_att_exec_write_req *exec_wr_req = (struct bt_att_exec_write_req *)bt_hci_acl_pkt->att_data;
788 printf("# BT_ATT_OP_EXEC_WRITE_REQ\n");
789 if (!ota_hdl && exec_wr_req->flags == BT_ATT_FLAG_EXEC) {
790 config_update(config_get_src());
791 }
792 bt_att_cmd_exec_wr_rsp(device->acl_handle);
793 break;
794 }
795 default:
796 printf("# Unsupported OPCODE: 0x%02X\n", bt_hci_acl_pkt->att_hdr.code);
797 }
798 }
799