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