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