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