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