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