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