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("%s length %d exceeded MTU %d", __func__, 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, p_buf->len) != 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 if ((new_len + 2) > org_len) {
365 osi_free(p_buf);
366 return BNEP_IGNORE_CMD;
367 }
368
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 if (new_len > org_len) return BNEP_IGNORE_CMD;
387 p_data[2] = 0;
388 p_data[3] = 0;
389 }
390 p_buf->len = new_len;
391 } else {
392 osi_free(p_buf);
393 return BNEP_IGNORE_CMD;
394 }
395 }
396
397 /* Check transmit queue */
398 if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) {
399 osi_free(p_buf);
400 return (BNEP_Q_SIZE_EXCEEDED);
401 }
402
403 /* Build the BNEP header */
404 bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr,
405 fw_ext_present);
406
407 /* Send the data or queue it up */
408 bnepu_check_send_packet(p_bcb, p_buf);
409
410 return (BNEP_SUCCESS);
411 }
412
413 /*******************************************************************************
414 *
415 * Function BNEP_Write
416 *
417 * Description This function sends data over a BNEP connection
418 *
419 * Parameters: handle - handle of the connection to write
420 * p_dest_addr - BD_ADDR/Ethernet addr of the destination
421 * p_data - pointer to data start
422 * protocol - protocol type of the packet
423 * p_src_addr - (optional) BD_ADDR/ethernet address of the
424 * source
425 * (should be NULL if it is local BD Addr)
426 * fw_ext_present - forwarded extensions present
427 *
428 * Returns: BNEP_WRONG_HANDLE - if passed handle is not valid
429 * BNEP_MTU_EXCEDED - If the data length is greater than
430 * the MTU
431 * BNEP_IGNORE_CMD - If the packet is filtered out
432 * BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full
433 * BNEP_NO_RESOURCES - If not able to allocate a buffer
434 * BNEP_SUCCESS - If written successfully
435 *
436 ******************************************************************************/
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)437 tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr,
438 uint8_t* p_data, uint16_t len, uint16_t protocol,
439 const RawAddress* p_src_addr, bool fw_ext_present) {
440 tBNEP_CONN* p_bcb;
441 uint8_t* p;
442
443 /* Check MTU size. Consider the possibility of having extension headers */
444 if (len > BNEP_MTU_SIZE) {
445 BNEP_TRACE_ERROR("%s length %d exceeded MTU %d", __func__, len,
446 BNEP_MTU_SIZE);
447 return (BNEP_MTU_EXCEDED);
448 }
449
450 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
451
452 p_bcb = &(bnep_cb.bcb[handle - 1]);
453
454 /* Check if the packet should be filtered out */
455 if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present,
456 p_data, len) != BNEP_SUCCESS) {
457 /*
458 ** If packet is filtered and ext headers are present
459 ** drop the data and forward the ext headers
460 */
461 if (fw_ext_present) {
462 uint8_t ext, length;
463 uint16_t org_len, new_len;
464 /* parse the extension headers and findout the new packet len */
465 org_len = len;
466 new_len = 0;
467 p = p_data;
468 do {
469 if ((new_len + 2) > org_len) {
470 return BNEP_IGNORE_CMD;
471 }
472
473 ext = *p_data++;
474 length = *p_data++;
475 p_data += length;
476
477 new_len += (length + 2);
478
479 if (new_len > org_len) return BNEP_IGNORE_CMD;
480
481 } while (ext & 0x80);
482
483 if (protocol != BNEP_802_1_P_PROTOCOL)
484 protocol = 0;
485 else {
486 new_len += 4;
487 if (new_len > org_len) return BNEP_IGNORE_CMD;
488 p_data[2] = 0;
489 p_data[3] = 0;
490 }
491 len = new_len;
492 p_data = p;
493 } else
494 return BNEP_IGNORE_CMD;
495 }
496
497 /* Check transmit queue */
498 if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH)
499 return (BNEP_Q_SIZE_EXCEEDED);
500
501 /* Get a buffer to copy the data into */
502 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
503
504 p_buf->len = len;
505 p_buf->offset = BNEP_MINIMUM_OFFSET;
506 p = (uint8_t*)(p_buf + 1) + BNEP_MINIMUM_OFFSET;
507
508 memcpy(p, p_data, len);
509
510 /* Build the BNEP header */
511 bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr,
512 fw_ext_present);
513
514 /* Send the data or queue it up */
515 bnepu_check_send_packet(p_bcb, p_buf);
516
517 return (BNEP_SUCCESS);
518 }
519
520 /*******************************************************************************
521 *
522 * Function BNEP_SetProtocolFilters
523 *
524 * Description This function sets the protocol filters on peer device
525 *
526 * Parameters: handle - Handle for the connection
527 * num_filters - total number of filter ranges
528 * p_start_array - Array of beginings of all protocol ranges
529 * p_end_array - Array of ends of all protocol ranges
530 *
531 * Returns BNEP_WRONG_HANDLE - if the connection handle is
532 * not valid
533 * BNEP_SET_FILTER_FAIL - if the connection is in wrong
534 * state
535 * BNEP_TOO_MANY_FILTERS - if too many filters
536 * BNEP_SUCCESS - if request sent successfully
537 *
538 ******************************************************************************/
BNEP_SetProtocolFilters(uint16_t handle,uint16_t num_filters,uint16_t * p_start_array,uint16_t * p_end_array)539 tBNEP_RESULT BNEP_SetProtocolFilters(uint16_t handle, uint16_t num_filters,
540 uint16_t* p_start_array,
541 uint16_t* p_end_array) {
542 uint16_t xx;
543 tBNEP_CONN* p_bcb;
544
545 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
546
547 p_bcb = &(bnep_cb.bcb[handle - 1]);
548
549 /* Check the connection state */
550 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
551 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
552 return (BNEP_WRONG_STATE);
553
554 /* Validate the parameters */
555 if (num_filters && (!p_start_array || !p_end_array))
556 return (BNEP_SET_FILTER_FAIL);
557
558 if (num_filters > BNEP_MAX_PROT_FILTERS) return (BNEP_TOO_MANY_FILTERS);
559
560 /* Fill the filter values in connnection block */
561 for (xx = 0; xx < num_filters; xx++) {
562 p_bcb->sent_prot_filter_start[xx] = *p_start_array++;
563 p_bcb->sent_prot_filter_end[xx] = *p_end_array++;
564 }
565
566 p_bcb->sent_num_filters = num_filters;
567
568 bnepu_send_peer_our_filters(p_bcb);
569
570 return (BNEP_SUCCESS);
571 }
572
573 /*******************************************************************************
574 *
575 * Function BNEP_SetMulticastFilters
576 *
577 * Description This function sets the filters for multicast addresses for
578 * BNEP.
579 *
580 * Parameters: handle - Handle for the connection
581 * num_filters - total number of filter ranges
582 * p_start_array - Pointer to sequence of beginings of all
583 * multicast address ranges
584 * p_end_array - Pointer to sequence of ends of all
585 * multicast address ranges
586 *
587 * Returns BNEP_WRONG_HANDLE - if the connection handle is
588 * not valid
589 * BNEP_SET_FILTER_FAIL - if the connection is in wrong
590 * state
591 * BNEP_TOO_MANY_FILTERS - if too many filters
592 * BNEP_SUCCESS - if request sent successfully
593 *
594 ******************************************************************************/
BNEP_SetMulticastFilters(uint16_t handle,uint16_t num_filters,uint8_t * p_start_array,uint8_t * p_end_array)595 tBNEP_RESULT BNEP_SetMulticastFilters(uint16_t handle, uint16_t num_filters,
596 uint8_t* p_start_array,
597 uint8_t* p_end_array) {
598 uint16_t xx;
599 tBNEP_CONN* p_bcb;
600
601 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
602
603 p_bcb = &(bnep_cb.bcb[handle - 1]);
604
605 /* Check the connection state */
606 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
607 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
608 return (BNEP_WRONG_STATE);
609
610 /* Validate the parameters */
611 if (num_filters && (!p_start_array || !p_end_array))
612 return (BNEP_SET_FILTER_FAIL);
613
614 if (num_filters > BNEP_MAX_MULTI_FILTERS) return (BNEP_TOO_MANY_FILTERS);
615
616 /* Fill the multicast filter values in connnection block */
617 for (xx = 0; xx < num_filters; xx++) {
618 memcpy(p_bcb->sent_mcast_filter_start[xx].address, p_start_array,
619 BD_ADDR_LEN);
620 memcpy(p_bcb->sent_mcast_filter_end[xx].address, p_end_array, BD_ADDR_LEN);
621
622 p_start_array += BD_ADDR_LEN;
623 p_end_array += BD_ADDR_LEN;
624 }
625
626 p_bcb->sent_mcast_filters = num_filters;
627
628 bnepu_send_peer_our_multi_filters(p_bcb);
629
630 return (BNEP_SUCCESS);
631 }
632
633 /*******************************************************************************
634 *
635 * Function BNEP_SetTraceLevel
636 *
637 * Description This function sets the trace level for BNEP. If called with
638 * a value of 0xFF, it simply reads the current trace level.
639 *
640 * Returns the new (current) trace level
641 *
642 ******************************************************************************/
BNEP_SetTraceLevel(uint8_t new_level)643 uint8_t BNEP_SetTraceLevel(uint8_t new_level) {
644 if (new_level != 0xFF) bnep_cb.trace_level = new_level;
645
646 return (bnep_cb.trace_level);
647 }
648
649 /*******************************************************************************
650 *
651 * Function BNEP_GetStatus
652 *
653 * Description This function gets the status information for BNEP
654 * connection
655 *
656 * Returns BNEP_SUCCESS - if the status is available
657 * BNEP_NO_RESOURCES - if no structure is passed for
658 * output
659 * BNEP_WRONG_HANDLE - if the handle is invalid
660 * BNEP_WRONG_STATE - if not in connected state
661 *
662 ******************************************************************************/
BNEP_GetStatus(uint16_t handle,tBNEP_STATUS * p_status)663 tBNEP_RESULT BNEP_GetStatus(uint16_t handle, tBNEP_STATUS* p_status) {
664 #if (BNEP_SUPPORTS_STATUS_API == TRUE)
665 tBNEP_CONN* p_bcb;
666
667 if (!p_status) return BNEP_NO_RESOURCES;
668
669 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
670
671 p_bcb = &(bnep_cb.bcb[handle - 1]);
672
673 memset(p_status, 0, sizeof(tBNEP_STATUS));
674 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
675 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
676 return BNEP_WRONG_STATE;
677
678 /* Read the status parameters from the connection control block */
679 p_status->con_status = BNEP_STATUS_CONNECTED;
680 p_status->l2cap_cid = p_bcb->l2cap_cid;
681 p_status->rem_mtu_size = p_bcb->rem_mtu_size;
682 p_status->xmit_q_depth = fixed_queue_length(p_bcb->xmit_q);
683 p_status->sent_num_filters = p_bcb->sent_num_filters;
684 p_status->sent_mcast_filters = p_bcb->sent_mcast_filters;
685 p_status->rcvd_num_filters = p_bcb->rcvd_num_filters;
686 p_status->rcvd_mcast_filters = p_bcb->rcvd_mcast_filters;
687
688 p_status->rem_bda = p_bcb->rem_bda;
689 p_status->src_uuid = p_bcb->src_uuid;
690 p_status->dst_uuid = p_bcb->dst_uuid;
691
692 return BNEP_SUCCESS;
693 #else
694 return (BNEP_IGNORE_CMD);
695 #endif
696 }
697