• 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 "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