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