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