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 ******************************************************************************/
BNEP_Init(void)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 ******************************************************************************/
BNEP_Register(tBNEP_REGISTER * p_reg_info)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 ******************************************************************************/
BNEP_Deregister(void)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 ******************************************************************************/
BNEP_Connect(const RawAddress & p_rem_bda,const Uuid & src_uuid,const Uuid & dst_uuid,uint16_t * p_handle)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 ******************************************************************************/
BNEP_ConnectResp(uint16_t handle,tBNEP_RESULT resp)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 ******************************************************************************/
BNEP_Disconnect(uint16_t handle)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 ******************************************************************************/
BNEP_WriteBuf(uint16_t handle,const RawAddress & p_dest_addr,BT_HDR * p_buf,uint16_t protocol,const RawAddress * p_src_addr,bool fw_ext_present)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 ******************************************************************************/
BNEP_Write(uint16_t handle,const RawAddress & p_dest_addr,uint8_t * p_data,uint16_t len,uint16_t protocol,const RawAddress * p_src_addr,bool fw_ext_present)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 ******************************************************************************/
BNEP_SetProtocolFilters(uint16_t handle,uint16_t num_filters,uint16_t * p_start_array,uint16_t * p_end_array)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 ******************************************************************************/
BNEP_SetMulticastFilters(uint16_t handle,uint16_t num_filters,uint8_t * p_start_array,uint8_t * p_end_array)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 ******************************************************************************/
BNEP_SetTraceLevel(uint8_t new_level)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 ******************************************************************************/
BNEP_GetStatus(uint16_t handle,tBNEP_STATUS * p_status)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