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