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