• 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 BNEP utility functions
22  *
23  ******************************************************************************/
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include "gki.h"
28 #include "bt_types.h"
29 #include "bnep_int.h"
30 #include "btu.h"
31 #include "btm_int.h"
32 #include "bt_utils.h"
33 
34 
35 /********************************************************************************/
36 /*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
37 /********************************************************************************/
38 static UINT8 *bnepu_init_hdr (BT_HDR *p_buf, UINT16 hdr_len, UINT8 pkt_type);
39 
40 void bnepu_process_peer_multicast_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len);
41 void bnepu_send_peer_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code);
42 
43 
44 /*******************************************************************************
45 **
46 ** Function         bnepu_find_bcb_by_cid
47 **
48 ** Description      This function searches the bcb table for an entry with the
49 **                  passed CID.
50 **
51 ** Returns          the BCB address, or NULL if not found.
52 **
53 *******************************************************************************/
bnepu_find_bcb_by_cid(UINT16 cid)54 tBNEP_CONN *bnepu_find_bcb_by_cid (UINT16 cid)
55 {
56     UINT16          xx;
57     tBNEP_CONN     *p_bcb;
58 
59     /* Look through each connection control block */
60     for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++)
61     {
62         if ((p_bcb->con_state != BNEP_STATE_IDLE) && (p_bcb->l2cap_cid == cid))
63             return (p_bcb);
64     }
65 
66     /* If here, not found */
67     return (NULL);
68 }
69 
70 
71 /*******************************************************************************
72 **
73 ** Function         bnepu_find_bcb_by_bd_addr
74 **
75 ** Description      This function searches the BCB table for an entry with the
76 **                  passed Bluetooth Address.
77 **
78 ** Returns          the BCB address, or NULL if not found.
79 **
80 *******************************************************************************/
bnepu_find_bcb_by_bd_addr(UINT8 * p_bda)81 tBNEP_CONN *bnepu_find_bcb_by_bd_addr (UINT8 *p_bda)
82 {
83     UINT16          xx;
84     tBNEP_CONN     *p_bcb;
85 
86     /* Look through each connection control block */
87     for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++)
88     {
89         if (p_bcb->con_state != BNEP_STATE_IDLE)
90         {
91             if (!memcmp ((UINT8 *)(p_bcb->rem_bda), p_bda, BD_ADDR_LEN))
92                 return (p_bcb);
93         }
94     }
95 
96     /* If here, not found */
97     return (NULL);
98 }
99 
100 
101 /*******************************************************************************
102 **
103 ** Function         bnepu_allocate_bcb
104 **
105 ** Description      This function allocates a new BCB.
106 **
107 ** Returns          BCB address, or NULL if none available.
108 **
109 *******************************************************************************/
bnepu_allocate_bcb(BD_ADDR p_rem_bda)110 tBNEP_CONN *bnepu_allocate_bcb (BD_ADDR p_rem_bda)
111 {
112     UINT16          xx;
113     tBNEP_CONN     *p_bcb;
114 
115     /* Look through each connection control block for a free one */
116     for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++)
117     {
118         if (p_bcb->con_state == BNEP_STATE_IDLE)
119         {
120             memset ((UINT8 *)p_bcb, 0, sizeof (tBNEP_CONN));
121 
122             p_bcb->conn_tle.param = (UINT32) p_bcb;
123 
124             memcpy ((UINT8 *)(p_bcb->rem_bda), (UINT8 *)p_rem_bda, BD_ADDR_LEN);
125             p_bcb->handle = xx + 1;
126 
127             return (p_bcb);
128         }
129     }
130 
131     /* If here, no free BCB found */
132     return (NULL);
133 }
134 
135 
136 /*******************************************************************************
137 **
138 ** Function         bnepu_release_bcb
139 **
140 ** Description      This function releases a BCB.
141 **
142 ** Returns          void
143 **
144 *******************************************************************************/
bnepu_release_bcb(tBNEP_CONN * p_bcb)145 void bnepu_release_bcb (tBNEP_CONN *p_bcb)
146 {
147     /* Ensure timer is stopped */
148     btu_stop_timer (&p_bcb->conn_tle);
149 
150     /* Drop any response pointer we may be holding */
151     p_bcb->con_state        = BNEP_STATE_IDLE;
152     p_bcb->p_pending_data   = NULL;
153 
154     /* Free transmit queue */
155     while (p_bcb->xmit_q.count)
156     {
157         GKI_freebuf (GKI_dequeue (&p_bcb->xmit_q));
158     }
159 }
160 
161 
162 /*******************************************************************************
163 **
164 ** Function         bnep_send_conn_req
165 **
166 ** Description      This function sends a BNEP connection request to peer
167 **
168 ** Returns          void
169 **
170 *******************************************************************************/
bnep_send_conn_req(tBNEP_CONN * p_bcb)171 void bnep_send_conn_req (tBNEP_CONN *p_bcb)
172 {
173     BT_HDR  *p_buf;
174     UINT8   *p, *p_start;
175 
176     BNEP_TRACE_DEBUG ("%s: sending setup req with dst uuid %x",
177         __func__, p_bcb->dst_uuid.uu.uuid16);
178     if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL)
179     {
180         BNEP_TRACE_ERROR ("%s: not able to send connection request", __func__);
181         return;
182     }
183 
184     p_buf->offset = L2CAP_MIN_OFFSET;
185     p = p_start = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
186 
187     /* Put in BNEP frame type - filter control */
188     UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
189 
190     /* Put in filter message type - set filters */
191     UINT8_TO_BE_STREAM (p, BNEP_SETUP_CONNECTION_REQUEST_MSG);
192 
193     UINT8_TO_BE_STREAM (p, p_bcb->dst_uuid.len);
194 
195     if (p_bcb->dst_uuid.len == 2)
196     {
197         UINT16_TO_BE_STREAM (p, p_bcb->dst_uuid.uu.uuid16);
198         UINT16_TO_BE_STREAM (p, p_bcb->src_uuid.uu.uuid16);
199     }
200 #if (defined (BNEP_SUPPORTS_ALL_UUID_LENGTHS) && BNEP_SUPPORTS_ALL_UUID_LENGTHS == TRUE)
201     else if (p_bcb->dst_uuid.len == 4)
202     {
203         UINT32_TO_BE_STREAM (p, p_bcb->dst_uuid.uu.uuid32);
204         UINT32_TO_BE_STREAM (p, p_bcb->src_uuid.uu.uuid32);
205     }
206     else if (p_bcb->dst_uuid.len == 16)
207     {
208         memcpy (p, p_bcb->dst_uuid.uu.uuid128, p_bcb->dst_uuid.len);
209         p += p_bcb->dst_uuid.len;
210         memcpy (p, p_bcb->src_uuid.uu.uuid128, p_bcb->dst_uuid.len);
211         p += p_bcb->dst_uuid.len;
212     }
213 #endif
214     else
215     {
216         BNEP_TRACE_ERROR ("%s: uuid: %x, invalid length: %x",
217             __func__, p_bcb->dst_uuid.uu.uuid16, p_bcb->dst_uuid.len);
218     }
219 
220     p_buf->len = (UINT16)(p - p_start);
221 
222     bnepu_check_send_packet (p_bcb, p_buf);
223 }
224 
225 
226 /*******************************************************************************
227 **
228 ** Function         bnep_send_conn_responce
229 **
230 ** Description      This function sends a BNEP setup response to peer
231 **
232 ** Returns          void
233 **
234 *******************************************************************************/
bnep_send_conn_responce(tBNEP_CONN * p_bcb,UINT16 resp_code)235 void bnep_send_conn_responce (tBNEP_CONN *p_bcb, UINT16 resp_code)
236 {
237     BT_HDR  *p_buf;
238     UINT8   *p;
239 
240     BNEP_TRACE_EVENT ("BNEP - bnep_send_conn_responce for CID: 0x%x", p_bcb->l2cap_cid);
241     if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL)
242     {
243         BNEP_TRACE_ERROR ("BNEP - not able to send connection response");
244         return;
245     }
246 
247     p_buf->offset = L2CAP_MIN_OFFSET;
248     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
249 
250     /* Put in BNEP frame type - filter control */
251     UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
252 
253     /* Put in filter message type - set filters */
254     UINT8_TO_BE_STREAM (p, BNEP_SETUP_CONNECTION_RESPONSE_MSG);
255 
256     UINT16_TO_BE_STREAM (p, resp_code);
257 
258     p_buf->len = 4;
259 
260     bnepu_check_send_packet (p_bcb, p_buf);
261 
262 }
263 
264 
265 /*******************************************************************************
266 **
267 ** Function         bnepu_send_peer_our_filters
268 **
269 ** Description      This function sends our filters to a peer
270 **
271 ** Returns          void
272 **
273 *******************************************************************************/
bnepu_send_peer_our_filters(tBNEP_CONN * p_bcb)274 void bnepu_send_peer_our_filters (tBNEP_CONN *p_bcb)
275 {
276 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE)
277     BT_HDR      *p_buf;
278     UINT8       *p;
279     UINT16      xx;
280 
281     BNEP_TRACE_DEBUG ("BNEP sending peer our filters");
282 
283     if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL)
284     {
285         BNEP_TRACE_ERROR ("BNEP - no buffer send filters");
286         return;
287     }
288 
289     p_buf->offset = L2CAP_MIN_OFFSET;
290     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
291 
292     /* Put in BNEP frame type - filter control */
293     UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
294 
295     /* Put in filter message type - set filters */
296     UINT8_TO_BE_STREAM (p, BNEP_FILTER_NET_TYPE_SET_MSG);
297 
298     UINT16_TO_BE_STREAM (p, (4 * p_bcb->sent_num_filters));
299     for (xx = 0; xx < p_bcb->sent_num_filters; xx++)
300     {
301         UINT16_TO_BE_STREAM (p, p_bcb->sent_prot_filter_start[xx]);
302         UINT16_TO_BE_STREAM (p, p_bcb->sent_prot_filter_end[xx]);
303     }
304 
305     p_buf->len = 4 + (4 * p_bcb->sent_num_filters);
306 
307     bnepu_check_send_packet (p_bcb, p_buf);
308 
309     p_bcb->con_flags |= BNEP_FLAGS_FILTER_RESP_PEND;
310 
311     /* Start timer waiting for setup response */
312     btu_start_timer (&p_bcb->conn_tle, BTU_TTYPE_BNEP, BNEP_FILTER_SET_TIMEOUT);
313 #endif
314 }
315 
316 
317 /*******************************************************************************
318 **
319 ** Function         bnepu_send_peer_our_multi_filters
320 **
321 ** Description      This function sends our multicast filters to a peer
322 **
323 ** Returns          void
324 **
325 *******************************************************************************/
bnepu_send_peer_our_multi_filters(tBNEP_CONN * p_bcb)326 void bnepu_send_peer_our_multi_filters (tBNEP_CONN *p_bcb)
327 {
328 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE)
329     BT_HDR      *p_buf;
330     UINT8       *p;
331     UINT16      xx;
332 
333     BNEP_TRACE_DEBUG ("BNEP sending peer our multicast filters");
334 
335     if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL)
336     {
337         BNEP_TRACE_ERROR ("BNEP - no buffer to send multicast filters");
338         return;
339     }
340 
341     p_buf->offset = L2CAP_MIN_OFFSET;
342     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
343 
344     /* Put in BNEP frame type - filter control */
345     UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
346 
347     /* Put in filter message type - set filters */
348     UINT8_TO_BE_STREAM (p, BNEP_FILTER_MULTI_ADDR_SET_MSG);
349 
350     UINT16_TO_BE_STREAM (p, (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters));
351     for (xx = 0; xx < p_bcb->sent_mcast_filters; xx++)
352     {
353         memcpy (p, p_bcb->sent_mcast_filter_start[xx], BD_ADDR_LEN);
354         p += BD_ADDR_LEN;
355         memcpy (p, p_bcb->sent_mcast_filter_end[xx], BD_ADDR_LEN);
356         p += BD_ADDR_LEN;
357     }
358 
359     p_buf->len = 4 + (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters);
360 
361     bnepu_check_send_packet (p_bcb, p_buf);
362 
363     p_bcb->con_flags |= BNEP_FLAGS_MULTI_RESP_PEND;
364 
365     /* Start timer waiting for setup response */
366     btu_start_timer (&p_bcb->conn_tle, BTU_TTYPE_BNEP, BNEP_FILTER_SET_TIMEOUT);
367 #endif
368 }
369 
370 
371 /*******************************************************************************
372 **
373 ** Function         bnepu_send_peer_filter_rsp
374 **
375 ** Description      This function sends a filter response to a peer
376 **
377 ** Returns          void
378 **
379 *******************************************************************************/
bnepu_send_peer_filter_rsp(tBNEP_CONN * p_bcb,UINT16 response_code)380 void bnepu_send_peer_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code)
381 {
382     BT_HDR  *p_buf;
383     UINT8   *p;
384 
385     BNEP_TRACE_DEBUG ("BNEP sending filter response");
386     if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL)
387     {
388         BNEP_TRACE_ERROR ("BNEP - no buffer filter rsp");
389         return;
390     }
391 
392     p_buf->offset = L2CAP_MIN_OFFSET;
393     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
394 
395     /* Put in BNEP frame type - filter control */
396     UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
397 
398     /* Put in filter message type - set filters */
399     UINT8_TO_BE_STREAM (p, BNEP_FILTER_NET_TYPE_RESPONSE_MSG);
400 
401     UINT16_TO_BE_STREAM (p, response_code);
402 
403     p_buf->len = 4;
404 
405     bnepu_check_send_packet (p_bcb, p_buf);
406 }
407 
408 
409 /*******************************************************************************
410 **
411 ** Function         bnep_send_command_not_understood
412 **
413 ** Description      This function sends a BNEP command not understood message
414 **
415 ** Returns          void
416 **
417 *******************************************************************************/
bnep_send_command_not_understood(tBNEP_CONN * p_bcb,UINT8 cmd_code)418 void bnep_send_command_not_understood (tBNEP_CONN *p_bcb, UINT8 cmd_code)
419 {
420     BT_HDR  *p_buf;
421     UINT8   *p;
422 
423     BNEP_TRACE_EVENT ("BNEP - bnep_send_command_not_understood for CID: 0x%x, cmd 0x%x", p_bcb->l2cap_cid, cmd_code);
424     if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL)
425     {
426         BNEP_TRACE_ERROR ("BNEP - not able to send connection response");
427         return;
428     }
429 
430     p_buf->offset = L2CAP_MIN_OFFSET;
431     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
432 
433     /* Put in BNEP frame type - filter control */
434     UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
435 
436     /* Put in filter message type - set filters */
437     UINT8_TO_BE_STREAM (p, BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD);
438 
439     UINT8_TO_BE_STREAM (p, cmd_code);
440 
441     p_buf->len = 3;
442 
443     bnepu_check_send_packet (p_bcb, p_buf);
444 
445 }
446 
447 
448 /*******************************************************************************
449 **
450 ** Function         bnepu_check_send_packet
451 **
452 ** Description      This function tries to send a packet to L2CAP.
453 **                  If L2CAP is flow controlled, it enqueues the
454 **                  packet to the transmit queue
455 **
456 ** Returns          void
457 **
458 *******************************************************************************/
bnepu_check_send_packet(tBNEP_CONN * p_bcb,BT_HDR * p_buf)459 void bnepu_check_send_packet (tBNEP_CONN *p_bcb, BT_HDR *p_buf)
460 {
461     BNEP_TRACE_EVENT ("BNEP - bnepu_check_send_packet for CID: 0x%x", p_bcb->l2cap_cid);
462     if (p_bcb->con_flags & BNEP_FLAGS_L2CAP_CONGESTED)
463     {
464         if (p_bcb->xmit_q.count >= BNEP_MAX_XMITQ_DEPTH)
465         {
466             BNEP_TRACE_EVENT ("BNEP - congested, dropping buf, CID: 0x%x", p_bcb->l2cap_cid);
467 
468             GKI_freebuf (p_buf);
469         }
470         else
471         {
472             GKI_enqueue (&p_bcb->xmit_q, p_buf);
473         }
474     }
475     else
476     {
477         L2CA_DataWrite (p_bcb->l2cap_cid, p_buf);
478     }
479 }
480 
481 
482 /*******************************************************************************
483 **
484 ** Function         bnepu_build_bnep_hdr
485 **
486 ** Description      This function builds the BNEP header for a packet
487 **                  Extension headers are not sent yet, so there is no
488 **                  check for that.
489 **
490 ** Returns          void
491 **
492 *******************************************************************************/
bnepu_build_bnep_hdr(tBNEP_CONN * p_bcb,BT_HDR * p_buf,UINT16 protocol,UINT8 * p_src_addr,UINT8 * p_dest_addr,BOOLEAN fw_ext_present)493 void bnepu_build_bnep_hdr (tBNEP_CONN *p_bcb, BT_HDR *p_buf, UINT16 protocol,
494                            UINT8 *p_src_addr, UINT8 *p_dest_addr, BOOLEAN fw_ext_present)
495 {
496     UINT8    ext_bit, *p = (UINT8 *)NULL;
497     UINT8    type = BNEP_FRAME_COMPRESSED_ETHERNET;
498 
499     ext_bit = fw_ext_present ? 0x80 : 0x00;
500 
501     if ((p_src_addr) && (memcmp (p_src_addr, bnep_cb.my_bda, BD_ADDR_LEN)))
502         type = BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY;
503 
504     if (memcmp (p_dest_addr, p_bcb->rem_bda, BD_ADDR_LEN))
505         type = (type == BNEP_FRAME_COMPRESSED_ETHERNET) ? BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY : BNEP_FRAME_GENERAL_ETHERNET;
506 
507     if (!p_src_addr)
508         p_src_addr = (UINT8 *)bnep_cb.my_bda;
509 
510     switch (type)
511     {
512     case BNEP_FRAME_GENERAL_ETHERNET:
513         p = bnepu_init_hdr (p_buf, 15, (UINT8)(ext_bit | BNEP_FRAME_GENERAL_ETHERNET));
514 
515         memcpy (p, p_dest_addr, BD_ADDR_LEN);
516         p += BD_ADDR_LEN;
517 
518         memcpy (p, p_src_addr, BD_ADDR_LEN);
519         p += BD_ADDR_LEN;
520         break;
521 
522     case BNEP_FRAME_COMPRESSED_ETHERNET:
523         p = bnepu_init_hdr (p_buf, 3, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET));
524         break;
525 
526     case BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY:
527         p = bnepu_init_hdr (p_buf, 9, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY));
528 
529         memcpy (p, p_src_addr, BD_ADDR_LEN);
530         p += BD_ADDR_LEN;
531         break;
532 
533     case BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY:
534         p = bnepu_init_hdr (p_buf, 9, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY));
535 
536         memcpy (p, p_dest_addr, BD_ADDR_LEN);
537         p += BD_ADDR_LEN;
538         break;
539     }
540 
541     UINT16_TO_BE_STREAM (p, protocol);
542 }
543 
544 
545 /*******************************************************************************
546 **
547 ** Function         bnepu_init_hdr
548 **
549 ** Description      This function initializes the BNEP header
550 **
551 ** Returns          pointer to header in buffer
552 **
553 *******************************************************************************/
bnepu_init_hdr(BT_HDR * p_buf,UINT16 hdr_len,UINT8 pkt_type)554 static UINT8 *bnepu_init_hdr (BT_HDR *p_buf, UINT16 hdr_len, UINT8 pkt_type)
555 {
556     UINT8    *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
557 
558     /* See if we need to make space in the buffer */
559     if (p_buf->offset < (hdr_len + L2CAP_MIN_OFFSET))
560     {
561         UINT16 xx, diff = BNEP_MINIMUM_OFFSET - p_buf->offset;
562         p = p + p_buf->len - 1;
563         for (xx = 0; xx < p_buf->len; xx++, p--)
564             p[diff] = *p;
565 
566         p_buf->offset = BNEP_MINIMUM_OFFSET;
567         p = (UINT8 *)(p_buf + 1) + p_buf->offset;
568     }
569 
570     p_buf->len    += hdr_len;
571     p_buf->offset -= hdr_len;
572     p             -= hdr_len;
573 
574     *p++ = pkt_type;
575 
576     return (p);
577 }
578 
579 
580 /*******************************************************************************
581 **
582 ** Function         bnep_process_setup_conn_req
583 **
584 ** Description      This function processes a peer's setup connection request
585 **                  message. The destination UUID is verified and response sent
586 **                  Connection open indication will be given to PAN profile
587 **
588 ** Returns          void
589 **
590 *******************************************************************************/
bnep_process_setup_conn_req(tBNEP_CONN * p_bcb,UINT8 * p_setup,UINT8 len)591 void bnep_process_setup_conn_req (tBNEP_CONN *p_bcb, UINT8 *p_setup, UINT8 len)
592 {
593     BNEP_TRACE_EVENT ("BNEP - bnep_process_setup_conn_req for CID: 0x%x", p_bcb->l2cap_cid);
594 
595     if (p_bcb->con_state != BNEP_STATE_CONN_SETUP &&
596         p_bcb->con_state != BNEP_STATE_SEC_CHECKING &&
597         p_bcb->con_state != BNEP_STATE_CONNECTED)
598     {
599         BNEP_TRACE_ERROR ("BNEP - setup request in bad state %d", p_bcb->con_state);
600         bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
601         return;
602     }
603 
604     /* Check if we already initiated security check or if waiting for user responce */
605     if (p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)
606     {
607         BNEP_TRACE_EVENT ("BNEP - Duplicate Setup message received while doing security check");
608         return;
609     }
610 
611     /* Check if peer is the originator */
612     if (p_bcb->con_state != BNEP_STATE_CONNECTED &&
613         (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) &&
614         (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG))
615     {
616         BNEP_TRACE_ERROR ("BNEP - setup request when we are originator", p_bcb->con_state);
617         bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
618         return;
619     }
620 
621     if (p_bcb->con_state == BNEP_STATE_CONNECTED)
622     {
623         memcpy ((UINT8 *)&(p_bcb->prv_src_uuid), (UINT8 *)&(p_bcb->src_uuid), sizeof (tBT_UUID));
624         memcpy ((UINT8 *)&(p_bcb->prv_dst_uuid), (UINT8 *)&(p_bcb->dst_uuid), sizeof (tBT_UUID));
625     }
626 
627     p_bcb->dst_uuid.len = p_bcb->src_uuid.len = len;
628 
629     if (p_bcb->dst_uuid.len == 2)
630     {
631         /* because peer initiated connection keep src uuid as dst uuid */
632         BE_STREAM_TO_UINT16 (p_bcb->src_uuid.uu.uuid16, p_setup);
633         BE_STREAM_TO_UINT16 (p_bcb->dst_uuid.uu.uuid16, p_setup);
634 
635         /* If nothing has changed don't bother the profile */
636         if (p_bcb->con_state == BNEP_STATE_CONNECTED &&
637             p_bcb->src_uuid.uu.uuid16 == p_bcb->prv_src_uuid.uu.uuid16 &&
638             p_bcb->dst_uuid.uu.uuid16 == p_bcb->prv_dst_uuid.uu.uuid16)
639         {
640             bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_OK);
641             return;
642         }
643     }
644 #if (defined (BNEP_SUPPORTS_ALL_UUID_LENGTHS) && BNEP_SUPPORTS_ALL_UUID_LENGTHS == TRUE)
645     else if (p_bcb->dst_uuid.len == 4)
646     {
647         BE_STREAM_TO_UINT32 (p_bcb->src_uuid.uu.uuid32, p_setup);
648         BE_STREAM_TO_UINT32 (p_bcb->dst_uuid.uu.uuid32, p_setup);
649     }
650     else if (p_bcb->dst_uuid.len == 16)
651     {
652         memcpy (p_bcb->src_uuid.uu.uuid128, p_setup, p_bcb->src_uuid.len);
653         p_setup += p_bcb->src_uuid.len;
654         memcpy (p_bcb->dst_uuid.uu.uuid128, p_setup, p_bcb->dst_uuid.len);
655         p_setup += p_bcb->dst_uuid.len;
656     }
657 #endif
658     else
659     {
660         BNEP_TRACE_ERROR ("BNEP - Bad UID len %d in ConnReq", p_bcb->dst_uuid.len);
661         bnep_send_conn_responce (p_bcb, BNEP_SETUP_INVALID_UUID_SIZE);
662         return;
663     }
664 
665     p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
666     p_bcb->con_flags |= BNEP_FLAGS_SETUP_RCVD;
667 
668     BNEP_TRACE_EVENT ("BNEP initiating security check for incoming call for uuid 0x%x", p_bcb->src_uuid.uu.uuid16);
669 #if (!defined (BNEP_DO_AUTH_FOR_ROLE_SWITCH) || BNEP_DO_AUTH_FOR_ROLE_SWITCH == FALSE)
670     if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
671         bnep_sec_check_complete (p_bcb->rem_bda, p_bcb, BTM_SUCCESS);
672     else
673 #endif
674     btm_sec_mx_access_request (p_bcb->rem_bda, BT_PSM_BNEP, FALSE,
675                                BTM_SEC_PROTO_BNEP, bnep_get_uuid32(&(p_bcb->src_uuid)),
676                                &bnep_sec_check_complete, p_bcb);
677 
678     return;
679 }
680 
681 
682 /*******************************************************************************
683 **
684 ** Function         bnep_process_setup_conn_responce
685 **
686 ** Description      This function processes a peer's setup connection response
687 **                  message. The response code is verified and
688 **                  Connection open indication will be given to PAN profile
689 **
690 ** Returns          void
691 **
692 *******************************************************************************/
bnep_process_setup_conn_responce(tBNEP_CONN * p_bcb,UINT8 * p_setup)693 void bnep_process_setup_conn_responce (tBNEP_CONN *p_bcb, UINT8 *p_setup)
694 {
695     tBNEP_RESULT    resp;
696     UINT16          resp_code;
697 
698     BNEP_TRACE_DEBUG ("BNEP received setup responce");
699     /* The state should be either SETUP or CONNECTED */
700     if (p_bcb->con_state != BNEP_STATE_CONN_SETUP)
701     {
702         /* Should we disconnect ? */
703         BNEP_TRACE_ERROR ("BNEP - setup response in bad state %d", p_bcb->con_state);
704         return;
705     }
706 
707     /* Check if we are the originator */
708     if (!(p_bcb->con_flags & BNEP_FLAGS_IS_ORIG))
709     {
710         BNEP_TRACE_ERROR ("BNEP - setup response when we are not originator", p_bcb->con_state);
711         return;
712     }
713 
714     BE_STREAM_TO_UINT16  (resp_code, p_setup);
715 
716     switch (resp_code)
717     {
718     case BNEP_SETUP_INVALID_SRC_UUID:
719         resp = BNEP_CONN_FAILED_SRC_UUID;
720         break;
721 
722     case BNEP_SETUP_INVALID_DEST_UUID:
723         resp = BNEP_CONN_FAILED_DST_UUID;
724         break;
725 
726     case BNEP_SETUP_INVALID_UUID_SIZE:
727         resp = BNEP_CONN_FAILED_UUID_SIZE;
728         break;
729 
730     case BNEP_SETUP_CONN_NOT_ALLOWED:
731     default:
732         resp = BNEP_CONN_FAILED;
733         break;
734     }
735 
736     /* Check the responce code */
737     if (resp_code != BNEP_SETUP_CONN_OK)
738     {
739         if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
740         {
741             BNEP_TRACE_EVENT ("BNEP - role change response is %d", resp_code);
742 
743             /* Restore the earlier BNEP status */
744             p_bcb->con_state = BNEP_STATE_CONNECTED;
745             p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
746             memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID));
747             memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID));
748 
749             /* Ensure timer is stopped */
750             btu_stop_timer (&p_bcb->conn_tle);
751             p_bcb->re_transmits = 0;
752 
753             /* Tell the user if he has a callback */
754             if (bnep_cb.p_conn_state_cb)
755                 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, resp, TRUE);
756 
757             return;
758         }
759         else
760         {
761             BNEP_TRACE_ERROR ("BNEP - setup response %d is not OK", resp_code);
762 
763             L2CA_DisconnectReq (p_bcb->l2cap_cid);
764 
765             /* Tell the user if he has a callback */
766             if ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) && (bnep_cb.p_conn_state_cb))
767                 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, resp, FALSE);
768 
769             bnepu_release_bcb (p_bcb);
770             return;
771         }
772     }
773 
774     /* Received successful responce */
775     bnep_connected (p_bcb);
776 }
777 
778 
779 /*******************************************************************************
780 **
781 ** Function         bnep_process_control_packet
782 **
783 ** Description      This function processes a peer's setup connection request
784 **                  message. The destination UUID is verified and response sent
785 **                  Connection open indication will be given to PAN profile
786 **
787 ** Returns          void
788 **
789 *******************************************************************************/
bnep_process_control_packet(tBNEP_CONN * p_bcb,UINT8 * p,UINT16 * rem_len,BOOLEAN is_ext)790 UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len, BOOLEAN is_ext)
791 {
792     UINT8       control_type;
793     BOOLEAN     bad_pkt = FALSE;
794     UINT16      len, ext_len = 0;
795 
796     if (is_ext)
797     {
798         ext_len = *p++;
799         *rem_len = *rem_len - 1;
800     }
801 
802     control_type = *p++;
803     *rem_len = *rem_len - 1;
804 
805     BNEP_TRACE_EVENT ("BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d", *rem_len, is_ext, control_type);
806 
807     switch (control_type)
808     {
809     case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
810         BNEP_TRACE_ERROR ("BNEP Received Cmd not understood for ctl pkt type: %d", *p);
811         p++;
812         *rem_len = *rem_len - 1;
813         break;
814 
815     case BNEP_SETUP_CONNECTION_REQUEST_MSG:
816         len = *p++;
817         if (*rem_len < ((2 * len) + 1))
818         {
819             bad_pkt = TRUE;
820             BNEP_TRACE_ERROR ("BNEP Received Setup message with bad length");
821             break;
822         }
823         if (!is_ext)
824             bnep_process_setup_conn_req (p_bcb, p, (UINT8)len);
825         p += (2 * len);
826         *rem_len = *rem_len - (2 * len) - 1;
827         break;
828 
829     case BNEP_SETUP_CONNECTION_RESPONSE_MSG:
830         if (!is_ext)
831             bnep_process_setup_conn_responce (p_bcb, p);
832         p += 2;
833         *rem_len = *rem_len - 2;
834         break;
835 
836     case BNEP_FILTER_NET_TYPE_SET_MSG:
837         BE_STREAM_TO_UINT16 (len, p);
838         if (*rem_len < (len + 2))
839         {
840             bad_pkt = TRUE;
841             BNEP_TRACE_ERROR ("BNEP Received Filter set message with bad length");
842             break;
843         }
844         bnepu_process_peer_filter_set (p_bcb, p, len);
845         p += len;
846         *rem_len = *rem_len - len - 2;
847         break;
848 
849     case BNEP_FILTER_NET_TYPE_RESPONSE_MSG:
850         bnepu_process_peer_filter_rsp (p_bcb, p);
851         p += 2;
852         *rem_len = *rem_len - 2;
853         break;
854 
855     case BNEP_FILTER_MULTI_ADDR_SET_MSG:
856         BE_STREAM_TO_UINT16 (len, p);
857         if (*rem_len < (len + 2))
858         {
859             bad_pkt = TRUE;
860             BNEP_TRACE_ERROR ("BNEP Received Multicast Filter Set message with bad length");
861             break;
862         }
863         bnepu_process_peer_multicast_filter_set (p_bcb, p, len);
864         p += len;
865         *rem_len = *rem_len - len - 2;
866         break;
867 
868     case BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG:
869         bnepu_process_multicast_filter_rsp (p_bcb, p);
870         p += 2;
871         *rem_len = *rem_len - 2;
872         break;
873 
874     default :
875         BNEP_TRACE_ERROR ("BNEP - bad ctl pkt type: %d", control_type);
876         bnep_send_command_not_understood (p_bcb, control_type);
877         if (is_ext)
878         {
879             p += (ext_len - 1);
880             *rem_len -= (ext_len - 1);
881         }
882         break;
883     }
884 
885     if (bad_pkt)
886     {
887         BNEP_TRACE_ERROR ("BNEP - bad ctl pkt length: %d", *rem_len);
888         *rem_len = 0;
889         return NULL;
890     }
891 
892     return p;
893 }
894 
895 
896 /*******************************************************************************
897 **
898 ** Function         bnepu_process_peer_filter_set
899 **
900 ** Description      This function processes a peer's filter control
901 **                  'set' message. The filters are stored in the BCB,
902 **                  and an appropriate filter response message sent.
903 **
904 ** Returns          void
905 **
906 *******************************************************************************/
bnepu_process_peer_filter_set(tBNEP_CONN * p_bcb,UINT8 * p_filters,UINT16 len)907 void bnepu_process_peer_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len)
908 {
909 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE)
910     UINT16      num_filters = 0;
911     UINT16      xx, resp_code = BNEP_FILTER_CRL_OK;
912     UINT16      start, end;
913     UINT8       *p_temp_filters;
914 
915     if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
916         (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
917     {
918         BNEP_TRACE_DEBUG ("BNEP received filter set from peer when there is no connection");
919         return;
920     }
921 
922     BNEP_TRACE_DEBUG ("BNEP received filter set from peer");
923     /* Check for length not a multiple of 4 */
924     if (len & 3)
925     {
926         BNEP_TRACE_EVENT ("BNEP - bad filter len: %d", len);
927         bnepu_send_peer_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
928         return;
929     }
930 
931     if (len)
932         num_filters = (UINT16) (len >> 2);
933 
934     /* Validate filter values */
935     if (num_filters <= BNEP_MAX_PROT_FILTERS)
936     {
937         p_temp_filters = p_filters;
938         for (xx = 0; xx < num_filters; xx++)
939         {
940             BE_STREAM_TO_UINT16  (start, p_temp_filters);
941             BE_STREAM_TO_UINT16  (end,   p_temp_filters);
942 
943             if (start > end)
944             {
945                 resp_code = BNEP_FILTER_CRL_BAD_RANGE;
946                 break;
947             }
948         }
949     }
950     else
951         resp_code   = BNEP_FILTER_CRL_MAX_REACHED;
952 
953     if (resp_code != BNEP_FILTER_CRL_OK)
954     {
955         bnepu_send_peer_filter_rsp (p_bcb, resp_code);
956         return;
957     }
958 
959     if (bnep_cb.p_filter_ind_cb)
960         (*bnep_cb.p_filter_ind_cb) (p_bcb->handle, TRUE, 0, len, p_filters);
961 
962     p_bcb->rcvd_num_filters = num_filters;
963     for (xx = 0; xx < num_filters; xx++)
964     {
965         BE_STREAM_TO_UINT16  (start, p_filters);
966         BE_STREAM_TO_UINT16  (end,   p_filters);
967 
968         p_bcb->rcvd_prot_filter_start[xx] = start;
969         p_bcb->rcvd_prot_filter_end[xx]   = end;
970     }
971 
972     bnepu_send_peer_filter_rsp (p_bcb, resp_code);
973 #else
974     bnepu_send_peer_filter_rsp (p_bcb, BNEP_FILTER_CRL_UNSUPPORTED);
975 #endif
976 }
977 
978 
979 /*******************************************************************************
980 **
981 ** Function         bnepu_process_peer_filter_rsp
982 **
983 ** Description      This function processes a peer's filter control
984 **                  'response' message.
985 **
986 ** Returns          void
987 **
988 *******************************************************************************/
bnepu_process_peer_filter_rsp(tBNEP_CONN * p_bcb,UINT8 * p_data)989 void bnepu_process_peer_filter_rsp (tBNEP_CONN *p_bcb, UINT8 *p_data)
990 {
991 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE)
992     UINT16          resp_code;
993     tBNEP_RESULT    result;
994 
995     BNEP_TRACE_DEBUG ("BNEP received filter responce");
996     /* The state should be  CONNECTED */
997     if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
998         (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
999     {
1000         BNEP_TRACE_ERROR ("BNEP - filter response in bad state %d", p_bcb->con_state);
1001         return;
1002     }
1003 
1004     /* Check if we are the originator */
1005     if (!(p_bcb->con_flags & BNEP_FLAGS_FILTER_RESP_PEND))
1006     {
1007         BNEP_TRACE_ERROR ("BNEP - filter response when not expecting");
1008         return;
1009     }
1010 
1011     /* Ensure timer is stopped */
1012     btu_stop_timer (&p_bcb->conn_tle);
1013     p_bcb->con_flags &= ~BNEP_FLAGS_FILTER_RESP_PEND;
1014     p_bcb->re_transmits = 0;
1015 
1016     BE_STREAM_TO_UINT16  (resp_code, p_data);
1017 
1018     result = BNEP_SUCCESS;
1019     if (resp_code != BNEP_FILTER_CRL_OK)
1020         result = BNEP_SET_FILTER_FAIL;
1021 
1022     if (bnep_cb.p_filter_ind_cb)
1023         (*bnep_cb.p_filter_ind_cb) (p_bcb->handle, FALSE, result, 0, NULL);
1024 
1025     return;
1026 #endif
1027 }
1028 
1029 
1030 
1031 /*******************************************************************************
1032 **
1033 ** Function         bnepu_process_multicast_filter_rsp
1034 **
1035 ** Description      This function processes multicast filter control
1036 **                  'response' message.
1037 **
1038 ** Returns          void
1039 **
1040 *******************************************************************************/
bnepu_process_multicast_filter_rsp(tBNEP_CONN * p_bcb,UINT8 * p_data)1041 void bnepu_process_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT8 *p_data)
1042 {
1043 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE)
1044     UINT16          resp_code;
1045     tBNEP_RESULT    result;
1046 
1047     BNEP_TRACE_DEBUG ("BNEP received multicast filter responce");
1048     /* The state should be  CONNECTED */
1049     if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
1050         (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
1051     {
1052         BNEP_TRACE_ERROR ("BNEP - multicast filter response in bad state %d", p_bcb->con_state);
1053         return;
1054     }
1055 
1056     /* Check if we are the originator */
1057     if (!(p_bcb->con_flags & BNEP_FLAGS_MULTI_RESP_PEND))
1058     {
1059         BNEP_TRACE_ERROR ("BNEP - multicast filter response when not expecting");
1060         return;
1061     }
1062 
1063     /* Ensure timer is stopped */
1064     btu_stop_timer (&p_bcb->conn_tle);
1065     p_bcb->con_flags &= ~BNEP_FLAGS_MULTI_RESP_PEND;
1066     p_bcb->re_transmits = 0;
1067 
1068     BE_STREAM_TO_UINT16  (resp_code, p_data);
1069 
1070     result = BNEP_SUCCESS;
1071     if (resp_code != BNEP_FILTER_CRL_OK)
1072         result = BNEP_SET_FILTER_FAIL;
1073 
1074     if (bnep_cb.p_mfilter_ind_cb)
1075         (*bnep_cb.p_mfilter_ind_cb) (p_bcb->handle, FALSE, result, 0, NULL);
1076 
1077     return;
1078 #endif
1079 }
1080 
1081 
1082 
1083 /*******************************************************************************
1084 **
1085 ** Function         bnepu_process_peer_multicast_filter_set
1086 **
1087 ** Description      This function processes a peer's filter control
1088 **                  'set' message. The filters are stored in the BCB,
1089 **                  and an appropriate filter response message sent.
1090 **
1091 ** Returns          void
1092 **
1093 *******************************************************************************/
bnepu_process_peer_multicast_filter_set(tBNEP_CONN * p_bcb,UINT8 * p_filters,UINT16 len)1094 void bnepu_process_peer_multicast_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len)
1095 {
1096 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE)
1097     UINT16          resp_code = BNEP_FILTER_CRL_OK;
1098     UINT16          num_filters, xx;
1099     UINT8           *p_temp_filters, null_bda[BD_ADDR_LEN] = {0,0,0,0,0,0};
1100 
1101     if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
1102         (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
1103     {
1104         BNEP_TRACE_DEBUG ("BNEP received multicast filter set from peer when there is no connection");
1105         return;
1106     }
1107 
1108     if (len % 12)
1109     {
1110         BNEP_TRACE_EVENT ("BNEP - bad filter len: %d", len);
1111         bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
1112         return;
1113     }
1114 
1115     if (len > (BNEP_MAX_MULTI_FILTERS * 2 * BD_ADDR_LEN))
1116     {
1117         BNEP_TRACE_EVENT ("BNEP - Too many filters");
1118         bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_MAX_REACHED);
1119         return;
1120     }
1121 
1122     num_filters = 0;
1123     if (len)
1124         num_filters = (UINT16) (len / 12);
1125 
1126     /* Validate filter values */
1127     if (num_filters <= BNEP_MAX_MULTI_FILTERS)
1128     {
1129         p_temp_filters = p_filters;
1130         for (xx = 0; xx < num_filters; xx++)
1131         {
1132             if (memcmp (p_temp_filters, p_temp_filters + BD_ADDR_LEN, BD_ADDR_LEN) > 0)
1133             {
1134                 bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
1135                 return;
1136             }
1137 
1138             p_temp_filters += (BD_ADDR_LEN * 2);
1139         }
1140     }
1141 
1142     p_bcb->rcvd_mcast_filters = num_filters;
1143     for (xx = 0; xx < num_filters; xx++)
1144     {
1145         memcpy (p_bcb->rcvd_mcast_filter_start[xx], p_filters, BD_ADDR_LEN);
1146         memcpy (p_bcb->rcvd_mcast_filter_end[xx], p_filters + BD_ADDR_LEN, BD_ADDR_LEN);
1147         p_filters += (BD_ADDR_LEN * 2);
1148 
1149         /* Check if any of the ranges have all zeros as both starting and ending addresses */
1150         if ((memcmp (null_bda, p_bcb->rcvd_mcast_filter_start[xx], BD_ADDR_LEN) == 0) &&
1151             (memcmp (null_bda, p_bcb->rcvd_mcast_filter_end[xx], BD_ADDR_LEN) == 0))
1152         {
1153             p_bcb->rcvd_mcast_filters = 0xFFFF;
1154             break;
1155         }
1156     }
1157 
1158     BNEP_TRACE_EVENT ("BNEP multicast filters %d", p_bcb->rcvd_mcast_filters);
1159     bnepu_send_peer_multicast_filter_rsp (p_bcb, resp_code);
1160 
1161     if (bnep_cb.p_mfilter_ind_cb)
1162         (*bnep_cb.p_mfilter_ind_cb) (p_bcb->handle, TRUE, 0, len, p_filters);
1163 #else
1164     bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_UNSUPPORTED);
1165 #endif
1166 }
1167 
1168 
1169 /*******************************************************************************
1170 **
1171 ** Function         bnepu_send_peer_multicast_filter_rsp
1172 **
1173 ** Description      This function sends a filter response to a peer
1174 **
1175 ** Returns          void
1176 **
1177 *******************************************************************************/
bnepu_send_peer_multicast_filter_rsp(tBNEP_CONN * p_bcb,UINT16 response_code)1178 void bnepu_send_peer_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code)
1179 {
1180     BT_HDR  *p_buf;
1181     UINT8   *p;
1182 
1183     BNEP_TRACE_DEBUG ("BNEP sending multicast filter response %d", response_code);
1184     if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL)
1185     {
1186         BNEP_TRACE_ERROR ("BNEP - no buffer filter rsp");
1187         return;
1188     }
1189 
1190     p_buf->offset = L2CAP_MIN_OFFSET;
1191     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
1192 
1193     /* Put in BNEP frame type - filter control */
1194     UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
1195 
1196     /* Put in filter message type - set filters */
1197     UINT8_TO_BE_STREAM (p, BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG);
1198 
1199     UINT16_TO_BE_STREAM (p, response_code);
1200 
1201     p_buf->len = 4;
1202 
1203     bnepu_check_send_packet (p_bcb, p_buf);
1204 }
1205 
1206 
1207 
1208 /*******************************************************************************
1209 **
1210 ** Function         bnep_sec_check_complete
1211 **
1212 ** Description      This function is registered with BTM and will be called
1213 **                  after completing the security procedures
1214 **
1215 ** Returns          void
1216 **
1217 *******************************************************************************/
bnep_sec_check_complete(BD_ADDR bd_addr,tBT_TRANSPORT trasnport,void * p_ref_data,UINT8 result)1218 void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
1219                                     void *p_ref_data, UINT8 result)
1220 {
1221     tBNEP_CONN      *p_bcb = (tBNEP_CONN *)p_ref_data;
1222     UINT16          resp_code = BNEP_SETUP_CONN_OK;
1223     BOOLEAN         is_role_change;
1224     UNUSED(bd_addr);
1225     UNUSED(trasnport);
1226 
1227     BNEP_TRACE_EVENT ("BNEP security callback returned result %d", result);
1228     if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
1229         is_role_change = TRUE;
1230     else
1231         is_role_change = FALSE;
1232 
1233     /* check if the port is still waiting for security to complete */
1234     if (p_bcb->con_state != BNEP_STATE_SEC_CHECKING)
1235     {
1236         BNEP_TRACE_ERROR ("BNEP Connection in wrong state %d when security is completed", p_bcb->con_state);
1237         return;
1238     }
1239 
1240     /* if it is outgoing call and result is FAILURE return security fail error */
1241     if (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD))
1242     {
1243         if (result != BTM_SUCCESS)
1244         {
1245             if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
1246             {
1247                 /* Tell the user that role change is failed because of security */
1248                 if (bnep_cb.p_conn_state_cb)
1249                     (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, BNEP_SECURITY_FAIL, is_role_change);
1250 
1251                 p_bcb->con_state = BNEP_STATE_CONNECTED;
1252                 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID));
1253                 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID));
1254                 return;
1255             }
1256 
1257             L2CA_DisconnectReq (p_bcb->l2cap_cid);
1258 
1259             /* Tell the user if he has a callback */
1260             if (bnep_cb.p_conn_state_cb)
1261                 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, BNEP_SECURITY_FAIL, is_role_change);
1262 
1263             bnepu_release_bcb (p_bcb);
1264             return;
1265         }
1266 
1267         /* Transition to the next appropriate state, waiting for connection confirm. */
1268         p_bcb->con_state = BNEP_STATE_CONN_SETUP;
1269 
1270         bnep_send_conn_req (p_bcb);
1271         btu_start_timer (&p_bcb->conn_tle, BTU_TTYPE_BNEP, BNEP_CONN_TIMEOUT);
1272         return;
1273     }
1274 
1275     /* it is an incoming call respond appropriately */
1276     if (result != BTM_SUCCESS)
1277     {
1278         bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
1279         if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
1280         {
1281             /* Role change is failed because of security. Revert back to connected state */
1282             p_bcb->con_state = BNEP_STATE_CONNECTED;
1283             p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
1284             memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID));
1285             memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID));
1286             return;
1287         }
1288 
1289         L2CA_DisconnectReq (p_bcb->l2cap_cid);
1290 
1291         bnepu_release_bcb (p_bcb);
1292         return;
1293     }
1294 
1295     if (bnep_cb.p_conn_ind_cb)
1296     {
1297         p_bcb->con_state = BNEP_STATE_CONN_SETUP;
1298         (*bnep_cb.p_conn_ind_cb) (p_bcb->handle, p_bcb->rem_bda, &p_bcb->dst_uuid, &p_bcb->src_uuid, is_role_change);
1299     }
1300     else
1301     {
1302         /* Profile didn't register connection indication call back */
1303         bnep_send_conn_responce (p_bcb, resp_code);
1304         bnep_connected (p_bcb);
1305     }
1306 
1307     return;
1308 }
1309 
1310 
1311 /*******************************************************************************
1312 **
1313 ** Function         bnep_is_packet_allowed
1314 **
1315 ** Description      This function verifies whether the protocol passes through
1316 **                  the protocol filters set by the peer
1317 **
1318 ** Returns          BNEP_SUCCESS          - if the protocol is allowed
1319 **                  BNEP_IGNORE_CMD       - if the protocol is filtered out
1320 **
1321 *******************************************************************************/
bnep_is_packet_allowed(tBNEP_CONN * p_bcb,BD_ADDR p_dest_addr,UINT16 protocol,BOOLEAN fw_ext_present,UINT8 * p_data)1322 tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb,
1323                                      BD_ADDR p_dest_addr,
1324                                      UINT16 protocol,
1325                                      BOOLEAN fw_ext_present,
1326                                      UINT8 *p_data)
1327 {
1328 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE)
1329     if (p_bcb->rcvd_num_filters)
1330     {
1331         UINT16          i, proto;
1332 
1333         /* Findout the actual protocol to check for the filtering */
1334         proto = protocol;
1335         if (proto == BNEP_802_1_P_PROTOCOL)
1336         {
1337             if (fw_ext_present)
1338             {
1339                 UINT8       len, ext;
1340                 /* parse the extension headers and findout actual protocol */
1341                 do {
1342 
1343                     ext     = *p_data++;
1344                     len     = *p_data++;
1345                     p_data += len;
1346 
1347                 } while (ext & 0x80);
1348             }
1349             p_data += 2;
1350             BE_STREAM_TO_UINT16 (proto, p_data);
1351         }
1352 
1353         for (i=0; i<p_bcb->rcvd_num_filters; i++)
1354         {
1355             if ((p_bcb->rcvd_prot_filter_start[i] <= proto) &&
1356                 (proto <= p_bcb->rcvd_prot_filter_end[i]))
1357                 break;
1358         }
1359 
1360         if (i == p_bcb->rcvd_num_filters)
1361         {
1362             BNEP_TRACE_DEBUG ("Ignoring protocol 0x%x in BNEP data write", proto);
1363             return BNEP_IGNORE_CMD;
1364         }
1365     }
1366 #endif
1367 
1368 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE)
1369     /* Ckeck for multicast address filtering */
1370     if ((p_dest_addr[0] & 0x01) &&
1371         p_bcb->rcvd_mcast_filters)
1372     {
1373         UINT16          i;
1374 
1375         /* Check if every multicast should be filtered */
1376         if (p_bcb->rcvd_mcast_filters != 0xFFFF)
1377         {
1378             /* Check if the address is mentioned in the filter range */
1379             for (i = 0; i < p_bcb->rcvd_mcast_filters; i++)
1380             {
1381                 if ((memcmp (p_bcb->rcvd_mcast_filter_start[i], p_dest_addr, BD_ADDR_LEN) <= 0) &&
1382                     (memcmp (p_bcb->rcvd_mcast_filter_end[i], p_dest_addr, BD_ADDR_LEN) >= 0))
1383                     break;
1384             }
1385         }
1386 
1387         /*
1388         ** If every multicast should be filtered or the address is not in the filter range
1389         ** drop the packet
1390         */
1391         if ((p_bcb->rcvd_mcast_filters == 0xFFFF) || (i == p_bcb->rcvd_mcast_filters))
1392         {
1393             BNEP_TRACE_DEBUG ("Ignoring multicast address %x.%x.%x.%x.%x.%x in BNEP data write",
1394                 p_dest_addr[0], p_dest_addr[1], p_dest_addr[2],
1395                 p_dest_addr[3], p_dest_addr[4], p_dest_addr[5]);
1396             return BNEP_IGNORE_CMD;
1397         }
1398     }
1399 #endif
1400 
1401     return BNEP_SUCCESS;
1402 }
1403 
1404 
1405 
1406 
1407 
1408 /*******************************************************************************
1409 **
1410 ** Function         bnep_get_uuid32
1411 **
1412 ** Description      This function returns the 32 bit equivalent of the given UUID
1413 **
1414 ** Returns          UINT32          - 32 bit equivalent of the UUID
1415 **
1416 *******************************************************************************/
bnep_get_uuid32(tBT_UUID * src_uuid)1417 UINT32 bnep_get_uuid32 (tBT_UUID *src_uuid)
1418 {
1419     UINT32      result;
1420 
1421     if (src_uuid->len == 2)
1422         return ((UINT32)src_uuid->uu.uuid16);
1423     else if (src_uuid->len == 4)
1424         return (src_uuid->uu.uuid32 & 0x0000FFFF);
1425     else
1426     {
1427         result = src_uuid->uu.uuid128[2];
1428         result = (result << 8) | (src_uuid->uu.uuid128[3]);
1429         return result;
1430     }
1431 }
1432 
1433 
1434 
1435 
1436 /*******************************************************************************
1437 **
1438 ** Function         bnep_dump_status
1439 **
1440 ** Description      This function dumps the bnep control block and connection
1441 **                  blocks information
1442 **
1443 ** Returns          none
1444 **
1445 *******************************************************************************/
bnep_dump_status(void)1446 void bnep_dump_status (void)
1447 {
1448 #if (defined (BNEP_SUPPORTS_DEBUG_DUMP) && BNEP_SUPPORTS_DEBUG_DUMP == TRUE)
1449     UINT16          i;
1450     char            buff[200];
1451     tBNEP_CONN     *p_bcb;
1452 
1453     BNEP_TRACE_DEBUG ("BNEP my BD Addr %x.%x.%x.%x.%x.%x",
1454         bnep_cb.my_bda[0], bnep_cb.my_bda[1], bnep_cb.my_bda[2],
1455         bnep_cb.my_bda[3], bnep_cb.my_bda[4], bnep_cb.my_bda[5]);
1456     BNEP_TRACE_DEBUG ("profile registered %d, trace %d, got_my_bd_addr %d",
1457         bnep_cb.profile_registered, bnep_cb.trace_level, bnep_cb.got_my_bd_addr);
1458 
1459     for (i = 0, p_bcb = bnep_cb.bcb; i < BNEP_MAX_CONNECTIONS; i++, p_bcb++)
1460     {
1461         sprintf (buff, "%d state %d, flags 0x%x, cid %d, pfilts %d, mfilts %d, src 0x%x, dst 0x%x, BD %x.%x.%x.%x.%x.%x",
1462             i, p_bcb->con_state, p_bcb->con_flags, p_bcb->l2cap_cid,
1463             p_bcb->rcvd_num_filters, p_bcb->rcvd_mcast_filters,
1464             p_bcb->src_uuid.uu.uuid16, p_bcb->dst_uuid.uu.uuid16,
1465             p_bcb->rem_bda[0], p_bcb->rem_bda[1], p_bcb->rem_bda[2],
1466             p_bcb->rem_bda[3], p_bcb->rem_bda[4], p_bcb->rem_bda[5]);
1467 
1468         BNEP_TRACE_DEBUG (buff);
1469     }
1470 #endif
1471 }
1472 
1473 
1474