1 /****************************************************************************** 2 * 3 * Copyright (C) 2001-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 BNEP utility functions 22 * 23 ******************************************************************************/ 24 25 #include <stdio.h> 26 #include <string.h> 27 #include "gki.h" 28 #include "bt_types.h" 29 #include "bnep_int.h" 30 #include "btu.h" 31 #include "btm_int.h" 32 #include "bt_utils.h" 33 34 35 /********************************************************************************/ 36 /* L O C A L F U N C T I O N P R O T O T Y P E S */ 37 /********************************************************************************/ 38 static UINT8 *bnepu_init_hdr (BT_HDR *p_buf, UINT16 hdr_len, UINT8 pkt_type); 39 40 void bnepu_process_peer_multicast_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len); 41 void bnepu_send_peer_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code); 42 43 44 /******************************************************************************* 45 ** 46 ** Function bnepu_find_bcb_by_cid 47 ** 48 ** Description This function searches the bcb table for an entry with the 49 ** passed CID. 50 ** 51 ** Returns the BCB address, or NULL if not found. 52 ** 53 *******************************************************************************/ 54 tBNEP_CONN *bnepu_find_bcb_by_cid (UINT16 cid) 55 { 56 UINT16 xx; 57 tBNEP_CONN *p_bcb; 58 59 /* Look through each connection control block */ 60 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) 61 { 62 if ((p_bcb->con_state != BNEP_STATE_IDLE) && (p_bcb->l2cap_cid == cid)) 63 return (p_bcb); 64 } 65 66 /* If here, not found */ 67 return (NULL); 68 } 69 70 71 /******************************************************************************* 72 ** 73 ** Function bnepu_find_bcb_by_bd_addr 74 ** 75 ** Description This function searches the BCB table for an entry with the 76 ** passed Bluetooth Address. 77 ** 78 ** Returns the BCB address, or NULL if not found. 79 ** 80 *******************************************************************************/ 81 tBNEP_CONN *bnepu_find_bcb_by_bd_addr (UINT8 *p_bda) 82 { 83 UINT16 xx; 84 tBNEP_CONN *p_bcb; 85 86 /* Look through each connection control block */ 87 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) 88 { 89 if (p_bcb->con_state != BNEP_STATE_IDLE) 90 { 91 if (!memcmp ((UINT8 *)(p_bcb->rem_bda), p_bda, BD_ADDR_LEN)) 92 return (p_bcb); 93 } 94 } 95 96 /* If here, not found */ 97 return (NULL); 98 } 99 100 101 /******************************************************************************* 102 ** 103 ** Function bnepu_allocate_bcb 104 ** 105 ** Description This function allocates a new BCB. 106 ** 107 ** Returns BCB address, or NULL if none available. 108 ** 109 *******************************************************************************/ 110 tBNEP_CONN *bnepu_allocate_bcb (BD_ADDR p_rem_bda) 111 { 112 UINT16 xx; 113 tBNEP_CONN *p_bcb; 114 115 /* Look through each connection control block for a free one */ 116 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) 117 { 118 if (p_bcb->con_state == BNEP_STATE_IDLE) 119 { 120 memset ((UINT8 *)p_bcb, 0, sizeof (tBNEP_CONN)); 121 122 p_bcb->conn_tle.param = (UINT32) p_bcb; 123 124 memcpy ((UINT8 *)(p_bcb->rem_bda), (UINT8 *)p_rem_bda, BD_ADDR_LEN); 125 p_bcb->handle = xx + 1; 126 127 return (p_bcb); 128 } 129 } 130 131 /* If here, no free BCB found */ 132 return (NULL); 133 } 134 135 136 /******************************************************************************* 137 ** 138 ** Function bnepu_release_bcb 139 ** 140 ** Description This function releases a BCB. 141 ** 142 ** Returns void 143 ** 144 *******************************************************************************/ 145 void bnepu_release_bcb (tBNEP_CONN *p_bcb) 146 { 147 /* Ensure timer is stopped */ 148 btu_stop_timer (&p_bcb->conn_tle); 149 150 /* Drop any response pointer we may be holding */ 151 p_bcb->con_state = BNEP_STATE_IDLE; 152 p_bcb->p_pending_data = NULL; 153 154 /* Free transmit queue */ 155 while (p_bcb->xmit_q.count) 156 { 157 GKI_freebuf (GKI_dequeue (&p_bcb->xmit_q)); 158 } 159 } 160 161 162 /******************************************************************************* 163 ** 164 ** Function bnep_send_conn_req 165 ** 166 ** Description This function sends a BNEP connection request to peer 167 ** 168 ** Returns void 169 ** 170 *******************************************************************************/ 171 void bnep_send_conn_req (tBNEP_CONN *p_bcb) 172 { 173 BT_HDR *p_buf; 174 UINT8 *p, *p_start; 175 176 BNEP_TRACE_DEBUG ("BNEP sending setup req with dst uuid %x", p_bcb->dst_uuid.uu.uuid16); 177 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL) 178 { 179 BNEP_TRACE_ERROR ("BNEP - not able to send connection request"); 180 return; 181 } 182 183 p_buf->offset = L2CAP_MIN_OFFSET; 184 p = p_start = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 185 186 /* Put in BNEP frame type - filter control */ 187 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL); 188 189 /* Put in filter message type - set filters */ 190 UINT8_TO_BE_STREAM (p, BNEP_SETUP_CONNECTION_REQUEST_MSG); 191 192 UINT8_TO_BE_STREAM (p, p_bcb->dst_uuid.len); 193 194 if (p_bcb->dst_uuid.len == 2) 195 { 196 UINT16_TO_BE_STREAM (p, p_bcb->dst_uuid.uu.uuid16); 197 UINT16_TO_BE_STREAM (p, p_bcb->src_uuid.uu.uuid16); 198 } 199 #if (defined (BNEP_SUPPORTS_ALL_UUID_LENGTHS) && BNEP_SUPPORTS_ALL_UUID_LENGTHS == TRUE) 200 else if (p_bcb->dst_uuid.len == 4) 201 { 202 UINT32_TO_BE_STREAM (p, p_bcb->dst_uuid.uu.uuid32); 203 UINT32_TO_BE_STREAM (p, p_bcb->src_uuid.uu.uuid32); 204 } 205 else 206 { 207 memcpy (p, p_bcb->dst_uuid.uu.uuid128, p_bcb->dst_uuid.len); 208 p += p_bcb->dst_uuid.len; 209 memcpy (p, p_bcb->src_uuid.uu.uuid128, p_bcb->dst_uuid.len); 210 p += p_bcb->dst_uuid.len; 211 } 212 #endif 213 214 p_buf->len = (UINT16)(p - p_start); 215 216 bnepu_check_send_packet (p_bcb, p_buf); 217 } 218 219 220 /******************************************************************************* 221 ** 222 ** Function bnep_send_conn_responce 223 ** 224 ** Description This function sends a BNEP setup response to peer 225 ** 226 ** Returns void 227 ** 228 *******************************************************************************/ 229 void bnep_send_conn_responce (tBNEP_CONN *p_bcb, UINT16 resp_code) 230 { 231 BT_HDR *p_buf; 232 UINT8 *p; 233 234 BNEP_TRACE_EVENT ("BNEP - bnep_send_conn_responce for CID: 0x%x", p_bcb->l2cap_cid); 235 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL) 236 { 237 BNEP_TRACE_ERROR ("BNEP - not able to send connection response"); 238 return; 239 } 240 241 p_buf->offset = L2CAP_MIN_OFFSET; 242 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 243 244 /* Put in BNEP frame type - filter control */ 245 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL); 246 247 /* Put in filter message type - set filters */ 248 UINT8_TO_BE_STREAM (p, BNEP_SETUP_CONNECTION_RESPONSE_MSG); 249 250 UINT16_TO_BE_STREAM (p, resp_code); 251 252 p_buf->len = 4; 253 254 bnepu_check_send_packet (p_bcb, p_buf); 255 256 } 257 258 259 /******************************************************************************* 260 ** 261 ** Function bnepu_send_peer_our_filters 262 ** 263 ** Description This function sends our filters to a peer 264 ** 265 ** Returns void 266 ** 267 *******************************************************************************/ 268 void bnepu_send_peer_our_filters (tBNEP_CONN *p_bcb) 269 { 270 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE) 271 BT_HDR *p_buf; 272 UINT8 *p; 273 UINT16 xx; 274 275 BNEP_TRACE_DEBUG ("BNEP sending peer our filters"); 276 277 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL) 278 { 279 BNEP_TRACE_ERROR ("BNEP - no buffer send filters"); 280 return; 281 } 282 283 p_buf->offset = L2CAP_MIN_OFFSET; 284 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 285 286 /* Put in BNEP frame type - filter control */ 287 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL); 288 289 /* Put in filter message type - set filters */ 290 UINT8_TO_BE_STREAM (p, BNEP_FILTER_NET_TYPE_SET_MSG); 291 292 UINT16_TO_BE_STREAM (p, (4 * p_bcb->sent_num_filters)); 293 for (xx = 0; xx < p_bcb->sent_num_filters; xx++) 294 { 295 UINT16_TO_BE_STREAM (p, p_bcb->sent_prot_filter_start[xx]); 296 UINT16_TO_BE_STREAM (p, p_bcb->sent_prot_filter_end[xx]); 297 } 298 299 p_buf->len = 4 + (4 * p_bcb->sent_num_filters); 300 301 bnepu_check_send_packet (p_bcb, p_buf); 302 303 p_bcb->con_flags |= BNEP_FLAGS_FILTER_RESP_PEND; 304 305 /* Start timer waiting for setup response */ 306 btu_start_timer (&p_bcb->conn_tle, BTU_TTYPE_BNEP, BNEP_FILTER_SET_TIMEOUT); 307 #endif 308 } 309 310 311 /******************************************************************************* 312 ** 313 ** Function bnepu_send_peer_our_multi_filters 314 ** 315 ** Description This function sends our multicast filters to a peer 316 ** 317 ** Returns void 318 ** 319 *******************************************************************************/ 320 void bnepu_send_peer_our_multi_filters (tBNEP_CONN *p_bcb) 321 { 322 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE) 323 BT_HDR *p_buf; 324 UINT8 *p; 325 UINT16 xx; 326 327 BNEP_TRACE_DEBUG ("BNEP sending peer our multicast filters"); 328 329 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL) 330 { 331 BNEP_TRACE_ERROR ("BNEP - no buffer to send multicast filters"); 332 return; 333 } 334 335 p_buf->offset = L2CAP_MIN_OFFSET; 336 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 337 338 /* Put in BNEP frame type - filter control */ 339 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL); 340 341 /* Put in filter message type - set filters */ 342 UINT8_TO_BE_STREAM (p, BNEP_FILTER_MULTI_ADDR_SET_MSG); 343 344 UINT16_TO_BE_STREAM (p, (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters)); 345 for (xx = 0; xx < p_bcb->sent_mcast_filters; xx++) 346 { 347 memcpy (p, p_bcb->sent_mcast_filter_start[xx], BD_ADDR_LEN); 348 p += BD_ADDR_LEN; 349 memcpy (p, p_bcb->sent_mcast_filter_end[xx], BD_ADDR_LEN); 350 p += BD_ADDR_LEN; 351 } 352 353 p_buf->len = 4 + (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters); 354 355 bnepu_check_send_packet (p_bcb, p_buf); 356 357 p_bcb->con_flags |= BNEP_FLAGS_MULTI_RESP_PEND; 358 359 /* Start timer waiting for setup response */ 360 btu_start_timer (&p_bcb->conn_tle, BTU_TTYPE_BNEP, BNEP_FILTER_SET_TIMEOUT); 361 #endif 362 } 363 364 365 /******************************************************************************* 366 ** 367 ** Function bnepu_send_peer_filter_rsp 368 ** 369 ** Description This function sends a filter response to a peer 370 ** 371 ** Returns void 372 ** 373 *******************************************************************************/ 374 void bnepu_send_peer_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code) 375 { 376 BT_HDR *p_buf; 377 UINT8 *p; 378 379 BNEP_TRACE_DEBUG ("BNEP sending filter response"); 380 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL) 381 { 382 BNEP_TRACE_ERROR ("BNEP - no buffer filter rsp"); 383 return; 384 } 385 386 p_buf->offset = L2CAP_MIN_OFFSET; 387 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 388 389 /* Put in BNEP frame type - filter control */ 390 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL); 391 392 /* Put in filter message type - set filters */ 393 UINT8_TO_BE_STREAM (p, BNEP_FILTER_NET_TYPE_RESPONSE_MSG); 394 395 UINT16_TO_BE_STREAM (p, response_code); 396 397 p_buf->len = 4; 398 399 bnepu_check_send_packet (p_bcb, p_buf); 400 } 401 402 403 /******************************************************************************* 404 ** 405 ** Function bnep_send_command_not_understood 406 ** 407 ** Description This function sends a BNEP command not understood message 408 ** 409 ** Returns void 410 ** 411 *******************************************************************************/ 412 void bnep_send_command_not_understood (tBNEP_CONN *p_bcb, UINT8 cmd_code) 413 { 414 BT_HDR *p_buf; 415 UINT8 *p; 416 417 BNEP_TRACE_EVENT ("BNEP - bnep_send_command_not_understood for CID: 0x%x, cmd 0x%x", p_bcb->l2cap_cid, cmd_code); 418 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL) 419 { 420 BNEP_TRACE_ERROR ("BNEP - not able to send connection response"); 421 return; 422 } 423 424 p_buf->offset = L2CAP_MIN_OFFSET; 425 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 426 427 /* Put in BNEP frame type - filter control */ 428 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL); 429 430 /* Put in filter message type - set filters */ 431 UINT8_TO_BE_STREAM (p, BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD); 432 433 UINT8_TO_BE_STREAM (p, cmd_code); 434 435 p_buf->len = 3; 436 437 bnepu_check_send_packet (p_bcb, p_buf); 438 439 } 440 441 442 /******************************************************************************* 443 ** 444 ** Function bnepu_check_send_packet 445 ** 446 ** Description This function tries to send a packet to L2CAP. 447 ** If L2CAP is flow controlled, it enqueues the 448 ** packet to the transmit queue 449 ** 450 ** Returns void 451 ** 452 *******************************************************************************/ 453 void bnepu_check_send_packet (tBNEP_CONN *p_bcb, BT_HDR *p_buf) 454 { 455 BNEP_TRACE_EVENT ("BNEP - bnepu_check_send_packet for CID: 0x%x", p_bcb->l2cap_cid); 456 if (p_bcb->con_flags & BNEP_FLAGS_L2CAP_CONGESTED) 457 { 458 if (p_bcb->xmit_q.count >= BNEP_MAX_XMITQ_DEPTH) 459 { 460 BNEP_TRACE_EVENT ("BNEP - congested, dropping buf, CID: 0x%x", p_bcb->l2cap_cid); 461 462 GKI_freebuf (p_buf); 463 } 464 else 465 { 466 GKI_enqueue (&p_bcb->xmit_q, p_buf); 467 } 468 } 469 else 470 { 471 L2CA_DataWrite (p_bcb->l2cap_cid, p_buf); 472 } 473 } 474 475 476 /******************************************************************************* 477 ** 478 ** Function bnepu_build_bnep_hdr 479 ** 480 ** Description This function builds the BNEP header for a packet 481 ** Extension headers are not sent yet, so there is no 482 ** check for that. 483 ** 484 ** Returns void 485 ** 486 *******************************************************************************/ 487 void bnepu_build_bnep_hdr (tBNEP_CONN *p_bcb, BT_HDR *p_buf, UINT16 protocol, 488 UINT8 *p_src_addr, UINT8 *p_dest_addr, BOOLEAN fw_ext_present) 489 { 490 UINT8 ext_bit, *p = (UINT8 *)NULL; 491 UINT8 type = BNEP_FRAME_COMPRESSED_ETHERNET; 492 493 ext_bit = fw_ext_present ? 0x80 : 0x00; 494 495 if ((p_src_addr) && (memcmp (p_src_addr, bnep_cb.my_bda, BD_ADDR_LEN))) 496 type = BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY; 497 498 if (memcmp (p_dest_addr, p_bcb->rem_bda, BD_ADDR_LEN)) 499 type = (type == BNEP_FRAME_COMPRESSED_ETHERNET) ? BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY : BNEP_FRAME_GENERAL_ETHERNET; 500 501 if (!p_src_addr) 502 p_src_addr = (UINT8 *)bnep_cb.my_bda; 503 504 switch (type) 505 { 506 case BNEP_FRAME_GENERAL_ETHERNET: 507 p = bnepu_init_hdr (p_buf, 15, (UINT8)(ext_bit | BNEP_FRAME_GENERAL_ETHERNET)); 508 509 memcpy (p, p_dest_addr, BD_ADDR_LEN); 510 p += BD_ADDR_LEN; 511 512 memcpy (p, p_src_addr, BD_ADDR_LEN); 513 p += BD_ADDR_LEN; 514 break; 515 516 case BNEP_FRAME_COMPRESSED_ETHERNET: 517 p = bnepu_init_hdr (p_buf, 3, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET)); 518 break; 519 520 case BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY: 521 p = bnepu_init_hdr (p_buf, 9, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY)); 522 523 memcpy (p, p_src_addr, BD_ADDR_LEN); 524 p += BD_ADDR_LEN; 525 break; 526 527 case BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY: 528 p = bnepu_init_hdr (p_buf, 9, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY)); 529 530 memcpy (p, p_dest_addr, BD_ADDR_LEN); 531 p += BD_ADDR_LEN; 532 break; 533 } 534 535 UINT16_TO_BE_STREAM (p, protocol); 536 } 537 538 539 /******************************************************************************* 540 ** 541 ** Function bnepu_init_hdr 542 ** 543 ** Description This function initializes the BNEP header 544 ** 545 ** Returns pointer to header in buffer 546 ** 547 *******************************************************************************/ 548 static UINT8 *bnepu_init_hdr (BT_HDR *p_buf, UINT16 hdr_len, UINT8 pkt_type) 549 { 550 UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset; 551 552 /* See if we need to make space in the buffer */ 553 if (p_buf->offset < (hdr_len + L2CAP_MIN_OFFSET)) 554 { 555 UINT16 xx, diff = BNEP_MINIMUM_OFFSET - p_buf->offset; 556 p = p + p_buf->len - 1; 557 for (xx = 0; xx < p_buf->len; xx++, p--) 558 p[diff] = *p; 559 560 p_buf->offset = BNEP_MINIMUM_OFFSET; 561 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 562 } 563 564 p_buf->len += hdr_len; 565 p_buf->offset -= hdr_len; 566 p -= hdr_len; 567 568 *p++ = pkt_type; 569 570 return (p); 571 } 572 573 574 /******************************************************************************* 575 ** 576 ** Function bnep_process_setup_conn_req 577 ** 578 ** Description This function processes a peer's setup connection request 579 ** message. The destination UUID is verified and response sent 580 ** Connection open indication will be given to PAN profile 581 ** 582 ** Returns void 583 ** 584 *******************************************************************************/ 585 void bnep_process_setup_conn_req (tBNEP_CONN *p_bcb, UINT8 *p_setup, UINT8 len) 586 { 587 BNEP_TRACE_EVENT ("BNEP - bnep_process_setup_conn_req for CID: 0x%x", p_bcb->l2cap_cid); 588 589 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP && 590 p_bcb->con_state != BNEP_STATE_SEC_CHECKING && 591 p_bcb->con_state != BNEP_STATE_CONNECTED) 592 { 593 BNEP_TRACE_ERROR ("BNEP - setup request in bad state %d", p_bcb->con_state); 594 bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED); 595 return; 596 } 597 598 /* Check if we already initiated security check or if waiting for user responce */ 599 if (p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD) 600 { 601 BNEP_TRACE_EVENT ("BNEP - Duplicate Setup message received while doing security check"); 602 return; 603 } 604 605 /* Check if peer is the originator */ 606 if (p_bcb->con_state != BNEP_STATE_CONNECTED && 607 (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) && 608 (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) 609 { 610 BNEP_TRACE_ERROR ("BNEP - setup request when we are originator", p_bcb->con_state); 611 bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED); 612 return; 613 } 614 615 if (p_bcb->con_state == BNEP_STATE_CONNECTED) 616 { 617 memcpy ((UINT8 *)&(p_bcb->prv_src_uuid), (UINT8 *)&(p_bcb->src_uuid), sizeof (tBT_UUID)); 618 memcpy ((UINT8 *)&(p_bcb->prv_dst_uuid), (UINT8 *)&(p_bcb->dst_uuid), sizeof (tBT_UUID)); 619 } 620 621 p_bcb->dst_uuid.len = p_bcb->src_uuid.len = len; 622 623 if (p_bcb->dst_uuid.len == 2) 624 { 625 /* because peer initiated connection keep src uuid as dst uuid */ 626 BE_STREAM_TO_UINT16 (p_bcb->src_uuid.uu.uuid16, p_setup); 627 BE_STREAM_TO_UINT16 (p_bcb->dst_uuid.uu.uuid16, p_setup); 628 629 /* If nothing has changed don't bother the profile */ 630 if (p_bcb->con_state == BNEP_STATE_CONNECTED && 631 p_bcb->src_uuid.uu.uuid16 == p_bcb->prv_src_uuid.uu.uuid16 && 632 p_bcb->dst_uuid.uu.uuid16 == p_bcb->prv_dst_uuid.uu.uuid16) 633 { 634 bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_OK); 635 return; 636 } 637 } 638 #if (defined (BNEP_SUPPORTS_ALL_UUID_LENGTHS) && BNEP_SUPPORTS_ALL_UUID_LENGTHS == TRUE) 639 else if (p_bcb->dst_uuid.len == 4) 640 { 641 BE_STREAM_TO_UINT32 (p_bcb->src_uuid.uu.uuid32, p_setup); 642 BE_STREAM_TO_UINT32 (p_bcb->dst_uuid.uu.uuid32, p_setup); 643 } 644 else if (p_bcb->dst_uuid.len == 16) 645 { 646 memcpy (p_bcb->src_uuid.uu.uuid128, p_setup, p_bcb->src_uuid.len); 647 p_setup += p_bcb->src_uuid.len; 648 memcpy (p_bcb->dst_uuid.uu.uuid128, p_setup, p_bcb->dst_uuid.len); 649 p_setup += p_bcb->dst_uuid.len; 650 } 651 #endif 652 else 653 { 654 BNEP_TRACE_ERROR ("BNEP - Bad UID len %d in ConnReq", p_bcb->dst_uuid.len); 655 bnep_send_conn_responce (p_bcb, BNEP_SETUP_INVALID_UUID_SIZE); 656 return; 657 } 658 659 p_bcb->con_state = BNEP_STATE_SEC_CHECKING; 660 p_bcb->con_flags |= BNEP_FLAGS_SETUP_RCVD; 661 662 BNEP_TRACE_EVENT ("BNEP initiating security check for incoming call for uuid 0x%x", p_bcb->src_uuid.uu.uuid16); 663 #if (!defined (BNEP_DO_AUTH_FOR_ROLE_SWITCH) || BNEP_DO_AUTH_FOR_ROLE_SWITCH == FALSE) 664 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) 665 bnep_sec_check_complete (p_bcb->rem_bda, p_bcb, BTM_SUCCESS); 666 else 667 #endif 668 btm_sec_mx_access_request (p_bcb->rem_bda, BT_PSM_BNEP, FALSE, 669 BTM_SEC_PROTO_BNEP, bnep_get_uuid32(&(p_bcb->src_uuid)), 670 &bnep_sec_check_complete, p_bcb); 671 672 return; 673 } 674 675 676 /******************************************************************************* 677 ** 678 ** Function bnep_process_setup_conn_responce 679 ** 680 ** Description This function processes a peer's setup connection response 681 ** message. The response code is verified and 682 ** Connection open indication will be given to PAN profile 683 ** 684 ** Returns void 685 ** 686 *******************************************************************************/ 687 void bnep_process_setup_conn_responce (tBNEP_CONN *p_bcb, UINT8 *p_setup) 688 { 689 tBNEP_RESULT resp; 690 UINT16 resp_code; 691 692 BNEP_TRACE_DEBUG ("BNEP received setup responce"); 693 /* The state should be either SETUP or CONNECTED */ 694 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP) 695 { 696 /* Should we disconnect ? */ 697 BNEP_TRACE_ERROR ("BNEP - setup response in bad state %d", p_bcb->con_state); 698 return; 699 } 700 701 /* Check if we are the originator */ 702 if (!(p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) 703 { 704 BNEP_TRACE_ERROR ("BNEP - setup response when we are not originator", p_bcb->con_state); 705 return; 706 } 707 708 BE_STREAM_TO_UINT16 (resp_code, p_setup); 709 710 switch (resp_code) 711 { 712 case BNEP_SETUP_INVALID_SRC_UUID: 713 resp = BNEP_CONN_FAILED_SRC_UUID; 714 break; 715 716 case BNEP_SETUP_INVALID_DEST_UUID: 717 resp = BNEP_CONN_FAILED_DST_UUID; 718 break; 719 720 case BNEP_SETUP_INVALID_UUID_SIZE: 721 resp = BNEP_CONN_FAILED_UUID_SIZE; 722 break; 723 724 case BNEP_SETUP_CONN_NOT_ALLOWED: 725 default: 726 resp = BNEP_CONN_FAILED; 727 break; 728 } 729 730 /* Check the responce code */ 731 if (resp_code != BNEP_SETUP_CONN_OK) 732 { 733 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) 734 { 735 BNEP_TRACE_EVENT ("BNEP - role change response is %d", resp_code); 736 737 /* Restore the earlier BNEP status */ 738 p_bcb->con_state = BNEP_STATE_CONNECTED; 739 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD); 740 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID)); 741 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID)); 742 743 /* Ensure timer is stopped */ 744 btu_stop_timer (&p_bcb->conn_tle); 745 p_bcb->re_transmits = 0; 746 747 /* Tell the user if he has a callback */ 748 if (bnep_cb.p_conn_state_cb) 749 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, resp, TRUE); 750 751 return; 752 } 753 else 754 { 755 BNEP_TRACE_ERROR ("BNEP - setup response %d is not OK", resp_code); 756 757 L2CA_DisconnectReq (p_bcb->l2cap_cid); 758 759 /* Tell the user if he has a callback */ 760 if ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) && (bnep_cb.p_conn_state_cb)) 761 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, resp, FALSE); 762 763 bnepu_release_bcb (p_bcb); 764 return; 765 } 766 } 767 768 /* Received successful responce */ 769 bnep_connected (p_bcb); 770 } 771 772 773 /******************************************************************************* 774 ** 775 ** Function bnep_process_control_packet 776 ** 777 ** Description This function processes a peer's setup connection request 778 ** message. The destination UUID is verified and response sent 779 ** Connection open indication will be given to PAN profile 780 ** 781 ** Returns void 782 ** 783 *******************************************************************************/ 784 UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len, BOOLEAN is_ext) 785 { 786 UINT8 control_type; 787 BOOLEAN bad_pkt = FALSE; 788 UINT16 len, ext_len = 0; 789 790 if (is_ext) 791 { 792 ext_len = *p++; 793 *rem_len = *rem_len - 1; 794 } 795 796 control_type = *p++; 797 *rem_len = *rem_len - 1; 798 799 BNEP_TRACE_EVENT ("BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d", *rem_len, is_ext, control_type); 800 801 switch (control_type) 802 { 803 case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD: 804 BNEP_TRACE_ERROR ("BNEP Received Cmd not understood for ctl pkt type: %d", *p); 805 p++; 806 *rem_len = *rem_len - 1; 807 break; 808 809 case BNEP_SETUP_CONNECTION_REQUEST_MSG: 810 len = *p++; 811 if (*rem_len < ((2 * len) + 1)) 812 { 813 bad_pkt = TRUE; 814 BNEP_TRACE_ERROR ("BNEP Received Setup message with bad length"); 815 break; 816 } 817 if (!is_ext) 818 bnep_process_setup_conn_req (p_bcb, p, (UINT8)len); 819 p += (2 * len); 820 *rem_len = *rem_len - (2 * len) - 1; 821 break; 822 823 case BNEP_SETUP_CONNECTION_RESPONSE_MSG: 824 if (!is_ext) 825 bnep_process_setup_conn_responce (p_bcb, p); 826 p += 2; 827 *rem_len = *rem_len - 2; 828 break; 829 830 case BNEP_FILTER_NET_TYPE_SET_MSG: 831 BE_STREAM_TO_UINT16 (len, p); 832 if (*rem_len < (len + 2)) 833 { 834 bad_pkt = TRUE; 835 BNEP_TRACE_ERROR ("BNEP Received Filter set message with bad length"); 836 break; 837 } 838 bnepu_process_peer_filter_set (p_bcb, p, len); 839 p += len; 840 *rem_len = *rem_len - len - 2; 841 break; 842 843 case BNEP_FILTER_NET_TYPE_RESPONSE_MSG: 844 bnepu_process_peer_filter_rsp (p_bcb, p); 845 p += 2; 846 *rem_len = *rem_len - 2; 847 break; 848 849 case BNEP_FILTER_MULTI_ADDR_SET_MSG: 850 BE_STREAM_TO_UINT16 (len, p); 851 if (*rem_len < (len + 2)) 852 { 853 bad_pkt = TRUE; 854 BNEP_TRACE_ERROR ("BNEP Received Multicast Filter Set message with bad length"); 855 break; 856 } 857 bnepu_process_peer_multicast_filter_set (p_bcb, p, len); 858 p += len; 859 *rem_len = *rem_len - len - 2; 860 break; 861 862 case BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG: 863 bnepu_process_multicast_filter_rsp (p_bcb, p); 864 p += 2; 865 *rem_len = *rem_len - 2; 866 break; 867 868 default : 869 BNEP_TRACE_ERROR ("BNEP - bad ctl pkt type: %d", control_type); 870 bnep_send_command_not_understood (p_bcb, control_type); 871 if (is_ext) 872 { 873 p += (ext_len - 1); 874 *rem_len -= (ext_len - 1); 875 } 876 break; 877 } 878 879 if (bad_pkt) 880 { 881 BNEP_TRACE_ERROR ("BNEP - bad ctl pkt length: %d", *rem_len); 882 *rem_len = 0; 883 return NULL; 884 } 885 886 return p; 887 } 888 889 890 /******************************************************************************* 891 ** 892 ** Function bnepu_process_peer_filter_set 893 ** 894 ** Description This function processes a peer's filter control 895 ** 'set' message. The filters are stored in the BCB, 896 ** and an appropriate filter response message sent. 897 ** 898 ** Returns void 899 ** 900 *******************************************************************************/ 901 void bnepu_process_peer_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len) 902 { 903 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE) 904 UINT16 num_filters = 0; 905 UINT16 xx, resp_code = BNEP_FILTER_CRL_OK; 906 UINT16 start, end; 907 UINT8 *p_temp_filters; 908 909 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 910 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 911 { 912 BNEP_TRACE_DEBUG ("BNEP received filter set from peer when there is no connection"); 913 return; 914 } 915 916 BNEP_TRACE_DEBUG ("BNEP received filter set from peer"); 917 /* Check for length not a multiple of 4 */ 918 if (len & 3) 919 { 920 BNEP_TRACE_EVENT ("BNEP - bad filter len: %d", len); 921 bnepu_send_peer_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE); 922 return; 923 } 924 925 if (len) 926 num_filters = (UINT16) (len >> 2); 927 928 /* Validate filter values */ 929 if (num_filters <= BNEP_MAX_PROT_FILTERS) 930 { 931 p_temp_filters = p_filters; 932 for (xx = 0; xx < num_filters; xx++) 933 { 934 BE_STREAM_TO_UINT16 (start, p_temp_filters); 935 BE_STREAM_TO_UINT16 (end, p_temp_filters); 936 937 if (start > end) 938 { 939 resp_code = BNEP_FILTER_CRL_BAD_RANGE; 940 break; 941 } 942 } 943 } 944 else 945 resp_code = BNEP_FILTER_CRL_MAX_REACHED; 946 947 if (resp_code != BNEP_FILTER_CRL_OK) 948 { 949 bnepu_send_peer_filter_rsp (p_bcb, resp_code); 950 return; 951 } 952 953 if (bnep_cb.p_filter_ind_cb) 954 (*bnep_cb.p_filter_ind_cb) (p_bcb->handle, TRUE, 0, len, p_filters); 955 956 p_bcb->rcvd_num_filters = num_filters; 957 for (xx = 0; xx < num_filters; xx++) 958 { 959 BE_STREAM_TO_UINT16 (start, p_filters); 960 BE_STREAM_TO_UINT16 (end, p_filters); 961 962 p_bcb->rcvd_prot_filter_start[xx] = start; 963 p_bcb->rcvd_prot_filter_end[xx] = end; 964 } 965 966 bnepu_send_peer_filter_rsp (p_bcb, resp_code); 967 #else 968 bnepu_send_peer_filter_rsp (p_bcb, BNEP_FILTER_CRL_UNSUPPORTED); 969 #endif 970 } 971 972 973 /******************************************************************************* 974 ** 975 ** Function bnepu_process_peer_filter_rsp 976 ** 977 ** Description This function processes a peer's filter control 978 ** 'response' message. 979 ** 980 ** Returns void 981 ** 982 *******************************************************************************/ 983 void bnepu_process_peer_filter_rsp (tBNEP_CONN *p_bcb, UINT8 *p_data) 984 { 985 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE) 986 UINT16 resp_code; 987 tBNEP_RESULT result; 988 989 BNEP_TRACE_DEBUG ("BNEP received filter responce"); 990 /* The state should be CONNECTED */ 991 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 992 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 993 { 994 BNEP_TRACE_ERROR ("BNEP - filter response in bad state %d", p_bcb->con_state); 995 return; 996 } 997 998 /* Check if we are the originator */ 999 if (!(p_bcb->con_flags & BNEP_FLAGS_FILTER_RESP_PEND)) 1000 { 1001 BNEP_TRACE_ERROR ("BNEP - filter response when not expecting"); 1002 return; 1003 } 1004 1005 /* Ensure timer is stopped */ 1006 btu_stop_timer (&p_bcb->conn_tle); 1007 p_bcb->con_flags &= ~BNEP_FLAGS_FILTER_RESP_PEND; 1008 p_bcb->re_transmits = 0; 1009 1010 BE_STREAM_TO_UINT16 (resp_code, p_data); 1011 1012 result = BNEP_SUCCESS; 1013 if (resp_code != BNEP_FILTER_CRL_OK) 1014 result = BNEP_SET_FILTER_FAIL; 1015 1016 if (bnep_cb.p_filter_ind_cb) 1017 (*bnep_cb.p_filter_ind_cb) (p_bcb->handle, FALSE, result, 0, NULL); 1018 1019 return; 1020 #endif 1021 } 1022 1023 1024 1025 /******************************************************************************* 1026 ** 1027 ** Function bnepu_process_multicast_filter_rsp 1028 ** 1029 ** Description This function processes multicast filter control 1030 ** 'response' message. 1031 ** 1032 ** Returns void 1033 ** 1034 *******************************************************************************/ 1035 void bnepu_process_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT8 *p_data) 1036 { 1037 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE) 1038 UINT16 resp_code; 1039 tBNEP_RESULT result; 1040 1041 BNEP_TRACE_DEBUG ("BNEP received multicast filter responce"); 1042 /* The state should be CONNECTED */ 1043 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 1044 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 1045 { 1046 BNEP_TRACE_ERROR ("BNEP - multicast filter response in bad state %d", p_bcb->con_state); 1047 return; 1048 } 1049 1050 /* Check if we are the originator */ 1051 if (!(p_bcb->con_flags & BNEP_FLAGS_MULTI_RESP_PEND)) 1052 { 1053 BNEP_TRACE_ERROR ("BNEP - multicast filter response when not expecting"); 1054 return; 1055 } 1056 1057 /* Ensure timer is stopped */ 1058 btu_stop_timer (&p_bcb->conn_tle); 1059 p_bcb->con_flags &= ~BNEP_FLAGS_MULTI_RESP_PEND; 1060 p_bcb->re_transmits = 0; 1061 1062 BE_STREAM_TO_UINT16 (resp_code, p_data); 1063 1064 result = BNEP_SUCCESS; 1065 if (resp_code != BNEP_FILTER_CRL_OK) 1066 result = BNEP_SET_FILTER_FAIL; 1067 1068 if (bnep_cb.p_mfilter_ind_cb) 1069 (*bnep_cb.p_mfilter_ind_cb) (p_bcb->handle, FALSE, result, 0, NULL); 1070 1071 return; 1072 #endif 1073 } 1074 1075 1076 1077 /******************************************************************************* 1078 ** 1079 ** Function bnepu_process_peer_multicast_filter_set 1080 ** 1081 ** Description This function processes a peer's filter control 1082 ** 'set' message. The filters are stored in the BCB, 1083 ** and an appropriate filter response message sent. 1084 ** 1085 ** Returns void 1086 ** 1087 *******************************************************************************/ 1088 void bnepu_process_peer_multicast_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len) 1089 { 1090 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE) 1091 UINT16 resp_code = BNEP_FILTER_CRL_OK; 1092 UINT16 num_filters, xx; 1093 UINT8 *p_temp_filters, null_bda[BD_ADDR_LEN] = {0,0,0,0,0,0}; 1094 1095 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 1096 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 1097 { 1098 BNEP_TRACE_DEBUG ("BNEP received multicast filter set from peer when there is no connection"); 1099 return; 1100 } 1101 1102 if (len % 12) 1103 { 1104 BNEP_TRACE_EVENT ("BNEP - bad filter len: %d", len); 1105 bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE); 1106 return; 1107 } 1108 1109 if (len > (BNEP_MAX_MULTI_FILTERS * 2 * BD_ADDR_LEN)) 1110 { 1111 BNEP_TRACE_EVENT ("BNEP - Too many filters"); 1112 bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_MAX_REACHED); 1113 return; 1114 } 1115 1116 num_filters = 0; 1117 if (len) 1118 num_filters = (UINT16) (len / 12); 1119 1120 /* Validate filter values */ 1121 if (num_filters <= BNEP_MAX_MULTI_FILTERS) 1122 { 1123 p_temp_filters = p_filters; 1124 for (xx = 0; xx < num_filters; xx++) 1125 { 1126 if (memcmp (p_temp_filters, p_temp_filters + BD_ADDR_LEN, BD_ADDR_LEN) > 0) 1127 { 1128 bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE); 1129 return; 1130 } 1131 1132 p_temp_filters += (BD_ADDR_LEN * 2); 1133 } 1134 } 1135 1136 p_bcb->rcvd_mcast_filters = num_filters; 1137 for (xx = 0; xx < num_filters; xx++) 1138 { 1139 memcpy (p_bcb->rcvd_mcast_filter_start[xx], p_filters, BD_ADDR_LEN); 1140 memcpy (p_bcb->rcvd_mcast_filter_end[xx], p_filters + BD_ADDR_LEN, BD_ADDR_LEN); 1141 p_filters += (BD_ADDR_LEN * 2); 1142 1143 /* Check if any of the ranges have all zeros as both starting and ending addresses */ 1144 if ((memcmp (null_bda, p_bcb->rcvd_mcast_filter_start[xx], BD_ADDR_LEN) == 0) && 1145 (memcmp (null_bda, p_bcb->rcvd_mcast_filter_end[xx], BD_ADDR_LEN) == 0)) 1146 { 1147 p_bcb->rcvd_mcast_filters = 0xFFFF; 1148 break; 1149 } 1150 } 1151 1152 BNEP_TRACE_EVENT ("BNEP multicast filters %d", p_bcb->rcvd_mcast_filters); 1153 bnepu_send_peer_multicast_filter_rsp (p_bcb, resp_code); 1154 1155 if (bnep_cb.p_mfilter_ind_cb) 1156 (*bnep_cb.p_mfilter_ind_cb) (p_bcb->handle, TRUE, 0, len, p_filters); 1157 #else 1158 bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_UNSUPPORTED); 1159 #endif 1160 } 1161 1162 1163 /******************************************************************************* 1164 ** 1165 ** Function bnepu_send_peer_multicast_filter_rsp 1166 ** 1167 ** Description This function sends a filter response to a peer 1168 ** 1169 ** Returns void 1170 ** 1171 *******************************************************************************/ 1172 void bnepu_send_peer_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code) 1173 { 1174 BT_HDR *p_buf; 1175 UINT8 *p; 1176 1177 BNEP_TRACE_DEBUG ("BNEP sending multicast filter response %d", response_code); 1178 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL) 1179 { 1180 BNEP_TRACE_ERROR ("BNEP - no buffer filter rsp"); 1181 return; 1182 } 1183 1184 p_buf->offset = L2CAP_MIN_OFFSET; 1185 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 1186 1187 /* Put in BNEP frame type - filter control */ 1188 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL); 1189 1190 /* Put in filter message type - set filters */ 1191 UINT8_TO_BE_STREAM (p, BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG); 1192 1193 UINT16_TO_BE_STREAM (p, response_code); 1194 1195 p_buf->len = 4; 1196 1197 bnepu_check_send_packet (p_bcb, p_buf); 1198 } 1199 1200 1201 1202 /******************************************************************************* 1203 ** 1204 ** Function bnep_sec_check_complete 1205 ** 1206 ** Description This function is registered with BTM and will be called 1207 ** after completing the security procedures 1208 ** 1209 ** Returns void 1210 ** 1211 *******************************************************************************/ 1212 void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport, 1213 void *p_ref_data, UINT8 result) 1214 { 1215 tBNEP_CONN *p_bcb = (tBNEP_CONN *)p_ref_data; 1216 UINT16 resp_code = BNEP_SETUP_CONN_OK; 1217 BOOLEAN is_role_change; 1218 UNUSED(bd_addr); 1219 UNUSED(trasnport); 1220 1221 BNEP_TRACE_EVENT ("BNEP security callback returned result %d", result); 1222 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) 1223 is_role_change = TRUE; 1224 else 1225 is_role_change = FALSE; 1226 1227 /* check if the port is still waiting for security to complete */ 1228 if (p_bcb->con_state != BNEP_STATE_SEC_CHECKING) 1229 { 1230 BNEP_TRACE_ERROR ("BNEP Connection in wrong state %d when security is completed", p_bcb->con_state); 1231 return; 1232 } 1233 1234 /* if it is outgoing call and result is FAILURE return security fail error */ 1235 if (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) 1236 { 1237 if (result != BTM_SUCCESS) 1238 { 1239 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) 1240 { 1241 /* Tell the user that role change is failed because of security */ 1242 if (bnep_cb.p_conn_state_cb) 1243 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, BNEP_SECURITY_FAIL, is_role_change); 1244 1245 p_bcb->con_state = BNEP_STATE_CONNECTED; 1246 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID)); 1247 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID)); 1248 return; 1249 } 1250 1251 L2CA_DisconnectReq (p_bcb->l2cap_cid); 1252 1253 /* Tell the user if he has a callback */ 1254 if (bnep_cb.p_conn_state_cb) 1255 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, BNEP_SECURITY_FAIL, is_role_change); 1256 1257 bnepu_release_bcb (p_bcb); 1258 return; 1259 } 1260 1261 /* Transition to the next appropriate state, waiting for connection confirm. */ 1262 p_bcb->con_state = BNEP_STATE_CONN_SETUP; 1263 1264 bnep_send_conn_req (p_bcb); 1265 btu_start_timer (&p_bcb->conn_tle, BTU_TTYPE_BNEP, BNEP_CONN_TIMEOUT); 1266 return; 1267 } 1268 1269 /* it is an incoming call respond appropriately */ 1270 if (result != BTM_SUCCESS) 1271 { 1272 bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED); 1273 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) 1274 { 1275 /* Role change is failed because of security. Revert back to connected state */ 1276 p_bcb->con_state = BNEP_STATE_CONNECTED; 1277 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD); 1278 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID)); 1279 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID)); 1280 return; 1281 } 1282 1283 L2CA_DisconnectReq (p_bcb->l2cap_cid); 1284 1285 bnepu_release_bcb (p_bcb); 1286 return; 1287 } 1288 1289 if (bnep_cb.p_conn_ind_cb) 1290 { 1291 p_bcb->con_state = BNEP_STATE_CONN_SETUP; 1292 (*bnep_cb.p_conn_ind_cb) (p_bcb->handle, p_bcb->rem_bda, &p_bcb->dst_uuid, &p_bcb->src_uuid, is_role_change); 1293 } 1294 else 1295 { 1296 /* Profile didn't register connection indication call back */ 1297 bnep_send_conn_responce (p_bcb, resp_code); 1298 bnep_connected (p_bcb); 1299 } 1300 1301 return; 1302 } 1303 1304 1305 /******************************************************************************* 1306 ** 1307 ** Function bnep_is_packet_allowed 1308 ** 1309 ** Description This function verifies whether the protocol passes through 1310 ** the protocol filters set by the peer 1311 ** 1312 ** Returns BNEP_SUCCESS - if the protocol is allowed 1313 ** BNEP_IGNORE_CMD - if the protocol is filtered out 1314 ** 1315 *******************************************************************************/ 1316 tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, 1317 BD_ADDR p_dest_addr, 1318 UINT16 protocol, 1319 BOOLEAN fw_ext_present, 1320 UINT8 *p_data) 1321 { 1322 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE) 1323 if (p_bcb->rcvd_num_filters) 1324 { 1325 UINT16 i, proto; 1326 1327 /* Findout the actual protocol to check for the filtering */ 1328 proto = protocol; 1329 if (proto == BNEP_802_1_P_PROTOCOL) 1330 { 1331 if (fw_ext_present) 1332 { 1333 UINT8 len, ext; 1334 /* parse the extension headers and findout actual protocol */ 1335 do { 1336 1337 ext = *p_data++; 1338 len = *p_data++; 1339 p_data += len; 1340 1341 } while (ext & 0x80); 1342 } 1343 p_data += 2; 1344 BE_STREAM_TO_UINT16 (proto, p_data); 1345 } 1346 1347 for (i=0; i<p_bcb->rcvd_num_filters; i++) 1348 { 1349 if ((p_bcb->rcvd_prot_filter_start[i] <= proto) && 1350 (proto <= p_bcb->rcvd_prot_filter_end[i])) 1351 break; 1352 } 1353 1354 if (i == p_bcb->rcvd_num_filters) 1355 { 1356 BNEP_TRACE_DEBUG ("Ignoring protocol 0x%x in BNEP data write", proto); 1357 return BNEP_IGNORE_CMD; 1358 } 1359 } 1360 #endif 1361 1362 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE) 1363 /* Ckeck for multicast address filtering */ 1364 if ((p_dest_addr[0] & 0x01) && 1365 p_bcb->rcvd_mcast_filters) 1366 { 1367 UINT16 i; 1368 1369 /* Check if every multicast should be filtered */ 1370 if (p_bcb->rcvd_mcast_filters != 0xFFFF) 1371 { 1372 /* Check if the address is mentioned in the filter range */ 1373 for (i = 0; i < p_bcb->rcvd_mcast_filters; i++) 1374 { 1375 if ((memcmp (p_bcb->rcvd_mcast_filter_start[i], p_dest_addr, BD_ADDR_LEN) <= 0) && 1376 (memcmp (p_bcb->rcvd_mcast_filter_end[i], p_dest_addr, BD_ADDR_LEN) >= 0)) 1377 break; 1378 } 1379 } 1380 1381 /* 1382 ** If every multicast should be filtered or the address is not in the filter range 1383 ** drop the packet 1384 */ 1385 if ((p_bcb->rcvd_mcast_filters == 0xFFFF) || (i == p_bcb->rcvd_mcast_filters)) 1386 { 1387 BNEP_TRACE_DEBUG ("Ignoring multicast address %x.%x.%x.%x.%x.%x in BNEP data write", 1388 p_dest_addr[0], p_dest_addr[1], p_dest_addr[2], 1389 p_dest_addr[3], p_dest_addr[4], p_dest_addr[5]); 1390 return BNEP_IGNORE_CMD; 1391 } 1392 } 1393 #endif 1394 1395 return BNEP_SUCCESS; 1396 } 1397 1398 1399 1400 1401 1402 /******************************************************************************* 1403 ** 1404 ** Function bnep_get_uuid32 1405 ** 1406 ** Description This function returns the 32 bit equivalent of the given UUID 1407 ** 1408 ** Returns UINT32 - 32 bit equivalent of the UUID 1409 ** 1410 *******************************************************************************/ 1411 UINT32 bnep_get_uuid32 (tBT_UUID *src_uuid) 1412 { 1413 UINT32 result; 1414 1415 if (src_uuid->len == 2) 1416 return ((UINT32)src_uuid->uu.uuid16); 1417 else if (src_uuid->len == 4) 1418 return (src_uuid->uu.uuid32 & 0x0000FFFF); 1419 else 1420 { 1421 result = src_uuid->uu.uuid128[2]; 1422 result = (result << 8) | (src_uuid->uu.uuid128[3]); 1423 return result; 1424 } 1425 } 1426 1427 1428 1429 1430 /******************************************************************************* 1431 ** 1432 ** Function bnep_dump_status 1433 ** 1434 ** Description This function dumps the bnep control block and connection 1435 ** blocks information 1436 ** 1437 ** Returns none 1438 ** 1439 *******************************************************************************/ 1440 void bnep_dump_status (void) 1441 { 1442 #if (defined (BNEP_SUPPORTS_DEBUG_DUMP) && BNEP_SUPPORTS_DEBUG_DUMP == TRUE) 1443 UINT16 i; 1444 char buff[200]; 1445 tBNEP_CONN *p_bcb; 1446 1447 BNEP_TRACE_DEBUG ("BNEP my BD Addr %x.%x.%x.%x.%x.%x", 1448 bnep_cb.my_bda[0], bnep_cb.my_bda[1], bnep_cb.my_bda[2], 1449 bnep_cb.my_bda[3], bnep_cb.my_bda[4], bnep_cb.my_bda[5]); 1450 BNEP_TRACE_DEBUG ("profile registered %d, trace %d, got_my_bd_addr %d", 1451 bnep_cb.profile_registered, bnep_cb.trace_level, bnep_cb.got_my_bd_addr); 1452 1453 for (i = 0, p_bcb = bnep_cb.bcb; i < BNEP_MAX_CONNECTIONS; i++, p_bcb++) 1454 { 1455 sprintf (buff, "%d state %d, flags 0x%x, cid %d, pfilts %d, mfilts %d, src 0x%x, dst 0x%x, BD %x.%x.%x.%x.%x.%x", 1456 i, p_bcb->con_state, p_bcb->con_flags, p_bcb->l2cap_cid, 1457 p_bcb->rcvd_num_filters, p_bcb->rcvd_mcast_filters, 1458 p_bcb->src_uuid.uu.uuid16, p_bcb->dst_uuid.uu.uuid16, 1459 p_bcb->rem_bda[0], p_bcb->rem_bda[1], p_bcb->rem_bda[2], 1460 p_bcb->rem_bda[3], p_bcb->rem_bda[4], p_bcb->rem_bda[5]); 1461 1462 BNEP_TRACE_DEBUG (buff); 1463 } 1464 #endif 1465 } 1466 1467 1468