fix: 对不支持weak的bsp, luat_http_client_onevent报重复定义了
[LuatOS.git] / components / nimble / src / luat_nimble_mode_peripheral.c
blobf2a7b1b624d49d512033a5c751d2227ad33bb25b
2 #include <assert.h>
3 #include <stdio.h>
4 #include <string.h>
6 #include "luat_base.h"
7 #if (defined(TLS_CONFIG_CPU_XT804))
8 #include "FreeRTOS.h"
9 #else
10 #include "freertos/FreeRTOS.h"
11 #endif
13 #include "host/ble_hs.h"
14 #include "host/ble_uuid.h"
15 #include "host/util/util.h"
16 #include "services/gap/ble_svc_gap.h"
17 #include "services/gatt/ble_svc_gatt.h"
19 #include "luat_msgbus.h"
20 #include "luat_mem.h"
21 #include "luat_nimble.h"
23 /* BLE */
24 #include "nimble/nimble_port.h"
26 typedef void (*TaskFunction_t)( void * );
28 struct ble_hs_cfg;
29 struct ble_gatt_register_ctxt;
31 static void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
32 static int gatt_svr_init(void);
34 extern uint16_t g_ble_conn_handle;
35 extern uint16_t g_ble_state;
37 extern ble_uuid_any_t ble_peripheral_srv_uuid;
39 extern uint16_t s_chr_flags[];
40 extern ble_uuid_any_t s_chr_uuids[];
41 extern uint16_t s_chr_val_handles[];
42 extern uint8_t s_chr_notify_states[];
43 extern uint8_t s_chr_indicate_states[];
45 #define LUAT_LOG_TAG "nimble"
46 #include "luat_log.h"
48 extern uint8_t luat_ble_dev_name[];
49 extern size_t luat_ble_dev_name_len;
50 extern struct ble_gap_adv_params adv_params;
52 static uint8_t buff_for_read[256];
53 static uint8_t buff_for_read_size;
55 typedef struct ble_write_msg {
56 // uint16_t conn_handle,
57 // uint16_t attr_handle,
58 ble_uuid_t* uuid;
59 uint16_t len;
60 char buff[1];
61 }ble_write_msg_t;
63 static int
64 gatt_svr_chr_access_func(uint16_t conn_handle, uint16_t attr_handle,
65 struct ble_gatt_access_ctxt *ctxt, void *arg);
68 int luat_nimble_peripheral_set_chr(int index, ble_uuid_any_t* chr_uuid, int flags) {
69 if (index < 0 || index >= LUAT_BLE_MAX_CHR)
70 return -1;
71 char buff[BLE_UUID_STR_LEN + 1];
72 ble_uuid_to_str(chr_uuid, buff);
73 // LLOGD("set chr[%d] %s flags %d", index, buff, flags);
74 ble_uuid_copy(&s_chr_uuids[index], chr_uuid);
75 s_chr_flags[index] = flags;
76 return 0;
79 static void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
81 char buf[BLE_UUID_STR_LEN];
82 // LLOGD("gatt_svr_register_cb op %d", ctxt->op);
83 switch (ctxt->op) {
84 case BLE_GATT_REGISTER_OP_SVC:
85 // LLOGD("registered service %s with handle=%d",
86 // ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
87 // ctxt->svc.handle);
88 break;
90 case BLE_GATT_REGISTER_OP_CHR:
91 // LLOGD("registering characteristic %s with "
92 // "def_handle=%d val_handle=%d",
93 // ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
94 // ctxt->chr.def_handle,
95 // ctxt->chr.val_handle);
96 break;
98 case BLE_GATT_REGISTER_OP_DSC:
99 // LLOGD("registering descriptor %s with handle=%d",
100 // ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
101 // ctxt->dsc.handle);
102 break;
104 default:
105 // assert(0);
106 break;
110 static int l_ble_chr_write_cb(lua_State* L, void* ptr) {
111 ble_write_msg_t* wmsg = (ble_write_msg_t*)ptr;
112 rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
113 lua_getglobal(L, "sys_pub");
114 if (lua_isfunction(L, -1)) {
115 lua_pushstring(L, "BLE_GATT_WRITE_CHR");
116 lua_newtable(L);
117 char buff[BLE_UUID_STR_LEN] = {0};
118 for (size_t i = 0; i < LUAT_BLE_MAX_CHR; i++)
120 if (s_chr_val_handles[i] == msg->arg2) {
121 ble_uuid_to_str(&s_chr_uuids[i], buff);
122 lua_pushstring(L, buff);
123 lua_setfield(L, -2, "chr_uuid");
124 break;
127 lua_pushlstring(L, wmsg->buff, wmsg->len);
128 lua_call(L, 3, 0);
130 luat_heap_free(wmsg);
131 return 0;
136 static int l_ble_chr_read_cb(lua_State* L, void* ptr) {
137 lua_getglobal(L, "sys_pub");
138 if (lua_isfunction(L, -1)) {
139 lua_pushstring(L, "BLE_GATT_READ_CHR");
140 lua_call(L, 1, 0);
142 return 0;
145 static int l_ble_state_cb(lua_State* L, void* ptr) {
146 rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
147 lua_getglobal(L, "sys_pub");
148 if (lua_isfunction(L, -1)) {
149 lua_pushstring(L, "BLE_SERVER_STATE_UPD");
150 lua_pushinteger(L, msg->arg1);
151 lua_call(L, 2, 0);
153 return 0;
156 static int
157 gatt_svr_chr_access_func(uint16_t conn_handle, uint16_t attr_handle,
158 struct ble_gatt_access_ctxt *ctxt, void *arg)
160 int rc = 0;
161 struct os_mbuf *om = ctxt->om;
162 ble_write_msg_t* wmsg;
163 rtos_msg_t msg = {0};
164 char buff[BLE_UUID_STR_LEN + 1] = {0};
165 int handle_index = -1;
166 for (size_t i = 0; i < LUAT_BLE_MAX_CHR; i++)
168 if (attr_handle == s_chr_val_handles[i]) {
169 ble_uuid_to_str(&s_chr_uuids[i], buff);
170 handle_index = i;
171 break;
175 LLOGD("gatt_svr_chr_access_func %d %d-%s %d", conn_handle, attr_handle, buff, ctxt->op);
176 switch (ctxt->op) {
177 case BLE_GATT_ACCESS_OP_WRITE_CHR:
178 wmsg = (ble_write_msg_t*)(luat_heap_malloc(sizeof(ble_write_msg_t) + MYNEWT_VAL(BLE_ATT_PREFERRED_MTU) - 1));
179 if (!wmsg) {
180 LLOGW("out of memory when malloc ble_write_msg_t");
181 return 0;
183 memset(wmsg, 0, sizeof(ble_write_msg_t) + MYNEWT_VAL(BLE_ATT_PREFERRED_MTU) - 1);
184 msg.handler = l_ble_chr_write_cb;
185 msg.ptr = wmsg;
186 msg.arg1 = conn_handle;
187 msg.arg2 = attr_handle;
188 while(om) {
189 memcpy(&wmsg->buff[wmsg->len], om->om_data, om->om_len);
190 wmsg->len += om->om_len;
191 om = SLIST_NEXT(om, om_next);
193 luat_msgbus_put(&msg, 0);
194 return 0;
195 case BLE_GATT_ACCESS_OP_READ_CHR:
196 LLOGD("gatt svr read size = %d", buff_for_read_size);
197 if (buff_for_read_size) {
198 rc = os_mbuf_append(ctxt->om, buff_for_read, buff_for_read_size);
199 buff_for_read_size = 0;
200 msg.handler = l_ble_chr_read_cb;
201 luat_msgbus_put(&msg, 0);
202 return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
204 return 0;
205 default:
206 // assert(0);
207 return BLE_ATT_ERR_UNLIKELY;
211 static struct ble_gatt_svc_def gatt_svr_svcs[] = {
213 .type = BLE_GATT_SVC_TYPE_PRIMARY,
214 .uuid = &ble_peripheral_srv_uuid,
215 .characteristics = (struct ble_gatt_chr_def[]) {
216 {0}, {0}, {0}, {0}
220 0, /* No more services */
224 static int gatt_svr_init(void)
226 int rc;
228 // ble_svc_gap_init();
229 //ble_gatts_reset();
230 // ble_svc_gatt_init();
232 struct ble_gatt_chr_def defs[] =
234 // .uuid = &ble_peripheral_write_uuid,
235 .uuid = &s_chr_uuids[0],
236 .val_handle = &s_chr_val_handles[0],
237 .access_cb = gatt_svr_chr_access_func,
238 .flags = s_chr_flags[0]
239 }, {
240 // .uuid = &ble_peripheral_indicate_uuid,
241 .uuid = &s_chr_uuids[1],
242 .val_handle = &s_chr_val_handles[1],
243 .access_cb = gatt_svr_chr_access_func,
244 .flags = s_chr_flags[1]
245 }, {
246 // .uuid = &ble_peripheral_notify_uuid,
247 .uuid = &s_chr_uuids[2],
248 .val_handle = &s_chr_val_handles[2],
249 .access_cb = gatt_svr_chr_access_func,
250 .flags = s_chr_flags[2]
251 }, {
252 0, /* No more characteristics in this service */
255 memcpy(gatt_svr_svcs[0].characteristics, defs, sizeof(defs));
257 char buff[BLE_UUID_STR_LEN + 1];
258 ble_uuid_to_str(defs[0].uuid, buff);
259 LLOGD("chr %s flags %d", buff,defs[0].flags);
260 ble_uuid_to_str(defs[1].uuid, buff);
261 LLOGD("chr %s flags %d", buff,defs[1].flags);
262 ble_uuid_to_str(defs[2].uuid, buff);
263 LLOGD("chr %s flags %d", buff,defs[2].flags);
265 rc = ble_gatts_count_cfg(gatt_svr_svcs);
266 if (rc != 0) {
267 LLOGE("ble_gatts_count_cfg rc %d", rc);
268 return rc;
271 rc = ble_gatts_add_svcs(gatt_svr_svcs);
272 if (rc != 0) {
273 LLOGE("ble_gatts_add_svcs rc %d", rc);
274 return rc;
276 return 0;
279 int luat_nimble_server_send(int id, char* data, size_t data_len) {
280 int rc;
281 struct os_mbuf *om;
283 if (g_ble_state != BT_STATE_CONNECTED) {
284 //LLOGI("Not connected yet");
285 return -1;
287 if (data_len <= 256) {
288 memcpy(buff_for_read, data, data_len);
289 buff_for_read_size = data_len;
291 else {
292 LLOGW("BLE package limit to 256 bytes");
293 return 1;
296 // 先发indicate, TODO 判断是否有监听
297 om = ble_hs_mbuf_from_flat((const void*)data, (uint16_t)data_len);
298 if (!om) {
299 LLOGE("ble_hs_mbuf_from_flat return NULL!!");
300 return BLE_HS_ENOMEM;
302 rc = ble_gattc_indicate_custom(g_ble_conn_handle, s_chr_val_handles[1], om);
303 LLOGD("ble_gattc_indicate_custom ret %d", rc);
305 // 然后发notify, TODO 判断是否有监听
306 om = ble_hs_mbuf_from_flat((const void*)data, (uint16_t)data_len);
307 if (om) {
308 rc = ble_gattc_notify_custom(g_ble_conn_handle, s_chr_val_handles[2], om);
309 LLOGD("ble_gattc_notify_custom ret %d", rc);
311 return rc;
314 int luat_nimble_server_send_notify(ble_uuid_any_t* srv, ble_uuid_any_t* chr, char* data, size_t data_len) {
315 int rc = 0;
316 struct os_mbuf *om;
317 uint16_t handle = 0;
318 char buff[BLE_UUID_STR_LEN] = {0};
319 ble_uuid_to_str(chr, buff);
320 for (size_t i = 0; i < LUAT_BLE_MAX_CHR; i++)
322 if (!ble_uuid_cmp(&s_chr_uuids[i], chr)) {
323 if (s_chr_notify_states[i] == 0) {
324 LLOGW("chr notify %s state == 0, skip", buff);
325 return -1;
327 om = ble_hs_mbuf_from_flat((const void*)data, (uint16_t)data_len);
328 if (!om) {
329 LLOGE("ble_hs_mbuf_from_flat return NULL!!");
330 return BLE_HS_ENOMEM;
332 rc = ble_gattc_notify_custom(g_ble_conn_handle, s_chr_val_handles[i], om);
333 LLOGD("ble_gattc_notify %s len %d ret %d", buff, data_len, rc);
334 return 0;
337 LLOGD("ble_gattc_notify not such chr %s", buff);
338 return -1;
341 int luat_nimble_server_send_indicate(ble_uuid_any_t* srv, ble_uuid_any_t* chr, char* data, size_t data_len) {
342 int rc = 0;
343 struct os_mbuf *om;
344 uint16_t handle = 0;
345 for (size_t i = 0; i < LUAT_BLE_MAX_CHR; i++)
347 if (!ble_uuid_cmp(&s_chr_uuids[i], chr)) {
348 if (s_chr_indicate_states[i] == 0) {
349 LLOGW("chr indicate state == 0, skip");
350 return -1;
352 om = ble_hs_mbuf_from_flat((const void*)data, (uint16_t)data_len);
353 if (!om) {
354 LLOGE("ble_hs_mbuf_from_flat return NULL!!");
355 return BLE_HS_ENOMEM;
357 rc = ble_gattc_indicate_custom(g_ble_conn_handle, s_chr_val_handles[i], om);
358 LLOGD("ble_gattc_indicate_custom ret %d", rc);
359 return 0;
362 return -1;
366 // static const char *tag = "NimBLE_BLE_PRPH";
367 static int bleprph_gap_event(struct ble_gap_event *event, void *arg);
368 #if CONFIG_EXAMPLE_RANDOM_ADDR
369 static uint8_t own_addr_type = BLE_OWN_ADDR_RANDOM;
370 #else
371 static uint8_t own_addr_type;
372 #endif
374 void ble_store_config_init(void);
377 * Logs information about a connection to the console.
380 #define ADDR_FMT "%02X%02X%02X%02X%02X%02X"
381 #define ADDR_T(addr) addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]
383 static void
384 bleprph_print_conn_desc(struct ble_gap_conn_desc *desc)
386 LLOGI("handle=%d our_ota_addr_type=%d our_ota_addr=" ADDR_FMT, desc->conn_handle, desc->our_ota_addr.type, ADDR_T(desc->our_ota_addr.val));
387 LLOGI(" our_id_addr_type=%d our_id_addr=" ADDR_FMT, desc->our_id_addr.type, ADDR_T(desc->our_id_addr.val));
388 LLOGI(" peer_ota_addr_type=%d peer_ota_addr=" ADDR_FMT, desc->peer_ota_addr.type, ADDR_T(desc->peer_ota_addr.val));
389 LLOGI(" peer_id_addr_type=%d peer_id_addr=" ADDR_FMT, desc->peer_id_addr.type, ADDR_T(desc->peer_id_addr.val));
390 LLOGI(" conn_itvl=%d conn_latency=%d supervision_timeout=%d "
391 "encrypted=%d authenticated=%d bonded=%d",
392 desc->conn_itvl, desc->conn_latency,
393 desc->supervision_timeout,
394 desc->sec_state.encrypted,
395 desc->sec_state.authenticated,
396 desc->sec_state.bonded);
399 #if CONFIG_EXAMPLE_EXTENDED_ADV
401 * Enables advertising with the following parameters:
402 * o General discoverable mode.
403 * o Undirected connectable mode.
405 static void
406 ext_bleprph_advertise(void)
408 struct ble_gap_ext_adv_params params;
409 struct os_mbuf *data;
410 uint8_t instance = 1;
411 int rc;
413 /* use defaults for non-set params */
414 memset (&params, 0, sizeof(params));
416 /* enable connectable advertising */
417 params.connectable = 1;
418 params.scannable = 1;
419 params.legacy_pdu = 1;
421 /* advertise using random addr */
422 params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
424 params.primary_phy = BLE_HCI_LE_PHY_1M;
425 params.secondary_phy = BLE_HCI_LE_PHY_2M;
426 //params.tx_power = 127;
427 params.sid = 1;
429 params.itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN;
430 params.itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MIN;
432 /* configure instance 0 */
433 rc = ble_gap_ext_adv_configure(instance, &params, NULL,
434 bleprph_gap_event, NULL);
435 assert (rc == 0);
437 /* in this case only scan response is allowed */
439 /* get mbuf for scan rsp data */
440 data = os_msys_get_pkthdr(sizeof(ext_adv_pattern_1), 0);
441 assert(data);
443 /* fill mbuf with scan rsp data */
444 rc = os_mbuf_append(data, ext_adv_pattern_1, sizeof(ext_adv_pattern_1));
445 assert(rc == 0);
447 rc = ble_gap_ext_adv_set_data(instance, data);
448 assert (rc == 0);
450 /* start advertising */
451 rc = ble_gap_ext_adv_start(instance, 0, 0);
452 assert (rc == 0);
454 #else
456 * Enables advertising with the following parameters:
457 * o General discoverable mode.
458 * o Undirected connectable mode.
460 static void
461 bleprph_advertise(void)
463 // struct ble_gap_adv_params adv_params;
464 struct ble_hs_adv_fields fields;
465 const char *name;
466 int rc;
469 * Set the advertisement data included in our advertisements:
470 * o Flags (indicates advertisement type and other general info).
471 * o Advertising tx power.
472 * o Device name.
473 * o 16-bit service UUIDs (alert notifications).
476 memset(&fields, 0, sizeof fields);
478 /* Advertise two flags:
479 * o Discoverability in forthcoming advertisement (general)
480 * o BLE-only (BR/EDR unsupported).
482 fields.flags = BLE_HS_ADV_F_DISC_GEN |
483 BLE_HS_ADV_F_BREDR_UNSUP;
485 /* Indicate that the TX power level field should be included; have the
486 * stack fill this value automatically. This is done by assigning the
487 * special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
489 fields.tx_pwr_lvl_is_present = 1;
490 fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
492 name = ble_svc_gap_device_name();
493 fields.name = (uint8_t *)name;
494 fields.name_len = strlen(name);
495 fields.name_is_complete = 1;
497 // fields.uuids16 = (ble_uuid16_t[]) {
498 // ble_peripheral_srv_uuid
499 // };
500 fields.uuids16 = (const ble_uuid16_t *)&ble_peripheral_srv_uuid;
501 fields.num_uuids16 = 1;
502 fields.uuids16_is_complete = 1;
504 rc = ble_gap_adv_set_fields(&fields);
505 if (rc != 0) {
506 LLOGE("error setting advertisement data; rc=%d", rc);
507 return;
510 /* Begin advertising. */
511 // memset(&adv_params, 0, sizeof adv_params);
512 adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
513 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
514 rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER,
515 &adv_params, bleprph_gap_event, NULL);
516 if (rc != 0) {
517 LLOGE("error enabling advertisement; rc=%d", rc);
518 return;
520 else {
521 LLOGD("ble_gap_adv start rc=0");
524 #endif
527 * The nimble host executes this callback when a GAP event occurs. The
528 * application associates a GAP event callback with each connection that forms.
529 * bleprph uses the same callback for all connections.
531 * @param event The type of event being signalled.
532 * @param ctxt Various information pertaining to the event.
533 * @param arg Application-specified argument; unused by
534 * bleprph.
536 * @return 0 if the application successfully handled the
537 * event; nonzero on failure. The semantics
538 * of the return code is specific to the
539 * particular GAP event being signalled.
541 static int
542 bleprph_gap_event(struct ble_gap_event *event, void *arg)
544 struct ble_gap_conn_desc desc;
545 int rc;
546 // LLOGD("gap event->type %d", event->type);
547 char buff[BLE_UUID_STR_LEN + 1] = {0};
548 rtos_msg_t msg = {
549 .handler = l_ble_state_cb
551 switch (event->type) {
552 case BLE_GAP_EVENT_CONNECT:
553 /* A new connection was established or a connection attempt failed. */
554 LLOGI("connection %s; status=%d ",
555 event->connect.status == 0 ? "established" : "failed",
556 event->connect.status);
557 if (event->connect.status == 0) {
558 g_ble_conn_handle = event->connect.conn_handle;
559 rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
560 // if (rc == 0)
561 // bleprph_print_conn_desc(&desc);
562 g_ble_state = BT_STATE_CONNECTED;
564 else {
565 g_ble_state = BT_STATE_DISCONNECT;
567 msg.arg1 = g_ble_state;
568 luat_msgbus_put(&msg, 0);
569 // LLOGI("");
571 if (event->connect.status != 0) {
572 /* Connection failed; resume advertising. */
573 #if CONFIG_EXAMPLE_EXTENDED_ADV
574 ext_bleprph_advertise();
575 #else
576 bleprph_advertise();
577 #endif
579 return 0;
581 case BLE_GAP_EVENT_DISCONNECT:
582 g_ble_state = BT_STATE_DISCONNECT;
583 LLOGI("disconnect; reason=%d ", event->disconnect.reason);
584 // bleprph_print_conn_desc(&event->disconnect.conn);
585 for (size_t i = 0; i < LUAT_BLE_MAX_CHR; i++)
587 s_chr_notify_states[i] = 0;
588 s_chr_indicate_states[i] = 0;
591 msg.arg1 = g_ble_state;
592 luat_msgbus_put(&msg, 0);
594 /* Connection terminated; resume advertising. */
595 #if CONFIG_EXAMPLE_EXTENDED_ADV
596 ext_bleprph_advertise();
597 #else
598 bleprph_advertise();
599 #endif
600 return 0;
602 case BLE_GAP_EVENT_CONN_UPDATE:
603 /* The central has updated the connection parameters. */
604 LLOGI("connection updated; status=%d ", event->conn_update.status);
605 rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
606 // if (rc == 0)
607 // bleprph_print_conn_desc(&desc);
608 // LLOGI("");
609 return 0;
611 case BLE_GAP_EVENT_ADV_COMPLETE:
612 LLOGI("advertise complete; reason=%d", event->adv_complete.reason);
613 #if !CONFIG_EXAMPLE_EXTENDED_ADV
614 bleprph_advertise();
615 #endif
616 return 0;
618 case BLE_GAP_EVENT_ENC_CHANGE:
619 /* Encryption has been enabled or disabled for this connection. */
620 LLOGI("encryption change event; status=%d ",
621 event->enc_change.status);
622 rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
623 if (rc == 0)
624 bleprph_print_conn_desc(&desc);
625 // LLOGI("");
626 return 0;
628 case BLE_GAP_EVENT_SUBSCRIBE:
629 // LLOGI("subscribe event; conn_handle=%d attr_handle=%d "
630 // "reason=%d prevn=%d curn=%d previ=%d curi=%d",
631 // event->subscribe.conn_handle,
632 // event->subscribe.attr_handle,
633 // event->subscribe.reason,
634 // event->subscribe.prev_notify,
635 // event->subscribe.cur_notify,
636 // event->subscribe.prev_indicate,
637 // event->subscribe.cur_indicate);
638 for (size_t i = 0; i < LUAT_BLE_MAX_CHR; i++)
640 if (s_chr_val_handles[i] == event->subscribe.attr_handle) {
641 ble_uuid_to_str(&s_chr_uuids[i], buff);
642 LLOGD("subscribe %s notify %d indicate %d", buff, event->subscribe.cur_notify, event->subscribe.cur_indicate);
643 s_chr_notify_states[i] = event->subscribe.cur_notify;
644 s_chr_indicate_states[i] = event->subscribe.cur_indicate;
645 // TODO 发送系统消息
646 return 0;
649 LLOGI("subscribe event but chr NOT FOUND");
650 return 0;
652 case BLE_GAP_EVENT_MTU:
653 LLOGI("mtu update event; conn_handle=%d cid=%d mtu=%d",
654 event->mtu.conn_handle,
655 event->mtu.channel_id,
656 event->mtu.value);
657 return 0;
659 case BLE_GAP_EVENT_REPEAT_PAIRING:
660 /* We already have a bond with the peer, but it is attempting to
661 * establish a new secure link. This app sacrifices security for
662 * convenience: just throw away the old bond and accept the new link.
665 /* Delete the old bond. */
666 rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
667 // assert(rc == 0);
668 ble_store_util_delete_peer(&desc.peer_id_addr);
670 /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
671 * continue with the pairing operation.
673 return BLE_GAP_REPEAT_PAIRING_RETRY;
675 case BLE_GAP_EVENT_PASSKEY_ACTION:
676 LLOGI("PASSKEY_ACTION_EVENT started");
677 #if 0
678 struct ble_sm_io pkey = {0};
679 int key = 0;
681 if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
682 pkey.action = event->passkey.params.action;
683 pkey.passkey = 123456; // This is the passkey to be entered on peer
684 // LLOGI("Enter passkey %d on the peer side", pkey.passkey);
685 rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
686 LLOGI("ble_sm_inject_io BLE_SM_IOACT_DISP result: %d", rc);
687 } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
688 LLOGI("Passkey on device's display: %d", event->passkey.params.numcmp);
689 LLOGI("Accept or reject the passkey through console in this format -> key Y or key N");
690 pkey.action = event->passkey.params.action;
691 // if (scli_receive_key(&key)) {
692 // pkey.numcmp_accept = key;
693 // } else {
694 // pkey.numcmp_accept = 0;
695 // ESP_LOGE(tag, "Timeout! Rejecting the key");
696 // }
697 pkey.numcmp_accept = 1;
698 rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
699 LLOGI("ble_sm_inject_io BLE_SM_IOACT_NUMCMP result: %d", rc);
700 } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) {
701 static uint8_t tem_oob[16] = {0};
702 pkey.action = event->passkey.params.action;
703 for (int i = 0; i < 16; i++) {
704 pkey.oob[i] = tem_oob[i];
706 rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
707 LLOGI("ble_sm_inject_io BLE_SM_IOACT_OOB result: %d", rc);
708 } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
709 LLOGI("Passkey on device's display: %d", event->passkey.params.numcmp);
710 LLOGI("Enter the passkey through console in this format-> key 123456");
711 pkey.action = event->passkey.params.action;
712 // if (scli_receive_key(&key)) {
713 // pkey.passkey = key;
714 // } else {
715 // pkey.passkey = 0;
716 // ESP_LOGE(tag, "Timeout! Passing 0 as the key");
717 // }
718 pkey.passkey = event->passkey.params.numcmp;
719 rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
720 LLOGI("ble_sm_inject_io BLE_SM_IOACT_INPUT result: %d", rc);
722 #endif
723 return 0;
726 return 0;
729 static void
730 bleprph_on_reset(int reason)
732 g_ble_state = BT_STATE_OFF;
733 LLOGE("Resetting state; reason=%d", reason);
734 //app_adapter_state_changed_callback(WM_BT_STATE_OFF);
738 static void
739 bleprph_on_sync(void)
741 int rc;
743 #if CONFIG_EXAMPLE_RANDOM_ADDR
744 /* Generate a non-resolvable private address. */
745 ble_app_set_addr();
746 #endif
748 /* Make sure we have proper identity address set (public preferred) */
749 #if CONFIG_EXAMPLE_RANDOM_ADDR
750 rc = ble_hs_util_ensure_addr(1);
751 #else
752 rc = ble_hs_util_ensure_addr(0);
753 #endif
754 // assert(rc == 0);
756 /* Figure out address to use while advertising (no privacy for now) */
757 rc = ble_hs_id_infer_auto(0, &own_addr_type);
758 if (rc != 0) {
759 LLOGE("error determining address type; rc=%d", rc);
760 return;
763 /* Printing ADDR */
764 uint8_t addr_val[6] = {0};
765 rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL);
766 if (rc) {
767 LLOGE("ble_hs_id_copy_addr rc %d", rc);
770 LLOGI("Device Address: " ADDR_FMT, ADDR_T(addr_val));
771 if (luat_ble_dev_name_len == 0) {
772 sprintf_((char*)luat_ble_dev_name, "LOS-" ADDR_FMT, ADDR_T(addr_val));
773 LLOGD("BLE name: %s", luat_ble_dev_name);
774 luat_ble_dev_name_len = strlen((const char*)luat_ble_dev_name);
775 rc = ble_svc_gap_device_name_set((const char*)luat_ble_dev_name);
776 if (rc) {
777 LLOGE("ble_svc_gap_device_name_set rc %d", rc);
780 rc = ble_gatts_start();
781 if (rc) {
782 LLOGE("ble_gatts_start rc %d", rc);
785 /* Begin advertising. */
786 #if CONFIG_EXAMPLE_EXTENDED_ADV
787 ext_bleprph_advertise();
788 #else
789 bleprph_advertise();
790 #endif
792 if (g_ble_state == BT_STATE_OFF)
793 g_ble_state = BT_STATE_ON;
798 int luat_nimble_init_peripheral(uint8_t uart_idx, char* name, int mode) {
799 int rc = 0;
800 nimble_port_init();
802 /* Set the default device name. */
803 if (name != NULL && strlen(name)) {
804 rc = ble_svc_gap_device_name_set((const char*)name);
807 /* Initialize the NimBLE host configuration. */
808 ble_hs_cfg.reset_cb = bleprph_on_reset;
809 ble_hs_cfg.sync_cb = bleprph_on_sync;
810 ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
811 ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
813 ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO;
814 ble_hs_cfg.sm_sc = 0;
816 ble_svc_gap_init();
817 ble_svc_gatt_init();
819 rc = gatt_svr_init();
820 if (rc)
821 LLOGD("gatt_svr_init rc %d", rc);
823 /* XXX Need to have template for store */
824 ble_store_config_init();
826 return 0;