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