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 "bt_common.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 cb_data;
186 tBTA_GATT_STATUS status = BTA_GATT_OK;
187 UINT8 i, first_unuse = 0xff;
188
189 if (p_cb->enabled == FALSE)
190 {
191 bta_gatts_enable(p_cb);
192 }
193
194 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
195 {
196 if (p_cb->rcb[i].in_use)
197 {
198 if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid))
199 {
200 APPL_TRACE_ERROR("application already registered.");
201 status = BTA_GATT_DUP_REG;
202 break;
203 }
204 }
205 }
206
207 if (status == BTA_GATT_OK)
208 {
209 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
210 {
211 if (first_unuse == 0xff && !p_cb->rcb[i].in_use)
212 {
213 first_unuse = i;
214 break;
215 }
216 }
217
218 cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
219 memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
220 if (first_unuse != 0xff)
221 {
222 APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d", first_unuse);
223
224 p_cb->rcb[first_unuse].in_use = TRUE;
225 p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
226 memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
227 cb_data.reg_oper.server_if =
228 p_cb->rcb[first_unuse].gatt_if =
229 GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
230 if ( !p_cb->rcb[first_unuse].gatt_if) {
231 status = BTA_GATT_NO_RESOURCES;
232 } else {
233 tBTA_GATTS_INT_START_IF *p_buf =
234 (tBTA_GATTS_INT_START_IF *)osi_malloc(sizeof(tBTA_GATTS_INT_START_IF));
235 p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
236 p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;
237
238 bta_sys_sendmsg(p_buf);
239 }
240 } else {
241 status = BTA_GATT_NO_RESOURCES;
242 }
243
244 }
245 cb_data.reg_oper.status = status;
246 if (p_msg->api_reg.p_cback)
247 (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
248 }
249
250
251 /*******************************************************************************
252 **
253 ** Function bta_gatts_start_if
254 **
255 ** Description start an application interface.
256 **
257 ** Returns none.
258 **
259 *******************************************************************************/
bta_gatts_start_if(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)260 void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
261 {
262 UNUSED(p_cb);
263
264 if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if))
265 {
266 GATT_StartIf(p_msg->int_start_if.server_if);
267 }
268 else
269 {
270 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
271 p_msg->int_start_if.server_if );
272 }
273 }
274 /*******************************************************************************
275 **
276 ** Function bta_gatts_deregister
277 **
278 ** Description deregister an application.
279 **
280 ** Returns none.
281 **
282 *******************************************************************************/
bta_gatts_deregister(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)283 void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
284 {
285 tBTA_GATT_STATUS status = BTA_GATT_ERROR;
286 tBTA_GATTS_CBACK *p_cback = NULL;
287 UINT8 i;
288 tBTA_GATTS cb_data;
289
290 cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
291 cb_data.reg_oper.status = status;
292
293 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
294 {
295 if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if)
296 {
297 p_cback = p_cb->rcb[i].p_cback;
298 status = BTA_GATT_OK;
299
300 /* deregister the app */
301 GATT_Deregister(p_cb->rcb[i].gatt_if);
302
303 /* reset cb */
304 memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
305 cb_data.reg_oper.status = status;
306 break;
307 }
308 }
309
310 if (p_cback)
311 {
312 (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
313 }
314 else
315 {
316 APPL_TRACE_ERROR("application not registered.");
317 }
318 }
319 /*******************************************************************************
320 **
321 ** Function bta_gatts_create_srvc
322 **
323 ** Description action function to create a service.
324 **
325 ** Returns none.
326 **
327 *******************************************************************************/
bta_gatts_create_srvc(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)328 void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
329 {
330 UINT8 rcb_idx;
331 tBTA_GATTS cb_data;
332 UINT8 srvc_idx;
333 UINT16 service_id = 0;
334
335 cb_data.create.status = BTA_GATT_ERROR;
336
337 rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);
338
339 APPL_TRACE_ERROR("create service rcb_idx = %d", rcb_idx);
340
341 if (rcb_idx != BTA_GATTS_INVALID_APP)
342 {
343 if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP)
344 {
345 /* create the service now */
346 service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if,
347 &p_msg->api_create_svc.service_uuid,
348 p_msg->api_create_svc.inst,
349 p_msg->api_create_svc.num_handle,
350 p_msg->api_create_svc.is_pri);
351
352 if (service_id != 0)
353 {
354 memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
355 &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
356 p_cb->srvc_cb[srvc_idx].service_id = service_id;
357 p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst;
358 p_cb->srvc_cb[srvc_idx].idx = srvc_idx;
359
360 cb_data.create.status = BTA_GATT_OK;
361 cb_data.create.service_id = service_id;
362 cb_data.create.is_primary = p_msg->api_create_svc.is_pri;
363 cb_data.create.server_if = p_cb->rcb[rcb_idx].gatt_if;
364 }
365 else
366 {
367 cb_data.status = BTA_GATT_ERROR;
368 memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
369 APPL_TRACE_ERROR("service creation failed.");
370 }
371 memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
372 cb_data.create.svc_instance= p_msg->api_create_svc.inst;
373 }
374 if (p_cb->rcb[rcb_idx].p_cback)
375 (* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);
376 }
377 else /* application not registered */
378 {
379 APPL_TRACE_ERROR("Application not registered");
380 }
381 }
382 /*******************************************************************************
383 **
384 ** Function bta_gatts_add_include_srvc
385 **
386 ** Description action function to add an included service.
387 **
388 ** Returns none.
389 **
390 *******************************************************************************/
bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)391 void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb,tBTA_GATTS_DATA * p_msg)
392 {
393 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
394 UINT16 attr_id = 0;
395 tBTA_GATTS cb_data;
396
397 attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific,
398 p_msg->api_add_incl_srvc.included_service_id);
399
400 cb_data.add_result.server_if = p_rcb->gatt_if;
401 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
402 cb_data.add_result.attr_id = attr_id;
403
404 if (attr_id)
405 {
406 cb_data.add_result.status = BTA_GATT_OK;
407 }
408 else
409 {
410 cb_data.add_result.status = BTA_GATT_ERROR;
411 }
412
413 if (p_rcb->p_cback)
414 (*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data);
415 }
416 /*******************************************************************************
417 **
418 ** Function bta_gatts_add_char
419 **
420 ** Description action function to add characteristic.
421 **
422 ** Returns none.
423 **
424 *******************************************************************************/
bta_gatts_add_char(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)425 void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
426 {
427 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
428 UINT16 attr_id = 0;
429 tBTA_GATTS cb_data;
430
431 attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
432 &p_msg->api_add_char.char_uuid,
433 p_msg->api_add_char.perm,
434 p_msg->api_add_char.property);
435 cb_data.add_result.server_if = p_rcb->gatt_if;
436 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
437 cb_data.add_result.attr_id = attr_id;
438 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID));
439
440 if (attr_id)
441 {
442 cb_data.add_result.status = BTA_GATT_OK;
443 }
444 else
445 {
446 cb_data.add_result.status = BTA_GATT_ERROR;
447 }
448
449 if (p_rcb->p_cback)
450 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
451 }
452 /*******************************************************************************
453 **
454 ** Function bta_gatts_add_char_descr
455 **
456 ** Description action function to add characteristic descriptor.
457 **
458 ** Returns none.
459 **
460 *******************************************************************************/
bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)461 void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
462 {
463 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
464 UINT16 attr_id = 0;
465 tBTA_GATTS cb_data;
466
467 attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
468 p_msg->api_add_char_descr.perm,
469 &p_msg->api_add_char_descr.descr_uuid);
470
471 cb_data.add_result.server_if = p_rcb->gatt_if;
472 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
473 cb_data.add_result.attr_id = attr_id;
474 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID));
475
476 if (attr_id)
477 {
478 cb_data.add_result.status = BTA_GATT_OK;
479 }
480 else
481 {
482 cb_data.add_result.status = BTA_GATT_ERROR;
483 }
484
485 if (p_rcb->p_cback)
486 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);
487
488 }
489 /*******************************************************************************
490 **
491 ** Function bta_gatts_delete_service
492 **
493 ** Description action function to delete a service.
494 **
495 ** Returns none.
496 **
497 *******************************************************************************/
bta_gatts_delete_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)498 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
499 {
500 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
501 tBTA_GATTS cb_data;
502
503 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
504 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
505
506 if (GATTS_DeleteService(p_rcb->gatt_if,
507 &p_srvc_cb->service_uuid,
508 p_srvc_cb->inst_num))
509 {
510 cb_data.srvc_oper.status = BTA_GATT_OK;
511 memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
512 }
513 else
514 {
515 cb_data.srvc_oper.status = BTA_GATT_ERROR;
516 }
517
518 if (p_rcb->p_cback)
519 (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
520
521 }
522 /*******************************************************************************
523 **
524 ** Function bta_gatts_start_service
525 **
526 ** Description action function to start a service.
527 **
528 ** Returns none.
529 **
530 *******************************************************************************/
bta_gatts_start_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)531 void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
532 {
533 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
534 tBTA_GATTS cb_data;
535
536 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
537 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
538
539 if (GATTS_StartService(p_rcb->gatt_if,
540 p_srvc_cb->service_id,
541 p_msg->api_start.transport) == GATT_SUCCESS)
542 {
543 APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
544 cb_data.srvc_oper.status = BTA_GATT_OK;
545 }
546 else
547 {
548 cb_data.srvc_oper.status = BTA_GATT_ERROR;
549 }
550
551 if (p_rcb->p_cback)
552 (*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data);
553
554 }
555 /*******************************************************************************
556 **
557 ** Function bta_gatts_stop_service
558 **
559 ** Description action function to stop a service.
560 **
561 ** Returns none.
562 **
563 *******************************************************************************/
bta_gatts_stop_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)564 void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
565 {
566 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
567 tBTA_GATTS cb_data;
568 UNUSED(p_msg);
569
570 GATTS_StopService(p_srvc_cb->service_id);
571 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
572 cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
573 cb_data.srvc_oper.status = BTA_GATT_OK;
574 APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
575
576 if (p_rcb->p_cback)
577 (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
578
579 }
580 /*******************************************************************************
581 **
582 ** Function bta_gatts_send_rsp
583 **
584 ** Description GATTS send response.
585 **
586 ** Returns none.
587 **
588 *******************************************************************************/
bta_gatts_send_rsp(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)589 void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
590 {
591 UNUSED(p_cb);
592
593 if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific,
594 p_msg->api_rsp.trans_id,
595 p_msg->api_rsp.status,
596 (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS)
597 {
598 APPL_TRACE_ERROR("Sending response failed");
599 }
600
601 }
602 /*******************************************************************************
603 **
604 ** Function bta_gatts_indicate_handle
605 **
606 ** Description GATTS send handle value indication or notification.
607 **
608 ** Returns none.
609 **
610 *******************************************************************************/
bta_gatts_indicate_handle(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)611 void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
612 {
613 tBTA_GATTS_SRVC_CB *p_srvc_cb;
614 tBTA_GATTS_RCB *p_rcb = NULL;
615 tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
616 tGATT_IF gatt_if;
617 BD_ADDR remote_bda;
618 tBTA_TRANSPORT transport;
619 tBTA_GATTS cb_data;
620
621 p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
622
623 if (p_srvc_cb )
624 {
625 if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
626 &gatt_if, remote_bda, &transport))
627 {
628 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
629
630 if (p_msg->api_indicate.need_confirm)
631
632 status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
633 p_msg->api_indicate.attr_id,
634 p_msg->api_indicate.len,
635 p_msg->api_indicate.value);
636 else
637 status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
638 p_msg->api_indicate.attr_id,
639 p_msg->api_indicate.len,
640 p_msg->api_indicate.value);
641
642 /* if over BR_EDR, inform PM for mode change */
643 if (transport == BTA_TRANSPORT_BR_EDR)
644 {
645 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
646 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
647 }
648 }
649 else
650 {
651 APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
652 p_msg->api_indicate.hdr.layer_specific);
653 }
654
655 if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
656 p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
657 {
658 cb_data.req_data.status = status;
659 cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
660
661 (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
662 }
663 }
664 else
665 {
666 APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
667 p_msg->api_indicate.attr_id);
668 }
669 }
670
671
672 /*******************************************************************************
673 **
674 ** Function bta_gatts_open
675 **
676 ** Description
677 **
678 ** Returns none.
679 **
680 *******************************************************************************/
bta_gatts_open(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)681 void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
682 {
683 tBTA_GATTS_RCB *p_rcb=NULL;
684 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
685 UINT16 conn_id;
686 UNUSED(p_cb);
687
688 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
689 {
690 /* should always get the connection ID */
691 if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
692 p_msg->api_open.is_direct, p_msg->api_open.transport, false))
693 {
694 status = BTA_GATT_OK;
695
696 if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
697 &conn_id, p_msg->api_open.transport))
698 {
699 status = BTA_GATT_ALREADY_OPEN;
700 }
701 }
702 }
703 else
704 {
705 APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
706 }
707
708 if (p_rcb && p_rcb->p_cback)
709 (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, (tBTA_GATTS *)&status);
710
711 }
712 /*******************************************************************************
713 **
714 ** Function bta_gatts_cancel_open
715 **
716 ** Description
717 **
718 ** Returns none.
719 **
720 *******************************************************************************/
bta_gatts_cancel_open(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)721 void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
722 {
723 tBTA_GATTS_RCB *p_rcb;
724 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
725 UNUSED(p_cb);
726
727 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
728 {
729 if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
730 p_msg->api_cancel_open.is_direct))
731 {
732 APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
733 }
734 else
735 {
736 status= BTA_GATT_OK;
737 }
738 }
739 else
740 {
741 APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
742 }
743
744 if (p_rcb && p_rcb->p_cback)
745 (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, (tBTA_GATTS *)&status);
746 }
747 /*******************************************************************************
748 **
749 ** Function bta_gatts_close
750 **
751 ** Description
752 **
753 ** Returns none.
754 **
755 *******************************************************************************/
bta_gatts_close(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)756 void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
757 {
758 tBTA_GATTS_RCB *p_rcb;
759 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
760 tGATT_IF gatt_if;
761 BD_ADDR remote_bda;
762 tBTA_GATT_TRANSPORT transport;
763
764 UNUSED(p_cb);
765
766 if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
767 {
768 if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
769 {
770 APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
771 }
772 else
773 {
774 status= BTA_GATT_OK;
775 }
776
777 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
778
779 if (p_rcb && p_rcb->p_cback)
780 {
781 if (transport == BTA_TRANSPORT_BR_EDR)
782 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);
783
784 (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status);
785 }
786 }
787 else
788 {
789 APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
790 }
791
792 }
793 /*******************************************************************************
794 **
795 ** Function bta_gatts_listen
796 **
797 ** Description Start or stop listening for LE connection on a GATT server
798 **
799 ** Returns none.
800 **
801 *******************************************************************************/
bta_gatts_listen(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)802 void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
803 {
804 tBTA_GATTS_RCB *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
805 tBTA_GATTS cb_data;
806 UNUSED(p_cb);
807
808 cb_data.reg_oper.status = BTA_GATT_OK;
809 cb_data.reg_oper.server_if = p_msg->api_listen.server_if;
810
811 if (p_rcb == NULL)
812 {
813 APPL_TRACE_ERROR("Unknown GATTS application");
814 return;
815 }
816
817 if (!GATT_Listen(p_msg->api_listen.server_if,
818 p_msg->api_listen.start,
819 p_msg->api_listen.remote_bda))
820 {
821 cb_data.status = BTA_GATT_ERROR;
822 APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
823 }
824
825 if (p_rcb->p_cback)
826 (*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
827 }
828
829 /*******************************************************************************
830 **
831 ** Function bta_gatts_request_cback
832 **
833 ** Description GATTS attribute request callback.
834 **
835 ** Returns none.
836 **
837 *******************************************************************************/
bta_gatts_send_request_cback(UINT16 conn_id,UINT32 trans_id,tGATTS_REQ_TYPE req_type,tGATTS_DATA * p_data)838 static void bta_gatts_send_request_cback (UINT16 conn_id,
839 UINT32 trans_id,
840 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data)
841 {
842 tBTA_GATTS cb_data;
843 tBTA_GATTS_RCB *p_rcb;
844 tGATT_IF gatt_if;
845 tBTA_GATT_TRANSPORT transport;
846
847 memset(&cb_data, 0 , sizeof(tBTA_GATTS));
848
849 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
850 {
851 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
852
853 APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
854 conn_id, trans_id, req_type);
855
856 if (p_rcb && p_rcb->p_cback)
857 {
858 /* if over BR_EDR, inform PM for mode change */
859 if (transport == BTA_TRANSPORT_BR_EDR)
860 {
861 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
862 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
863 }
864
865 cb_data.req_data.conn_id = conn_id;
866 cb_data.req_data.trans_id = trans_id;
867 cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data;
868
869 (*p_rcb->p_cback)(req_type, &cb_data);
870 }
871 else
872 {
873 APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
874 }
875 }
876 else
877 {
878 APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id);
879 }
880 }
881
882 /*******************************************************************************
883 **
884 ** Function bta_gatts_conn_cback
885 **
886 ** Description connection callback.
887 **
888 ** Returns none.
889 **
890 *******************************************************************************/
bta_gatts_conn_cback(tGATT_IF gatt_if,BD_ADDR bda,UINT16 conn_id,BOOLEAN connected,tGATT_DISCONN_REASON reason,tGATT_TRANSPORT transport)891 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
892 BOOLEAN connected, tGATT_DISCONN_REASON reason,
893 tGATT_TRANSPORT transport)
894 {
895 tBTA_GATTS cb_data;
896 UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
897 tBTA_GATTS_RCB *p_reg;
898
899 APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
900 gatt_if, conn_id, connected, reason);
901 APPL_TRACE_DEBUG("bta_gatts_conn_cback bda :%02x-%02x-%02x-%02x-%02x-%02x ",
902 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
903
904 bt_bdaddr_t bdaddr;
905 bdcpy(bdaddr.address, bda);
906 if (connected)
907 btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
908 else
909 btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
910
911 p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
912
913 if (p_reg && p_reg->p_cback)
914 {
915 /* there is no RM for GATT */
916 if (transport == BTA_TRANSPORT_BR_EDR)
917 {
918 if (connected)
919 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
920 else
921 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda);
922 }
923
924 cb_data.conn.conn_id = conn_id;
925 cb_data.conn.server_if = gatt_if;
926 cb_data.conn.reason = reason;
927 cb_data.conn.transport = transport;
928 memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
929 (*p_reg->p_cback)(evt, &cb_data);
930 }
931 else
932 {
933 APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found",gatt_if);
934 }
935 }
936
937 /*******************************************************************************
938 **
939 ** Function bta_gatts_cong_cback
940 **
941 ** Description congestion callback.
942 **
943 ** Returns none.
944 **
945 *******************************************************************************/
bta_gatts_cong_cback(UINT16 conn_id,BOOLEAN congested)946 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
947 {
948 tBTA_GATTS_RCB *p_rcb;
949 tGATT_IF gatt_if;
950 tBTA_GATT_TRANSPORT transport;
951 tBTA_GATTS cb_data;
952
953 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
954 {
955 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
956
957 if (p_rcb && p_rcb->p_cback)
958 {
959 cb_data.congest.conn_id = conn_id;
960 cb_data.congest.congested = congested;
961
962 (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
963 }
964 }
965 }
966 #endif /* BTA_GATT_INCLUDED */
967