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