1 /******************************************************************************
2 *
3 * Copyright (C) 2003-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains the GATT Server action functions for the state
22 * machine.
23 *
24 ******************************************************************************/
25
26
27 #include "bt_target.h"
28
29 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
30
31 #include "utl.h"
32 #include "gki.h"
33 #include "bta_sys.h"
34 #include "bta_gatts_int.h"
35 #include "bta_gatts_co.h"
36 #include "btm_ble_api.h"
37 #include "btif/include/btif_debug_conn.h"
38 #include <string.h>
39
40 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
41 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
42 tGATTS_SRV_CHG_RSP *p_rsp);
43
44 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
45 BOOLEAN connected, tGATT_DISCONN_REASON reason,
46 tGATT_TRANSPORT transport);
47 static void bta_gatts_send_request_cback (UINT16 conn_id,
48 UINT32 trans_id,
49 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
50 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);
51
52 static tGATT_CBACK bta_gatts_cback =
53 {
54 bta_gatts_conn_cback,
55 NULL,
56 NULL,
57 NULL,
58 bta_gatts_send_request_cback,
59 NULL,
60 bta_gatts_cong_cback
61 };
62
63 tGATT_APPL_INFO bta_gatts_nv_cback =
64 {
65 bta_gatts_nv_save_cback,
66 bta_gatts_nv_srv_chg_cback
67 };
68
69 /*******************************************************************************
70 **
71 ** Function bta_gatts_nv_save_cback
72 **
73 ** Description NV save callback function.
74 **
75 ** Parameter is_add: true is to add a handle range; otherwise is to delete.
76 ** Returns none.
77 **
78 *******************************************************************************/
bta_gatts_nv_save_cback(BOOLEAN is_add,tGATTS_HNDL_RANGE * p_hndl_range)79 static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_range)
80 {
81 bta_gatts_co_update_handle_range(is_add, (tBTA_GATTS_HNDL_RANGE *)p_hndl_range);
82 }
83
84
85 /*******************************************************************************
86 **
87 ** Function bta_gatts_nv_srv_chg_cback
88 **
89 ** Description NV save callback function.
90 **
91 ** Parameter is_add: true is to add a handle range; otherwise is to delete.
92 ** Returns none.
93 **
94 *******************************************************************************/
bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,tGATTS_SRV_CHG_REQ * p_req,tGATTS_SRV_CHG_RSP * p_rsp)95 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
96 tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
97 {
98 return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
99 (tBTA_GATTS_SRV_CHG_REQ *) p_req,
100 (tBTA_GATTS_SRV_CHG_RSP *) p_rsp);
101 }
102
103
104 /*******************************************************************************
105 **
106 ** Function bta_gatts_enable
107 **
108 ** Description enable BTA GATTS module.
109 **
110 ** Returns none.
111 **
112 *******************************************************************************/
bta_gatts_enable(tBTA_GATTS_CB * p_cb)113 void bta_gatts_enable(tBTA_GATTS_CB *p_cb)
114 {
115 UINT8 index=0;
116 tBTA_GATTS_HNDL_RANGE handle_range;
117
118 if (p_cb->enabled)
119 {
120 APPL_TRACE_DEBUG("GATTS already enabled.");
121 }
122 else
123 {
124 memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
125
126 p_cb->enabled = TRUE;
127
128 while ( bta_gatts_co_load_handle_range(index, &handle_range))
129 {
130 GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
131 memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
132 index++;
133 }
134
135 APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);
136
137 if (!GATTS_NVRegister(&bta_gatts_nv_cback))
138 {
139 APPL_TRACE_ERROR("BTA GATTS NV register failed.");
140 }
141 }
142 }
143
144 /*******************************************************************************
145 **
146 ** Function bta_gatts_api_disable
147 **
148 ** Description disable BTA GATTS module.
149 **
150 ** Returns none.
151 **
152 *******************************************************************************/
bta_gatts_api_disable(tBTA_GATTS_CB * p_cb)153 void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
154 {
155 UINT8 i;
156
157 if (p_cb->enabled)
158 {
159 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
160 {
161 if (p_cb->rcb[i].in_use)
162 {
163 GATT_Deregister(p_cb->rcb[i].gatt_if);
164 }
165 }
166 memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
167 }
168 else
169 {
170 APPL_TRACE_ERROR("GATTS not enabled");
171 }
172 }
173
174 /*******************************************************************************
175 **
176 ** Function bta_gatts_register
177 **
178 ** Description register an application.
179 **
180 ** Returns none.
181 **
182 *******************************************************************************/
bta_gatts_register(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)183 void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
184 {
185 tBTA_GATTS_INT_START_IF *p_buf;
186 tBTA_GATTS cb_data;
187 tBTA_GATT_STATUS status = BTA_GATT_OK;
188 UINT8 i, first_unuse = 0xff;
189
190 if (p_cb->enabled == FALSE)
191 {
192 bta_gatts_enable(p_cb);
193 }
194
195 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
196 {
197 if (p_cb->rcb[i].in_use)
198 {
199 if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid))
200 {
201 APPL_TRACE_ERROR("application already registered.");
202 status = BTA_GATT_DUP_REG;
203 break;
204 }
205 }
206 }
207
208 if (status == BTA_GATT_OK)
209 {
210 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
211 {
212 if (first_unuse == 0xff && !p_cb->rcb[i].in_use)
213 {
214 first_unuse = i;
215 break;
216 }
217 }
218
219 cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
220 // btla-specific ++
221 memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
222 // btla-specific --
223 if (first_unuse != 0xff)
224 {
225 APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d", first_unuse);
226
227 p_cb->rcb[first_unuse].in_use = TRUE;
228 p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
229 memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
230 cb_data.reg_oper.server_if =
231 p_cb->rcb[first_unuse].gatt_if =
232 GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
233 if ( !p_cb->rcb[first_unuse].gatt_if)
234 {
235 status = BTA_GATT_NO_RESOURCES;
236 }
237 else
238 {
239 if ((p_buf =
240 (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
241 {
242 p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
243 p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;
244
245 bta_sys_sendmsg(p_buf);
246 }
247 else
248 {
249 status = BTA_GATT_NO_RESOURCES;
250 memset( &p_cb->rcb[first_unuse], 0 , sizeof(tBTA_GATTS_RCB));
251 }
252 }
253 }
254 else
255 {
256 status = BTA_GATT_NO_RESOURCES;
257 }
258
259 }
260 cb_data.reg_oper.status = status;
261 if (p_msg->api_reg.p_cback)
262 (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
263 }
264
265
266 /*******************************************************************************
267 **
268 ** Function bta_gatts_start_if
269 **
270 ** Description start an application interface.
271 **
272 ** Returns none.
273 **
274 *******************************************************************************/
bta_gatts_start_if(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)275 void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
276 {
277 UNUSED(p_cb);
278
279 if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if))
280 {
281 GATT_StartIf(p_msg->int_start_if.server_if);
282 }
283 else
284 {
285 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
286 p_msg->int_start_if.server_if );
287 }
288 }
289 /*******************************************************************************
290 **
291 ** Function bta_gatts_deregister
292 **
293 ** Description deregister an application.
294 **
295 ** Returns none.
296 **
297 *******************************************************************************/
bta_gatts_deregister(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)298 void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
299 {
300 tBTA_GATT_STATUS status = BTA_GATT_ERROR;
301 tBTA_GATTS_CBACK *p_cback = NULL;
302 UINT8 i;
303 tBTA_GATTS cb_data;
304
305 cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
306 cb_data.reg_oper.status = status;
307
308 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
309 {
310 if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if)
311 {
312 p_cback = p_cb->rcb[i].p_cback;
313 status = BTA_GATT_OK;
314
315 /* deregister the app */
316 GATT_Deregister(p_cb->rcb[i].gatt_if);
317
318 /* reset cb */
319 memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
320 cb_data.reg_oper.status = status;
321 break;
322 }
323 }
324
325 if (p_cback)
326 {
327 (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
328 }
329 else
330 {
331 APPL_TRACE_ERROR("application not registered.");
332 }
333 }
334 /*******************************************************************************
335 **
336 ** Function bta_gatts_create_srvc
337 **
338 ** Description action function to create a service.
339 **
340 ** Returns none.
341 **
342 *******************************************************************************/
bta_gatts_create_srvc(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)343 void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
344 {
345 UINT8 rcb_idx;
346 tBTA_GATTS cb_data;
347 UINT8 srvc_idx;
348 UINT16 service_id = 0;
349
350 cb_data.create.status = BTA_GATT_ERROR;
351
352 rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);
353
354 APPL_TRACE_ERROR("create service rcb_idx = %d", rcb_idx);
355
356 if (rcb_idx != BTA_GATTS_INVALID_APP)
357 {
358 if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP)
359 {
360 /* create the service now */
361 service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if,
362 &p_msg->api_create_svc.service_uuid,
363 p_msg->api_create_svc.inst,
364 p_msg->api_create_svc.num_handle,
365 p_msg->api_create_svc.is_pri);
366
367 if (service_id != 0)
368 {
369 memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
370 &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
371 p_cb->srvc_cb[srvc_idx].service_id = service_id;
372 p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst;
373 p_cb->srvc_cb[srvc_idx].idx = srvc_idx;
374
375 cb_data.create.status = BTA_GATT_OK;
376 cb_data.create.service_id = service_id;
377 // btla-specific ++
378 cb_data.create.is_primary = p_msg->api_create_svc.is_pri;
379 // btla-specific --
380 cb_data.create.server_if = p_cb->rcb[rcb_idx].gatt_if;
381 }
382 else
383 {
384 cb_data.status = BTA_GATT_ERROR;
385 memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
386 APPL_TRACE_ERROR("service creation failed.");
387 }
388 // btla-specific ++
389 memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
390 cb_data.create.svc_instance= p_msg->api_create_svc.inst;
391 // btla-specific --
392 }
393 if (p_cb->rcb[rcb_idx].p_cback)
394 (* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);
395 }
396 else /* application not registered */
397 {
398 APPL_TRACE_ERROR("Application not registered");
399 }
400 }
401 /*******************************************************************************
402 **
403 ** Function bta_gatts_add_include_srvc
404 **
405 ** Description action function to add an included service.
406 **
407 ** Returns none.
408 **
409 *******************************************************************************/
bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)410 void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb,tBTA_GATTS_DATA * p_msg)
411 {
412 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
413 UINT16 attr_id = 0;
414 tBTA_GATTS cb_data;
415
416 attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific,
417 p_msg->api_add_incl_srvc.included_service_id);
418
419 cb_data.add_result.server_if = p_rcb->gatt_if;
420 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
421 cb_data.add_result.attr_id = attr_id;
422
423 if (attr_id)
424 {
425 cb_data.add_result.status = BTA_GATT_OK;
426 }
427 else
428 {
429 cb_data.add_result.status = BTA_GATT_ERROR;
430 }
431
432 if (p_rcb->p_cback)
433 (*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data);
434 }
435 /*******************************************************************************
436 **
437 ** Function bta_gatts_add_char
438 **
439 ** Description action function to add characteristic.
440 **
441 ** Returns none.
442 **
443 *******************************************************************************/
bta_gatts_add_char(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)444 void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
445 {
446 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
447 UINT16 attr_id = 0;
448 tBTA_GATTS cb_data;
449
450 attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
451 &p_msg->api_add_char.char_uuid,
452 p_msg->api_add_char.perm,
453 p_msg->api_add_char.property);
454 cb_data.add_result.server_if = p_rcb->gatt_if;
455 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
456 cb_data.add_result.attr_id = attr_id;
457 // btla-specific ++
458 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID));
459 // btla-specific --
460
461 if (attr_id)
462 {
463 cb_data.add_result.status = BTA_GATT_OK;
464 }
465 else
466 {
467 cb_data.add_result.status = BTA_GATT_ERROR;
468 }
469
470 if (p_rcb->p_cback)
471 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
472 }
473 /*******************************************************************************
474 **
475 ** Function bta_gatts_add_char_descr
476 **
477 ** Description action function to add characteristic descriptor.
478 **
479 ** Returns none.
480 **
481 *******************************************************************************/
bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)482 void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
483 {
484 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
485 UINT16 attr_id = 0;
486 tBTA_GATTS cb_data;
487
488 attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
489 p_msg->api_add_char_descr.perm,
490 &p_msg->api_add_char_descr.descr_uuid);
491
492 cb_data.add_result.server_if = p_rcb->gatt_if;
493 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
494 cb_data.add_result.attr_id = attr_id;
495 // btla-specific ++
496 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID));
497 // btla-specific --
498
499 if (attr_id)
500 {
501 cb_data.add_result.status = BTA_GATT_OK;
502 }
503 else
504 {
505 cb_data.add_result.status = BTA_GATT_ERROR;
506 }
507
508 if (p_rcb->p_cback)
509 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);
510
511 }
512 /*******************************************************************************
513 **
514 ** Function bta_gatts_delete_service
515 **
516 ** Description action function to delete a service.
517 **
518 ** Returns none.
519 **
520 *******************************************************************************/
bta_gatts_delete_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)521 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
522 {
523 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
524 tBTA_GATTS cb_data;
525
526 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
527 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
528
529 if (GATTS_DeleteService(p_rcb->gatt_if,
530 &p_srvc_cb->service_uuid,
531 p_srvc_cb->inst_num))
532 {
533 cb_data.srvc_oper.status = BTA_GATT_OK;
534 memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
535 }
536 else
537 {
538 cb_data.srvc_oper.status = BTA_GATT_ERROR;
539 }
540
541 if (p_rcb->p_cback)
542 (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
543
544 }
545 /*******************************************************************************
546 **
547 ** Function bta_gatts_start_service
548 **
549 ** Description action function to start a service.
550 **
551 ** Returns none.
552 **
553 *******************************************************************************/
bta_gatts_start_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)554 void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
555 {
556 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
557 tBTA_GATTS cb_data;
558
559 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
560 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
561
562 if (GATTS_StartService(p_rcb->gatt_if,
563 p_srvc_cb->service_id,
564 p_msg->api_start.transport) == GATT_SUCCESS)
565 {
566 APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
567 cb_data.srvc_oper.status = BTA_GATT_OK;
568 }
569 else
570 {
571 cb_data.srvc_oper.status = BTA_GATT_ERROR;
572 }
573
574 if (p_rcb->p_cback)
575 (*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data);
576
577 }
578 /*******************************************************************************
579 **
580 ** Function bta_gatts_stop_service
581 **
582 ** Description action function to stop a service.
583 **
584 ** Returns none.
585 **
586 *******************************************************************************/
bta_gatts_stop_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)587 void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
588 {
589 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
590 tBTA_GATTS cb_data;
591 UNUSED(p_msg);
592
593 GATTS_StopService(p_srvc_cb->service_id);
594 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
595 cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
596 cb_data.srvc_oper.status = BTA_GATT_OK;
597 APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
598
599 if (p_rcb->p_cback)
600 (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
601
602 }
603 /*******************************************************************************
604 **
605 ** Function bta_gatts_send_rsp
606 **
607 ** Description GATTS send response.
608 **
609 ** Returns none.
610 **
611 *******************************************************************************/
bta_gatts_send_rsp(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)612 void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
613 {
614 UNUSED(p_cb);
615
616 if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific,
617 p_msg->api_rsp.trans_id,
618 p_msg->api_rsp.status,
619 (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS)
620 {
621 APPL_TRACE_ERROR("Sending response failed");
622 }
623
624 }
625 /*******************************************************************************
626 **
627 ** Function bta_gatts_indicate_handle
628 **
629 ** Description GATTS send handle value indication or notification.
630 **
631 ** Returns none.
632 **
633 *******************************************************************************/
bta_gatts_indicate_handle(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)634 void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
635 {
636 tBTA_GATTS_SRVC_CB *p_srvc_cb;
637 tBTA_GATTS_RCB *p_rcb = NULL;
638 tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
639 tGATT_IF gatt_if;
640 BD_ADDR remote_bda;
641 tBTA_TRANSPORT transport;
642 tBTA_GATTS cb_data;
643
644 p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
645
646 if (p_srvc_cb )
647 {
648 if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
649 &gatt_if, remote_bda, &transport))
650 {
651 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
652
653 if (p_msg->api_indicate.need_confirm)
654
655 status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
656 p_msg->api_indicate.attr_id,
657 p_msg->api_indicate.len,
658 p_msg->api_indicate.value);
659 else
660 status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
661 p_msg->api_indicate.attr_id,
662 p_msg->api_indicate.len,
663 p_msg->api_indicate.value);
664
665 /* if over BR_EDR, inform PM for mode change */
666 if (transport == BTA_TRANSPORT_BR_EDR)
667 {
668 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
669 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
670 }
671 }
672 else
673 {
674 APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
675 p_msg->api_indicate.hdr.layer_specific);
676 }
677
678 if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
679 p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
680 {
681 cb_data.req_data.status = status;
682 cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
683
684 (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
685 }
686 }
687 else
688 {
689 APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
690 p_msg->api_indicate.attr_id);
691 }
692 }
693
694
695 /*******************************************************************************
696 **
697 ** Function bta_gatts_open
698 **
699 ** Description
700 **
701 ** Returns none.
702 **
703 *******************************************************************************/
bta_gatts_open(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)704 void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
705 {
706 tBTA_GATTS_RCB *p_rcb=NULL;
707 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
708 UINT16 conn_id;
709 UNUSED(p_cb);
710
711 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
712 {
713 /* should always get the connection ID */
714 if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
715 p_msg->api_open.is_direct, p_msg->api_open.transport))
716 {
717 status = BTA_GATT_OK;
718
719 if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
720 &conn_id, p_msg->api_open.transport))
721 {
722 status = BTA_GATT_ALREADY_OPEN;
723 }
724 }
725 }
726 else
727 {
728 APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
729 }
730
731 if (p_rcb && p_rcb->p_cback)
732 (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, (tBTA_GATTS *)&status);
733
734 }
735 /*******************************************************************************
736 **
737 ** Function bta_gatts_cancel_open
738 **
739 ** Description
740 **
741 ** Returns none.
742 **
743 *******************************************************************************/
bta_gatts_cancel_open(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)744 void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
745 {
746 tBTA_GATTS_RCB *p_rcb;
747 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
748 UNUSED(p_cb);
749
750 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
751 {
752 if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
753 p_msg->api_cancel_open.is_direct))
754 {
755 APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
756 }
757 else
758 {
759 status= BTA_GATT_OK;
760 }
761 }
762 else
763 {
764 APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
765 }
766
767 if (p_rcb && p_rcb->p_cback)
768 (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, (tBTA_GATTS *)&status);
769 }
770 /*******************************************************************************
771 **
772 ** Function bta_gatts_close
773 **
774 ** Description
775 **
776 ** Returns none.
777 **
778 *******************************************************************************/
bta_gatts_close(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)779 void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
780 {
781 tBTA_GATTS_RCB *p_rcb;
782 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
783 tGATT_IF gatt_if;
784 BD_ADDR remote_bda;
785 tBTA_GATT_TRANSPORT transport;
786
787 UNUSED(p_cb);
788
789 if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
790 {
791 if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
792 {
793 APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
794 }
795 else
796 {
797 status= BTA_GATT_OK;
798 }
799
800 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
801
802 if (p_rcb && p_rcb->p_cback)
803 {
804 if (transport == BTA_TRANSPORT_BR_EDR)
805 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);
806
807 (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status);
808 }
809 }
810 else
811 {
812 APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
813 }
814
815 }
816 /*******************************************************************************
817 **
818 ** Function bta_gatts_listen
819 **
820 ** Description Start or stop listening for LE connection on a GATT server
821 **
822 ** Returns none.
823 **
824 *******************************************************************************/
bta_gatts_listen(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)825 void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
826 {
827 tBTA_GATTS_RCB *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
828 tBTA_GATTS cb_data;
829 UNUSED(p_cb);
830
831 cb_data.reg_oper.status = BTA_GATT_OK;
832 cb_data.reg_oper.server_if = p_msg->api_listen.server_if;
833
834 if (p_rcb == NULL)
835 {
836 APPL_TRACE_ERROR("Unknown GATTS application");
837 return;
838 }
839
840 if (!GATT_Listen(p_msg->api_listen.server_if,
841 p_msg->api_listen.start,
842 p_msg->api_listen.remote_bda))
843 {
844 cb_data.status = BTA_GATT_ERROR;
845 APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
846 }
847
848 if (p_rcb->p_cback)
849 (*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
850 }
851
852 /*******************************************************************************
853 **
854 ** Function bta_gatts_request_cback
855 **
856 ** Description GATTS attribute request callback.
857 **
858 ** Returns none.
859 **
860 *******************************************************************************/
bta_gatts_send_request_cback(UINT16 conn_id,UINT32 trans_id,tGATTS_REQ_TYPE req_type,tGATTS_DATA * p_data)861 static void bta_gatts_send_request_cback (UINT16 conn_id,
862 UINT32 trans_id,
863 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data)
864 {
865 tBTA_GATTS cb_data;
866 tBTA_GATTS_RCB *p_rcb;
867 tGATT_IF gatt_if;
868 tBTA_GATT_TRANSPORT transport;
869
870 memset(&cb_data, 0 , sizeof(tBTA_GATTS));
871
872 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
873 {
874 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
875
876 APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
877 conn_id, trans_id, req_type);
878
879 if (p_rcb && p_rcb->p_cback)
880 {
881 /* if over BR_EDR, inform PM for mode change */
882 if (transport == BTA_TRANSPORT_BR_EDR)
883 {
884 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
885 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
886 }
887
888 cb_data.req_data.conn_id = conn_id;
889 cb_data.req_data.trans_id = trans_id;
890 cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data;
891
892 (*p_rcb->p_cback)(req_type, &cb_data);
893 }
894 else
895 {
896 APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
897 }
898 }
899 else
900 {
901 APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id);
902 }
903 }
904
905 /*******************************************************************************
906 **
907 ** Function bta_gatts_conn_cback
908 **
909 ** Description connection callback.
910 **
911 ** Returns none.
912 **
913 *******************************************************************************/
bta_gatts_conn_cback(tGATT_IF gatt_if,BD_ADDR bda,UINT16 conn_id,BOOLEAN connected,tGATT_DISCONN_REASON reason,tGATT_TRANSPORT transport)914 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
915 BOOLEAN connected, tGATT_DISCONN_REASON reason,
916 tGATT_TRANSPORT transport)
917 {
918 tBTA_GATTS cb_data;
919 UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
920 tBTA_GATTS_RCB *p_reg;
921
922 APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
923 gatt_if, conn_id, connected, reason);
924 APPL_TRACE_DEBUG("bta_gatts_conn_cback bda :%02x-%02x-%02x-%02x-%02x-%02x ",
925 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
926
927 bt_bdaddr_t bdaddr;
928 bdcpy(bdaddr.address, bda);
929 if (connected)
930 btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
931 else
932 btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
933
934 p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
935
936 if (p_reg && p_reg->p_cback)
937 {
938 /* there is no RM for GATT */
939 if (transport == BTA_TRANSPORT_BR_EDR)
940 {
941 if (connected)
942 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
943 else
944 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda);
945 }
946
947 cb_data.conn.conn_id = conn_id;
948 cb_data.conn.server_if = gatt_if;
949 cb_data.conn.reason = reason;
950 cb_data.conn.transport = transport;
951 memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
952 (*p_reg->p_cback)(evt, &cb_data);
953 }
954 else
955 {
956 APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found",gatt_if);
957 }
958 }
959
960 /*******************************************************************************
961 **
962 ** Function bta_gatts_cong_cback
963 **
964 ** Description congestion callback.
965 **
966 ** Returns none.
967 **
968 *******************************************************************************/
bta_gatts_cong_cback(UINT16 conn_id,BOOLEAN congested)969 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
970 {
971 tBTA_GATTS_RCB *p_rcb;
972 tGATT_IF gatt_if;
973 tBTA_GATT_TRANSPORT transport;
974 tBTA_GATTS cb_data;
975
976 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
977 {
978 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
979
980 if (p_rcb && p_rcb->p_cback)
981 {
982 cb_data.congest.conn_id = conn_id;
983 cb_data.congest.congested = congested;
984
985 (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
986 }
987 }
988 }
989 #endif /* BTA_GATT_INCLUDED */
990