15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2001-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  This file contains BNEP utility functions
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
27911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bnep_int.h"
28258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_types.h"
305cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
31911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btm_int.h"
32911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btu.h"
3379ecab5d0418fde77e9afcdd451bd713af73e180Chris Manton#include "device/include/controller.h"
34d7ffd64accbd50a27289a388856e56244ccbb5daMyles Watson#include "osi/include/osi.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
36911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonextern fixed_queue_t* btu_general_alarm_queue;
3778bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov
38ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/
399ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
40ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/
41911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic uint8_t* bnepu_init_hdr(BT_HDR* p_buf, uint16_t hdr_len,
42911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                               uint8_t pkt_type);
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
44911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_process_peer_multicast_filter_set(tBNEP_CONN* p_bcb,
45911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                             uint8_t* p_filters, uint16_t len);
46911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_send_peer_multicast_filter_rsp(tBNEP_CONN* p_bcb,
47911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                          uint16_t response_code);
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
50ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
51ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_find_bcb_by_cid
52ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
53ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function searches the bcb table for an entry with the
54ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  passed CID.
55ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
56ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          the BCB address, or NULL if not found.
57ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
58ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
59911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontBNEP_CONN* bnepu_find_bcb_by_cid(uint16_t cid) {
60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t xx;
61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Look through each connection control block */
64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) {
65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_bcb->con_state != BNEP_STATE_IDLE) && (p_bcb->l2cap_cid == cid))
66911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return (p_bcb);
67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
68911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
69911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* If here, not found */
70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return (NULL);
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
74ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
75ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_find_bcb_by_bd_addr
76ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
77ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function searches the BCB table for an entry with the
78ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  passed Bluetooth Address.
79ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
80ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          the BCB address, or NULL if not found.
81ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
82ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
83911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontBNEP_CONN* bnepu_find_bcb_by_bd_addr(uint8_t* p_bda) {
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t xx;
85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Look through each connection control block */
88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) {
89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->con_state != BNEP_STATE_IDLE) {
90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (!memcmp((uint8_t*)(p_bcb->rem_bda), p_bda, BD_ADDR_LEN))
91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        return (p_bcb);
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
93911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* If here, not found */
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return (NULL);
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
100ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
101ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_allocate_bcb
102ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
103ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function allocates a new BCB.
104ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
105ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          BCB address, or NULL if none available.
106ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
107ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
108911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontBNEP_CONN* bnepu_allocate_bcb(BD_ADDR p_rem_bda) {
109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t xx;
110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Look through each connection control block for a free one */
113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) {
114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->con_state == BNEP_STATE_IDLE) {
115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      alarm_free(p_bcb->conn_timer);
116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memset((uint8_t*)p_bcb, 0, sizeof(tBNEP_CONN));
117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->conn_timer = alarm_new("bnep.conn_timer");
118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy((uint8_t*)(p_bcb->rem_bda), (uint8_t*)p_rem_bda, BD_ADDR_LEN);
120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->handle = xx + 1;
121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->xmit_q = fixed_queue_new(SIZE_MAX);
122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return (p_bcb);
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* If here, no free BCB found */
128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return (NULL);
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
132ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
133ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_release_bcb
134ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
135ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function releases a BCB.
136ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
137ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
138ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
139ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_release_bcb(tBNEP_CONN* p_bcb) {
141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Ensure timer is stopped */
142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_free(p_bcb->conn_timer);
143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->conn_timer = NULL;
144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Drop any response pointer we may be holding */
146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_state = BNEP_STATE_IDLE;
147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->p_pending_data = NULL;
148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Free transmit queue */
150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  while (!fixed_queue_is_empty(p_bcb->xmit_q)) {
151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    osi_free(fixed_queue_try_dequeue(p_bcb->xmit_q));
152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  fixed_queue_free(p_bcb->xmit_q, NULL);
154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->xmit_q = NULL;
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
158ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
159ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_send_conn_req
160ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
161ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function sends a BNEP connection request to peer
162ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
163ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
164ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
165ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
166911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnep_send_conn_req(tBNEP_CONN* p_bcb) {
167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t *p, *p_start;
169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("%s: sending setup req with dst uuid %x", __func__,
171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_bcb->dst_uuid.uu.uuid16);
172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = p_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in BNEP frame type - filter control */
177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
178911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in filter message type - set filters */
180911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_SETUP_CONNECTION_REQUEST_MSG);
181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, p_bcb->dst_uuid.len);
183911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->dst_uuid.len == 2) {
185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p, p_bcb->dst_uuid.uu.uuid16);
186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p, p_bcb->src_uuid.uu.uuid16);
187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_bcb->dst_uuid.len == 4) {
188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT32_TO_BE_STREAM(p, p_bcb->dst_uuid.uu.uuid32);
189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT32_TO_BE_STREAM(p, p_bcb->src_uuid.uu.uuid32);
190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_bcb->dst_uuid.len == 16) {
191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p, p_bcb->dst_uuid.uu.uuid128, p_bcb->dst_uuid.len);
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p += p_bcb->dst_uuid.len;
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p, p_bcb->src_uuid.uu.uuid128, p_bcb->dst_uuid.len);
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p += p_bcb->dst_uuid.len;
195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("%s: uuid: %x, invalid length: %x", __func__,
197911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     p_bcb->dst_uuid.uu.uuid16, p_bcb->dst_uuid.len);
198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = (uint16_t)(p - p_start);
201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
202911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_check_send_packet(p_bcb, p_buf);
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
206ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
207ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_send_conn_responce
208ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
209ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function sends a BNEP setup response to peer
210ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
211ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
212ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
213ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
214911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnep_send_conn_responce(tBNEP_CONN* p_bcb, uint16_t resp_code) {
215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
216911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP - bnep_send_conn_responce for CID: 0x%x",
219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_bcb->l2cap_cid);
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in BNEP frame type - filter control */
225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in filter message type - set filters */
228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_SETUP_CONNECTION_RESPONSE_MSG);
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p, resp_code);
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 4;
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_check_send_packet(p_bcb, p_buf);
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
238ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
239ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_send_peer_our_filters
240ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
241ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function sends our filters to a peer
242ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
243ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
244ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
245ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_send_peer_our_filters(tBNEP_CONN* p_bcb) {
247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
249911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t xx;
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP sending peer our filters");
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in BNEP frame type - filter control */
257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in filter message type - set filters */
260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FILTER_NET_TYPE_SET_MSG);
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
262911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p, (4 * p_bcb->sent_num_filters));
263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = 0; xx < p_bcb->sent_num_filters; xx++) {
264911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p, p_bcb->sent_prot_filter_start[xx]);
265911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p, p_bcb->sent_prot_filter_end[xx]);
266911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
268911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 4 + (4 * p_bcb->sent_num_filters);
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
270911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_check_send_packet(p_bcb, p_buf);
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
272911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_flags |= BNEP_FLAGS_FILTER_RESP_PEND;
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
274911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Start timer waiting for setup response */
275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
280ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
281ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_send_peer_our_multi_filters
282ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
283ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function sends our multicast filters to a peer
284ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
285ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
286ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
287ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_send_peer_our_multi_filters(tBNEP_CONN* p_bcb) {
289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
291911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t xx;
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP sending peer our multicast filters");
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
295911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
298911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in BNEP frame type - filter control */
299911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in filter message type - set filters */
302911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FILTER_MULTI_ADDR_SET_MSG);
303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p, (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters));
305911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = 0; xx < p_bcb->sent_mcast_filters; xx++) {
306911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p, p_bcb->sent_mcast_filter_start[xx], BD_ADDR_LEN);
307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p += BD_ADDR_LEN;
308911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p, p_bcb->sent_mcast_filter_end[xx], BD_ADDR_LEN);
309911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p += BD_ADDR_LEN;
310911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
312911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 4 + (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters);
313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
314911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_check_send_packet(p_bcb, p_buf);
315911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
316911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_flags |= BNEP_FLAGS_MULTI_RESP_PEND;
317911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
318911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Start timer waiting for setup response */
319911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
320911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
321911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson}
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
324ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
325ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_send_peer_filter_rsp
326ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
327ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function sends a filter response to a peer
328ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
329ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
330ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
331ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
332911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_send_peer_filter_rsp(tBNEP_CONN* p_bcb, uint16_t response_code) {
333911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
334911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
336911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP sending filter response");
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
338911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
341911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in BNEP frame type - filter control */
342911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
344911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in filter message type - set filters */
345911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FILTER_NET_TYPE_RESPONSE_MSG);
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
347911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p, response_code);
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
349911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 4;
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
351911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_check_send_packet(p_bcb, p_buf);
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
355ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
356ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_send_command_not_understood
357ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
358ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function sends a BNEP command not understood message
359ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
360ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
361ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
362ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
363911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnep_send_command_not_understood(tBNEP_CONN* p_bcb, uint8_t cmd_code) {
364911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
365911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
367911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT(
368911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      "BNEP - bnep_send_command_not_understood for CID: 0x%x, cmd 0x%x",
369911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->l2cap_cid, cmd_code);
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
371911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
372911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
374911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in BNEP frame type - filter control */
375911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
377911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in filter message type - set filters */
378911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD);
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
380911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, cmd_code);
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
382911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 3;
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
384911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_check_send_packet(p_bcb, p_buf);
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
388ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
389ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_check_send_packet
390ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
391ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function tries to send a packet to L2CAP.
392ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  If L2CAP is flow controlled, it enqueues the
393ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  packet to the transmit queue
394ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
395ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
396ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
397ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
398911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_check_send_packet(tBNEP_CONN* p_bcb, BT_HDR* p_buf) {
399911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP - bnepu_check_send_packet for CID: 0x%x",
400911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_bcb->l2cap_cid);
401911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_flags & BNEP_FLAGS_L2CAP_CONGESTED) {
402911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) {
403911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BNEP_TRACE_EVENT("BNEP - congested, dropping buf, CID: 0x%x",
404911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       p_bcb->l2cap_cid);
405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
406911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      osi_free(p_buf);
407911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
408911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      fixed_queue_enqueue(p_bcb->xmit_q, p_buf);
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
410911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
411911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    L2CA_DataWrite(p_bcb->l2cap_cid, p_buf);
412911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
416ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
417ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_build_bnep_hdr
418ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
419ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function builds the BNEP header for a packet
420ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  Extension headers are not sent yet, so there is no
421ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  check for that.
422ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
423ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
424ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
425ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
426911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf, uint16_t protocol,
427911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                          uint8_t* p_src_addr, uint8_t* p_dest_addr,
428911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                          bool fw_ext_present) {
429911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  const controller_t* controller = controller_get_interface();
430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t ext_bit, *p = (uint8_t *)NULL;
431911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t type = BNEP_FRAME_COMPRESSED_ETHERNET;
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
433911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  ext_bit = fw_ext_present ? 0x80 : 0x00;
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
435911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_src_addr) &&
436911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (memcmp(p_src_addr, &controller->get_address()->address, BD_ADDR_LEN)))
437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    type = BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY;
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
439911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (memcmp(p_dest_addr, p_bcb->rem_bda, BD_ADDR_LEN))
440911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    type = (type == BNEP_FRAME_COMPRESSED_ETHERNET)
441911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson               ? BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY
442911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson               : BNEP_FRAME_GENERAL_ETHERNET;
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
444911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_src_addr) p_src_addr = (uint8_t*)controller->get_address();
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
446911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (type) {
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_GENERAL_ETHERNET:
448911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = bnepu_init_hdr(p_buf, 15,
449911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                         (uint8_t)(ext_bit | BNEP_FRAME_GENERAL_ETHERNET));
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
451911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy(p, p_dest_addr, BD_ADDR_LEN);
452911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += BD_ADDR_LEN;
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
454911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy(p, p_src_addr, BD_ADDR_LEN);
455911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += BD_ADDR_LEN;
456911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_COMPRESSED_ETHERNET:
459911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = bnepu_init_hdr(p_buf, 3,
460911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                         (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET));
461911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY:
464911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = bnepu_init_hdr(
465911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_buf, 9,
466911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY));
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
468911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy(p, p_src_addr, BD_ADDR_LEN);
469911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += BD_ADDR_LEN;
470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY:
473911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = bnepu_init_hdr(
474911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_buf, 9,
475911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY));
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
477911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy(p, p_dest_addr, BD_ADDR_LEN);
478911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += BD_ADDR_LEN;
479911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
480911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
482911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p, protocol);
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
486ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
487ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_init_hdr
488ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
489ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function initializes the BNEP header
490ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
491ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          pointer to header in buffer
492ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
493ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
494911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic uint8_t* bnepu_init_hdr(BT_HDR* p_buf, uint16_t hdr_len,
495911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                               uint8_t pkt_type) {
496911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
498911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* See if we need to make space in the buffer */
499911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_buf->offset < (hdr_len + L2CAP_MIN_OFFSET)) {
500911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint16_t xx, diff = BNEP_MINIMUM_OFFSET - p_buf->offset;
501911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = p + p_buf->len - 1;
502911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    for (xx = 0; xx < p_buf->len; xx++, p--) p[diff] = *p;
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
504911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_buf->offset = BNEP_MINIMUM_OFFSET;
505911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = (uint8_t*)(p_buf + 1) + p_buf->offset;
506911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
508911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len += hdr_len;
509911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset -= hdr_len;
510911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p -= hdr_len;
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
512911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  *p++ = pkt_type;
513911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
514911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return (p);
515911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson}
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
518ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
519ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_process_setup_conn_req
520ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
521ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes a peer's setup connection request
522ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  message. The destination UUID is verified and response sent
523ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  Connection open indication will be given to PAN profile
524ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
525ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
526ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
527ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
528911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnep_process_setup_conn_req(tBNEP_CONN* p_bcb, uint8_t* p_setup,
529911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                 uint8_t len) {
530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP - bnep_process_setup_conn_req for CID: 0x%x",
531911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_bcb->l2cap_cid);
532911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
533911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_state != BNEP_STATE_CONN_SETUP &&
534911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->con_state != BNEP_STATE_SEC_CHECKING &&
535911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->con_state != BNEP_STATE_CONNECTED) {
536911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - setup request in bad state %d", p_bcb->con_state);
537911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnep_send_conn_responce(p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
538911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
539911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
541911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Check if we already initiated security check or if waiting for user
542911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   * responce */
543911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD) {
544911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT(
545911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        "BNEP - Duplicate Setup message received while doing security check");
546911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
547911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
548911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
549911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Check if peer is the originator */
550911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_state != BNEP_STATE_CONNECTED &&
551911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) &&
552911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) {
553911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - setup request when we are originator",
554911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     p_bcb->con_state);
555911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnep_send_conn_responce(p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
556911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
557911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
558911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
559911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_state == BNEP_STATE_CONNECTED) {
560911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy((uint8_t*)&(p_bcb->prv_src_uuid), (uint8_t*)&(p_bcb->src_uuid),
561911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           sizeof(tBT_UUID));
562911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy((uint8_t*)&(p_bcb->prv_dst_uuid), (uint8_t*)&(p_bcb->dst_uuid),
563911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           sizeof(tBT_UUID));
564911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
565911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
566911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->dst_uuid.len = p_bcb->src_uuid.len = len;
567911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
568911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->dst_uuid.len == 2) {
569911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* because peer initiated connection keep src uuid as dst uuid */
570911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT16(p_bcb->src_uuid.uu.uuid16, p_setup);
571911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT16(p_bcb->dst_uuid.uu.uuid16, p_setup);
572911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
573911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* If nothing has changed don't bother the profile */
574911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->con_state == BNEP_STATE_CONNECTED &&
575911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->src_uuid.uu.uuid16 == p_bcb->prv_src_uuid.uu.uuid16 &&
576911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->dst_uuid.uu.uuid16 == p_bcb->prv_dst_uuid.uu.uuid16) {
577911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnep_send_conn_responce(p_bcb, BNEP_SETUP_CONN_OK);
578911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
580911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_bcb->dst_uuid.len == 4) {
581911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT32(p_bcb->src_uuid.uu.uuid32, p_setup);
582911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT32(p_bcb->dst_uuid.uu.uuid32, p_setup);
583911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_bcb->dst_uuid.len == 16) {
584911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p_bcb->src_uuid.uu.uuid128, p_setup, p_bcb->src_uuid.len);
585911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_setup += p_bcb->src_uuid.len;
586911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p_bcb->dst_uuid.uu.uuid128, p_setup, p_bcb->dst_uuid.len);
587911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_setup += p_bcb->dst_uuid.len;
588911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
589911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - Bad UID len %d in ConnReq", p_bcb->dst_uuid.len);
590911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnep_send_conn_responce(p_bcb, BNEP_SETUP_INVALID_UUID_SIZE);
591911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
592911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
594911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
595911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_flags |= BNEP_FLAGS_SETUP_RCVD;
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
597911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT(
598911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      "BNEP initiating security check for incoming call for uuid 0x%x",
599911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->src_uuid.uu.uuid16);
600d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (BNEP_DO_AUTH_FOR_ROLE_SWITCH == FALSE)
601911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
602911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnep_sec_check_complete(p_bcb->rem_bda, p_bcb, BTM_SUCCESS);
603911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
605911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_mx_access_request(
606911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->rem_bda, BT_PSM_BNEP, false, BTM_SEC_PROTO_BNEP,
607911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        bnep_get_uuid32(&(p_bcb->src_uuid)), &bnep_sec_check_complete, p_bcb);
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
609911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return;
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
613ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
614ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_process_setup_conn_responce
615ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
616ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes a peer's setup connection response
617ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  message. The response code is verified and
618ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  Connection open indication will be given to PAN profile
619ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
620ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
621ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
622ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
623911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnep_process_setup_conn_responce(tBNEP_CONN* p_bcb, uint8_t* p_setup) {
624911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_RESULT resp;
625911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t resp_code;
626911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
627911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP received setup responce");
628911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* The state should be either SETUP or CONNECTED */
629911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_state != BNEP_STATE_CONN_SETUP) {
630911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Should we disconnect ? */
631911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - setup response in bad state %d", p_bcb->con_state);
632911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
633911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
635911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Check if we are the originator */
636911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!(p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) {
637911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - setup response when we are not originator",
638911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     p_bcb->con_state);
639911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
640911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
642911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BE_STREAM_TO_UINT16(resp_code, p_setup);
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
644911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (resp_code) {
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_SETUP_INVALID_SRC_UUID:
646911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      resp = BNEP_CONN_FAILED_SRC_UUID;
647911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_SETUP_INVALID_DEST_UUID:
650911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      resp = BNEP_CONN_FAILED_DST_UUID;
651911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_SETUP_INVALID_UUID_SIZE:
654911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      resp = BNEP_CONN_FAILED_UUID_SIZE;
655911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_SETUP_CONN_NOT_ALLOWED:
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    default:
659911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      resp = BNEP_CONN_FAILED;
660911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
661911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
662911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
663911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Check the responce code */
664911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (resp_code != BNEP_SETUP_CONN_OK) {
665911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) {
666911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BNEP_TRACE_EVENT("BNEP - role change response is %d", resp_code);
667911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
668911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Restore the earlier BNEP status */
669911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->con_state = BNEP_STATE_CONNECTED;
670911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
671911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)&(p_bcb->prv_src_uuid),
672911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson             sizeof(tBT_UUID));
673911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)&(p_bcb->prv_dst_uuid),
674911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson             sizeof(tBT_UUID));
675911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
676911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Ensure timer is stopped */
677911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      alarm_cancel(p_bcb->conn_timer);
678911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->re_transmits = 0;
679911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
680911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Tell the user if he has a callback */
681911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (bnep_cb.p_conn_state_cb)
682911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda, resp, true);
683911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
684911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
685911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
686911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BNEP_TRACE_ERROR("BNEP - setup response %d is not OK", resp_code);
687911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
688911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      L2CA_DisconnectReq(p_bcb->l2cap_cid);
689911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
690911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Tell the user if he has a callback */
691911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) && (bnep_cb.p_conn_state_cb))
692911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda, resp, false);
693911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
694911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_release_bcb(p_bcb);
695911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
697911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
699911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Received successful responce */
700911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_connected(p_bcb);
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
704ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
705ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_process_control_packet
706ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
707ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes a peer's setup connection request
708ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  message. The destination UUID is verified and response sent
709ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  Connection open indication will be given to PAN profile
710ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
711ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
712ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
713ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
714911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
715911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                     uint16_t* rem_len, bool is_ext) {
716911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t control_type;
717911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool bad_pkt = false;
718911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t len, ext_len = 0;
719911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
720911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (is_ext) {
721911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ext_len = *p++;
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *rem_len = *rem_len - 1;
723911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
725911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  control_type = *p++;
726911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  *rem_len = *rem_len - 1;
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
728911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT(
729911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      "BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d",
730911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      *rem_len, is_ext, control_type);
731911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
732911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (control_type) {
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
734911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BNEP_TRACE_ERROR("BNEP Received Cmd not understood for ctl pkt type: %d",
735911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       *p);
736911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p++;
737911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      *rem_len = *rem_len - 1;
738911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_SETUP_CONNECTION_REQUEST_MSG:
741911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      len = *p++;
742911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (*rem_len < ((2 * len) + 1)) {
743911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        bad_pkt = true;
744911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        BNEP_TRACE_ERROR("BNEP Received Setup message with bad length");
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
746911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
747911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (!is_ext) bnep_process_setup_conn_req(p_bcb, p, (uint8_t)len);
748911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += (2 * len);
749911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      *rem_len = *rem_len - (2 * len) - 1;
750911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_SETUP_CONNECTION_RESPONSE_MSG:
753911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (!is_ext) bnep_process_setup_conn_responce(p_bcb, p);
754911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += 2;
755911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      *rem_len = *rem_len - 2;
756911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FILTER_NET_TYPE_SET_MSG:
759911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(len, p);
760911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (*rem_len < (len + 2)) {
761911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        bad_pkt = true;
762911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        BNEP_TRACE_ERROR("BNEP Received Filter set message with bad length");
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
764911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
765911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_process_peer_filter_set(p_bcb, p, len);
766911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += len;
767911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      *rem_len = *rem_len - len - 2;
768911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FILTER_NET_TYPE_RESPONSE_MSG:
771911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_process_peer_filter_rsp(p_bcb, p);
772911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += 2;
773911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      *rem_len = *rem_len - 2;
774911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FILTER_MULTI_ADDR_SET_MSG:
777911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(len, p);
778911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (*rem_len < (len + 2)) {
779911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        bad_pkt = true;
780911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        BNEP_TRACE_ERROR(
781911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            "BNEP Received Multicast Filter Set message with bad length");
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
783911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
784911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_process_peer_multicast_filter_set(p_bcb, p, len);
785911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += len;
786911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      *rem_len = *rem_len - len - 2;
787911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG:
790911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_process_multicast_filter_rsp(p_bcb, p);
791911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += 2;
792911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      *rem_len = *rem_len - 2;
793911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
795911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    default:
796911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BNEP_TRACE_ERROR("BNEP - bad ctl pkt type: %d", control_type);
797911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnep_send_command_not_understood(p_bcb, control_type);
798911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (is_ext) {
799911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p += (ext_len - 1);
800911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        *rem_len -= (ext_len - 1);
801911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
802911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
803911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
804911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
805911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (bad_pkt) {
806911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - bad ctl pkt length: %d", *rem_len);
807911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    *rem_len = 0;
808911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return NULL;
809911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
810911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
811911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p;
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
815ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
816ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_process_peer_filter_set
817ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
818ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes a peer's filter control
819ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  'set' message. The filters are stored in the BCB,
820ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  and an appropriate filter response message sent.
821ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
822ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
823ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
824ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
825911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_process_peer_filter_set(tBNEP_CONN* p_bcb, uint8_t* p_filters,
826911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   uint16_t len) {
827911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t num_filters = 0;
828911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t xx, resp_code = BNEP_FILTER_CRL_OK;
829911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t start, end;
830911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p_temp_filters;
831911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
832911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
833911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) {
834911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_DEBUG(
835911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        "BNEP received filter set from peer when there is no connection");
836911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
837911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
839911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP received filter set from peer");
840911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Check for length not a multiple of 4 */
841911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (len & 3) {
842911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - bad filter len: %d", len);
843911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnepu_send_peer_filter_rsp(p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
844911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
845911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
847911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (len) num_filters = (uint16_t)(len >> 2);
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
849911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Validate filter values */
850911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (num_filters <= BNEP_MAX_PROT_FILTERS) {
851911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_temp_filters = p_filters;
852911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    for (xx = 0; xx < num_filters; xx++) {
853911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(start, p_temp_filters);
854911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(end, p_temp_filters);
855911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
856911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (start > end) {
857911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        resp_code = BNEP_FILTER_CRL_BAD_RANGE;
858911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
859911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
861911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else
862911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    resp_code = BNEP_FILTER_CRL_MAX_REACHED;
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
864911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (resp_code != BNEP_FILTER_CRL_OK) {
865911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnepu_send_peer_filter_rsp(p_bcb, resp_code);
866911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
867911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
869911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (bnep_cb.p_filter_ind_cb)
870911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    (*bnep_cb.p_filter_ind_cb)(p_bcb->handle, true, 0, len, p_filters);
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
872911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->rcvd_num_filters = num_filters;
873911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = 0; xx < num_filters; xx++) {
874911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT16(start, p_filters);
875911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT16(end, p_filters);
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
877911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->rcvd_prot_filter_start[xx] = start;
878911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->rcvd_prot_filter_end[xx] = end;
879911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
881911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_send_peer_filter_rsp(p_bcb, resp_code);
882911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson}
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
885ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
886ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_process_peer_filter_rsp
887ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
888ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes a peer's filter control
889ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  'response' message.
890ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
891ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
892ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
893ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
894911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_process_peer_filter_rsp(tBNEP_CONN* p_bcb, uint8_t* p_data) {
895911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t resp_code;
896911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_RESULT result;
897911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
898911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP received filter responce");
899911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* The state should be  CONNECTED */
900911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
901911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) {
902911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - filter response in bad state %d",
903911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     p_bcb->con_state);
904911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
905911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
907911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Check if we are the originator */
908911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!(p_bcb->con_flags & BNEP_FLAGS_FILTER_RESP_PEND)) {
909911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - filter response when not expecting");
910911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
911911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
913911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Ensure timer is stopped */
914911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_cancel(p_bcb->conn_timer);
915911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_flags &= ~BNEP_FLAGS_FILTER_RESP_PEND;
916911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->re_transmits = 0;
9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
918911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BE_STREAM_TO_UINT16(resp_code, p_data);
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
920911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  result = BNEP_SUCCESS;
921911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (resp_code != BNEP_FILTER_CRL_OK) result = BNEP_SET_FILTER_FAIL;
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
923911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (bnep_cb.p_filter_ind_cb)
924911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    (*bnep_cb.p_filter_ind_cb)(p_bcb->handle, false, result, 0, NULL);
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
928ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
929ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_process_multicast_filter_rsp
930ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
931ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes multicast filter control
932ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  'response' message.
933ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
934ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
935ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
936ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
937911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_process_multicast_filter_rsp(tBNEP_CONN* p_bcb, uint8_t* p_data) {
938911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t resp_code;
939911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_RESULT result;
940911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
941911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP received multicast filter responce");
942911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* The state should be  CONNECTED */
943911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
944911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) {
945911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - multicast filter response in bad state %d",
946911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     p_bcb->con_state);
947911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
948911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
950911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Check if we are the originator */
951911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!(p_bcb->con_flags & BNEP_FLAGS_MULTI_RESP_PEND)) {
952911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - multicast filter response when not expecting");
953911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
954911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
956911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Ensure timer is stopped */
957911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_cancel(p_bcb->conn_timer);
958911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_flags &= ~BNEP_FLAGS_MULTI_RESP_PEND;
959911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->re_transmits = 0;
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
961911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BE_STREAM_TO_UINT16(resp_code, p_data);
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
963911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  result = BNEP_SUCCESS;
964911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (resp_code != BNEP_FILTER_CRL_OK) result = BNEP_SET_FILTER_FAIL;
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
966911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (bnep_cb.p_mfilter_ind_cb)
967911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    (*bnep_cb.p_mfilter_ind_cb)(p_bcb->handle, false, result, 0, NULL);
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
971ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
972ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_process_peer_multicast_filter_set
973ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
974ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes a peer's filter control
975ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  'set' message. The filters are stored in the BCB,
976ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  and an appropriate filter response message sent.
977ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
978ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
979ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
980ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
981911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_process_peer_multicast_filter_set(tBNEP_CONN* p_bcb,
982911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                             uint8_t* p_filters, uint16_t len) {
983911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t resp_code = BNEP_FILTER_CRL_OK;
984911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t num_filters, xx;
985911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t *p_temp_filters, null_bda[BD_ADDR_LEN] = {0, 0, 0, 0, 0, 0};
986911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
987911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
988911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) {
989911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_DEBUG(
990911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        "BNEP received multicast filter set from peer when there is no "
991911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        "connection");
992911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
993911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
995911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (len % 12) {
996911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - bad filter len: %d", len);
997911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnepu_send_peer_multicast_filter_rsp(p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
998911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
999911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1001911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (len > (BNEP_MAX_MULTI_FILTERS * 2 * BD_ADDR_LEN)) {
1002911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - Too many filters");
1003911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnepu_send_peer_multicast_filter_rsp(p_bcb, BNEP_FILTER_CRL_MAX_REACHED);
1004911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
1005911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1006911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1007911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  num_filters = 0;
1008911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (len) num_filters = (uint16_t)(len / 12);
1009911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1010911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Validate filter values */
1011911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (num_filters <= BNEP_MAX_MULTI_FILTERS) {
1012911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_temp_filters = p_filters;
1013911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    for (xx = 0; xx < num_filters; xx++) {
1014911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (memcmp(p_temp_filters, p_temp_filters + BD_ADDR_LEN, BD_ADDR_LEN) >
1015911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          0) {
1016911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        bnepu_send_peer_multicast_filter_rsp(p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
1018911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1020911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_temp_filters += (BD_ADDR_LEN * 2);
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1022911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1023911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1024911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->rcvd_mcast_filters = num_filters;
1025911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = 0; xx < num_filters; xx++) {
1026911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p_bcb->rcvd_mcast_filter_start[xx], p_filters, BD_ADDR_LEN);
1027911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p_bcb->rcvd_mcast_filter_end[xx], p_filters + BD_ADDR_LEN,
1028911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           BD_ADDR_LEN);
1029911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_filters += (BD_ADDR_LEN * 2);
1030911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1031911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Check if any of the ranges have all zeros as both starting and ending
1032911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     * addresses */
1033911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((memcmp(null_bda, p_bcb->rcvd_mcast_filter_start[xx], BD_ADDR_LEN) ==
1034911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         0) &&
1035911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (memcmp(null_bda, p_bcb->rcvd_mcast_filter_end[xx], BD_ADDR_LEN) ==
1036911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         0)) {
1037911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->rcvd_mcast_filters = 0xFFFF;
1038911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1040911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1042911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP multicast filters %d", p_bcb->rcvd_mcast_filters);
1043911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_send_peer_multicast_filter_rsp(p_bcb, resp_code);
10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1045911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (bnep_cb.p_mfilter_ind_cb)
1046911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    (*bnep_cb.p_mfilter_ind_cb)(p_bcb->handle, true, 0, len, p_filters);
10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1050ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1051ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnepu_send_peer_multicast_filter_rsp
1052ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1053ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function sends a filter response to a peer
1054ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1055ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
1056ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1057ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1058911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnepu_send_peer_multicast_filter_rsp(tBNEP_CONN* p_bcb,
1059911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                          uint16_t response_code) {
1060911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
1061911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1063911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP sending multicast filter response %d", response_code);
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1065911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
1066911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1068911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in BNEP frame type - filter control */
1069911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1071911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Put in filter message type - set filters */
1072911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG);
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1074911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p, response_code);
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1076911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 4;
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1078911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_check_send_packet(p_bcb, p_buf);
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1082ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1083ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_sec_check_complete
1084ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1085ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is registered with BTM and will be called
1086ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  after completing the security procedures
1087ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1088ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
1089ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1090ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1091911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnep_sec_check_complete(UNUSED_ATTR BD_ADDR bd_addr,
1092911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             UNUSED_ATTR tBT_TRANSPORT trasnport,
1093911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             void* p_ref_data, uint8_t result) {
1094911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb = (tBNEP_CONN*)p_ref_data;
1095911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t resp_code = BNEP_SETUP_CONN_OK;
1096911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool is_role_change;
1097911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1098911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP security callback returned result %d", result);
1099911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
1100911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    is_role_change = true;
1101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
1102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    is_role_change = false;
1103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* check if the port is still waiting for security to complete */
1105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_state != BNEP_STATE_SEC_CHECKING) {
1106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR(
1107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        "BNEP Connection in wrong state %d when security is completed",
1108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->con_state);
1109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
1110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* if it is outgoing call and result is FAILURE return security fail error */
1113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) {
1114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (result != BTM_SUCCESS) {
1115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) {
1116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* Tell the user that role change is failed because of security */
1117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (bnep_cb.p_conn_state_cb)
1118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
1119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                     BNEP_SECURITY_FAIL, is_role_change);
1120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->con_state = BNEP_STATE_CONNECTED;
1122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)&(p_bcb->prv_src_uuid),
1123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson               sizeof(tBT_UUID));
1124911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)&(p_bcb->prv_dst_uuid),
1125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson               sizeof(tBT_UUID));
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
1127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      L2CA_DisconnectReq(p_bcb->l2cap_cid);
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Tell the user if he has a callback */
1132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (bnep_cb.p_conn_state_cb)
1133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
1134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   BNEP_SECURITY_FAIL, is_role_change);
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_release_bcb(p_bcb);
1137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Transition to the next appropriate state, waiting for connection confirm.
1141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     */
1142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->con_state = BNEP_STATE_CONN_SETUP;
1143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnep_send_conn_req(p_bcb);
1145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
1146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
1147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
1148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* it is an incoming call respond appropriately */
1151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (result != BTM_SUCCESS) {
1152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnep_send_conn_responce(p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
1153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) {
1154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Role change is failed because of security. Revert back to connected
1155911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       * state */
1156911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->con_state = BNEP_STATE_CONNECTED;
1157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
1158911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)&(p_bcb->prv_src_uuid),
1159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson             sizeof(tBT_UUID));
1160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)&(p_bcb->prv_dst_uuid),
1161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson             sizeof(tBT_UUID));
1162911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1165911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    L2CA_DisconnectReq(p_bcb->l2cap_cid);
1166911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnepu_release_bcb(p_bcb);
11685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return;
1169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (bnep_cb.p_conn_ind_cb) {
1172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->con_state = BNEP_STATE_CONN_SETUP;
1173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    (*bnep_cb.p_conn_ind_cb)(p_bcb->handle, p_bcb->rem_bda, &p_bcb->dst_uuid,
1174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             &p_bcb->src_uuid, is_role_change);
1175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
1176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Profile didn't register connection indication call back */
1177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnep_send_conn_responce(p_bcb, resp_code);
1178911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnep_connected(p_bcb);
1179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1180911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return;
11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1185ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1186ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_is_packet_allowed
1187ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1188ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function verifies whether the protocol passes through
1189ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the protocol filters set by the peer
1190ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1191ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          BNEP_SUCCESS          - if the protocol is allowed
1192ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  BNEP_IGNORE_CMD       - if the protocol is filtered out
1193ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1194ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1195911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb, BD_ADDR p_dest_addr,
1196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                    uint16_t protocol, bool fw_ext_present,
1197911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                    uint8_t* p_data) {
1198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->rcvd_num_filters) {
1199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint16_t i, proto;
1200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Findout the actual protocol to check for the filtering */
1202911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    proto = protocol;
1203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (proto == BNEP_802_1_P_PROTOCOL) {
1204911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (fw_ext_present) {
1205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        uint8_t len, ext;
1206911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* parse the extension headers and findout actual protocol */
1207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        do {
1208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          ext = *p_data++;
1209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          len = *p_data++;
1210911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_data += len;
1211911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        } while (ext & 0x80);
1213911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1214911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_data += 2;
1215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(proto, p_data);
12165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    for (i = 0; i < p_bcb->rcvd_num_filters; i++) {
1219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if ((p_bcb->rcvd_prot_filter_start[i] <= proto) &&
1220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          (proto <= p_bcb->rcvd_prot_filter_end[i]))
1221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
12225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (i == p_bcb->rcvd_num_filters) {
1225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BNEP_TRACE_DEBUG("Ignoring protocol 0x%x in BNEP data write", proto);
1226911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return BNEP_IGNORE_CMD;
1227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
1228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Ckeck for multicast address filtering */
1231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_dest_addr[0] & 0x01) && p_bcb->rcvd_mcast_filters) {
1232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint16_t i;
1233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Check if every multicast should be filtered */
1235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->rcvd_mcast_filters != 0xFFFF) {
1236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Check if the address is mentioned in the filter range */
1237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      for (i = 0; i < p_bcb->rcvd_mcast_filters; i++) {
1238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if ((memcmp(p_bcb->rcvd_mcast_filter_start[i], p_dest_addr,
1239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    BD_ADDR_LEN) <= 0) &&
1240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            (memcmp(p_bcb->rcvd_mcast_filter_end[i], p_dest_addr,
1241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    BD_ADDR_LEN) >= 0))
1242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
1243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
1245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /*
1247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ** If every multicast should be filtered or the address is not in the filter
1248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    *range
1249911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ** drop the packet
1250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    */
1251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_bcb->rcvd_mcast_filters == 0xFFFF) ||
1252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (i == p_bcb->rcvd_mcast_filters)) {
1253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BNEP_TRACE_DEBUG(
1254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          "Ignoring multicast address %x.%x.%x.%x.%x.%x in BNEP data write",
1255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_dest_addr[0], p_dest_addr[1], p_dest_addr[2], p_dest_addr[3],
1256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_dest_addr[4], p_dest_addr[5]);
1257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return BNEP_IGNORE_CMD;
1258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
1259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1261911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return BNEP_SUCCESS;
12625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
12635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1265ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1266ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_get_uuid32
1267ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
12689ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function returns the 32-bit equivalent of the UUID
1269ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
12709ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Returns          uint32_t - 32-bit equivalent of the UUID
1271ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1272ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1273911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint32_t bnep_get_uuid32(tBT_UUID* src_uuid) {
1274911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint32_t result;
1275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (src_uuid->len == 2)
1277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return ((uint32_t)src_uuid->uu.uuid16);
1278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else if (src_uuid->len == 4)
1279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return (src_uuid->uu.uuid32 & 0x0000FFFF);
1280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else {
1281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    result = src_uuid->uu.uuid128[2];
1282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    result = (result << 8) | (src_uuid->uu.uuid128[3]);
1283911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return result;
1284911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
12855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1286