1 /****************************************************************************** 2 * 3 * Copyright (C) 2008-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 functions 22 * 23 ******************************************************************************/ 24 25 #include "bt_target.h" 26 27 #if BLE_INCLUDED == TRUE 28 #include <string.h> 29 #include "gatt_int.h" 30 #include "l2c_api.h" 31 32 #define GATT_MTU_REQ_MIN_LEN 2 33 34 35 /******************************************************************************* 36 ** 37 ** Function gatt_sr_enqueue_cmd 38 ** 39 ** Description This function enqueue the request from client which needs a 40 ** application response, and update the transaction ID. 41 ** 42 ** Returns void 43 ** 44 *******************************************************************************/ 45 UINT32 gatt_sr_enqueue_cmd (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 handle) 46 { 47 tGATT_SR_CMD *p_cmd = &p_tcb->sr_cmd; 48 UINT32 trans_id = 0; 49 50 if ( (p_cmd->op_code == 0) || 51 (op_code == GATT_HANDLE_VALUE_CONF)) /* no pending request */ 52 { 53 if (op_code == GATT_CMD_WRITE || 54 op_code == GATT_SIGN_CMD_WRITE || 55 op_code == GATT_REQ_MTU || 56 op_code == GATT_HANDLE_VALUE_CONF) 57 { 58 trans_id = ++p_tcb->trans_id; 59 } 60 else 61 { 62 p_cmd->trans_id = ++p_tcb->trans_id; 63 p_cmd->op_code = op_code; 64 p_cmd->handle = handle; 65 p_cmd->status = GATT_NOT_FOUND; 66 p_tcb->trans_id %= GATT_TRANS_ID_MAX; 67 trans_id = p_cmd->trans_id; 68 } 69 } 70 71 return trans_id; 72 } 73 74 /******************************************************************************* 75 ** 76 ** Function gatt_sr_cmd_empty 77 ** 78 ** Description This function check the server command queue is empty or not. 79 ** 80 ** Returns TRUE if empty, FALSE if there is pending command. 81 ** 82 *******************************************************************************/ 83 BOOLEAN gatt_sr_cmd_empty (tGATT_TCB *p_tcb) 84 { 85 return(p_tcb->sr_cmd.op_code == 0); 86 } 87 88 /******************************************************************************* 89 ** 90 ** Function gatt_dequeue_sr_cmd 91 ** 92 ** Description This function dequeue the request from command queue. 93 ** 94 ** Returns void 95 ** 96 *******************************************************************************/ 97 void gatt_dequeue_sr_cmd (tGATT_TCB *p_tcb) 98 { 99 /* Double check in case any buffers are queued */ 100 GATT_TRACE_DEBUG0("gatt_dequeue_sr_cmd" ); 101 if (p_tcb->sr_cmd.p_rsp_msg) 102 { 103 GATT_TRACE_ERROR1("free p_tcb->sr_cmd.p_rsp_msg = %d", p_tcb->sr_cmd.p_rsp_msg); 104 105 GKI_freebuf (p_tcb->sr_cmd.p_rsp_msg); 106 } 107 108 while (p_tcb->sr_cmd.multi_rsp_q.p_first) 109 GKI_freebuf (GKI_dequeue (&p_tcb->sr_cmd.multi_rsp_q)); 110 memset( &p_tcb->sr_cmd, 0, sizeof(tGATT_SR_CMD)); 111 } 112 113 /******************************************************************************* 114 ** 115 ** Function process_read_multi_rsp 116 ** 117 ** Description This function check the read multiple response. 118 ** 119 ** Returns BOOLEAN if all replies have been received 120 ** 121 *******************************************************************************/ 122 static BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status, 123 tGATTS_RSP *p_msg, UINT16 mtu) 124 { 125 tGATTS_RSP *p_rsp; 126 UINT16 ii, total_len, len; 127 BT_HDR *p_buf = (BT_HDR *)GKI_getbuf((UINT16)sizeof(tGATTS_RSP)); 128 UINT8 *p; 129 BOOLEAN is_overflow = FALSE; 130 131 GATT_TRACE_DEBUG2 ("process_read_multi_rsp status=%d mtu=%d", status, mtu); 132 133 if (p_buf == NULL) 134 { 135 p_cmd->status = GATT_INSUF_RESOURCE; 136 return FALSE; 137 } 138 139 /* Enqueue the response */ 140 memcpy((void *)p_buf, (const void *)p_msg, sizeof(tGATTS_RSP)); 141 GKI_enqueue (&p_cmd->multi_rsp_q, p_buf); 142 143 p_cmd->status = status; 144 if (status == GATT_SUCCESS) 145 { 146 GATT_TRACE_DEBUG2 ("Multi read count=%d num_hdls=%d", 147 p_cmd->multi_rsp_q.count, p_cmd->multi_req.num_handles); 148 /* Wait till we get all the responses */ 149 if (p_cmd->multi_rsp_q.count == p_cmd->multi_req.num_handles) 150 { 151 len = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu; 152 if ((p_buf = (BT_HDR *)GKI_getbuf(len)) == NULL) 153 { 154 p_cmd->status = GATT_INSUF_RESOURCE; 155 return(TRUE); 156 } 157 158 memset(p_buf, 0, len); 159 p_buf->offset = L2CAP_MIN_OFFSET; 160 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 161 162 /* First byte in the response is the opcode */ 163 *p++ = GATT_RSP_READ_MULTI; 164 p_buf->len = 1; 165 166 /* Now walk through the buffers puting the data into the response in order */ 167 for (ii = 0; ii < p_cmd->multi_req.num_handles; ii++) 168 { 169 if (ii==0) 170 { 171 p_rsp = (tGATTS_RSP *)GKI_getfirst (&p_cmd->multi_rsp_q); 172 } 173 else 174 { 175 p_rsp = (tGATTS_RSP *)GKI_getnext (p_rsp); 176 } 177 178 if (p_rsp != NULL) 179 { 180 181 total_len = (p_buf->len + p_rsp->attr_value.len); 182 183 if (total_len > mtu) 184 { 185 /* just send the partial response for the overflow case */ 186 len = p_rsp->attr_value.len - (total_len - mtu); 187 is_overflow = TRUE; 188 GATT_TRACE_DEBUG2 ("multi read overflow available len=%d val_len=%d", len, p_rsp->attr_value.len ); 189 } 190 else 191 { 192 len = p_rsp->attr_value.len; 193 } 194 195 if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) 196 { 197 memcpy (p, p_rsp->attr_value.value, len); 198 if (!is_overflow) 199 p += len; 200 p_buf->len += len; 201 } 202 else 203 { 204 p_cmd->status = GATT_NOT_FOUND; 205 break; 206 } 207 208 if (is_overflow) 209 break; 210 211 } 212 else 213 { 214 p_cmd->status = GATT_NOT_FOUND; 215 break; 216 } 217 218 } /* loop through all handles*/ 219 220 221 /* Sanity check on the buffer length */ 222 if (p_buf->len == 0) 223 { 224 GATT_TRACE_ERROR0("process_read_multi_rsp - nothing found!!"); 225 p_cmd->status = GATT_NOT_FOUND; 226 GKI_freebuf (p_buf); 227 GATT_TRACE_DEBUG0(" GKI_freebuf (p_buf)"); 228 } 229 else if (p_cmd->p_rsp_msg != NULL) 230 { 231 GKI_freebuf (p_buf); 232 } 233 else 234 { 235 p_cmd->p_rsp_msg = p_buf; 236 } 237 238 return(TRUE); 239 } 240 } 241 else /* any handle read exception occurs, return error */ 242 { 243 return(TRUE); 244 } 245 246 /* If here, still waiting */ 247 return(FALSE); 248 } 249 250 /******************************************************************************* 251 ** 252 ** Function gatt_sr_process_app_rsp 253 ** 254 ** Description This function checks whether the response message from application 255 ** match any pending request or not. 256 ** 257 ** Returns void 258 ** 259 *******************************************************************************/ 260 tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if, 261 UINT32 trans_id, UINT8 op_code, 262 tGATT_STATUS status, tGATTS_RSP *p_msg) 263 { 264 tGATT_STATUS ret_code = GATT_SUCCESS; 265 266 GATT_TRACE_DEBUG1("gatt_sr_process_app_rsp gatt_if=%d", gatt_if); 267 268 gatt_sr_update_cback_cnt(p_tcb, gatt_if, FALSE, FALSE); 269 270 if (op_code == GATT_REQ_READ_MULTI) 271 { 272 /* If no error and still waiting, just return */ 273 if (!process_read_multi_rsp (&p_tcb->sr_cmd, status, p_msg, p_tcb->payload_size)) 274 return(GATT_SUCCESS); 275 } 276 else 277 { 278 if (op_code == GATT_REQ_PREPARE_WRITE && status == GATT_SUCCESS) 279 gatt_sr_update_prep_cnt(p_tcb, gatt_if, TRUE, FALSE); 280 281 if (op_code == GATT_REQ_EXEC_WRITE && status != GATT_SUCCESS) 282 gatt_sr_reset_cback_cnt(p_tcb); 283 284 p_tcb->sr_cmd.status = status; 285 286 if (gatt_sr_is_cback_cnt_zero(p_tcb) 287 && status == GATT_SUCCESS) 288 { 289 if (p_tcb->sr_cmd.p_rsp_msg == NULL) 290 { 291 p_tcb->sr_cmd.p_rsp_msg = attp_build_sr_msg (p_tcb, (UINT8)(op_code + 1), (tGATT_SR_MSG *)p_msg); 292 } 293 else 294 { 295 GATT_TRACE_ERROR0("Exception!!! already has respond message"); 296 } 297 } 298 } 299 if (gatt_sr_is_cback_cnt_zero(p_tcb)) 300 { 301 if ( (p_tcb->sr_cmd.status == GATT_SUCCESS) && (p_tcb->sr_cmd.p_rsp_msg) ) 302 { 303 ret_code = attp_send_sr_msg (p_tcb, p_tcb->sr_cmd.p_rsp_msg); 304 p_tcb->sr_cmd.p_rsp_msg = NULL; 305 } 306 else 307 { 308 ret_code = gatt_send_error_rsp (p_tcb, status, op_code, p_tcb->sr_cmd.handle, FALSE); 309 } 310 311 gatt_dequeue_sr_cmd(p_tcb); 312 } 313 314 GATT_TRACE_DEBUG1("gatt_sr_process_app_rsp ret_code=%d", ret_code); 315 316 return ret_code; 317 } 318 319 /******************************************************************************* 320 ** 321 ** Function gatt_process_exec_write_req 322 ** 323 ** Description This function is called to process the execute write request 324 ** from client. 325 ** 326 ** Returns void 327 ** 328 *******************************************************************************/ 329 void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 330 { 331 UINT8 *p = p_data, flag, i = 0; 332 UINT32 trans_id = 0; 333 BT_HDR *p_buf; 334 tGATT_IF gatt_if; 335 UINT16 conn_id; 336 337 #if GATT_CONFORMANCE_TESTING == TRUE 338 if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) 339 { 340 GATT_TRACE_DEBUG2("conf test forced err rsp for %s error status=%d", 341 __FUNCTION__,gatt_cb.err_status); 342 343 gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, gatt_cb.handle, FALSE); 344 345 return; 346 } 347 #endif 348 349 STREAM_TO_UINT8(flag, p); 350 351 /* mask the flag */ 352 flag &= GATT_PREP_WRITE_EXEC; 353 354 355 /* no prep write is queued */ 356 if (!gatt_sr_is_prep_cnt_zero(p_tcb)) 357 { 358 trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, 0); 359 gatt_sr_copy_prep_cnt_to_cback_cnt(p_tcb); 360 361 for (i=0; i<GATT_MAX_APPS; i++) 362 { 363 if (p_tcb->prep_cnt[i]) 364 { 365 gatt_if = (tGATT_IF) (i+1); 366 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if); 367 gatt_sr_send_req_callback(conn_id, 368 trans_id, 369 GATTS_REQ_TYPE_WRITE_EXEC, 370 (tGATTS_DATA *)&flag); 371 p_tcb->prep_cnt[i]= 0; 372 } 373 } 374 } 375 else /* nothing needs to be executed , send response now */ 376 { 377 GATT_TRACE_ERROR0("gatt_process_exec_write_req: no prepare write pending"); 378 379 if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_EXEC_WRITE, NULL)) != NULL) 380 { 381 attp_send_sr_msg (p_tcb, p_buf); 382 } 383 384 } 385 } 386 387 /******************************************************************************* 388 ** 389 ** Function gatt_process_read_multi_req 390 ** 391 ** Description This function is called to process the read multiple request 392 ** from client. 393 ** 394 ** Returns void 395 ** 396 *******************************************************************************/ 397 void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 398 { 399 UINT32 trans_id; 400 UINT16 handle = 0, ll = len; 401 UINT8 *p = p_data, i_rcb; 402 tGATT_STATUS err = GATT_SUCCESS; 403 UINT8 sec_flag, key_size; 404 tGATTS_RSP *p_msg; 405 406 GATT_TRACE_DEBUG0("gatt_process_read_multi_req" ); 407 p_tcb->sr_cmd.multi_req.num_handles = 0; 408 409 gatt_sr_get_sec_info(p_tcb->peer_bda, 410 (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), 411 &sec_flag, 412 &key_size); 413 414 #if GATT_CONFORMANCE_TESTING == TRUE 415 if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) 416 { 417 GATT_TRACE_DEBUG1("Conformance tst: forced err rspvofr ReadMultiple: error status=%d", gatt_cb.err_status); 418 419 STREAM_TO_UINT16(handle, p); 420 421 gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle, FALSE); 422 423 return; 424 } 425 #endif 426 427 while (ll >= 2 && p_tcb->sr_cmd.multi_req.num_handles < GATT_MAX_READ_MULTI_HANDLES) 428 { 429 STREAM_TO_UINT16(handle, p); 430 431 if ((i_rcb = gatt_sr_find_i_rcb_by_handle(handle)) < GATT_MAX_SR_PROFILES) 432 { 433 p_tcb->sr_cmd.multi_req.handles[p_tcb->sr_cmd.multi_req.num_handles++] = handle; 434 435 /* check read permission */ 436 if ((err = gatts_read_attr_perm_check( gatt_cb.sr_reg[i_rcb].p_db, 437 FALSE, 438 handle, 439 sec_flag, 440 key_size)) 441 != GATT_SUCCESS) 442 { 443 GATT_TRACE_DEBUG1("read permission denied : 0x%02x", err); 444 break; 445 } 446 } 447 else 448 { 449 /* invalid handle */ 450 err = GATT_INVALID_HANDLE; 451 break; 452 } 453 ll -= 2; 454 } 455 456 if (ll != 0) 457 { 458 GATT_TRACE_ERROR0("max attribute handle reached in ReadMultiple Request."); 459 } 460 461 if (p_tcb->sr_cmd.multi_req.num_handles == 0) 462 err = GATT_INVALID_HANDLE; 463 464 if (err == GATT_SUCCESS) 465 { 466 if ((trans_id = gatt_sr_enqueue_cmd (p_tcb, op_code, p_tcb->sr_cmd.multi_req.handles[0])) != 0) 467 { 468 gatt_sr_reset_cback_cnt(p_tcb); /* read multiple use multi_rsp_q's count*/ 469 470 for (ll = 0; ll < p_tcb->sr_cmd.multi_req.num_handles; ll ++) 471 { 472 if ((p_msg = (tGATTS_RSP *)GKI_getbuf(sizeof(tGATTS_RSP))) != NULL) 473 { 474 memset(p_msg, 0, sizeof(tGATTS_RSP)) 475 ; 476 handle = p_tcb->sr_cmd.multi_req.handles[ll]; 477 i_rcb = gatt_sr_find_i_rcb_by_handle(handle); 478 479 p_msg->attr_value.handle = handle; 480 err = gatts_read_attr_value_by_handle(p_tcb, 481 gatt_cb.sr_reg[i_rcb].p_db, 482 op_code, 483 handle, 484 0, 485 p_msg->attr_value.value, 486 &p_msg->attr_value.len, 487 GATT_MAX_ATTR_LEN, 488 sec_flag, 489 key_size, 490 trans_id); 491 492 if (err == GATT_SUCCESS) 493 { 494 gatt_sr_process_app_rsp(p_tcb, gatt_cb.sr_reg[i_rcb].gatt_if ,trans_id, op_code, GATT_SUCCESS, p_msg); 495 } 496 /* either not using or done using the buffer, release it now */ 497 GKI_freebuf(p_msg); 498 } 499 else 500 { 501 err = GATT_NO_RESOURCES; 502 gatt_dequeue_sr_cmd(p_tcb); 503 break; 504 } 505 } 506 } 507 else 508 err = GATT_NO_RESOURCES; 509 } 510 511 /* in theroy BUSY is not possible(should already been checked), protected check */ 512 if (err != GATT_SUCCESS && err != GATT_PENDING && err != GATT_BUSY) 513 gatt_send_error_rsp(p_tcb, err, op_code, handle, FALSE); 514 } 515 516 /******************************************************************************* 517 ** 518 ** Function gatt_build_primary_service_rsp 519 ** 520 ** Description Primamry service request processed internally. Theretically 521 ** only deal with ReadByTypeVAlue and ReadByGroupType. 522 ** 523 ** Returns void 524 ** 525 *******************************************************************************/ 526 static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_tcb, 527 UINT8 op_code, UINT16 s_hdl, 528 UINT16 e_hdl, UINT8 *p_data, tBT_UUID value) 529 { 530 tGATT_STATUS status = GATT_NOT_FOUND; 531 UINT8 handle_len =4, *p ; 532 tGATT_SR_REG *p_rcb; 533 tGATT_SRV_LIST_INFO *p_list= &gatt_cb.srv_list_info; 534 tGATT_SRV_LIST_ELEM *p_srv=NULL; 535 tBT_UUID *p_uuid; 536 537 p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; 538 539 p_srv = p_list->p_first; 540 541 while (p_srv) 542 { 543 p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg); 544 545 if (p_rcb->in_use && 546 p_rcb->s_hdl >= s_hdl && 547 p_rcb->s_hdl <= e_hdl && 548 p_rcb->type == GATT_UUID_PRI_SERVICE) 549 { 550 if ((p_uuid = gatts_get_service_uuid (p_rcb->p_db)) != NULL) 551 { 552 if (op_code == GATT_REQ_READ_BY_GRP_TYPE) 553 handle_len = 4 + p_uuid->len; 554 555 /* get the length byte in the repsonse */ 556 if (p_msg->offset ==0) 557 { 558 *p ++ = op_code + 1; 559 p_msg->len ++; 560 p_msg->offset = handle_len; 561 562 if (op_code == GATT_REQ_READ_BY_GRP_TYPE) 563 { 564 *p ++ = (UINT8)p_msg->offset; /* length byte */ 565 p_msg->len ++; 566 } 567 } 568 569 if (p_msg->len + p_msg->offset <= p_tcb->payload_size && 570 handle_len == p_msg->offset) 571 { 572 if (op_code != GATT_REQ_FIND_TYPE_VALUE || 573 gatt_uuid_compare(value, *p_uuid)) 574 { 575 UINT16_TO_STREAM(p, p_rcb->s_hdl); 576 577 if (p_list->p_last_primary == p_srv && 578 p_list->p_last_primary == p_list->p_last) 579 { 580 GATT_TRACE_DEBUG0("Use 0xFFFF for the last primary attribute"); 581 UINT16_TO_STREAM(p, 0xFFFF); /* see GATT ERRATA 4065, 4063, ATT ERRATA 4062 */ 582 } 583 else 584 { 585 UINT16_TO_STREAM(p, p_rcb->e_hdl); 586 } 587 588 if (op_code == GATT_REQ_READ_BY_GRP_TYPE) 589 gatt_build_uuid_to_stream(&p, *p_uuid); 590 591 status = GATT_SUCCESS; 592 p_msg->len += p_msg->offset; 593 } 594 } 595 else 596 break; 597 } 598 } 599 p_srv = p_srv->p_next; 600 } 601 p_msg->offset = L2CAP_MIN_OFFSET; 602 603 return status; 604 } 605 606 /******************************************************************************* 607 ** 608 ** Function gatt_build_find_info_rsp 609 ** 610 ** Description fill the find information response information in the given 611 ** buffer. 612 ** 613 ** Returns TRUE: if data filled sucessfully. 614 ** FALSE: packet full, or format mismatch. 615 ** 616 *******************************************************************************/ 617 static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, UINT16 *p_len, 618 UINT16 s_hdl, UINT16 e_hdl) 619 { 620 tGATT_STATUS status = GATT_NOT_FOUND; 621 UINT8 *p; 622 UINT16 len = *p_len; 623 tGATT_ATTR16 *p_attr = NULL; 624 UINT8 info_pair_len[2] = {4, 18}; 625 626 if (!p_rcb->p_db || !p_rcb->p_db->p_attr_list) 627 return status; 628 629 /* check the attribute database */ 630 p_attr = (tGATT_ATTR16 *) p_rcb->p_db->p_attr_list; 631 632 p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET + p_msg->len; 633 634 while (p_attr) 635 { 636 if (p_attr->handle > e_hdl) 637 { 638 break; 639 } 640 641 if (p_attr->handle >= s_hdl) 642 { 643 if (p_msg->offset == 0) 644 p_msg->offset = (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128) ? GATT_INFO_TYPE_PAIR_128 : GATT_INFO_TYPE_PAIR_16; 645 646 if (len >= info_pair_len[p_msg->offset - 1]) 647 { 648 if (p_msg->offset == GATT_INFO_TYPE_PAIR_16 && p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) 649 { 650 UINT16_TO_STREAM(p, p_attr->handle); 651 UINT16_TO_STREAM(p, p_attr->uuid); 652 } 653 else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && 654 p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 ) 655 { 656 UINT16_TO_STREAM(p, p_attr->handle); 657 ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *) p_attr)->uuid, LEN_UUID_128); 658 } 659 else 660 { 661 GATT_TRACE_ERROR0("format mismatch"); 662 status = GATT_NO_RESOURCES; 663 break; 664 /* format mismatch */ 665 } 666 p_msg->len += info_pair_len[p_msg->offset - 1]; 667 len -= info_pair_len[p_msg->offset - 1]; 668 status = GATT_SUCCESS; 669 670 } 671 else 672 { 673 status = GATT_NO_RESOURCES; 674 break; 675 } 676 } 677 p_attr = (tGATT_ATTR16 *)p_attr->p_next; 678 } 679 680 *p_len = len; 681 return status; 682 } 683 684 /******************************************************************************* 685 ** 686 ** Function gatts_internal_read_by_type_req 687 ** 688 ** Description check to see if the ReadByType request can be handled internally. 689 ** 690 ** Returns void 691 ** 692 *******************************************************************************/ 693 static tGATT_STATUS gatts_validate_packet_format(UINT8 op_code, UINT16 *p_len, 694 UINT8 **p_data, tBT_UUID *p_uuid_filter, 695 UINT16 *p_s_hdl, UINT16 *p_e_hdl) 696 { 697 tGATT_STATUS reason = GATT_SUCCESS; 698 UINT16 uuid_len, s_hdl = 0, e_hdl = 0; 699 UINT16 len = *p_len; 700 UINT8 *p = *p_data; 701 702 if (len >= 4) 703 { 704 /* obtain starting handle, and ending handle */ 705 STREAM_TO_UINT16(s_hdl, p); 706 STREAM_TO_UINT16(e_hdl, p); 707 len -= 4; 708 709 if (s_hdl > e_hdl || !GATT_HANDLE_IS_VALID(s_hdl) || !GATT_HANDLE_IS_VALID(e_hdl)) 710 { 711 reason = GATT_INVALID_HANDLE; 712 } 713 /* for these PDUs, uuid filter must present */ 714 else if (op_code == GATT_REQ_READ_BY_GRP_TYPE || 715 op_code == GATT_REQ_FIND_TYPE_VALUE || 716 op_code == GATT_REQ_READ_BY_TYPE) 717 { 718 if (len >= 2 && p_uuid_filter != NULL) 719 { 720 uuid_len = (op_code == GATT_REQ_FIND_TYPE_VALUE) ? 2 : len; 721 722 /* parse uuid now */ 723 if (gatt_parse_uuid_from_cmd (p_uuid_filter, uuid_len, &p) == FALSE || 724 p_uuid_filter->len == 0) 725 { 726 GATT_TRACE_DEBUG0("UUID filter does not exsit"); 727 reason = GATT_INVALID_PDU; 728 } 729 else 730 len -= p_uuid_filter->len; 731 } 732 else 733 reason = GATT_INVALID_PDU; 734 } 735 } 736 else 737 reason = GATT_INVALID_PDU; 738 739 *p_data = p; 740 *p_len = len; 741 *p_s_hdl = s_hdl; 742 *p_e_hdl = e_hdl; 743 744 return reason; 745 } 746 747 /******************************************************************************* 748 ** 749 ** Function gatts_process_primary_service_req 750 ** 751 ** Description process ReadByGroupType/ReadByTypeValue request, for discover 752 ** all primary services or discover primary service by UUID request. 753 ** 754 ** Returns void 755 ** 756 *******************************************************************************/ 757 void gatts_process_primary_service_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 758 { 759 UINT8 reason = GATT_INVALID_PDU; 760 UINT16 s_hdl = 0, e_hdl = 0; 761 tBT_UUID uuid, value, primary_service = {LEN_UUID_16, {GATT_UUID_PRI_SERVICE}}; 762 BT_HDR *p_msg = NULL; 763 UINT16 msg_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); 764 765 reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl); 766 767 if (reason == GATT_SUCCESS) 768 { 769 if (gatt_uuid_compare(uuid, primary_service)) 770 { 771 if (op_code == GATT_REQ_FIND_TYPE_VALUE) 772 { 773 if (gatt_parse_uuid_from_cmd(&value, len, &p_data) == FALSE) 774 reason = GATT_INVALID_PDU; 775 } 776 777 if (reason == GATT_SUCCESS) 778 { 779 if ((p_msg = (BT_HDR *)GKI_getbuf(msg_len)) == NULL) 780 { 781 GATT_TRACE_ERROR0("gatts_process_primary_service_req failed. no resources."); 782 reason = GATT_NO_RESOURCES; 783 } 784 else 785 { 786 memset(p_msg, 0, msg_len); 787 reason = gatt_build_primary_service_rsp (p_msg, p_tcb, op_code, s_hdl, e_hdl, p_data, value); 788 } 789 } 790 } 791 else 792 { 793 if (op_code == GATT_REQ_READ_BY_GRP_TYPE) 794 { 795 reason = GATT_UNSUPPORT_GRP_TYPE; 796 GATT_TRACE_DEBUG1("unexpected ReadByGrpType Group: 0x%04x", uuid.uu.uuid16); 797 } 798 else 799 { 800 /* we do not support ReadByTypeValue with any non-primamry_service type */ 801 reason = GATT_NOT_FOUND; 802 GATT_TRACE_DEBUG1("unexpected ReadByTypeValue type: 0x%04x", uuid.uu.uuid16); 803 } 804 } 805 } 806 807 if (reason != GATT_SUCCESS) 808 { 809 if (p_msg) GKI_freebuf(p_msg); 810 gatt_send_error_rsp (p_tcb, reason, op_code, s_hdl, FALSE); 811 } 812 else 813 attp_send_sr_msg(p_tcb, p_msg); 814 815 } 816 817 /******************************************************************************* 818 ** 819 ** Function gatts_process_find_info 820 ** 821 ** Description process find information request, for discover character 822 ** descriptors. 823 ** 824 ** Returns void 825 ** 826 *******************************************************************************/ 827 static void gatts_process_find_info(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 828 { 829 UINT8 reason = GATT_INVALID_PDU, *p; 830 UINT16 s_hdl = 0, e_hdl = 0, buf_len; 831 BT_HDR *p_msg = NULL; 832 tGATT_SR_REG *p_rcb; 833 tGATT_SRV_LIST_INFO *p_list= &gatt_cb.srv_list_info; 834 tGATT_SRV_LIST_ELEM *p_srv=NULL; 835 836 reason = gatts_validate_packet_format(op_code, &len, &p_data, NULL, &s_hdl, &e_hdl); 837 838 if (reason == GATT_SUCCESS) 839 { 840 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); 841 842 if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) 843 { 844 reason = GATT_NO_RESOURCES; 845 } 846 else 847 { 848 reason = GATT_NOT_FOUND; 849 850 memset(p_msg, 0, buf_len); 851 p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; 852 *p ++ = op_code + 1; 853 p_msg->len = 2; 854 855 buf_len = p_tcb->payload_size - 2; 856 857 p_srv = p_list->p_first; 858 859 while (p_srv) 860 { 861 p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg); 862 863 if (p_rcb->in_use && 864 !(p_rcb->s_hdl > e_hdl || 865 p_rcb->e_hdl < s_hdl)) 866 { 867 reason = gatt_build_find_info_rsp(p_rcb, p_msg, &buf_len, s_hdl, e_hdl); 868 if (reason == GATT_NO_RESOURCES) 869 { 870 reason = GATT_SUCCESS; 871 break; 872 } 873 } 874 p_srv = p_srv->p_next; 875 } 876 *p = (UINT8)p_msg->offset; 877 878 p_msg->offset = L2CAP_MIN_OFFSET; 879 } 880 } 881 882 if (reason != GATT_SUCCESS) 883 { 884 if (p_msg) GKI_freebuf(p_msg); 885 gatt_send_error_rsp (p_tcb, reason, op_code, s_hdl, FALSE); 886 } 887 else 888 attp_send_sr_msg(p_tcb, p_msg); 889 890 } 891 892 /******************************************************************************* 893 ** 894 ** Function gatts_process_mtu_req 895 ** 896 ** Description This function is called to process excahnge MTU request. 897 ** Only used on LE. 898 ** 899 ** Returns void 900 ** 901 *******************************************************************************/ 902 static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data) 903 { 904 UINT16 mtu = 0; 905 UINT8 *p = p_data, i; 906 BT_HDR *p_buf; 907 UINT16 conn_id; 908 909 /* BR/EDR conenction, send error response */ 910 if (p_tcb->att_lcid != L2CAP_ATT_CID) 911 { 912 gatt_send_error_rsp (p_tcb, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, FALSE); 913 } 914 else if (len < GATT_MTU_REQ_MIN_LEN) 915 { 916 GATT_TRACE_ERROR0("invalid MTU request PDU received."); 917 gatt_send_error_rsp (p_tcb, GATT_INVALID_PDU, GATT_REQ_MTU, 0, FALSE); 918 } 919 else 920 { 921 STREAM_TO_UINT16 (mtu, p); 922 /* mtu must be greater than default MTU which is 23/48 */ 923 if (mtu < GATT_DEF_BLE_MTU_SIZE) 924 p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE; 925 else if (mtu > GATT_MAX_MTU_SIZE) 926 p_tcb->payload_size = GATT_MAX_MTU_SIZE; 927 else 928 p_tcb->payload_size = mtu; 929 930 if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_MTU, (tGATT_SR_MSG *) &p_tcb->payload_size)) != NULL) 931 { 932 attp_send_sr_msg (p_tcb, p_buf); 933 934 /* Notify all registered applicaiton with new MTU size. Us a transaction ID */ 935 /* of 0, as no response is allowed from applcations */ 936 937 for (i = 0; i < GATT_MAX_APPS; i ++) 938 { 939 if (gatt_cb.cl_rcb[i].in_use ) 940 { 941 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_cb.cl_rcb[i].gatt_if); 942 gatt_sr_send_req_callback(conn_id, 0, GATTS_REQ_TYPE_MTU, 943 (tGATTS_DATA *)&p_tcb->payload_size); 944 } 945 } 946 947 } 948 } 949 } 950 951 /******************************************************************************* 952 ** 953 ** Function gatts_process_read_by_type_req 954 ** 955 ** Description process Read By type request. 956 ** This PDU can be used to perform: 957 ** - read characteristic value 958 ** - read characteristic descriptor value 959 ** - discover characteristic 960 ** - discover characteristic by UUID 961 ** - relationship discovery 962 ** 963 ** Returns void 964 ** 965 *******************************************************************************/ 966 void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 967 { 968 tBT_UUID uuid; 969 tGATT_SR_REG *p_rcb; 970 UINT16 msg_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET), 971 buf_len, 972 s_hdl, e_hdl, err_hdl = 0; 973 BT_HDR *p_msg = NULL; 974 tGATT_STATUS reason, ret; 975 UINT8 *p; 976 UINT8 sec_flag, key_size; 977 tGATT_SRV_LIST_INFO *p_list= &gatt_cb.srv_list_info; 978 tGATT_SRV_LIST_ELEM *p_srv=NULL; 979 980 reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl); 981 982 #if GATT_CONFORMANCE_TESTING == TRUE 983 if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) 984 { 985 GATT_TRACE_DEBUG1("Conformance tst: forced err rsp for ReadByType: error status=%d", gatt_cb.err_status); 986 987 gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl, FALSE); 988 989 return; 990 } 991 #endif 992 993 if (reason == GATT_SUCCESS) 994 { 995 if ((p_msg = (BT_HDR *)GKI_getbuf(msg_len)) == NULL) 996 { 997 GATT_TRACE_ERROR0("gatts_process_find_info failed. no resources."); 998 999 reason = GATT_NO_RESOURCES; 1000 } 1001 else 1002 { 1003 memset(p_msg, 0, msg_len); 1004 p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; 1005 1006 *p ++ = op_code + 1; 1007 /* reserve length byte */ 1008 p_msg->len = 2; 1009 buf_len = p_tcb->payload_size - 2; 1010 1011 reason = GATT_NOT_FOUND; 1012 1013 p_srv = p_list->p_first; 1014 1015 while (p_srv) 1016 { 1017 p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg); 1018 1019 if (p_rcb->in_use && 1020 !(p_rcb->s_hdl > e_hdl || 1021 p_rcb->e_hdl < s_hdl)) 1022 { 1023 gatt_sr_get_sec_info(p_tcb->peer_bda, 1024 (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), 1025 &sec_flag, 1026 &key_size); 1027 1028 ret = gatts_db_read_attr_value_by_type(p_tcb, 1029 p_rcb->p_db, 1030 op_code, 1031 p_msg, 1032 s_hdl, 1033 e_hdl, 1034 uuid, 1035 &buf_len, 1036 sec_flag, 1037 key_size, 1038 0, 1039 &err_hdl); 1040 if (ret != GATT_NOT_FOUND) 1041 { 1042 reason = ret; 1043 1044 if (ret == GATT_NO_RESOURCES) 1045 reason = GATT_SUCCESS; 1046 } 1047 if (ret != GATT_SUCCESS && ret != GATT_NOT_FOUND) 1048 { 1049 s_hdl = err_hdl; 1050 break; 1051 } 1052 } 1053 p_srv = p_srv->p_next; 1054 } 1055 *p = (UINT8)p_msg->offset; 1056 p_msg->offset = L2CAP_MIN_OFFSET; 1057 } 1058 } 1059 if (reason != GATT_SUCCESS) 1060 { 1061 if (p_msg) GKI_freebuf(p_msg); 1062 1063 /* in theroy BUSY is not possible(should already been checked), protected check */ 1064 if (reason != GATT_PENDING && reason != GATT_BUSY) 1065 gatt_send_error_rsp (p_tcb, reason, op_code, s_hdl, FALSE); 1066 } 1067 else 1068 attp_send_sr_msg(p_tcb, p_msg); 1069 1070 } 1071 1072 /******************************************************************************* 1073 ** 1074 ** Function gatts_process_write_req 1075 ** 1076 ** Description This function is called to process the write request 1077 ** from client. 1078 ** 1079 ** Returns void 1080 ** 1081 *******************************************************************************/ 1082 void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, 1083 UINT8 op_code, UINT16 len, UINT8 *p_data) 1084 { 1085 tGATTS_DATA sr_data; 1086 UINT32 trans_id; 1087 tGATT_STATUS status; 1088 UINT8 sec_flag, key_size, *p = p_data; 1089 tGATT_SR_REG *p_sreg; 1090 UINT16 conn_id; 1091 1092 memset(&sr_data, 0, sizeof(tGATTS_DATA)); 1093 1094 switch (op_code) 1095 { 1096 case GATT_REQ_PREPARE_WRITE: 1097 sr_data.write_req.is_prep = TRUE; 1098 STREAM_TO_UINT16(sr_data.write_req.offset, p); 1099 len -= 2; 1100 /* fall through */ 1101 case GATT_SIGN_CMD_WRITE: 1102 if (op_code == GATT_SIGN_CMD_WRITE) 1103 { 1104 GATT_TRACE_DEBUG0("Write CMD with data sigining" ); 1105 len -= GATT_AUTH_SIGN_LEN; 1106 } 1107 /* fall through */ 1108 case GATT_CMD_WRITE: 1109 case GATT_REQ_WRITE: 1110 if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) 1111 sr_data.write_req.need_rsp = TRUE; 1112 sr_data.write_req.handle = handle; 1113 sr_data.write_req.len = len; 1114 memcpy (sr_data.write_req.value, p, len); 1115 break; 1116 } 1117 1118 gatt_sr_get_sec_info(p_tcb->peer_bda, 1119 (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), 1120 &sec_flag, 1121 &key_size); 1122 1123 status = gatts_write_attr_perm_check (gatt_cb.sr_reg[i_rcb].p_db, 1124 op_code, 1125 handle, 1126 sr_data.write_req.offset, 1127 p, 1128 len, 1129 sec_flag, 1130 key_size); 1131 1132 if (status == GATT_SUCCESS) 1133 { 1134 if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) 1135 { 1136 p_sreg = &gatt_cb.sr_reg[i_rcb]; 1137 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if); 1138 gatt_sr_send_req_callback(conn_id, 1139 trans_id, 1140 GATTS_REQ_TYPE_WRITE, 1141 &sr_data); 1142 1143 status = GATT_PENDING; 1144 } 1145 else 1146 { 1147 GATT_TRACE_ERROR0("max pending command, send error"); 1148 status = GATT_BUSY; /* max pending command, application error */ 1149 } 1150 } 1151 1152 /* in theroy BUSY is not possible(should already been checked), protected check */ 1153 if (status != GATT_PENDING && status != GATT_BUSY && 1154 (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_REQ_WRITE)) 1155 { 1156 gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE); 1157 } 1158 return; 1159 } 1160 1161 /******************************************************************************* 1162 ** 1163 ** Function gatts_process_read_req 1164 ** 1165 ** Description This function is called to process the read request 1166 ** from client. 1167 ** 1168 ** Returns void 1169 ** 1170 *******************************************************************************/ 1171 static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code, 1172 UINT16 handle, UINT16 len, UINT8 *p_data) 1173 { 1174 UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); 1175 tGATT_STATUS reason; 1176 BT_HDR *p_msg = NULL; 1177 UINT8 sec_flag, key_size, *p; 1178 UINT16 offset = 0, value_len = 0; 1179 1180 if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) 1181 { 1182 GATT_TRACE_ERROR0("gatts_process_find_info failed. no resources."); 1183 1184 reason = GATT_NO_RESOURCES; 1185 } 1186 else 1187 { 1188 if (op_code == GATT_REQ_READ_BLOB) 1189 STREAM_TO_UINT16(offset, p_data); 1190 1191 memset(p_msg, 0, buf_len); 1192 p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; 1193 *p ++ = op_code + 1; 1194 p_msg->len = 1; 1195 buf_len = p_tcb->payload_size - 1; 1196 1197 gatt_sr_get_sec_info(p_tcb->peer_bda, 1198 (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), 1199 &sec_flag, 1200 &key_size); 1201 1202 reason = gatts_read_attr_value_by_handle(p_tcb, 1203 p_rcb->p_db, 1204 op_code, 1205 handle, 1206 offset, 1207 p, 1208 &value_len, 1209 buf_len, 1210 sec_flag, 1211 key_size, 1212 0); 1213 1214 p_msg->len += value_len; 1215 } 1216 1217 if (reason != GATT_SUCCESS) 1218 { 1219 if (p_msg) GKI_freebuf(p_msg); 1220 1221 /* in theroy BUSY is not possible(should already been checked), protected check */ 1222 if (reason != GATT_PENDING && reason != GATT_BUSY) 1223 gatt_send_error_rsp (p_tcb, reason, op_code, handle, FALSE); 1224 } 1225 else 1226 attp_send_sr_msg(p_tcb, p_msg); 1227 1228 } 1229 1230 /******************************************************************************* 1231 ** 1232 ** Function gatts_process_attribute_req 1233 ** 1234 ** Description This function is called to process the per attribute handle request 1235 ** from client. 1236 ** 1237 ** Returns void 1238 ** 1239 *******************************************************************************/ 1240 void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code, 1241 UINT16 len, UINT8 *p_data) 1242 { 1243 UINT16 handle = 0; 1244 UINT8 *p = p_data, i; 1245 tGATT_SR_REG *p_rcb = gatt_cb.sr_reg; 1246 tGATT_STATUS status = GATT_INVALID_HANDLE; 1247 tGATT_ATTR16 *p_attr; 1248 1249 if (len < 2) 1250 { 1251 GATT_TRACE_ERROR0("Illegal PDU length, discard request"); 1252 status = GATT_INVALID_PDU; 1253 } 1254 else 1255 { 1256 STREAM_TO_UINT16(handle, p); 1257 len -= 2; 1258 } 1259 1260 #if GATT_CONFORMANCE_TESTING == TRUE 1261 gatt_cb.handle = handle; 1262 if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) 1263 { 1264 GATT_TRACE_DEBUG1("Conformance tst: forced err rsp: error status=%d", gatt_cb.err_status); 1265 1266 gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle, FALSE); 1267 1268 return; 1269 } 1270 #endif 1271 1272 if (GATT_HANDLE_IS_VALID(handle)) 1273 { 1274 for (i = 0; i < GATT_MAX_SR_PROFILES; i ++, p_rcb ++) 1275 { 1276 if (p_rcb->in_use && p_rcb->s_hdl <= handle && p_rcb->e_hdl >= handle) 1277 { 1278 p_attr = (tGATT_ATTR16 *)p_rcb->p_db->p_attr_list; 1279 1280 while (p_attr) 1281 { 1282 if (p_attr->handle == handle) 1283 { 1284 switch (op_code) 1285 { 1286 case GATT_REQ_READ: /* read char/char descriptor value */ 1287 case GATT_REQ_READ_BLOB: 1288 gatts_process_read_req(p_tcb, p_rcb, op_code, handle, len, p); 1289 break; 1290 1291 case GATT_REQ_WRITE: /* write char/char descriptor value */ 1292 case GATT_CMD_WRITE: 1293 case GATT_SIGN_CMD_WRITE: 1294 case GATT_REQ_PREPARE_WRITE: 1295 gatts_process_write_req(p_tcb, i, handle, op_code, len, p); 1296 break; 1297 default: 1298 break; 1299 } 1300 status = GATT_SUCCESS; 1301 break; 1302 } 1303 p_attr = (tGATT_ATTR16 *)p_attr->p_next; 1304 } 1305 break; 1306 } 1307 } 1308 } 1309 1310 if (status != GATT_SUCCESS && op_code != GATT_CMD_WRITE && op_code != GATT_SIGN_CMD_WRITE) 1311 gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE); 1312 } 1313 1314 /******************************************************************************* 1315 ** 1316 ** Function gatts_proc_srv_chg_ind_ack 1317 ** 1318 ** Description This function process the service changed indicaiton ACK 1319 ** 1320 ** Returns void 1321 ** 1322 *******************************************************************************/ 1323 static void gatts_proc_srv_chg_ind_ack(tGATT_TCB *p_tcb ) 1324 { 1325 tGATTS_SRV_CHG_REQ req; 1326 tGATTS_SRV_CHG *p_buf = NULL; 1327 1328 GATT_TRACE_DEBUG0("gatts_proc_srv_chg_ind_ack"); 1329 1330 if ((p_buf = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda)) != NULL) 1331 { 1332 GATT_TRACE_DEBUG0("NV update set srv chg = FALSE"); 1333 p_buf->srv_changed = FALSE; 1334 memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG)); 1335 if (gatt_cb.cb_info.p_srv_chg_callback) 1336 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT,&req, NULL); 1337 } 1338 } 1339 1340 /******************************************************************************* 1341 ** 1342 ** Function gatts_chk_pending_ind 1343 ** 1344 ** Description This function check any pending indication needs to be sent if 1345 ** there is a pending indication then sent the indication 1346 ** 1347 ** Returns void 1348 ** 1349 *******************************************************************************/ 1350 static void gatts_chk_pending_ind(tGATT_TCB *p_tcb ) 1351 { 1352 tGATT_VALUE *p_buf = (tGATT_VALUE *)GKI_getfirst(&p_tcb->pending_ind_q); 1353 GATT_TRACE_DEBUG0("gatts_chk_pending_ind"); 1354 1355 if (p_buf ) 1356 { 1357 GATTS_HandleValueIndication (p_buf->conn_id, 1358 p_buf->handle, 1359 p_buf->len, 1360 p_buf->value); 1361 GKI_freebuf(GKI_remove_from_queue (&p_tcb->pending_ind_q, p_buf)); 1362 } 1363 } 1364 1365 /******************************************************************************* 1366 ** 1367 ** Function gatts_proc_ind_ack 1368 ** 1369 ** Description This function process the Indication ack 1370 ** 1371 ** Returns TRUE continue to process the indication ack by the aaplication 1372 ** if the ACk is not a Service Changed Indication Ack 1373 ** 1374 *******************************************************************************/ 1375 static BOOLEAN gatts_proc_ind_ack(tGATT_TCB *p_tcb, UINT16 ack_handle) 1376 { 1377 BOOLEAN continue_processing = TRUE; 1378 1379 GATT_TRACE_DEBUG1 ("gatts_proc_ind_ack ack handle=%d", ack_handle); 1380 1381 if (ack_handle == gatt_cb.handle_of_h_r) 1382 { 1383 gatts_proc_srv_chg_ind_ack(p_tcb); 1384 /* there is no need to inform the application since srv chg is handled internally by GATT */ 1385 continue_processing = FALSE; 1386 } 1387 1388 gatts_chk_pending_ind(p_tcb); 1389 return continue_processing; 1390 } 1391 1392 /******************************************************************************* 1393 ** 1394 ** Function gatts_process_value_conf 1395 ** 1396 ** Description This function is called to process the handle value confirmation. 1397 ** 1398 ** Returns void 1399 ** 1400 *******************************************************************************/ 1401 void gatts_process_value_conf(tGATT_TCB *p_tcb, UINT8 op_code) 1402 { 1403 UINT16 handle = p_tcb->indicate_handle; 1404 UINT32 trans_id; 1405 UINT8 i; 1406 tGATT_SR_REG *p_rcb = gatt_cb.sr_reg; 1407 BOOLEAN continue_processing; 1408 UINT16 conn_id; 1409 1410 btu_stop_timer (&p_tcb->conf_timer_ent); 1411 if (GATT_HANDLE_IS_VALID(handle)) 1412 { 1413 p_tcb->indicate_handle = 0; 1414 continue_processing = gatts_proc_ind_ack(p_tcb, handle); 1415 1416 if (continue_processing) 1417 { 1418 for (i = 0; i < GATT_MAX_SR_PROFILES; i ++, p_rcb ++) 1419 { 1420 if (p_rcb->in_use && p_rcb->s_hdl <= handle && p_rcb->e_hdl >= handle) 1421 { 1422 trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle); 1423 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_rcb->gatt_if); 1424 gatt_sr_send_req_callback(conn_id, 1425 trans_id, GATTS_REQ_TYPE_CONF, (tGATTS_DATA *)&handle); 1426 } 1427 } 1428 } 1429 } 1430 else 1431 { 1432 GATT_TRACE_ERROR0("unexpected handle value confirmation"); 1433 } 1434 } 1435 1436 /******************************************************************************* 1437 ** 1438 ** Function gatt_server_handle_client_req 1439 ** 1440 ** Description This function is called to handle the client requests to 1441 ** server. 1442 ** 1443 ** 1444 ** Returns void 1445 ** 1446 *******************************************************************************/ 1447 void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, 1448 UINT16 len, UINT8 *p_data) 1449 { 1450 /* there is pending command, discard this one */ 1451 if (!gatt_sr_cmd_empty(p_tcb) && op_code != GATT_HANDLE_VALUE_CONF) 1452 return; 1453 1454 /* the size of the message may not be bigger than the local max PDU size*/ 1455 /* The message has to be smaller than the agreed MTU, len does not include op code */ 1456 if (len >= p_tcb->payload_size) 1457 { 1458 GATT_TRACE_ERROR2("server receive invalid PDU size:%d pdu size:%d", len + 1, p_tcb->payload_size ); 1459 /* for invalid request expecting response, send it now */ 1460 if (op_code != GATT_CMD_WRITE && 1461 op_code != GATT_SIGN_CMD_WRITE && 1462 op_code != GATT_HANDLE_VALUE_CONF) 1463 { 1464 gatt_send_error_rsp (p_tcb, GATT_INVALID_PDU, op_code, 0, FALSE); 1465 } 1466 /* otherwise, ignore the pkt */ 1467 } 1468 else 1469 { 1470 switch (op_code) 1471 { 1472 case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */ 1473 case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */ 1474 gatts_process_primary_service_req (p_tcb, op_code, len, p_data); 1475 break; 1476 1477 case GATT_REQ_FIND_INFO:/* discover char descrptor */ 1478 gatts_process_find_info(p_tcb, op_code, len, p_data); 1479 break; 1480 1481 case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */ 1482 /* discover characteristic, discover char by UUID */ 1483 gatts_process_read_by_type_req(p_tcb, op_code, len, p_data); 1484 break; 1485 1486 1487 case GATT_REQ_READ: /* read char/char descriptor value */ 1488 case GATT_REQ_READ_BLOB: 1489 case GATT_REQ_WRITE: /* write char/char descriptor value */ 1490 case GATT_CMD_WRITE: 1491 case GATT_SIGN_CMD_WRITE: 1492 case GATT_REQ_PREPARE_WRITE: 1493 gatts_process_attribute_req (p_tcb, op_code, len, p_data); 1494 break; 1495 1496 case GATT_HANDLE_VALUE_CONF: 1497 gatts_process_value_conf (p_tcb, op_code); 1498 break; 1499 1500 case GATT_REQ_MTU: 1501 gatts_process_mtu_req (p_tcb, len, p_data); 1502 break; 1503 1504 case GATT_REQ_EXEC_WRITE: 1505 gatt_process_exec_write_req (p_tcb, op_code, len, p_data); 1506 break; 1507 1508 case GATT_REQ_READ_MULTI: 1509 gatt_process_read_multi_req (p_tcb, op_code, len, p_data); 1510 break; 1511 1512 default: 1513 break; 1514 } 1515 } 1516 } 1517 1518 #endif /* BLE_INCLUDED */ 1519