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/********************************************************************************/
37static UINT8 *bnepu_init_hdr (BT_HDR *p_buf, UINT16 hdr_len, UINT8 pkt_type);
38
39void bnepu_process_peer_multicast_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len);
40void 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*******************************************************************************/
53tBNEP_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*******************************************************************************/
80tBNEP_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*******************************************************************************/
109tBNEP_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*******************************************************************************/
144void 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*******************************************************************************/
170void 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*******************************************************************************/
228void 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*******************************************************************************/
267void 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*******************************************************************************/
319void 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*******************************************************************************/
373void 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*******************************************************************************/
411void 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*******************************************************************************/
452void 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*******************************************************************************/
486void 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*******************************************************************************/
547static 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*******************************************************************************/
584void 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*******************************************************************************/
686void 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*******************************************************************************/
783UINT8 *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*******************************************************************************/
900void 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*******************************************************************************/
982void 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*******************************************************************************/
1034void 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*******************************************************************************/
1087void 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*******************************************************************************/
1171void 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*******************************************************************************/
1211void 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*******************************************************************************/
1312tBNEP_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*******************************************************************************/
1407UINT32 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*******************************************************************************/
1436void 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