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