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