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