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