1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include <string.h>
9 #include <stdbool.h>
10 #include <stdio.h>
11 
12 //#include "bluedroid_test.h"
13 #include "bta/bta_api.h"
14 #include "bta/bta_gatt_api.h"
15 #include "device/controller.h"
16 
17 #include "gatt_int.h"
18 #include "common/bt_trace.h"
19 #include "stack/btm_api.h"
20 #include "stack/bt_types.h"
21 #include "dis_api.h"
22 
23 #if BLE_INCLUDED == true
24 
25 #define BA_MAX_CHAR_NUM     1
26 #define BA_MAX_ATTR_NUM     (BA_MAX_CHAR_NUM * 5 + 1)
27 /*max 3 descriptors, 1 desclaration and 1 value*/
28 
29 #ifndef BATTER_LEVEL_PROP
30 #define BATTER_LEVEL_PROP   (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_NOTIFY)
31 #endif
32 
33 #ifndef BATTER_LEVEL_PERM
34 #define BATTER_LEVEL_PERM   (GATT_PERM_READ)
35 #endif
36 
37 #define BT_BD_ADDR_STR         "%02x:%02x:%02x:%02x:%02x:%02x"
38 #define BT_BD_ADDR_HEX(addr)   addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
39 esp_gatts_if_t server_if;
40 
41 tBATTERY_CB         battery_cb;
42 tGATT_CHAR_PROP     prop = GATT_CHAR_PROP_BIT_READ;
43 tBA_REG_INFO        ba_reg_info;
44 UINT8               attr_handle_bit = 0x00;
45 
46 extern tDIS_CB      dis_cb;
47 esp_bt_uuid_t       bas_uuid = {LEN_UUID_16, {UUID_SERVCLASS_BATTERY}};
48 /******************************************************************************
49 ** Function      bas_gatts_callback
50 **
51 ** Description   battery service register callback function
52 *******************************************************************************/
bas_gatts_callback(esp_gatts_evt_t event,tBTA_GATTS * p_data)53 static void bas_gatts_callback(esp_gatts_evt_t event, tBTA_GATTS *p_data)
54 {
55     switch (event) {
56     case ESP_GATTS_REG_EVT: {
57         esp_gatt_status_t  status = p_data->reg_oper.status;
58         server_if = p_data->reg_oper.server_if;
59         BTC_TRACE_ERROR("BAS register completed: event=%d, status=%d, server_if=%d\n",
60                   event, status, server_if);
61 
62         UINT8 app_id = 0xff;
63         bas_init(server_if, app_id);
64 
65         tDIS_ATTR_MASK mask = 0x01ff;
66         DIS_Init(server_if, mask);
67     }
68     break;
69 
70     /*connect callback*/
71     case ESP_GATTS_CONNECT_EVT: {
72         BTC_TRACE_ERROR("\ndevice is connected "BT_BD_ADDR_STR", server_if=%d,reason=0x%x,connect_id=%d\n",
73                   BT_BD_ADDR_HEX(p_data->conn.remote_bda), p_data->conn.server_if,
74                   p_data->conn.reason, p_data->conn.conn_id);
75         /*return whether the remote device is currently connected*/
76         int is_connected = BTA_DmGetConnectionState(p_data->conn.remote_bda);
77         BTC_TRACE_ERROR("is_connected=%d\n", is_connected);
78     }
79     break;
80 
81     /*create service callback*/
82     case ESP_GATTS_CREATE_EVT: {
83         BTC_TRACE_ERROR("create service:server_if=%d,service_id=0x%x,service_uuid=0x%x\n",
84                   p_data->create.server_if, p_data->create.service_id,
85                   p_data->create.uuid.uu.uuid16);
86         UINT16 service_uuid = p_data->create.uuid.uu.uuid16;
87         UINT16 service_id = p_data->create.service_id;
88         if (service_uuid == 0x180f) {
89             tBT_UUID   uuid = {LEN_UUID_16, {GATT_UUID_BATTERY_LEVEL}};
90             bas_AddChar(service_id, &uuid);
91         }
92         if (service_uuid == 0x180a) {
93             dis_cb.service_handle = service_id;
94             dis_cb.max_handle = service_id + DIS_MAX_ATTR_NUM;
95             dis_AddChar(service_id);
96         }
97 
98     }
99     break;
100 
101     case ESP_GATTS_ADD_CHAR_EVT: {
102         BTC_TRACE_ERROR("create characteristic:server_if=%d,service_id=0x%x,char_uuid=0x%x\n",
103                   p_data->add_result.server_if, p_data->add_result.service_id,
104                   p_data->add_result.char_uuid.uu.uuid16);
105         UINT16 char_uuid = p_data->add_result.char_uuid.uu.uuid16;
106         UINT16 service_id = p_data->add_result.service_id;
107         UINT16 uuid_len = p_data->add_result.char_uuid.len;
108 
109         if (uuid_len == ESP_UUID_LEN_16) {
110             if (char_uuid == GATT_UUID_BATTERY_LEVEL) {
111                 bas_AddCharDescr(service_id, p_data->add_result.attr_id);
112             }
113 
114             switch (char_uuid) {
115             case GATT_UUID_SYSTEM_ID:
116                 dis_cb.dis_attr[0].handle = service_id; break;
117             case GATT_UUID_MODEL_NUMBER_STR:
118                 dis_cb.dis_attr[1].handle = service_id; break;
119             case GATT_UUID_SERIAL_NUMBER_STR:
120                 dis_cb.dis_attr[2].handle = service_id; break;
121             case GATT_UUID_FW_VERSION_STR:
122                 dis_cb.dis_attr[3].handle = service_id; break;
123             case GATT_UUID_HW_VERSION_STR:
124                 dis_cb.dis_attr[4].handle = service_id; break;
125             case GATT_UUID_SW_VERSION_STR:
126                 dis_cb.dis_attr[5].handle = service_id; break;
127             case GATT_UUID_MANU_NAME:
128                 dis_cb.dis_attr[6].handle = service_id; break;
129             case GATT_UUID_IEEE_DATA:
130                 dis_cb.dis_attr[7].handle = service_id; break;
131             case GATT_UUID_PNP_ID:
132                 dis_cb.dis_attr[8].handle = service_id; break;
133             }
134             default:
135                 break;
136         }
137     }
138     break;
139 
140     case ESP_GATTS_ADD_CHAR_DESCR_EVT: {
141 
142         BTC_TRACE_ERROR("create descriptor:server_if=%d,service_id=0x%x,attr_id=0x%x,char_uuid=0x%x\n",
143                   p_data->add_result.server_if, p_data->add_result.service_id,
144                   p_data->add_result.attr_id, p_data->add_result.char_uuid.uu.uuid16);
145         bas_AddCharDescr(p_data->add_result.service_id, p_data->add_result.attr_id);
146     }
147     break;
148 
149     case ESP_GATTS_START_EVT: {
150         BTC_TRACE_ERROR("start service:server_if=%d,service_id=0x%x\n", p_data->srvc_oper.server_if,
151                   p_data->srvc_oper.service_id);
152         bas_service_cmpl(p_data->srvc_oper.service_id, p_data->srvc_oper.status);
153 
154         /*start advertising*/
155         //if(p_data->srvc_oper.status == GATT_SUCCESS)
156         // BTA_GATTS_Listen(server_if, true, NULL);
157         //    BTA_GATTC_Broadcast(client_if, true);       //non-connectable
158     }
159     break;
160 
161     case ESP_GATTS_READ_EVT: {
162         UINT32 trans_id = p_data->req_data.trans_id;
163         UINT16 conn_id = p_data->req_data.conn_id;
164         UINT16 handle = p_data->req_data.p_data->read_req.handle;
165         bool   is_long = p_data->req_data.p_data->read_req.is_long;
166         BTC_TRACE_ERROR("read request:event=0x%x,handle=0x%x,trans_id=0x%x,conn_id=0x%x\n",
167                   event, handle, trans_id, conn_id);
168 
169         if (dis_valid_handle_range(handle)) {
170             tGATT_VALUE p_value;
171             p_value.handle = handle;
172             p_value.conn_id = conn_id;
173             p_value.offset = p_data->req_data.p_data->read_req.offset;
174             dis_s_read_attr_value(p_data->req_data.p_data, &p_value, trans_id, conn_id);
175         } else {
176             bas_s_read_attr_value(p_data->req_data.p_data, trans_id, conn_id);
177         }
178     }
179     break;
180 
181     case ESP_GATTS_WRITE_EVT: {
182 
183         UINT32 trans_id = p_data->req_data.trans_id;
184         UINT16 conn_id = p_data->req_data.conn_id;
185         UINT16 handle = p_data->req_data.p_data->write_req.handle;
186         BTC_TRACE_ERROR("write request:event=0x%x,handle=0x%x,trans_id=0x%x,conn_id=0x%x\n",
187                   event, handle, trans_id, conn_id);
188         bas_s_write_attr_value(p_data->req_data.p_data, trans_id, conn_id,
189                                p_data->req_data.remote_bda);
190     }
191     break;
192 
193     case ESP_GATTS_EXEC_WRITE_EVT: {
194         UINT32 trans_id = p_data->req_data.trans_id;
195         UINT16 conn_id = p_data->req_data.conn_id;
196         UINT8  exec_write = p_data->req_data.p_data->exec_write;
197         BTC_TRACE_ERROR("execute write request:event=0x%x,exce_write=0x%x,trans_id=0x%x,conn_id=0x%x\n",
198                   event, exec_write, trans_id, conn_id);
199     }
200     break;
201 
202     case ESP_GATTS_MTU_EVT: {
203         UINT32 trans_id = p_data->req_data.trans_id;
204         UINT16 conn_id = p_data->req_data.conn_id;
205         UINT16 mtu = p_data->req_data.p_data->mtu;
206         BTC_TRACE_ERROR("exchange mtu request:event=0x%x,mtu=0x%x,trans_id=0x%x,conn_id=0x%x\n",
207                   event, mtu, trans_id, conn_id);
208     }
209     break;
210 
211     case ESP_GATTS_CFM_EVT: {
212 
213         UINT32 trans_id = p_data->req_data.trans_id;
214         UINT16 conn_id = p_data->req_data.conn_id;
215         BTC_TRACE_ERROR("configue request:trans_id=0x%x,conn_id=0x%x\n",
216                   trans_id, conn_id);
217     }
218     break;
219 
220     default:
221         BTC_TRACE_ERROR("unsettled event: %d\n", event);
222         break;
223     }
224 
225 }
226 /******************************************************************************
227 ** Function      bas_callback
228 **
229 ** Description   battery service callback for client request
230 *******************************************************************************/
bas_callback(UINT32 trans_id,UINT16 conn_id,UINT8 app_id,UINT8 event,tBA_WRITE_DATA * p_data)231 static void bas_callback(UINT32 trans_id, UINT16 conn_id, UINT8 app_id,
232                          UINT8 event, tBA_WRITE_DATA *p_data)
233 {
234     tBA_RSP_DATA p_rsp;
235     tGATT_STATUS st = ESP_GATT_OK;
236     switch (event) {
237     case BA_READ_LEVEL_REQ : {
238         BTC_TRACE_ERROR("read battery level\n");
239         p_rsp.ba_level = 60;     //battery level
240         Battery_Rsp(trans_id, conn_id, app_id, st, event, &p_rsp);
241     }
242     break;
243 
244     case BA_READ_PRE_FMT_REQ : {
245         BTC_TRACE_ERROR("read presentation format\n");
246     }
247     break;
248 
249     case BA_READ_CLT_CFG_REQ : {
250         BTC_TRACE_ERROR("read client characteristic configuration request\n");
251         p_rsp.clt_cfg = 0x0001;   //notification
252         Battery_Rsp(trans_id, conn_id, app_id, st, event, &p_rsp);
253     }
254     break;
255 
256     case BA_READ_RPT_REF_REQ : {
257         BTC_TRACE_ERROR("read report reference descriptor\n");
258     }
259     break;
260 
261     /*battery level notify*/
262     case BA_WRITE_CLT_CFG_REQ : {
263         BTC_TRACE_ERROR("write client characteristic configuration request\n");
264         Battery_Rsp(trans_id, conn_id, app_id, st, event, NULL);
265 
266         int battery_level = 50;
267         Battery_Notify(conn_id, app_id, p_data->remote_bda, battery_level);
268     }
269     break;
270 
271     default:
272         break;
273     }
274 
275     return;
276 }
277 /*****************************************************************************
278 ** Function      bas_s_read_attr_value
279 **
280 ** Description   it will be called when client sends a read request
281 ******************************************************************************/
bas_s_read_attr_value(tGATTS_DATA * p_data,UINT32 trans_id,UINT16 conn_id)282 void bas_s_read_attr_value(tGATTS_DATA *p_data, UINT32 trans_id, UINT16 conn_id)
283 {
284 
285     tBA_INST            *p_inst = &battery_cb.battery_inst[0];
286     UINT8               i;
287     esp_gatt_status_t   st = ESP_GATT_NOT_FOUND;
288     UINT16              handle = p_data->read_req.handle;
289 
290 
291     for (i = 0; i < BA_MAX_INT_NUM; i ++, p_inst ++) {
292         // read battery level
293         if (handle == p_inst->ba_level_hdl ||
294                 handle == p_inst->clt_cfg_hdl ||
295                 handle == p_inst->rpt_ref_hdl ||
296                 handle == p_inst->pres_fmt_hdl) {
297             if (p_data->read_req.is_long) {
298                 st = ESP_GATT_NOT_LONG;
299             }
300 
301             if (p_inst->p_cback) {
302                 if (handle == p_inst->ba_level_hdl) {
303                     p_inst->pending_evt = BA_READ_LEVEL_REQ;
304                 }
305                 if (handle == p_inst->clt_cfg_hdl) {
306                     p_inst->pending_evt = BA_READ_CLT_CFG_REQ;
307                 }
308                 if (handle == p_inst->pres_fmt_hdl) {
309                     p_inst->pending_evt = BA_READ_PRE_FMT_REQ;
310                 }
311                 if (handle == p_inst->rpt_ref_hdl) {
312                     p_inst->pending_evt = BA_READ_RPT_REF_REQ ;
313                 }
314 
315                 // p_inst->pending_clcb_idx = clcb_idx;
316                 p_inst->pending_handle = handle;
317                 //act = SRVC_ACT_PENDING;
318                 (*p_inst->p_cback)(trans_id, conn_id, p_inst->app_id, p_inst->pending_evt, NULL);
319             } else { /* application is not registered */
320                 st = ESP_GATT_ERR_UNLIKELY;
321             }
322             break;
323         }
324         /* else attribute not found */
325     }
326 }
327 
328 /*****************************************************************************
329 ** Function      bas_s_write_attr_value
330 **
331 ** Description   it will be called when client sends a write request
332 ******************************************************************************/
bas_s_write_attr_value(tGATTS_DATA * p_data,UINT32 trans_id,UINT16 conn_id,BD_ADDR bd_addr)333 void bas_s_write_attr_value(tGATTS_DATA *p_data, UINT32 trans_id, UINT16 conn_id, BD_ADDR bd_addr)
334 {
335     tBA_WRITE_DATA   cfg;
336     UINT8            *p = p_data->write_req.value;
337     tBA_INST         *p_inst = &battery_cb.battery_inst[0];
338     UINT8             i;
339     esp_gatt_status_t st = ESP_GATT_NOT_FOUND;
340     UINT16            handle = p_data->write_req.handle;
341 
342 
343     for (i = 0; i < BA_MAX_INT_NUM; i ++, p_inst ++) {
344         if (handle == p_inst->clt_cfg_hdl) {
345             memcpy(cfg.remote_bda, bd_addr, BD_ADDR_LEN);
346             STREAM_TO_UINT16(cfg.clt_cfg, p);
347 
348             if (p_inst->p_cback) {
349                 p_inst->pending_evt = BA_WRITE_CLT_CFG_REQ;
350                 p_inst->pending_handle = handle;
351                 cfg.need_rsp = p_data->write_req.need_rsp;
352                 (*p_inst->p_cback)(trans_id, conn_id, p_inst->app_id, p_inst->pending_evt, &cfg);
353             } else { /* all other handle is not writable */
354                 st = ESP_GATT_WRITE_NOT_PERMIT;
355             }
356             break;
357         }
358 
359     }
360 }
361 /***************************************************************
362 **
363 ** Function     bas_register
364 **
365 ** Description  register app for battery service
366 **
367 ****************************************************************/
bas_register(void)368 void bas_register(void)
369 {
370     esp_ble_gatts_app_register(&bas_uuid, bas_gatts_callback);
371 
372 }
373 /***************************************************************
374 **
375 ** Function     bas_init
376 **
377 ** Description  register battery service
378 **
379 ****************************************************************/
bas_init(tBTA_GATTS_IF gatt_if,UINT16 app_id)380 void bas_init(tBTA_GATTS_IF gatt_if, UINT16 app_id)
381 {
382 
383     tBA_INST    *p_inst;
384 
385     ba_reg_info.is_pri = true;
386     ba_reg_info.ba_level_descr = BA_LEVEL_NOTIFY;
387     ba_reg_info.transport = GATT_TRANSPORT_LE;
388     ba_reg_info.p_cback = bas_callback;
389     if (battery_cb.inst_id == BA_MAX_INT_NUM) {
390         GATT_TRACE_ERROR("MAX battery service has been reached\n");
391         return;
392     }
393 
394     p_inst = &battery_cb.battery_inst[battery_cb.inst_id];
395 
396     BTC_TRACE_ERROR("create battery service\n");
397     BTC_TRACE_ERROR("inst_id=%d\n", battery_cb.inst_id);
398     esp_ble_gatts_create_srvc (gatt_if, &bas_uuid, battery_cb.inst_id ,
399                                BA_MAX_ATTR_NUM, ba_reg_info.is_pri);
400 
401     battery_cb.inst_id ++;
402 
403     p_inst->app_id  =   app_id;
404     p_inst->p_cback =   ba_reg_info.p_cback;
405 
406 }
407 
408 /***************************************************************
409 **
410 ** Function     bas_AddChar
411 **
412 ** Description  add characteristic for battery service
413 **
414 ****************************************************************/
bas_AddChar(UINT16 service_id,tBT_UUID * char_uuid)415 void bas_AddChar(UINT16 service_id, tBT_UUID *char_uuid)
416 {
417     if (ba_reg_info.ba_level_descr & BA_LEVEL_NOTIFY) {
418         prop |= GATT_CHAR_PROP_BIT_NOTIFY;
419     }
420     attr_handle_bit = 0x01;
421     esp_ble_gatts_add_char(service_id, char_uuid, BATTER_LEVEL_PERM, prop);
422 
423 }
424 
425 /***************************************************************
426 **
427 ** Function     bas_AddCharDescr
428 **
429 ** Description  add descriptor for battery service if needed
430 **
431 ****************************************************************/
bas_AddCharDescr(UINT16 service_id,UINT16 attr_id)432 void bas_AddCharDescr(UINT16 service_id, UINT16 attr_id)
433 {
434     tBT_UUID uuid;
435     uuid.len = LEN_UUID_16;
436 
437     battery_cb.inst_id --;
438     tBA_INST *p_inst = &battery_cb.battery_inst[battery_cb.inst_id++];
439     /*store the attribute handles*/
440     if (attr_handle_bit == 0x01) {
441         p_inst->ba_level_hdl = attr_id;
442     } else if (attr_handle_bit == 0x02) {
443         p_inst->clt_cfg_hdl = attr_id;
444     } else if (attr_handle_bit == 0x04) {
445         p_inst->pres_fmt_hdl = attr_id;
446     } else if (attr_handle_bit == 0x08) {
447         p_inst->rpt_ref_hdl = attr_id;
448     }
449 
450 
451     if (ba_reg_info.ba_level_descr != 0) {
452         if (ba_reg_info.ba_level_descr & BA_LEVEL_NOTIFY) {
453             uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
454             ba_reg_info.ba_level_descr &= 0xfe;
455             attr_handle_bit = 0x02;
456             esp_ble_gatts_add_char_descr(service_id, (GATT_PERM_READ | GATT_PERM_WRITE), &uuid);
457             return;
458         }
459 
460         /* need presentation format descriptor? */
461         if (ba_reg_info.ba_level_descr & BA_LEVEL_PRE_FMT) {
462             uuid.uu.uuid16 = GATT_UUID_CHAR_PRESENT_FORMAT;
463             esp_ble_gatts_add_char_descr(service_id, GATT_PERM_READ, &uuid);
464             ba_reg_info.ba_level_descr &= 0xfd;
465             attr_handle_bit = 0x04;
466             return;
467         }
468         /* need report reference format descriptor? */
469         if (ba_reg_info.ba_level_descr & BA_LEVEL_RPT_REF) {
470             uuid.uu.uuid16 = GATT_UUID_RPT_REF_DESCR;
471             ba_reg_info.ba_level_descr &= 0xfb;
472             esp_ble_gatts_add_char_descr(service_id, GATT_PERM_READ, &uuid);
473             attr_handle_bit = 0x08;
474             return;
475         }
476     }
477 
478     else {
479         esp_ble_gatts_start_srvc(service_id);
480     }
481 
482 }
483 
484 /***************************************************************
485 **
486 ** Function     bas_service_cmpl
487 **
488 ** Description  create battery service complete
489 **
490 ****************************************************************/
bas_service_cmpl(UINT16 service_id,esp_gatt_status_t status)491 void bas_service_cmpl(UINT16 service_id, esp_gatt_status_t status)
492 {
493     if (status != ESP_GATT_OK) {
494         battery_cb.inst_id --;
495         esp_ble_gatts_dele_srvc(service_id);
496     }
497 
498 }
499 /*******************************************************************************
500 **
501 ** Function         Battery_Rsp
502 **
503 ** Description      Respond to a battery service request
504 **
505 *******************************************************************************/
Battery_Rsp(UINT32 trans_id,UINT16 conn_id,UINT8 app_id,esp_gatt_status_t st,UINT8 event,tBA_RSP_DATA * p_rsp)506 void Battery_Rsp (UINT32 trans_id, UINT16 conn_id, UINT8 app_id,
507                   esp_gatt_status_t st, UINT8 event, tBA_RSP_DATA *p_rsp)
508 {
509     tBA_INST *p_inst = &battery_cb.battery_inst[0];
510     tGATTS_RSP  rsp;
511     UINT8   *pp;
512 
513     UINT8   i = 0;
514     while (i < BA_MAX_INT_NUM) {
515         if (p_inst->app_id == app_id && p_inst->ba_level_hdl != 0) {
516             break;
517         }
518         i ++;
519     }
520 
521     if (i == BA_MAX_INT_NUM) {
522         return;
523     }
524 
525     memset(&rsp, 0, sizeof(tGATTS_RSP));
526 
527     if (p_inst->pending_evt == event) {
528         switch (event) {
529         case BA_READ_CLT_CFG_REQ:
530             rsp.attr_value.handle = p_inst->pending_handle;
531             rsp.attr_value.len = 2;
532             pp = rsp.attr_value.value;
533             UINT16_TO_STREAM(pp, p_rsp->clt_cfg);
534             esp_ble_gatts_send_rsp(conn_id, trans_id, st, &rsp);
535             //srvc_sr_rsp(p_inst->pending_clcb_idx, st, &rsp);
536             break;
537 
538         case BA_READ_LEVEL_REQ:
539             rsp.attr_value.handle = p_inst->pending_handle;
540             rsp.attr_value.len = 1;
541             pp = rsp.attr_value.value;
542             UINT8_TO_STREAM(pp, p_rsp->ba_level);
543             esp_ble_gatts_send_rsp(conn_id, trans_id, st, &rsp);
544             //srvc_sr_rsp(p_inst->pending_clcb_idx, st, &rsp);
545             break;
546 
547         case BA_WRITE_CLT_CFG_REQ:
548             esp_ble_gatts_send_rsp(conn_id, trans_id, st, NULL);
549             //srvc_sr_rsp(p_inst->pending_clcb_idx, st, NULL);
550             break;
551 
552         case BA_READ_RPT_REF_REQ:
553             rsp.attr_value.handle = p_inst->pending_handle;
554             rsp.attr_value.len = 2;
555             pp = rsp.attr_value.value;
556             UINT8_TO_STREAM(pp, p_rsp->rpt_ref.rpt_id);
557             UINT8_TO_STREAM(pp, p_rsp->rpt_ref.rpt_type);
558             esp_ble_gatts_send_rsp(conn_id, trans_id, st, &rsp);
559             //srvc_sr_rsp(p_inst->pending_clcb_idx, st, &rsp);
560             break;
561 
562         default:
563             break;
564         }
565         // p_inst->pending_clcb_idx = 0;
566         p_inst->pending_evt = 0;
567         p_inst->pending_handle = 0;
568     }
569     return;
570 }
571 /*******************************************************************************
572 **
573 ** Function         Battery_Notify
574 **
575 ** Description      Send battery level notification
576 **
577 *******************************************************************************/
Battery_Notify(UINT16 conn_id,UINT8 app_id,BD_ADDR remote_bda,UINT8 battery_level)578 void Battery_Notify (UINT16 conn_id, UINT8 app_id, BD_ADDR remote_bda, UINT8 battery_level)
579 {
580     tBA_INST *p_inst = &battery_cb.battery_inst[0];
581     UINT8    i = 0;
582 
583     while (i < BA_MAX_INT_NUM) {
584         if (p_inst->app_id == app_id && p_inst->ba_level_hdl != 0) {
585             break;
586         }
587         i ++;
588     }
589 
590     if (i == BA_MAX_INT_NUM || p_inst->clt_cfg_hdl == 0) {
591         return;
592     }
593     esp_ble_gatts_hdl_val_indica(conn_id, p_inst->ba_level_hdl, 1, &battery_level, false);
594     //srvc_sr_notify(remote_bda, p_inst->ba_level_hdl, 1, &battery_level);
595 
596 }
597 #endif
598