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