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