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