1 /****************************************************************************** 2 * 3 * Copyright (C) 2010-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 is the implementation of the API for GATT server of BTA. 22 * 23 ******************************************************************************/ 24 25 #include "bt_target.h" 26 27 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) 28 29 #include <string.h> 30 #include "gki.h" 31 #include "bta_sys.h" 32 #include "bta_gatt_api.h" 33 #include "bta_gatts_int.h" 34 35 /***************************************************************************** 36 ** Externs 37 *****************************************************************************/ 38 #if BTA_DYNAMIC_MEMORY == FALSE 39 extern tBTA_GATTS_CB bta_gatts_cb; 40 #endif 41 42 /***************************************************************************** 43 ** Constants 44 *****************************************************************************/ 45 46 static const tBTA_SYS_REG bta_gatts_reg = 47 { 48 bta_gatts_hdl_event, 49 NULL /* need a disable functino to be called when BT is disabled */ 50 }; 51 52 /******************************************************************************* 53 ** 54 ** Function BTA_GATTS_Init 55 ** 56 ** Description This function is called to initalize GATTS module 57 ** 58 ** Parameters None 59 ** 60 ** Returns None 61 ** 62 *******************************************************************************/ 63 void BTA_GATTS_Init() 64 { 65 memset(&bta_gatts_cb, 0, sizeof(tBTA_GATTS_CB)); 66 } 67 68 /******************************************************************************* 69 ** 70 ** Function BTA_GATTS_AppRegister 71 ** 72 ** Description This function is called to register application callbacks 73 ** with BTA GATTS module. 74 ** 75 ** Parameters p_app_uuid - applicaiton UUID 76 ** p_cback - pointer to the application callback function. 77 ** 78 ** Returns None 79 ** 80 *******************************************************************************/ 81 void BTA_GATTS_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTS_CBACK *p_cback) 82 { 83 tBTA_GATTS_API_REG *p_buf; 84 85 /* register with BTA system manager */ 86 GKI_sched_lock(); 87 if (!bta_gatts_cb.enabled) 88 { 89 bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg); 90 } 91 GKI_sched_unlock(); 92 93 if ((p_buf = (tBTA_GATTS_API_REG *) GKI_getbuf(sizeof(tBTA_GATTS_API_REG))) != NULL) 94 { 95 p_buf->hdr.event = BTA_GATTS_API_REG_EVT; 96 97 if (p_app_uuid != NULL) 98 memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_UUID)); 99 p_buf->p_cback = p_cback; 100 101 bta_sys_sendmsg(p_buf); 102 } 103 return; 104 } 105 106 107 108 /******************************************************************************* 109 ** 110 ** Function BTA_GATTS_AppDeregister 111 ** 112 ** Description De-register with GATT Server. 113 ** 114 ** Parameters app_id: applicatino ID. 115 ** 116 ** Returns void 117 ** 118 *******************************************************************************/ 119 void BTA_GATTS_AppDeregister(tBTA_GATTS_IF server_if) 120 { 121 tBTA_GATTS_API_DEREG *p_buf; 122 123 if ((p_buf = (tBTA_GATTS_API_DEREG *) GKI_getbuf(sizeof(tBTA_GATTS_API_DEREG))) != NULL) 124 { 125 p_buf->hdr.event = BTA_GATTS_API_DEREG_EVT; 126 p_buf->server_if = server_if; 127 128 bta_sys_sendmsg(p_buf); 129 } 130 return; 131 } 132 133 /******************************************************************************* 134 ** 135 ** Function BTA_GATTS_CreateService 136 ** 137 ** Description Create a service. When service creation is done, a callback 138 ** event BTA_GATTS_CREATE_SRVC_EVT is called to report status 139 ** and service ID to the profile. The service ID obtained in 140 ** the callback function needs to be used when adding included 141 ** service and characteristics/descriptors into the service. 142 ** 143 ** Parameters app_id: Profile ID this service is belonged to. 144 ** p_service_uuid: service UUID. 145 ** inst: instance ID number of this service. 146 ** num_handle: numble of handle requessted for this service. 147 ** is_primary: is this service a primary one or not. 148 ** 149 ** Returns void 150 ** 151 *******************************************************************************/ 152 void BTA_GATTS_CreateService(tBTA_GATTS_IF server_if, tBT_UUID *p_service_uuid, UINT8 inst, 153 UINT16 num_handle, BOOLEAN is_primary) 154 { 155 tBTA_GATTS_API_CREATE_SRVC *p_buf; 156 157 if ((p_buf = (tBTA_GATTS_API_CREATE_SRVC *) GKI_getbuf(sizeof(tBTA_GATTS_API_CREATE_SRVC))) != NULL) 158 { 159 p_buf->hdr.event = BTA_GATTS_API_CREATE_SRVC_EVT; 160 161 p_buf->server_if = server_if; 162 p_buf->inst = inst; 163 memcpy(&p_buf->service_uuid, p_service_uuid, sizeof(tBT_UUID)); 164 p_buf->num_handle = num_handle; 165 p_buf->is_pri = is_primary; 166 167 bta_sys_sendmsg(p_buf); 168 } 169 return; 170 } 171 /******************************************************************************* 172 ** 173 ** Function BTA_GATTS_AddIncludeService 174 ** 175 ** Description This function is called to add an included service. After included 176 ** service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT 177 ** is reported the included service ID. 178 ** 179 ** Parameters service_id: service ID to which this included service is to 180 ** be added. 181 ** included_service_id: the service ID to be included. 182 ** 183 ** Returns void 184 ** 185 *******************************************************************************/ 186 void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_service_id) 187 { 188 tBTA_GATTS_API_ADD_INCL_SRVC *p_buf; 189 190 if ((p_buf = 191 (tBTA_GATTS_API_ADD_INCL_SRVC *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_INCL_SRVC))) 192 != NULL) 193 { 194 p_buf->hdr.event = BTA_GATTS_API_ADD_INCL_SRVC_EVT; 195 196 p_buf->hdr.layer_specific = service_id; 197 p_buf->included_service_id = included_service_id; 198 199 bta_sys_sendmsg(p_buf); 200 } 201 return; 202 203 } 204 /******************************************************************************* 205 ** 206 ** Function BTA_GATTS_AddCharacteristic 207 ** 208 ** Description This function is called to add a characteristic into a service. 209 ** 210 ** Parameters service_id: service ID to which this included service is to 211 ** be added. 212 ** p_char_uuid : Characteristic UUID. 213 ** perm : Characteristic value declaration attribute permission. 214 ** property : Characteristic Properties 215 ** 216 ** Returns None 217 ** 218 *******************************************************************************/ 219 void BTA_GATTS_AddCharacteristic (UINT16 service_id, tBT_UUID *p_char_uuid, 220 tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property) 221 { 222 tBTA_GATTS_API_ADD_CHAR *p_buf; 223 224 if ((p_buf = (tBTA_GATTS_API_ADD_CHAR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_CHAR))) != NULL) 225 { 226 memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_CHAR)); 227 228 p_buf->hdr.event = BTA_GATTS_API_ADD_CHAR_EVT; 229 p_buf->hdr.layer_specific = service_id; 230 p_buf->perm = perm; 231 p_buf->property = property; 232 233 if (p_char_uuid) 234 { 235 memcpy(&p_buf->char_uuid, p_char_uuid, sizeof(tBT_UUID)); 236 } 237 bta_sys_sendmsg(p_buf); 238 } 239 return; 240 } 241 242 /******************************************************************************* 243 ** 244 ** Function BTA_GATTS_AddCharDescriptor 245 ** 246 ** Description This function is called to add characteristic descriptor. When 247 ** it's done, a callback event BTA_GATTS_ADD_DESCR_EVT is called 248 ** to report the status and an ID number for this descriptor. 249 ** 250 ** Parameters service_id: service ID to which this charatceristic descriptor is to 251 ** be added. 252 ** perm: descriptor access permission. 253 ** p_descr_uuid: descriptor UUID. 254 ** 255 ** Returns returns status. 256 ** 257 *******************************************************************************/ 258 void BTA_GATTS_AddCharDescriptor (UINT16 service_id, 259 tBTA_GATT_PERM perm, 260 tBT_UUID * p_descr_uuid) 261 { 262 tBTA_GATTS_API_ADD_DESCR *p_buf; 263 UINT16 len = sizeof(tBTA_GATTS_API_ADD_DESCR); 264 265 266 if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(len)) != NULL) 267 { 268 memset(p_buf, 0, len); 269 270 p_buf->hdr.event = BTA_GATTS_API_ADD_DESCR_EVT; 271 p_buf->hdr.layer_specific = service_id; 272 p_buf->perm = perm; 273 274 if (p_descr_uuid) 275 { 276 memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID)); 277 } 278 bta_sys_sendmsg(p_buf); 279 } 280 return; 281 282 } 283 284 /******************************************************************************* 285 ** 286 ** Function BTA_GATTS_DeleteService 287 ** 288 ** Description This function is called to delete a service. When this is done, 289 ** a callback event BTA_GATTS_DELETE_EVT is report with the status. 290 ** 291 ** Parameters service_id: service_id to be deleted. 292 ** 293 ** Returns returns none. 294 ** 295 *******************************************************************************/ 296 void BTA_GATTS_DeleteService(UINT16 service_id) 297 { 298 BT_HDR *p_buf; 299 300 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) 301 { 302 p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT; 303 304 p_buf->layer_specific = service_id; 305 306 bta_sys_sendmsg(p_buf); 307 } 308 return; 309 310 } 311 312 /******************************************************************************* 313 ** 314 ** Function BTA_GATTS_StartService 315 ** 316 ** Description This function is called to start a service. 317 ** 318 ** Parameters service_id: the service ID to be started. 319 ** sup_transport: supported trasnport. 320 ** 321 ** Returns None. 322 ** 323 *******************************************************************************/ 324 void BTA_GATTS_StartService(UINT16 service_id, tBTA_GATT_TRANSPORT sup_transport) 325 { 326 tBTA_GATTS_API_START *p_buf; 327 328 if ((p_buf = (tBTA_GATTS_API_START *) GKI_getbuf(sizeof(tBTA_GATTS_API_START))) != NULL) 329 { 330 p_buf->hdr.event = BTA_GATTS_API_START_SRVC_EVT; 331 332 p_buf->hdr.layer_specific = service_id; 333 p_buf->transport = sup_transport; 334 335 bta_sys_sendmsg(p_buf); 336 } 337 return; 338 } 339 340 /******************************************************************************* 341 ** 342 ** Function BTA_GATTS_StopService 343 ** 344 ** Description This function is called to stop a service. 345 ** 346 ** Parameters service_id - service to be topped. 347 ** 348 ** Returns None 349 ** 350 *******************************************************************************/ 351 void BTA_GATTS_StopService(UINT16 service_id) 352 { 353 BT_HDR *p_buf; 354 355 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) 356 { 357 p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT; 358 359 p_buf->layer_specific = service_id; 360 361 bta_sys_sendmsg(p_buf); 362 } 363 return; 364 } 365 366 /******************************************************************************* 367 ** 368 ** Function BTA_GATTS_HandleValueIndication 369 ** 370 ** Description This function is called to read a characteristics descriptor. 371 ** 372 ** Parameters bda - remote device bd address to indicate. 373 ** attr_id - attribute ID to indicate. 374 ** data_len - indicate data length. 375 ** p_data: data to indicate. 376 ** need_confirm - if this indication expects a confirmation or not. 377 ** 378 ** Returns None 379 ** 380 *******************************************************************************/ 381 void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 data_len, 382 UINT8 *p_data, BOOLEAN need_confirm) 383 { 384 tBTA_GATTS_API_INDICATION *p_buf; 385 UINT16 len = sizeof(tBTA_GATTS_API_INDICATION); 386 387 if ((p_buf = (tBTA_GATTS_API_INDICATION *) GKI_getbuf(len)) != NULL) 388 { 389 memset(p_buf, 0, len); 390 391 p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT; 392 p_buf->hdr.layer_specific = conn_id; 393 p_buf->attr_id = attr_id; 394 p_buf->need_confirm = need_confirm; 395 396 if (data_len > 0 && p_data != NULL) 397 { 398 p_buf->len = data_len; 399 memcpy(p_buf->value, p_data, data_len); 400 401 } 402 bta_sys_sendmsg(p_buf); 403 } 404 return; 405 406 } 407 /******************************************************************************* 408 ** 409 ** Function BTA_GATTS_SendRsp 410 ** 411 ** Description This function is called to send a response to a request. 412 ** 413 ** Parameters conn_id - connection identifier. 414 ** trans_id - transaction ID. 415 ** status - response status 416 ** p_msg - response data. 417 ** 418 ** Returns None 419 ** 420 *******************************************************************************/ 421 void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id, 422 tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg) 423 { 424 tBTA_GATTS_API_RSP *p_buf; 425 UINT16 len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tBTA_GATTS_RSP); 426 427 if ((p_buf = (tBTA_GATTS_API_RSP *) GKI_getbuf(len)) != NULL) 428 { 429 memset(p_buf, 0, len); 430 431 p_buf->hdr.event = BTA_GATTS_API_RSP_EVT; 432 p_buf->hdr.layer_specific = conn_id; 433 p_buf->trans_id = trans_id; 434 p_buf->status = status; 435 436 if (p_msg != NULL) 437 { 438 p_buf->p_rsp = (tBTA_GATTS_RSP *)(p_buf + 1); 439 memcpy(p_buf->p_rsp, p_msg, sizeof(tBTA_GATTS_RSP)); 440 } 441 442 bta_sys_sendmsg(p_buf); 443 } 444 return; 445 446 } 447 448 449 450 /******************************************************************************* 451 ** 452 ** Function BTA_GATTS_Open 453 ** 454 ** Description Open a direct open connection or add a background auto connection 455 ** bd address 456 ** 457 ** Parameters server_if: server interface. 458 ** remote_bda: remote device BD address. 459 ** is_direct: direct connection or background auto connection 460 ** 461 ** Returns void 462 ** 463 *******************************************************************************/ 464 void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct) 465 { 466 tBTA_GATTS_API_OPEN *p_buf; 467 468 if ((p_buf = (tBTA_GATTS_API_OPEN *) GKI_getbuf(sizeof(tBTA_GATTS_API_OPEN))) != NULL) 469 { 470 p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT; 471 p_buf->server_if = server_if; 472 p_buf->is_direct = is_direct; 473 memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN); 474 475 bta_sys_sendmsg(p_buf); 476 } 477 return; 478 } 479 480 481 /******************************************************************************* 482 ** 483 ** Function BTA_GATTS_CancelOpen 484 ** 485 ** Description Cancel a direct open connection or remove a background auto connection 486 ** bd address 487 ** 488 ** Parameters server_if: server interface. 489 ** remote_bda: remote device BD address. 490 ** is_direct: direct connection or background auto connection 491 ** 492 ** Returns void 493 ** 494 *******************************************************************************/ 495 void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct) 496 { 497 tBTA_GATTS_API_CANCEL_OPEN *p_buf; 498 499 if ((p_buf = (tBTA_GATTS_API_CANCEL_OPEN *) GKI_getbuf(sizeof(tBTA_GATTS_API_CANCEL_OPEN))) != NULL) 500 { 501 p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT; 502 p_buf->server_if = server_if; 503 p_buf->is_direct = is_direct; 504 memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN); 505 bta_sys_sendmsg(p_buf); 506 } 507 return; 508 } 509 510 /******************************************************************************* 511 ** 512 ** Function BTA_GATTS_Close 513 ** 514 ** Description Close a connection a remote device. 515 ** 516 ** Parameters conn_id: connectino ID to be closed. 517 ** 518 ** Returns void 519 ** 520 *******************************************************************************/ 521 void BTA_GATTS_Close(UINT16 conn_id) 522 { 523 BT_HDR *p_buf; 524 525 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) 526 { 527 p_buf->event = BTA_GATTS_API_CLOSE_EVT; 528 p_buf->layer_specific = conn_id; 529 bta_sys_sendmsg(p_buf); 530 } 531 return; 532 533 } 534 535 #endif /* BTA_GATT_INCLUDED */ 536