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