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