1 /******************************************************************************
3 * Copyright (C) 2001-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains BNEP utility functions
23 ******************************************************************************/
27 #include "bt_common.h"
33 #include "device/include/controller.h"
36 extern fixed_queue_t *btu_general_alarm_queue;
38 /********************************************************************************/
39 /* L O C A L F U N C T I O N P R O T O T Y P E S */
40 /********************************************************************************/
41 static UINT8 *bnepu_init_hdr (BT_HDR *p_buf, UINT16 hdr_len, UINT8 pkt_type);
43 void bnepu_process_peer_multicast_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len);
44 void bnepu_send_peer_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code);
47 /*******************************************************************************
49 ** Function bnepu_find_bcb_by_cid
51 ** Description This function searches the bcb table for an entry with the
54 ** Returns the BCB address, or NULL if not found.
56 *******************************************************************************/
57 tBNEP_CONN *bnepu_find_bcb_by_cid (UINT16 cid)
62 /* Look through each connection control block */
63 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++)
65 if ((p_bcb->con_state != BNEP_STATE_IDLE) && (p_bcb->l2cap_cid == cid))
69 /* If here, not found */
74 /*******************************************************************************
76 ** Function bnepu_find_bcb_by_bd_addr
78 ** Description This function searches the BCB table for an entry with the
79 ** passed Bluetooth Address.
81 ** Returns the BCB address, or NULL if not found.
83 *******************************************************************************/
84 tBNEP_CONN *bnepu_find_bcb_by_bd_addr (UINT8 *p_bda)
89 /* Look through each connection control block */
90 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++)
92 if (p_bcb->con_state != BNEP_STATE_IDLE)
94 if (!memcmp ((UINT8 *)(p_bcb->rem_bda), p_bda, BD_ADDR_LEN))
99 /* If here, not found */
104 /*******************************************************************************
106 ** Function bnepu_allocate_bcb
108 ** Description This function allocates a new BCB.
110 ** Returns BCB address, or NULL if none available.
112 *******************************************************************************/
113 tBNEP_CONN *bnepu_allocate_bcb (BD_ADDR p_rem_bda)
118 /* Look through each connection control block for a free one */
119 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++)
121 if (p_bcb->con_state == BNEP_STATE_IDLE)
123 alarm_free(p_bcb->conn_timer);
124 memset ((UINT8 *)p_bcb, 0, sizeof (tBNEP_CONN));
125 p_bcb->conn_timer = alarm_new("bnep.conn_timer");
127 memcpy ((UINT8 *)(p_bcb->rem_bda), (UINT8 *)p_rem_bda, BD_ADDR_LEN);
128 p_bcb->handle = xx + 1;
129 p_bcb->xmit_q = fixed_queue_new(SIZE_MAX);
135 /* If here, no free BCB found */
140 /*******************************************************************************
142 ** Function bnepu_release_bcb
144 ** Description This function releases a BCB.
148 *******************************************************************************/
149 void bnepu_release_bcb (tBNEP_CONN *p_bcb)
151 /* Ensure timer is stopped */
152 alarm_free(p_bcb->conn_timer);
153 p_bcb->conn_timer = NULL;
155 /* Drop any response pointer we may be holding */
156 p_bcb->con_state = BNEP_STATE_IDLE;
157 osi_free(p_bcb->p_pending_data);
158 p_bcb->p_pending_data = NULL;
160 /* Free transmit queue */
161 while (!fixed_queue_is_empty(p_bcb->xmit_q))
163 osi_free(fixed_queue_try_dequeue(p_bcb->xmit_q));
165 fixed_queue_free(p_bcb->xmit_q, NULL);
166 p_bcb->xmit_q = NULL;
170 /*******************************************************************************
172 ** Function bnep_send_conn_req
174 ** Description This function sends a BNEP connection request to peer
178 *******************************************************************************/
179 void bnep_send_conn_req (tBNEP_CONN *p_bcb)
181 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BNEP_BUF_SIZE);
184 BNEP_TRACE_DEBUG ("%s: sending setup req with dst uuid %x",
185 __func__, p_bcb->dst_uuid.uu.uuid16);
187 p_buf->offset = L2CAP_MIN_OFFSET;
188 p = p_start = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
190 /* Put in BNEP frame type - filter control */
191 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
193 /* Put in filter message type - set filters */
194 UINT8_TO_BE_STREAM (p, BNEP_SETUP_CONNECTION_REQUEST_MSG);
196 UINT8_TO_BE_STREAM (p, p_bcb->dst_uuid.len);
198 if (p_bcb->dst_uuid.len == 2)
200 UINT16_TO_BE_STREAM (p, p_bcb->dst_uuid.uu.uuid16);
201 UINT16_TO_BE_STREAM (p, p_bcb->src_uuid.uu.uuid16);
203 else if (p_bcb->dst_uuid.len == 4)
205 UINT32_TO_BE_STREAM (p, p_bcb->dst_uuid.uu.uuid32);
206 UINT32_TO_BE_STREAM (p, p_bcb->src_uuid.uu.uuid32);
208 else if (p_bcb->dst_uuid.len == 16)
210 memcpy (p, p_bcb->dst_uuid.uu.uuid128, p_bcb->dst_uuid.len);
211 p += p_bcb->dst_uuid.len;
212 memcpy (p, p_bcb->src_uuid.uu.uuid128, p_bcb->dst_uuid.len);
213 p += p_bcb->dst_uuid.len;
217 BNEP_TRACE_ERROR ("%s: uuid: %x, invalid length: %x",
218 __func__, p_bcb->dst_uuid.uu.uuid16, p_bcb->dst_uuid.len);
221 p_buf->len = (UINT16)(p - p_start);
223 bnepu_check_send_packet (p_bcb, p_buf);
227 /*******************************************************************************
229 ** Function bnep_send_conn_responce
231 ** Description This function sends a BNEP setup response to peer
235 *******************************************************************************/
236 void bnep_send_conn_responce (tBNEP_CONN *p_bcb, UINT16 resp_code)
238 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BNEP_BUF_SIZE);
241 BNEP_TRACE_EVENT ("BNEP - bnep_send_conn_responce for CID: 0x%x", p_bcb->l2cap_cid);
243 p_buf->offset = L2CAP_MIN_OFFSET;
244 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
246 /* Put in BNEP frame type - filter control */
247 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
249 /* Put in filter message type - set filters */
250 UINT8_TO_BE_STREAM (p, BNEP_SETUP_CONNECTION_RESPONSE_MSG);
252 UINT16_TO_BE_STREAM (p, resp_code);
256 bnepu_check_send_packet (p_bcb, p_buf);
261 /*******************************************************************************
263 ** Function bnepu_send_peer_our_filters
265 ** Description This function sends our filters to a peer
269 *******************************************************************************/
270 void bnepu_send_peer_our_filters (tBNEP_CONN *p_bcb)
272 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BNEP_BUF_SIZE);
276 BNEP_TRACE_DEBUG ("BNEP sending peer our filters");
278 p_buf->offset = L2CAP_MIN_OFFSET;
279 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
281 /* Put in BNEP frame type - filter control */
282 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
284 /* Put in filter message type - set filters */
285 UINT8_TO_BE_STREAM (p, BNEP_FILTER_NET_TYPE_SET_MSG);
287 UINT16_TO_BE_STREAM (p, (4 * p_bcb->sent_num_filters));
288 for (xx = 0; xx < p_bcb->sent_num_filters; xx++)
290 UINT16_TO_BE_STREAM (p, p_bcb->sent_prot_filter_start[xx]);
291 UINT16_TO_BE_STREAM (p, p_bcb->sent_prot_filter_end[xx]);
294 p_buf->len = 4 + (4 * p_bcb->sent_num_filters);
296 bnepu_check_send_packet (p_bcb, p_buf);
298 p_bcb->con_flags |= BNEP_FLAGS_FILTER_RESP_PEND;
300 /* Start timer waiting for setup response */
301 alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
302 bnep_conn_timer_timeout, p_bcb,
303 btu_general_alarm_queue);
307 /*******************************************************************************
309 ** Function bnepu_send_peer_our_multi_filters
311 ** Description This function sends our multicast filters to a peer
315 *******************************************************************************/
316 void bnepu_send_peer_our_multi_filters (tBNEP_CONN *p_bcb)
318 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BNEP_BUF_SIZE);
322 BNEP_TRACE_DEBUG ("BNEP sending peer our multicast filters");
324 p_buf->offset = L2CAP_MIN_OFFSET;
325 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
327 /* Put in BNEP frame type - filter control */
328 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
330 /* Put in filter message type - set filters */
331 UINT8_TO_BE_STREAM (p, BNEP_FILTER_MULTI_ADDR_SET_MSG);
333 UINT16_TO_BE_STREAM (p, (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters));
334 for (xx = 0; xx < p_bcb->sent_mcast_filters; xx++)
336 memcpy (p, p_bcb->sent_mcast_filter_start[xx], BD_ADDR_LEN);
338 memcpy (p, p_bcb->sent_mcast_filter_end[xx], BD_ADDR_LEN);
342 p_buf->len = 4 + (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters);
344 bnepu_check_send_packet (p_bcb, p_buf);
346 p_bcb->con_flags |= BNEP_FLAGS_MULTI_RESP_PEND;
348 /* Start timer waiting for setup response */
349 alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
350 bnep_conn_timer_timeout, p_bcb,
351 btu_general_alarm_queue);
355 /*******************************************************************************
357 ** Function bnepu_send_peer_filter_rsp
359 ** Description This function sends a filter response to a peer
363 *******************************************************************************/
364 void bnepu_send_peer_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code)
366 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BNEP_BUF_SIZE);
369 BNEP_TRACE_DEBUG ("BNEP sending filter response");
371 p_buf->offset = L2CAP_MIN_OFFSET;
372 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
374 /* Put in BNEP frame type - filter control */
375 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
377 /* Put in filter message type - set filters */
378 UINT8_TO_BE_STREAM (p, BNEP_FILTER_NET_TYPE_RESPONSE_MSG);
380 UINT16_TO_BE_STREAM (p, response_code);
384 bnepu_check_send_packet (p_bcb, p_buf);
388 /*******************************************************************************
390 ** Function bnep_send_command_not_understood
392 ** Description This function sends a BNEP command not understood message
396 *******************************************************************************/
397 void bnep_send_command_not_understood (tBNEP_CONN *p_bcb, UINT8 cmd_code)
399 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BNEP_BUF_SIZE);
402 BNEP_TRACE_EVENT ("BNEP - bnep_send_command_not_understood for CID: 0x%x, cmd 0x%x", p_bcb->l2cap_cid, cmd_code);
404 p_buf->offset = L2CAP_MIN_OFFSET;
405 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
407 /* Put in BNEP frame type - filter control */
408 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
410 /* Put in filter message type - set filters */
411 UINT8_TO_BE_STREAM (p, BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD);
413 UINT8_TO_BE_STREAM (p, cmd_code);
417 bnepu_check_send_packet (p_bcb, p_buf);
422 /*******************************************************************************
424 ** Function bnepu_check_send_packet
426 ** Description This function tries to send a packet to L2CAP.
427 ** If L2CAP is flow controlled, it enqueues the
428 ** packet to the transmit queue
432 *******************************************************************************/
433 void bnepu_check_send_packet (tBNEP_CONN *p_bcb, BT_HDR *p_buf)
435 BNEP_TRACE_EVENT ("BNEP - bnepu_check_send_packet for CID: 0x%x", p_bcb->l2cap_cid);
436 if (p_bcb->con_flags & BNEP_FLAGS_L2CAP_CONGESTED)
438 if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH)
440 BNEP_TRACE_EVENT ("BNEP - congested, dropping buf, CID: 0x%x", p_bcb->l2cap_cid);
446 fixed_queue_enqueue(p_bcb->xmit_q, p_buf);
451 L2CA_DataWrite (p_bcb->l2cap_cid, p_buf);
456 /*******************************************************************************
458 ** Function bnepu_build_bnep_hdr
460 ** Description This function builds the BNEP header for a packet
461 ** Extension headers are not sent yet, so there is no
466 *******************************************************************************/
467 void bnepu_build_bnep_hdr (tBNEP_CONN *p_bcb, BT_HDR *p_buf, UINT16 protocol,
468 UINT8 *p_src_addr, UINT8 *p_dest_addr, BOOLEAN fw_ext_present)
470 const controller_t *controller = controller_get_interface();
471 UINT8 ext_bit, *p = (UINT8 *)NULL;
472 UINT8 type = BNEP_FRAME_COMPRESSED_ETHERNET;
474 ext_bit = fw_ext_present ? 0x80 : 0x00;
476 if ((p_src_addr) && (memcmp (p_src_addr, &controller->get_address()->address, BD_ADDR_LEN)))
477 type = BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY;
479 if (memcmp (p_dest_addr, p_bcb->rem_bda, BD_ADDR_LEN))
480 type = (type == BNEP_FRAME_COMPRESSED_ETHERNET) ? BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY : BNEP_FRAME_GENERAL_ETHERNET;
483 p_src_addr = (UINT8 *)controller->get_address();
487 case BNEP_FRAME_GENERAL_ETHERNET:
488 p = bnepu_init_hdr (p_buf, 15, (UINT8)(ext_bit | BNEP_FRAME_GENERAL_ETHERNET));
490 memcpy (p, p_dest_addr, BD_ADDR_LEN);
493 memcpy (p, p_src_addr, BD_ADDR_LEN);
497 case BNEP_FRAME_COMPRESSED_ETHERNET:
498 p = bnepu_init_hdr (p_buf, 3, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET));
501 case BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY:
502 p = bnepu_init_hdr (p_buf, 9, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY));
504 memcpy (p, p_src_addr, BD_ADDR_LEN);
508 case BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY:
509 p = bnepu_init_hdr (p_buf, 9, (UINT8)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY));
511 memcpy (p, p_dest_addr, BD_ADDR_LEN);
516 UINT16_TO_BE_STREAM (p, protocol);
520 /*******************************************************************************
522 ** Function bnepu_init_hdr
524 ** Description This function initializes the BNEP header
526 ** Returns pointer to header in buffer
528 *******************************************************************************/
529 static UINT8 *bnepu_init_hdr (BT_HDR *p_buf, UINT16 hdr_len, UINT8 pkt_type)
531 UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
533 /* See if we need to make space in the buffer */
534 if (p_buf->offset < (hdr_len + L2CAP_MIN_OFFSET))
536 UINT16 xx, diff = BNEP_MINIMUM_OFFSET - p_buf->offset;
537 p = p + p_buf->len - 1;
538 for (xx = 0; xx < p_buf->len; xx++, p--)
541 p_buf->offset = BNEP_MINIMUM_OFFSET;
542 p = (UINT8 *)(p_buf + 1) + p_buf->offset;
545 p_buf->len += hdr_len;
546 p_buf->offset -= hdr_len;
555 /*******************************************************************************
557 ** Function bnep_process_setup_conn_req
559 ** Description This function processes a peer's setup connection request
560 ** message. The destination UUID is verified and response sent
561 ** Connection open indication will be given to PAN profile
565 *******************************************************************************/
566 void bnep_process_setup_conn_req (tBNEP_CONN *p_bcb, UINT8 *p_setup, UINT8 len)
568 BNEP_TRACE_EVENT ("BNEP - bnep_process_setup_conn_req for CID: 0x%x", p_bcb->l2cap_cid);
570 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP &&
571 p_bcb->con_state != BNEP_STATE_SEC_CHECKING &&
572 p_bcb->con_state != BNEP_STATE_CONNECTED)
574 BNEP_TRACE_ERROR ("BNEP - setup request in bad state %d", p_bcb->con_state);
575 bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
579 /* Check if we already initiated security check or if waiting for user responce */
580 if (p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)
582 BNEP_TRACE_EVENT ("BNEP - Duplicate Setup message received while doing security check");
586 /* Check if peer is the originator */
587 if (p_bcb->con_state != BNEP_STATE_CONNECTED &&
588 (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) &&
589 (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG))
591 BNEP_TRACE_ERROR ("BNEP - setup request when we are originator", p_bcb->con_state);
592 bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
596 if (p_bcb->con_state == BNEP_STATE_CONNECTED)
598 memcpy ((UINT8 *)&(p_bcb->prv_src_uuid), (UINT8 *)&(p_bcb->src_uuid), sizeof (tBT_UUID));
599 memcpy ((UINT8 *)&(p_bcb->prv_dst_uuid), (UINT8 *)&(p_bcb->dst_uuid), sizeof (tBT_UUID));
602 p_bcb->dst_uuid.len = p_bcb->src_uuid.len = len;
604 if (p_bcb->dst_uuid.len == 2)
606 /* because peer initiated connection keep src uuid as dst uuid */
607 BE_STREAM_TO_UINT16 (p_bcb->src_uuid.uu.uuid16, p_setup);
608 BE_STREAM_TO_UINT16 (p_bcb->dst_uuid.uu.uuid16, p_setup);
610 /* If nothing has changed don't bother the profile */
611 if (p_bcb->con_state == BNEP_STATE_CONNECTED &&
612 p_bcb->src_uuid.uu.uuid16 == p_bcb->prv_src_uuid.uu.uuid16 &&
613 p_bcb->dst_uuid.uu.uuid16 == p_bcb->prv_dst_uuid.uu.uuid16)
615 bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_OK);
619 else if (p_bcb->dst_uuid.len == 4)
621 BE_STREAM_TO_UINT32 (p_bcb->src_uuid.uu.uuid32, p_setup);
622 BE_STREAM_TO_UINT32 (p_bcb->dst_uuid.uu.uuid32, p_setup);
624 else if (p_bcb->dst_uuid.len == 16)
626 memcpy (p_bcb->src_uuid.uu.uuid128, p_setup, p_bcb->src_uuid.len);
627 p_setup += p_bcb->src_uuid.len;
628 memcpy (p_bcb->dst_uuid.uu.uuid128, p_setup, p_bcb->dst_uuid.len);
629 p_setup += p_bcb->dst_uuid.len;
633 BNEP_TRACE_ERROR ("BNEP - Bad UID len %d in ConnReq", p_bcb->dst_uuid.len);
634 bnep_send_conn_responce (p_bcb, BNEP_SETUP_INVALID_UUID_SIZE);
638 p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
639 p_bcb->con_flags |= BNEP_FLAGS_SETUP_RCVD;
641 BNEP_TRACE_EVENT ("BNEP initiating security check for incoming call for uuid 0x%x", p_bcb->src_uuid.uu.uuid16);
642 #if (!defined (BNEP_DO_AUTH_FOR_ROLE_SWITCH) || BNEP_DO_AUTH_FOR_ROLE_SWITCH == FALSE)
643 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
644 bnep_sec_check_complete (p_bcb->rem_bda, p_bcb, BTM_SUCCESS);
647 btm_sec_mx_access_request (p_bcb->rem_bda, BT_PSM_BNEP, FALSE,
648 BTM_SEC_PROTO_BNEP, bnep_get_uuid32(&(p_bcb->src_uuid)),
649 &bnep_sec_check_complete, p_bcb);
655 /*******************************************************************************
657 ** Function bnep_process_setup_conn_responce
659 ** Description This function processes a peer's setup connection response
660 ** message. The response code is verified and
661 ** Connection open indication will be given to PAN profile
665 *******************************************************************************/
666 void bnep_process_setup_conn_responce (tBNEP_CONN *p_bcb, UINT8 *p_setup)
671 BNEP_TRACE_DEBUG ("BNEP received setup responce");
672 /* The state should be either SETUP or CONNECTED */
673 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP)
675 /* Should we disconnect ? */
676 BNEP_TRACE_ERROR ("BNEP - setup response in bad state %d", p_bcb->con_state);
680 /* Check if we are the originator */
681 if (!(p_bcb->con_flags & BNEP_FLAGS_IS_ORIG))
683 BNEP_TRACE_ERROR ("BNEP - setup response when we are not originator", p_bcb->con_state);
687 BE_STREAM_TO_UINT16 (resp_code, p_setup);
691 case BNEP_SETUP_INVALID_SRC_UUID:
692 resp = BNEP_CONN_FAILED_SRC_UUID;
695 case BNEP_SETUP_INVALID_DEST_UUID:
696 resp = BNEP_CONN_FAILED_DST_UUID;
699 case BNEP_SETUP_INVALID_UUID_SIZE:
700 resp = BNEP_CONN_FAILED_UUID_SIZE;
703 case BNEP_SETUP_CONN_NOT_ALLOWED:
705 resp = BNEP_CONN_FAILED;
709 /* Check the responce code */
710 if (resp_code != BNEP_SETUP_CONN_OK)
712 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
714 BNEP_TRACE_EVENT ("BNEP - role change response is %d", resp_code);
716 /* Restore the earlier BNEP status */
717 p_bcb->con_state = BNEP_STATE_CONNECTED;
718 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
719 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID));
720 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID));
722 /* Ensure timer is stopped */
723 alarm_cancel(p_bcb->conn_timer);
724 p_bcb->re_transmits = 0;
726 /* Tell the user if he has a callback */
727 if (bnep_cb.p_conn_state_cb)
728 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, resp, TRUE);
734 BNEP_TRACE_ERROR ("BNEP - setup response %d is not OK", resp_code);
736 L2CA_DisconnectReq (p_bcb->l2cap_cid);
738 /* Tell the user if he has a callback */
739 if ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) && (bnep_cb.p_conn_state_cb))
740 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, resp, FALSE);
742 bnepu_release_bcb (p_bcb);
747 /* Received successful responce */
748 bnep_connected (p_bcb);
752 /*******************************************************************************
754 ** Function bnep_process_control_packet
756 ** Description This function processes a peer's setup connection request
757 ** message. The destination UUID is verified and response sent
758 ** Connection open indication will be given to PAN profile
762 *******************************************************************************/
763 UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len, BOOLEAN is_ext)
766 UINT16 len, ext_len = 0;
768 if (p == NULL || rem_len == NULL) {
769 if (rem_len != NULL) *rem_len = 0;
770 BNEP_TRACE_DEBUG("%s: invalid packet: p = %p rem_len = %p", __func__, p,
774 UINT16 rem_len_orig = *rem_len;
778 if (*rem_len < 1) goto bad_packet_length;
780 *rem_len = *rem_len - 1;
783 if (*rem_len < 1) goto bad_packet_length;
785 *rem_len = *rem_len - 1;
787 BNEP_TRACE_EVENT("%s: BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d",
788 __func__, *rem_len, is_ext, control_type);
790 switch (control_type)
792 case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
795 "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD with bad length",
797 goto bad_packet_length;
800 "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD for pkt type: %d",
803 *rem_len = *rem_len - 1;
806 case BNEP_SETUP_CONNECTION_REQUEST_MSG:
808 if (*rem_len < ((2 * len) + 1)) {
810 "%s: Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length",
812 goto bad_packet_length;
815 bnep_process_setup_conn_req (p_bcb, p, (UINT8)len);
817 *rem_len = *rem_len - (2 * len) - 1;
820 case BNEP_SETUP_CONNECTION_RESPONSE_MSG:
823 "%s: Received BNEP_SETUP_CONNECTION_RESPONSE_MSG with bad length",
825 goto bad_packet_length;
828 bnep_process_setup_conn_responce (p_bcb, p);
830 *rem_len = *rem_len - 2;
833 case BNEP_FILTER_NET_TYPE_SET_MSG:
834 BE_STREAM_TO_UINT16 (len, p);
835 if (*rem_len < (len + 2))
838 "%s: Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length",
840 goto bad_packet_length;
842 bnepu_process_peer_filter_set (p_bcb, p, len);
844 *rem_len = *rem_len - len - 2;
847 case BNEP_FILTER_NET_TYPE_RESPONSE_MSG:
850 "%s: Received BNEP_FILTER_NET_TYPE_RESPONSE_MSG with bad length",
852 goto bad_packet_length;
854 bnepu_process_peer_filter_rsp (p_bcb, p);
856 *rem_len = *rem_len - 2;
859 case BNEP_FILTER_MULTI_ADDR_SET_MSG:
860 BE_STREAM_TO_UINT16 (len, p);
861 if (*rem_len < (len + 2))
864 "%s: Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length",
866 goto bad_packet_length;
868 bnepu_process_peer_multicast_filter_set (p_bcb, p, len);
870 *rem_len = *rem_len - len - 2;
873 case BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG:
876 "%s: Received BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG with bad length",
878 goto bad_packet_length;
880 bnepu_process_multicast_filter_rsp (p_bcb, p);
882 *rem_len = *rem_len - 2;
886 BNEP_TRACE_ERROR("%s: BNEP - bad ctl pkt type: %d", __func__,
888 bnep_send_command_not_understood (p_bcb, control_type);
891 if (*rem_len < (ext_len - 1)) {
892 goto bad_packet_length;
895 *rem_len -= (ext_len - 1);
902 BNEP_TRACE_ERROR("%s: bad control packet length: original=%d remaining=%d",
903 __func__, rem_len_orig, *rem_len);
909 /*******************************************************************************
911 ** Function bnepu_process_peer_filter_set
913 ** Description This function processes a peer's filter control
914 ** 'set' message. The filters are stored in the BCB,
915 ** and an appropriate filter response message sent.
919 *******************************************************************************/
920 void bnepu_process_peer_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len)
922 UINT16 num_filters = 0;
923 UINT16 xx, resp_code = BNEP_FILTER_CRL_OK;
925 UINT8 *p_temp_filters;
927 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
928 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
930 BNEP_TRACE_DEBUG ("BNEP received filter set from peer when there is no connection");
934 BNEP_TRACE_DEBUG ("BNEP received filter set from peer");
935 /* Check for length not a multiple of 4 */
938 BNEP_TRACE_EVENT ("BNEP - bad filter len: %d", len);
939 bnepu_send_peer_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
944 num_filters = (UINT16) (len >> 2);
946 /* Validate filter values */
947 if (num_filters <= BNEP_MAX_PROT_FILTERS)
949 p_temp_filters = p_filters;
950 for (xx = 0; xx < num_filters; xx++)
952 BE_STREAM_TO_UINT16 (start, p_temp_filters);
953 BE_STREAM_TO_UINT16 (end, p_temp_filters);
957 resp_code = BNEP_FILTER_CRL_BAD_RANGE;
963 resp_code = BNEP_FILTER_CRL_MAX_REACHED;
965 if (resp_code != BNEP_FILTER_CRL_OK)
967 bnepu_send_peer_filter_rsp (p_bcb, resp_code);
971 if (bnep_cb.p_filter_ind_cb)
972 (*bnep_cb.p_filter_ind_cb) (p_bcb->handle, TRUE, 0, len, p_filters);
974 p_bcb->rcvd_num_filters = num_filters;
975 for (xx = 0; xx < num_filters; xx++)
977 BE_STREAM_TO_UINT16 (start, p_filters);
978 BE_STREAM_TO_UINT16 (end, p_filters);
980 p_bcb->rcvd_prot_filter_start[xx] = start;
981 p_bcb->rcvd_prot_filter_end[xx] = end;
984 bnepu_send_peer_filter_rsp (p_bcb, resp_code);
988 /*******************************************************************************
990 ** Function bnepu_process_peer_filter_rsp
992 ** Description This function processes a peer's filter control
993 ** 'response' message.
997 *******************************************************************************/
998 void bnepu_process_peer_filter_rsp (tBNEP_CONN *p_bcb, UINT8 *p_data)
1001 tBNEP_RESULT result;
1003 BNEP_TRACE_DEBUG ("BNEP received filter responce");
1004 /* The state should be CONNECTED */
1005 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
1006 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
1008 BNEP_TRACE_ERROR ("BNEP - filter response in bad state %d", p_bcb->con_state);
1012 /* Check if we are the originator */
1013 if (!(p_bcb->con_flags & BNEP_FLAGS_FILTER_RESP_PEND))
1015 BNEP_TRACE_ERROR ("BNEP - filter response when not expecting");
1019 /* Ensure timer is stopped */
1020 alarm_cancel(p_bcb->conn_timer);
1021 p_bcb->con_flags &= ~BNEP_FLAGS_FILTER_RESP_PEND;
1022 p_bcb->re_transmits = 0;
1024 BE_STREAM_TO_UINT16 (resp_code, p_data);
1026 result = BNEP_SUCCESS;
1027 if (resp_code != BNEP_FILTER_CRL_OK)
1028 result = BNEP_SET_FILTER_FAIL;
1030 if (bnep_cb.p_filter_ind_cb)
1031 (*bnep_cb.p_filter_ind_cb) (p_bcb->handle, FALSE, result, 0, NULL);
1034 /*******************************************************************************
1036 ** Function bnepu_process_multicast_filter_rsp
1038 ** Description This function processes multicast filter control
1039 ** 'response' message.
1043 *******************************************************************************/
1044 void bnepu_process_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT8 *p_data)
1047 tBNEP_RESULT result;
1049 BNEP_TRACE_DEBUG ("BNEP received multicast filter responce");
1050 /* The state should be CONNECTED */
1051 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
1052 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
1054 BNEP_TRACE_ERROR ("BNEP - multicast filter response in bad state %d", p_bcb->con_state);
1058 /* Check if we are the originator */
1059 if (!(p_bcb->con_flags & BNEP_FLAGS_MULTI_RESP_PEND))
1061 BNEP_TRACE_ERROR ("BNEP - multicast filter response when not expecting");
1065 /* Ensure timer is stopped */
1066 alarm_cancel(p_bcb->conn_timer);
1067 p_bcb->con_flags &= ~BNEP_FLAGS_MULTI_RESP_PEND;
1068 p_bcb->re_transmits = 0;
1070 BE_STREAM_TO_UINT16 (resp_code, p_data);
1072 result = BNEP_SUCCESS;
1073 if (resp_code != BNEP_FILTER_CRL_OK)
1074 result = BNEP_SET_FILTER_FAIL;
1076 if (bnep_cb.p_mfilter_ind_cb)
1077 (*bnep_cb.p_mfilter_ind_cb) (p_bcb->handle, FALSE, result, 0, NULL);
1080 /*******************************************************************************
1082 ** Function bnepu_process_peer_multicast_filter_set
1084 ** Description This function processes a peer's filter control
1085 ** 'set' message. The filters are stored in the BCB,
1086 ** and an appropriate filter response message sent.
1090 *******************************************************************************/
1091 void bnepu_process_peer_multicast_filter_set (tBNEP_CONN *p_bcb, UINT8 *p_filters, UINT16 len)
1093 UINT16 resp_code = BNEP_FILTER_CRL_OK;
1094 UINT16 num_filters, xx;
1095 UINT8 *p_temp_filters, null_bda[BD_ADDR_LEN] = {0,0,0,0,0,0};
1097 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
1098 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
1100 BNEP_TRACE_DEBUG ("BNEP received multicast filter set from peer when there is no connection");
1106 BNEP_TRACE_EVENT ("BNEP - bad filter len: %d", len);
1107 bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
1111 if (len > (BNEP_MAX_MULTI_FILTERS * 2 * BD_ADDR_LEN))
1113 BNEP_TRACE_EVENT ("BNEP - Too many filters");
1114 bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_MAX_REACHED);
1120 num_filters = (UINT16) (len / 12);
1122 /* Validate filter values */
1123 if (num_filters <= BNEP_MAX_MULTI_FILTERS)
1125 p_temp_filters = p_filters;
1126 for (xx = 0; xx < num_filters; xx++)
1128 if (memcmp (p_temp_filters, p_temp_filters + BD_ADDR_LEN, BD_ADDR_LEN) > 0)
1130 bnepu_send_peer_multicast_filter_rsp (p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
1134 p_temp_filters += (BD_ADDR_LEN * 2);
1138 p_bcb->rcvd_mcast_filters = num_filters;
1139 for (xx = 0; xx < num_filters; xx++)
1141 memcpy (p_bcb->rcvd_mcast_filter_start[xx], p_filters, BD_ADDR_LEN);
1142 memcpy (p_bcb->rcvd_mcast_filter_end[xx], p_filters + BD_ADDR_LEN, BD_ADDR_LEN);
1143 p_filters += (BD_ADDR_LEN * 2);
1145 /* Check if any of the ranges have all zeros as both starting and ending addresses */
1146 if ((memcmp (null_bda, p_bcb->rcvd_mcast_filter_start[xx], BD_ADDR_LEN) == 0) &&
1147 (memcmp (null_bda, p_bcb->rcvd_mcast_filter_end[xx], BD_ADDR_LEN) == 0))
1149 p_bcb->rcvd_mcast_filters = 0xFFFF;
1154 BNEP_TRACE_EVENT ("BNEP multicast filters %d", p_bcb->rcvd_mcast_filters);
1155 bnepu_send_peer_multicast_filter_rsp (p_bcb, resp_code);
1157 if (bnep_cb.p_mfilter_ind_cb)
1158 (*bnep_cb.p_mfilter_ind_cb) (p_bcb->handle, TRUE, 0, len, p_filters);
1162 /*******************************************************************************
1164 ** Function bnepu_send_peer_multicast_filter_rsp
1166 ** Description This function sends a filter response to a peer
1170 *******************************************************************************/
1171 void bnepu_send_peer_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_code)
1173 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BNEP_BUF_SIZE);
1176 BNEP_TRACE_DEBUG ("BNEP sending multicast filter response %d", response_code);
1178 p_buf->offset = L2CAP_MIN_OFFSET;
1179 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
1181 /* Put in BNEP frame type - filter control */
1182 UINT8_TO_BE_STREAM (p, BNEP_FRAME_CONTROL);
1184 /* Put in filter message type - set filters */
1185 UINT8_TO_BE_STREAM (p, BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG);
1187 UINT16_TO_BE_STREAM (p, response_code);
1191 bnepu_check_send_packet (p_bcb, p_buf);
1196 /*******************************************************************************
1198 ** Function bnep_sec_check_complete
1200 ** Description This function is registered with BTM and will be called
1201 ** after completing the security procedures
1205 *******************************************************************************/
1206 void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
1207 void *p_ref_data, UINT8 result)
1209 tBNEP_CONN *p_bcb = (tBNEP_CONN *)p_ref_data;
1210 UINT16 resp_code = BNEP_SETUP_CONN_OK;
1211 BOOLEAN is_role_change;
1215 BNEP_TRACE_EVENT ("BNEP security callback returned result %d", result);
1216 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
1217 is_role_change = TRUE;
1219 is_role_change = FALSE;
1221 /* check if the port is still waiting for security to complete */
1222 if (p_bcb->con_state != BNEP_STATE_SEC_CHECKING)
1224 BNEP_TRACE_ERROR ("BNEP Connection in wrong state %d when security is completed", p_bcb->con_state);
1228 /* if it is outgoing call and result is FAILURE return security fail error */
1229 if (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD))
1231 if (result != BTM_SUCCESS)
1233 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
1235 /* Tell the user that role change is failed because of security */
1236 if (bnep_cb.p_conn_state_cb)
1237 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, BNEP_SECURITY_FAIL, is_role_change);
1239 p_bcb->con_state = BNEP_STATE_CONNECTED;
1240 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID));
1241 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID));
1245 L2CA_DisconnectReq (p_bcb->l2cap_cid);
1247 /* Tell the user if he has a callback */
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);
1251 bnepu_release_bcb (p_bcb);
1255 /* Transition to the next appropriate state, waiting for connection confirm. */
1256 p_bcb->con_state = BNEP_STATE_CONN_SETUP;
1258 bnep_send_conn_req (p_bcb);
1259 alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
1260 bnep_conn_timer_timeout, p_bcb,
1261 btu_general_alarm_queue);
1265 /* it is an incoming call respond appropriately */
1266 if (result != BTM_SUCCESS)
1268 bnep_send_conn_responce (p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
1269 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
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));
1279 L2CA_DisconnectReq (p_bcb->l2cap_cid);
1281 bnepu_release_bcb (p_bcb);
1285 if (bnep_cb.p_conn_ind_cb)
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);
1292 /* Profile didn't register connection indication call back */
1293 bnep_send_conn_responce (p_bcb, resp_code);
1294 bnep_connected (p_bcb);
1301 /*******************************************************************************
1303 ** Function bnep_is_packet_allowed
1305 ** Description This function verifies whether the protocol passes through
1306 ** the protocol filters set by the peer
1308 ** Returns BNEP_SUCCESS - if the protocol is allowed
1309 ** BNEP_IGNORE_CMD - if the protocol is filtered out
1311 *******************************************************************************/
1312 tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb,
1313 BD_ADDR p_dest_addr,
1315 BOOLEAN fw_ext_present,
1318 if (p_bcb->rcvd_num_filters)
1322 /* Findout the actual protocol to check for the filtering */
1324 if (proto == BNEP_802_1_P_PROTOCOL)
1329 /* parse the extension headers and findout actual protocol */
1336 } while (ext & 0x80);
1339 BE_STREAM_TO_UINT16 (proto, p_data);
1342 for (i=0; i<p_bcb->rcvd_num_filters; i++)
1344 if ((p_bcb->rcvd_prot_filter_start[i] <= proto) &&
1345 (proto <= p_bcb->rcvd_prot_filter_end[i]))
1349 if (i == p_bcb->rcvd_num_filters)
1351 BNEP_TRACE_DEBUG ("Ignoring protocol 0x%x in BNEP data write", proto);
1352 return BNEP_IGNORE_CMD;
1356 /* Ckeck for multicast address filtering */
1357 if ((p_dest_addr[0] & 0x01) &&
1358 p_bcb->rcvd_mcast_filters)
1362 /* Check if every multicast should be filtered */
1363 if (p_bcb->rcvd_mcast_filters != 0xFFFF)
1365 /* Check if the address is mentioned in the filter range */
1366 for (i = 0; i < p_bcb->rcvd_mcast_filters; i++)
1368 if ((memcmp (p_bcb->rcvd_mcast_filter_start[i], p_dest_addr, BD_ADDR_LEN) <= 0) &&
1369 (memcmp (p_bcb->rcvd_mcast_filter_end[i], p_dest_addr, BD_ADDR_LEN) >= 0))
1375 ** If every multicast should be filtered or the address is not in the filter range
1378 if ((p_bcb->rcvd_mcast_filters == 0xFFFF) || (i == p_bcb->rcvd_mcast_filters))
1380 BNEP_TRACE_DEBUG ("Ignoring multicast address %x.%x.%x.%x.%x.%x in BNEP data write",
1381 p_dest_addr[0], p_dest_addr[1], p_dest_addr[2],
1382 p_dest_addr[3], p_dest_addr[4], p_dest_addr[5]);
1383 return BNEP_IGNORE_CMD;
1387 return BNEP_SUCCESS;
1390 /*******************************************************************************
1392 ** Function bnep_get_uuid32
1394 ** Description This function returns the 32 bit equivalent of the given UUID
1396 ** Returns UINT32 - 32 bit equivalent of the UUID
1398 *******************************************************************************/
1399 UINT32 bnep_get_uuid32 (tBT_UUID *src_uuid)
1403 if (src_uuid->len == 2)
1404 return ((UINT32)src_uuid->uu.uuid16);
1405 else if (src_uuid->len == 4)
1406 return (src_uuid->uu.uuid32 & 0x0000FFFF);
1409 result = src_uuid->uu.uuid128[2];
1410 result = (result << 8) | (src_uuid->uu.uuid128[3]);