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 the BNEP API code 22 * 23 ******************************************************************************/ 24 25 #include "bnep_api.h" 26 #include <string.h> 27 #include "bnep_int.h" 28 29 /******************************************************************************* 30 * 31 * Function BNEP_Init 32 * 33 * Description This function initializes the BNEP unit. It should be called 34 * before accessing any other APIs to initialize the control 35 * block. 36 * 37 * Returns void 38 * 39 ******************************************************************************/ 40 void BNEP_Init(void) { 41 memset(&bnep_cb, 0, sizeof(tBNEP_CB)); 42 43 #if defined(BNEP_INITIAL_TRACE_LEVEL) 44 bnep_cb.trace_level = BNEP_INITIAL_TRACE_LEVEL; 45 #else 46 bnep_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ 47 #endif 48 } 49 50 /******************************************************************************* 51 * 52 * Function BNEP_Register 53 * 54 * Description This function is called by the upper layer to register 55 * its callbacks with BNEP 56 * 57 * Parameters: p_reg_info - contains all callback function pointers 58 * 59 * 60 * Returns BNEP_SUCCESS if registered successfully 61 * BNEP_FAILURE if connection state callback is missing 62 * 63 ******************************************************************************/ 64 tBNEP_RESULT BNEP_Register(tBNEP_REGISTER* p_reg_info) { 65 /* There should be connection state call back registered */ 66 if ((!p_reg_info) || (!(p_reg_info->p_conn_state_cb))) 67 return BNEP_SECURITY_FAIL; 68 69 bnep_cb.p_conn_ind_cb = p_reg_info->p_conn_ind_cb; 70 bnep_cb.p_conn_state_cb = p_reg_info->p_conn_state_cb; 71 bnep_cb.p_data_ind_cb = p_reg_info->p_data_ind_cb; 72 bnep_cb.p_data_buf_cb = p_reg_info->p_data_buf_cb; 73 bnep_cb.p_filter_ind_cb = p_reg_info->p_filter_ind_cb; 74 bnep_cb.p_mfilter_ind_cb = p_reg_info->p_mfilter_ind_cb; 75 bnep_cb.p_tx_data_flow_cb = p_reg_info->p_tx_data_flow_cb; 76 77 if (bnep_register_with_l2cap()) return BNEP_SECURITY_FAIL; 78 79 bnep_cb.profile_registered = true; 80 return BNEP_SUCCESS; 81 } 82 83 /******************************************************************************* 84 * 85 * Function BNEP_Deregister 86 * 87 * Description This function is called by the upper layer to de-register 88 * its callbacks. 89 * 90 * Parameters: void 91 * 92 * 93 * Returns void 94 * 95 ******************************************************************************/ 96 void BNEP_Deregister(void) { 97 /* Clear all the call backs registered */ 98 bnep_cb.p_conn_ind_cb = NULL; 99 bnep_cb.p_conn_state_cb = NULL; 100 bnep_cb.p_data_ind_cb = NULL; 101 bnep_cb.p_data_buf_cb = NULL; 102 bnep_cb.p_filter_ind_cb = NULL; 103 bnep_cb.p_mfilter_ind_cb = NULL; 104 105 bnep_cb.profile_registered = false; 106 L2CA_Deregister(BT_PSM_BNEP); 107 } 108 109 /******************************************************************************* 110 * 111 * Function BNEP_Connect 112 * 113 * Description This function creates a BNEP connection to a remote 114 * device. 115 * 116 * Parameters: p_rem_addr - BD_ADDR of the peer 117 * src_uuid - source uuid for the connection 118 * dst_uuid - destination uuid for the connection 119 * p_handle - pointer to return the handle for the 120 * connection 121 * 122 * Returns BNEP_SUCCESS if connection started 123 * BNEP_NO_RESOURCES if no resources 124 * 125 ******************************************************************************/ 126 tBNEP_RESULT BNEP_Connect(const RawAddress& p_rem_bda, tBT_UUID* src_uuid, 127 tBT_UUID* dst_uuid, uint16_t* p_handle) { 128 uint16_t cid; 129 tBNEP_CONN* p_bcb = bnepu_find_bcb_by_bd_addr(p_rem_bda); 130 131 VLOG(0) << __func__ << " BDA:" << p_rem_bda; 132 133 if (!bnep_cb.profile_registered) return BNEP_WRONG_STATE; 134 135 /* Both source and destination UUID lengths should be same */ 136 if (src_uuid->len != dst_uuid->len) return BNEP_CONN_FAILED_UUID_SIZE; 137 138 if (!p_bcb) { 139 p_bcb = bnepu_allocate_bcb(p_rem_bda); 140 if (p_bcb == NULL) return (BNEP_NO_RESOURCES); 141 } else if (p_bcb->con_state != BNEP_STATE_CONNECTED) 142 return BNEP_WRONG_STATE; 143 else { 144 /* Backup current UUID values to restore if role change fails */ 145 memcpy((uint8_t*)&(p_bcb->prv_src_uuid), (uint8_t*)&(p_bcb->src_uuid), 146 sizeof(tBT_UUID)); 147 memcpy((uint8_t*)&(p_bcb->prv_dst_uuid), (uint8_t*)&(p_bcb->dst_uuid), 148 sizeof(tBT_UUID)); 149 } 150 151 /* We are the originator of this connection */ 152 p_bcb->con_flags |= BNEP_FLAGS_IS_ORIG; 153 154 memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)src_uuid, sizeof(tBT_UUID)); 155 memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)dst_uuid, sizeof(tBT_UUID)); 156 157 if (p_bcb->con_state == BNEP_STATE_CONNECTED) { 158 /* Transition to the next appropriate state, waiting for connection confirm. 159 */ 160 p_bcb->con_state = BNEP_STATE_SEC_CHECKING; 161 162 BNEP_TRACE_API("BNEP initiating security procedures for src uuid 0x%x", 163 p_bcb->src_uuid.uu.uuid16); 164 165 #if (BNEP_DO_AUTH_FOR_ROLE_SWITCH == TRUE) 166 btm_sec_mx_access_request(p_bcb->rem_bda, BT_PSM_BNEP, true, 167 BTM_SEC_PROTO_BNEP, bnep_get_uuid32(src_uuid), 168 &bnep_sec_check_complete, p_bcb); 169 #else 170 bnep_sec_check_complete(p_bcb->rem_bda, p_bcb, BTM_SUCCESS); 171 #endif 172 173 } else { 174 /* Transition to the next appropriate state, waiting for connection confirm. 175 */ 176 p_bcb->con_state = BNEP_STATE_CONN_START; 177 178 cid = L2CA_ConnectReq(BT_PSM_BNEP, p_bcb->rem_bda); 179 if (cid != 0) { 180 p_bcb->l2cap_cid = cid; 181 182 } else { 183 BNEP_TRACE_ERROR("BNEP - Originate failed"); 184 if (bnep_cb.p_conn_state_cb) 185 (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda, 186 BNEP_CONN_FAILED, false); 187 bnepu_release_bcb(p_bcb); 188 return BNEP_CONN_FAILED; 189 } 190 191 /* Start timer waiting for connect */ 192 alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS, 193 bnep_conn_timer_timeout, p_bcb); 194 } 195 196 *p_handle = p_bcb->handle; 197 return (BNEP_SUCCESS); 198 } 199 200 /******************************************************************************* 201 * 202 * Function BNEP_ConnectResp 203 * 204 * Description This function is called in responce to connection indication 205 * 206 * 207 * Parameters: handle - handle given in the connection indication 208 * resp - responce for the connection indication 209 * 210 * Returns BNEP_SUCCESS if connection started 211 * BNEP_WRONG_HANDLE if the connection is not found 212 * BNEP_WRONG_STATE if the responce is not expected 213 * 214 ******************************************************************************/ 215 tBNEP_RESULT BNEP_ConnectResp(uint16_t handle, tBNEP_RESULT resp) { 216 tBNEP_CONN* p_bcb; 217 uint16_t resp_code = BNEP_SETUP_CONN_OK; 218 219 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE); 220 221 p_bcb = &(bnep_cb.bcb[handle - 1]); 222 223 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP || 224 (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD))) 225 return (BNEP_WRONG_STATE); 226 227 BNEP_TRACE_API("BNEP_ConnectResp() for handle %d, responce %d", handle, 228 resp); 229 230 /* Form appropriate responce based on profile responce */ 231 if (resp == BNEP_CONN_FAILED_SRC_UUID) 232 resp_code = BNEP_SETUP_INVALID_SRC_UUID; 233 else if (resp == BNEP_CONN_FAILED_DST_UUID) 234 resp_code = BNEP_SETUP_INVALID_DEST_UUID; 235 else if (resp == BNEP_CONN_FAILED_UUID_SIZE) 236 resp_code = BNEP_SETUP_INVALID_UUID_SIZE; 237 else if (resp == BNEP_SUCCESS) 238 resp_code = BNEP_SETUP_CONN_OK; 239 else 240 resp_code = BNEP_SETUP_CONN_NOT_ALLOWED; 241 242 bnep_send_conn_responce(p_bcb, resp_code); 243 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD); 244 245 if (resp == BNEP_SUCCESS) 246 bnep_connected(p_bcb); 247 else if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) { 248 /* Restore the original parameters */ 249 p_bcb->con_state = BNEP_STATE_CONNECTED; 250 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD); 251 252 memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)&(p_bcb->prv_src_uuid), 253 sizeof(tBT_UUID)); 254 memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)&(p_bcb->prv_dst_uuid), 255 sizeof(tBT_UUID)); 256 } 257 258 /* Process remaining part of the setup message (extension headers) */ 259 if (p_bcb->p_pending_data) { 260 uint8_t extension_present = true, *p, ext_type; 261 uint16_t rem_len; 262 263 rem_len = p_bcb->p_pending_data->len; 264 p = (uint8_t*)(p_bcb->p_pending_data + 1) + p_bcb->p_pending_data->offset; 265 while (extension_present && p && rem_len) { 266 ext_type = *p++; 267 extension_present = ext_type >> 7; 268 ext_type &= 0x7F; 269 270 /* if unknown extension present stop processing */ 271 if (ext_type) break; 272 273 p = bnep_process_control_packet(p_bcb, p, &rem_len, true); 274 } 275 276 osi_free_and_reset((void**)&p_bcb->p_pending_data); 277 } 278 return (BNEP_SUCCESS); 279 } 280 281 /******************************************************************************* 282 * 283 * Function BNEP_Disconnect 284 * 285 * Description This function is called to close the specified connection. 286 * 287 * Parameters: handle - handle of the connection 288 * 289 * Returns BNEP_SUCCESS if connection is disconnected 290 * BNEP_WRONG_HANDLE if no connection is not found 291 * 292 ******************************************************************************/ 293 tBNEP_RESULT BNEP_Disconnect(uint16_t handle) { 294 tBNEP_CONN* p_bcb; 295 296 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE); 297 298 p_bcb = &(bnep_cb.bcb[handle - 1]); 299 300 if (p_bcb->con_state == BNEP_STATE_IDLE) return (BNEP_WRONG_HANDLE); 301 302 BNEP_TRACE_API("BNEP_Disconnect() for handle %d", handle); 303 304 L2CA_DisconnectReq(p_bcb->l2cap_cid); 305 306 bnepu_release_bcb(p_bcb); 307 308 return (BNEP_SUCCESS); 309 } 310 311 /******************************************************************************* 312 * 313 * Function BNEP_WriteBuf 314 * 315 * Description This function sends data in a GKI buffer on BNEP connection 316 * 317 * Parameters: handle - handle of the connection to write 318 * p_dest_addr - BD_ADDR/Ethernet addr of the destination 319 * p_buf - pointer to address of buffer with data 320 * protocol - protocol type of the packet 321 * p_src_addr - (optional) BD_ADDR/ethernet address of the 322 * source 323 * (should be NULL if it is local BD Addr) 324 * fw_ext_present - forwarded extensions present 325 * 326 * Returns: BNEP_WRONG_HANDLE - if passed handle is not valid 327 * BNEP_MTU_EXCEDED - If the data length is greater than 328 * the MTU 329 * BNEP_IGNORE_CMD - If the packet is filtered out 330 * BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full 331 * BNEP_SUCCESS - If written successfully 332 * 333 ******************************************************************************/ 334 tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, 335 BT_HDR* p_buf, uint16_t protocol, 336 const RawAddress* p_src_addr, bool fw_ext_present) { 337 tBNEP_CONN* p_bcb; 338 uint8_t* p_data; 339 340 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) { 341 osi_free(p_buf); 342 return (BNEP_WRONG_HANDLE); 343 } 344 345 p_bcb = &(bnep_cb.bcb[handle - 1]); 346 /* Check MTU size */ 347 if (p_buf->len > BNEP_MTU_SIZE) { 348 BNEP_TRACE_ERROR("BNEP_Write() length %d exceeded MTU %d", p_buf->len, 349 BNEP_MTU_SIZE); 350 osi_free(p_buf); 351 return (BNEP_MTU_EXCEDED); 352 } 353 354 /* Check if the packet should be filtered out */ 355 p_data = (uint8_t*)(p_buf + 1) + p_buf->offset; 356 if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present, 357 p_data) != BNEP_SUCCESS) { 358 /* 359 ** If packet is filtered and ext headers are present 360 ** drop the data and forward the ext headers 361 */ 362 if (fw_ext_present) { 363 uint8_t ext, length; 364 uint16_t org_len, new_len; 365 /* parse the extension headers and findout the new packet len */ 366 org_len = p_buf->len; 367 new_len = 0; 368 do { 369 ext = *p_data++; 370 length = *p_data++; 371 p_data += length; 372 373 new_len += (length + 2); 374 375 if (new_len > org_len) { 376 osi_free(p_buf); 377 return BNEP_IGNORE_CMD; 378 } 379 380 } while (ext & 0x80); 381 382 if (protocol != BNEP_802_1_P_PROTOCOL) 383 protocol = 0; 384 else { 385 new_len += 4; 386 p_data[2] = 0; 387 p_data[3] = 0; 388 } 389 p_buf->len = new_len; 390 } else { 391 osi_free(p_buf); 392 return BNEP_IGNORE_CMD; 393 } 394 } 395 396 /* Check transmit queue */ 397 if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) { 398 osi_free(p_buf); 399 return (BNEP_Q_SIZE_EXCEEDED); 400 } 401 402 /* Build the BNEP header */ 403 bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr, 404 fw_ext_present); 405 406 /* Send the data or queue it up */ 407 bnepu_check_send_packet(p_bcb, p_buf); 408 409 return (BNEP_SUCCESS); 410 } 411 412 /******************************************************************************* 413 * 414 * Function BNEP_Write 415 * 416 * Description This function sends data over a BNEP connection 417 * 418 * Parameters: handle - handle of the connection to write 419 * p_dest_addr - BD_ADDR/Ethernet addr of the destination 420 * p_data - pointer to data start 421 * protocol - protocol type of the packet 422 * p_src_addr - (optional) BD_ADDR/ethernet address of the 423 * source 424 * (should be NULL if it is local BD Addr) 425 * fw_ext_present - forwarded extensions present 426 * 427 * Returns: BNEP_WRONG_HANDLE - if passed handle is not valid 428 * BNEP_MTU_EXCEDED - If the data length is greater than 429 * the MTU 430 * BNEP_IGNORE_CMD - If the packet is filtered out 431 * BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full 432 * BNEP_NO_RESOURCES - If not able to allocate a buffer 433 * BNEP_SUCCESS - If written successfully 434 * 435 ******************************************************************************/ 436 tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr, 437 uint8_t* p_data, uint16_t len, uint16_t protocol, 438 const RawAddress* p_src_addr, bool fw_ext_present) { 439 tBNEP_CONN* p_bcb; 440 uint8_t* p; 441 442 /* Check MTU size. Consider the possibility of having extension headers */ 443 if (len > BNEP_MTU_SIZE) { 444 BNEP_TRACE_ERROR("BNEP_Write() length %d exceeded MTU %d", len, 445 BNEP_MTU_SIZE); 446 return (BNEP_MTU_EXCEDED); 447 } 448 449 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE); 450 451 p_bcb = &(bnep_cb.bcb[handle - 1]); 452 453 /* Check if the packet should be filtered out */ 454 if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present, 455 p_data) != BNEP_SUCCESS) { 456 /* 457 ** If packet is filtered and ext headers are present 458 ** drop the data and forward the ext headers 459 */ 460 if (fw_ext_present) { 461 uint8_t ext, length; 462 uint16_t org_len, new_len; 463 /* parse the extension headers and findout the new packet len */ 464 org_len = len; 465 new_len = 0; 466 p = p_data; 467 do { 468 ext = *p_data++; 469 length = *p_data++; 470 p_data += length; 471 472 new_len += (length + 2); 473 474 if (new_len > org_len) return BNEP_IGNORE_CMD; 475 476 } while (ext & 0x80); 477 478 if (protocol != BNEP_802_1_P_PROTOCOL) 479 protocol = 0; 480 else { 481 new_len += 4; 482 p_data[2] = 0; 483 p_data[3] = 0; 484 } 485 len = new_len; 486 p_data = p; 487 } else 488 return BNEP_IGNORE_CMD; 489 } 490 491 /* Check transmit queue */ 492 if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) 493 return (BNEP_Q_SIZE_EXCEEDED); 494 495 /* Get a buffer to copy the data into */ 496 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE); 497 498 p_buf->len = len; 499 p_buf->offset = BNEP_MINIMUM_OFFSET; 500 p = (uint8_t*)(p_buf + 1) + BNEP_MINIMUM_OFFSET; 501 502 memcpy(p, p_data, len); 503 504 /* Build the BNEP header */ 505 bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr, 506 fw_ext_present); 507 508 /* Send the data or queue it up */ 509 bnepu_check_send_packet(p_bcb, p_buf); 510 511 return (BNEP_SUCCESS); 512 } 513 514 /******************************************************************************* 515 * 516 * Function BNEP_SetProtocolFilters 517 * 518 * Description This function sets the protocol filters on peer device 519 * 520 * Parameters: handle - Handle for the connection 521 * num_filters - total number of filter ranges 522 * p_start_array - Array of beginings of all protocol ranges 523 * p_end_array - Array of ends of all protocol ranges 524 * 525 * Returns BNEP_WRONG_HANDLE - if the connection handle is 526 * not valid 527 * BNEP_SET_FILTER_FAIL - if the connection is in wrong 528 * state 529 * BNEP_TOO_MANY_FILTERS - if too many filters 530 * BNEP_SUCCESS - if request sent successfully 531 * 532 ******************************************************************************/ 533 tBNEP_RESULT BNEP_SetProtocolFilters(uint16_t handle, uint16_t num_filters, 534 uint16_t* p_start_array, 535 uint16_t* p_end_array) { 536 uint16_t xx; 537 tBNEP_CONN* p_bcb; 538 539 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE); 540 541 p_bcb = &(bnep_cb.bcb[handle - 1]); 542 543 /* Check the connection state */ 544 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 545 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 546 return (BNEP_WRONG_STATE); 547 548 /* Validate the parameters */ 549 if (num_filters && (!p_start_array || !p_end_array)) 550 return (BNEP_SET_FILTER_FAIL); 551 552 if (num_filters > BNEP_MAX_PROT_FILTERS) return (BNEP_TOO_MANY_FILTERS); 553 554 /* Fill the filter values in connnection block */ 555 for (xx = 0; xx < num_filters; xx++) { 556 p_bcb->sent_prot_filter_start[xx] = *p_start_array++; 557 p_bcb->sent_prot_filter_end[xx] = *p_end_array++; 558 } 559 560 p_bcb->sent_num_filters = num_filters; 561 562 bnepu_send_peer_our_filters(p_bcb); 563 564 return (BNEP_SUCCESS); 565 } 566 567 /******************************************************************************* 568 * 569 * Function BNEP_SetMulticastFilters 570 * 571 * Description This function sets the filters for multicast addresses for 572 * BNEP. 573 * 574 * Parameters: handle - Handle for the connection 575 * num_filters - total number of filter ranges 576 * p_start_array - Pointer to sequence of beginings of all 577 * multicast address ranges 578 * p_end_array - Pointer to sequence of ends of all 579 * multicast address ranges 580 * 581 * Returns BNEP_WRONG_HANDLE - if the connection handle is 582 * not valid 583 * BNEP_SET_FILTER_FAIL - if the connection is in wrong 584 * state 585 * BNEP_TOO_MANY_FILTERS - if too many filters 586 * BNEP_SUCCESS - if request sent successfully 587 * 588 ******************************************************************************/ 589 tBNEP_RESULT BNEP_SetMulticastFilters(uint16_t handle, uint16_t num_filters, 590 uint8_t* p_start_array, 591 uint8_t* p_end_array) { 592 uint16_t xx; 593 tBNEP_CONN* p_bcb; 594 595 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE); 596 597 p_bcb = &(bnep_cb.bcb[handle - 1]); 598 599 /* Check the connection state */ 600 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 601 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 602 return (BNEP_WRONG_STATE); 603 604 /* Validate the parameters */ 605 if (num_filters && (!p_start_array || !p_end_array)) 606 return (BNEP_SET_FILTER_FAIL); 607 608 if (num_filters > BNEP_MAX_MULTI_FILTERS) return (BNEP_TOO_MANY_FILTERS); 609 610 /* Fill the multicast filter values in connnection block */ 611 for (xx = 0; xx < num_filters; xx++) { 612 memcpy(p_bcb->sent_mcast_filter_start[xx].address, p_start_array, 613 BD_ADDR_LEN); 614 memcpy(p_bcb->sent_mcast_filter_end[xx].address, p_end_array, BD_ADDR_LEN); 615 616 p_start_array += BD_ADDR_LEN; 617 p_end_array += BD_ADDR_LEN; 618 } 619 620 p_bcb->sent_mcast_filters = num_filters; 621 622 bnepu_send_peer_our_multi_filters(p_bcb); 623 624 return (BNEP_SUCCESS); 625 } 626 627 /******************************************************************************* 628 * 629 * Function BNEP_SetTraceLevel 630 * 631 * Description This function sets the trace level for BNEP. If called with 632 * a value of 0xFF, it simply reads the current trace level. 633 * 634 * Returns the new (current) trace level 635 * 636 ******************************************************************************/ 637 uint8_t BNEP_SetTraceLevel(uint8_t new_level) { 638 if (new_level != 0xFF) bnep_cb.trace_level = new_level; 639 640 return (bnep_cb.trace_level); 641 } 642 643 /******************************************************************************* 644 * 645 * Function BNEP_GetStatus 646 * 647 * Description This function gets the status information for BNEP 648 * connection 649 * 650 * Returns BNEP_SUCCESS - if the status is available 651 * BNEP_NO_RESOURCES - if no structure is passed for 652 * output 653 * BNEP_WRONG_HANDLE - if the handle is invalid 654 * BNEP_WRONG_STATE - if not in connected state 655 * 656 ******************************************************************************/ 657 tBNEP_RESULT BNEP_GetStatus(uint16_t handle, tBNEP_STATUS* p_status) { 658 #if (BNEP_SUPPORTS_STATUS_API == TRUE) 659 tBNEP_CONN* p_bcb; 660 661 if (!p_status) return BNEP_NO_RESOURCES; 662 663 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE); 664 665 p_bcb = &(bnep_cb.bcb[handle - 1]); 666 667 memset(p_status, 0, sizeof(tBNEP_STATUS)); 668 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 669 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 670 return BNEP_WRONG_STATE; 671 672 /* Read the status parameters from the connection control block */ 673 p_status->con_status = BNEP_STATUS_CONNECTED; 674 p_status->l2cap_cid = p_bcb->l2cap_cid; 675 p_status->rem_mtu_size = p_bcb->rem_mtu_size; 676 p_status->xmit_q_depth = fixed_queue_length(p_bcb->xmit_q); 677 p_status->sent_num_filters = p_bcb->sent_num_filters; 678 p_status->sent_mcast_filters = p_bcb->sent_mcast_filters; 679 p_status->rcvd_num_filters = p_bcb->rcvd_num_filters; 680 p_status->rcvd_mcast_filters = p_bcb->rcvd_mcast_filters; 681 682 p_status->rem_bda = p_bcb->rem_bda; 683 memcpy(&(p_status->src_uuid), &(p_bcb->src_uuid), sizeof(tBT_UUID)); 684 memcpy(&(p_status->dst_uuid), &(p_bcb->dst_uuid), sizeof(tBT_UUID)); 685 686 return BNEP_SUCCESS; 687 #else 688 return (BNEP_IGNORE_CMD); 689 #endif 690 } 691