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 the main BNEP functions
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include <stdio.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h>
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
28911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bt_target.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_types.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcidefs.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcimsgs.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2cdefs.h"
373eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang#include "log/log.h"
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h"
40911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btu.h"
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bnep_api.h"
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bnep_int.h"
445cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4679ecab5d0418fde77e9afcdd451bd713af73e180Chris Manton#include "device/include/controller.h"
47d7ffd64accbd50a27289a388856e56244ccbb5daMyles Watson#include "osi/include/osi.h"
4839110ec88460421618330863807804e03594ef67Zach Johnson
49ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/
509ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/*                     G L O B A L    B N E P       D A T A                   */
51ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/
5237c1b5f8ccf4fc6d5132e07f98f0f40f65d5bfafPavlin RadoslavovtBNEP_CB bnep_cb;
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
54d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenconst uint16_t bnep_frame_hdr_sizes[] = {14, 1, 2, 8, 8};
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
56ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/
579ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
58ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/
599e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskistatic void bnep_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid,
60c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski                             uint16_t psm, uint8_t l2cap_id);
61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_connect_cfm(uint16_t l2cap_cid, uint16_t result);
62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_config_cfm(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_disconnect_ind(uint16_t l2cap_cid, bool ack_needed);
65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_disconnect_cfm(uint16_t l2cap_cid, uint16_t result);
66911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg);
67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_congestion_ind(uint16_t lcid, bool is_congested);
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
70ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
71ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_register_with_l2cap
72ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
73ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function registers BNEP PSM with L2CAP
74ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
75ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
76ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
77ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
78911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontBNEP_RESULT bnep_register_with_l2cap(void) {
79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Initialize the L2CAP configuration. We only care about MTU and flush */
80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memset(&bnep_cb.l2cap_my_cfg, 0, sizeof(tL2CAP_CFG_INFO));
81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.l2cap_my_cfg.mtu_present = true;
83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.l2cap_my_cfg.mtu = BNEP_MTU_SIZE;
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.l2cap_my_cfg.flush_to_present = true;
85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.l2cap_my_cfg.flush_to = BNEP_FLUSH_TO;
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.reg_info.pL2CA_ConnectInd_Cb = bnep_connect_ind;
88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.reg_info.pL2CA_ConnectCfm_Cb = bnep_connect_cfm;
89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.reg_info.pL2CA_ConfigInd_Cb = bnep_config_ind;
90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.reg_info.pL2CA_ConfigCfm_Cb = bnep_config_cfm;
91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.reg_info.pL2CA_DisconnectInd_Cb = bnep_disconnect_ind;
92911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.reg_info.pL2CA_DisconnectCfm_Cb = bnep_disconnect_cfm;
93911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.reg_info.pL2CA_DataInd_Cb = bnep_data_ind;
94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnep_cb.reg_info.pL2CA_CongestionStatus_Cb = bnep_congestion_ind;
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Now, register with L2CAP */
97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!L2CA_Register(BT_PSM_BNEP, &bnep_cb.reg_info)) {
98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_ERROR("BNEP - Registration failed");
99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return BNEP_SECURITY_FAIL;
100911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return BNEP_SUCCESS;
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
106ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
107ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_connect_ind
108ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
109ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function handles an inbound connection indication
110ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  from L2CAP. This is the case where we are acting as a
111ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  server.
112ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
113ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
114ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
115ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1169e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskistatic void bnep_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid,
117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             UNUSED_ATTR uint16_t psm, uint8_t l2cap_id) {
118a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski  tBNEP_CONN* p_bcb = bnepu_find_bcb_by_bd_addr(bd_addr);
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* If we are not acting as server, or already have a connection, or have */
121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* no more resources to handle the connection, reject the connection.    */
122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!(bnep_cb.profile_registered) || (p_bcb) ||
123a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski      ((p_bcb = bnepu_allocate_bcb(bd_addr)) == NULL)) {
124911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    L2CA_ConnectRsp(bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_NO_PSM, 0);
125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Transition to the next appropriate state, waiting for config setup. */
129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_state = BNEP_STATE_CFG_SETUP;
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Save the L2CAP Channel ID. */
132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->l2cap_cid = l2cap_cid;
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Send response to the L2CAP layer. */
135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  L2CA_ConnectRsp(bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK);
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Send a Configuration Request. */
138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  L2CA_ConfigReq(l2cap_cid, &bnep_cb.l2cap_my_cfg);
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Start timer waiting for config setup */
14147616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski  alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
14247616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski                     bnep_conn_timer_timeout, p_bcb);
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP - Rcvd L2CAP conn ind, CID: 0x%x", p_bcb->l2cap_cid);
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
148ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
149ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_connect_cfm
150ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
151ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function handles the connect confirm events
152ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  from L2CAP. This is the case when we are acting as a
153ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  client and have sent a connect request.
154ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
155ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
156ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
157ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
158911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_connect_cfm(uint16_t l2cap_cid, uint16_t result) {
159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Find CCB based on CID */
162911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb = bnepu_find_bcb_by_cid(l2cap_cid);
163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb == NULL) {
164911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_WARNING("BNEP - Rcvd conn cnf for unknown CID 0x%x", l2cap_cid);
165911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
166911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* If the connection response contains success status, then */
169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Transition to the next state and startup the timer.      */
170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((result == L2CAP_CONN_OK) &&
171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_bcb->con_state == BNEP_STATE_CONN_START)) {
172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->con_state = BNEP_STATE_CFG_SETUP;
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Send a Configuration Request. */
175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    L2CA_ConfigReq(l2cap_cid, &bnep_cb.l2cap_my_cfg);
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Start timer waiting for config results */
17847616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski    alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
17947616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski                       bnep_conn_timer_timeout, p_bcb);
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - got conn cnf, sent cfg req, CID: 0x%x",
182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     p_bcb->l2cap_cid);
183911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_WARNING("BNEP - Rcvd conn cnf with error: 0x%x  CID 0x%x",
185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       result, p_bcb->l2cap_cid);
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Tell the upper layer, if he has a callback */
188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (bnep_cb.p_conn_state_cb && p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) {
189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                 BNEP_CONN_FAILED, false);
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnepu_release_bcb(p_bcb);
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
198ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
199ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_config_ind
200ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
201ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes the L2CAP configuration indication
202ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  event.
203ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
204ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
205ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
206ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg) {
208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t result, mtu = 0;
210911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
211911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Find CCB based on CID */
212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb = bnepu_find_bcb_by_cid(l2cap_cid);
213911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb == NULL) {
214911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_WARNING("BNEP - Rcvd L2CAP cfg ind, unknown CID: 0x%x",
215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       l2cap_cid);
216911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
217911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP - Rcvd cfg ind, CID: 0x%x", l2cap_cid);
220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Remember the remote MTU size */
222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((!p_cfg->mtu_present) || (p_cfg->mtu < BNEP_MIN_MTU_SIZE)) {
223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    mtu = p_cfg->mtu;
224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cfg->flush_to_present = false;
225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cfg->mtu_present = true;
226911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cfg->mtu = BNEP_MIN_MTU_SIZE;
227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cfg->result = result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cfg->mtu > BNEP_MTU_SIZE)
230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->rem_mtu_size = BNEP_MTU_SIZE;
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->rem_mtu_size = p_cfg->mtu;
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* For now, always accept configuration from the other side */
235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cfg->flush_to_present = false;
236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cfg->mtu_present = false;
237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cfg->result = result = L2CAP_CFG_OK;
238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  L2CA_ConfigRsp(l2cap_cid, p_cfg);
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (result != L2CAP_CFG_OK) {
243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - Rcvd cfg ind with bad MTU %d, CID: 0x%x", mtu,
244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     l2cap_cid);
245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_flags |= BNEP_FLAGS_HIS_CFG_DONE;
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_flags & BNEP_FLAGS_MY_CFG_DONE) {
251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Start timer waiting for setup or response */
25447616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski    alarm_set_on_mloop(p_bcb->conn_timer, BNEP_HOST_TIMEOUT_MS,
25547616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski                       bnep_conn_timer_timeout, p_bcb);
256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) {
258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      btm_sec_mx_access_request(
259a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski          p_bcb->rem_bda, BT_PSM_BNEP, true, BTM_SEC_PROTO_BNEP,
260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          bnep_get_uuid32(&(p_bcb->src_uuid)), &bnep_sec_check_complete, p_bcb);
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
262911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
266ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
267ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_config_cfm
268ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
269ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes the L2CAP configuration confirmation
270ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  event.
271ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
272ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
273ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
274ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_config_cfm(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg) {
276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP - Rcvd cfg cfm, CID: 0x%x  Result: %d", l2cap_cid,
279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_cfg->result);
280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Find CCB based on CID */
282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb = bnepu_find_bcb_by_cid(l2cap_cid);
283911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb == NULL) {
284911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_WARNING("BNEP - Rcvd L2CAP cfg ind, unknown CID: 0x%x",
285911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       l2cap_cid);
286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
287911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* For now, always accept configuration from the other side */
290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cfg->result == L2CAP_CFG_OK) {
291911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->con_flags |= BNEP_FLAGS_MY_CFG_DONE;
292911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->con_flags & BNEP_FLAGS_HIS_CFG_DONE) {
294911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
295911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Start timer waiting for setup or response */
29747616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski      alarm_set_on_mloop(p_bcb->conn_timer, BNEP_HOST_TIMEOUT_MS,
29847616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski                         bnep_conn_timer_timeout, p_bcb);
299911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
300911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) {
301a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski        btm_sec_mx_access_request(p_bcb->rem_bda, BT_PSM_BNEP, true,
302a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski                                  BTM_SEC_PROTO_BNEP,
303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  bnep_get_uuid32(&(p_bcb->src_uuid)),
304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  &bnep_sec_check_complete, p_bcb);
305911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
308911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Tell the upper layer, if he has a callback */
309911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) && (bnep_cb.p_conn_state_cb)) {
310911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
311911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                 BNEP_CONN_FAILED_CFG, false);
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
314911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    L2CA_DisconnectReq(p_bcb->l2cap_cid);
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
316911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnepu_release_bcb(p_bcb);
317911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
321ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
322ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_disconnect_ind
323ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
324ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function handles a disconnect event from L2CAP. If
325ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  requested to, we ack the disconnect before dropping the CCB
326ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
327ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
328ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
329ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
330911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_disconnect_ind(uint16_t l2cap_cid, bool ack_needed) {
331911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
333911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (ack_needed) L2CA_DisconnectRsp(l2cap_cid);
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
335911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Find CCB based on CID */
336911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb = bnepu_find_bcb_by_cid(l2cap_cid);
337911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb == NULL) {
338911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_WARNING("BNEP - Rcvd L2CAP disc, unknown CID: 0x%x", l2cap_cid);
339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
340911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
342911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
344911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Tell the user if he has a callback */
345911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_state == BNEP_STATE_CONNECTED) {
346911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (bnep_cb.p_conn_state_cb)
347911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
348911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                 BNEP_CONN_DISCONNECTED, false);
349911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
350911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((bnep_cb.p_conn_state_cb) &&
351911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) ||
352911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
353911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
354911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                 BNEP_CONN_FAILED, false);
355911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
356911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
357911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bnepu_release_bcb(p_bcb);
358911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson}
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
361ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
362ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_disconnect_cfm
363ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
364ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function gets the disconnect confirm event from L2CAP
365ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
366ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
367ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
368ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
369911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_disconnect_cfm(uint16_t l2cap_cid, uint16_t result) {
370911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT("BNEP - Rcvd L2CAP disc cfm, CID: 0x%x, Result 0x%x",
371911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   l2cap_cid, result);
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
375ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
376ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_congestion_ind
377ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
378ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This is a callback function called by L2CAP when
379ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  congestion status changes
380ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
381ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
382911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_congestion_ind(uint16_t l2cap_cid, bool is_congested) {
383911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
384911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
385911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Find BCB based on CID */
386911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb = bnepu_find_bcb_by_cid(l2cap_cid);
387911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb == NULL) {
388911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_WARNING("BNEP - Rcvd L2CAP cong, unknown CID: 0x%x", l2cap_cid);
389911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
390911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
391911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
392911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (is_congested) {
393911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->con_flags |= BNEP_FLAGS_L2CAP_CONGESTED;
394911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (bnep_cb.p_tx_data_flow_cb) {
395911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnep_cb.p_tx_data_flow_cb(p_bcb->handle, BNEP_TX_FLOW_OFF);
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
397911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
398911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_bcb->con_flags &= ~BNEP_FLAGS_L2CAP_CONGESTED;
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
400911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (bnep_cb.p_tx_data_flow_cb) {
401911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnep_cb.p_tx_data_flow_cb(p_bcb->handle, BNEP_TX_FLOW_ON);
402911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
404911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* While not congested, send as many buffers as we can */
405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    while (!(p_bcb->con_flags & BNEP_FLAGS_L2CAP_CONGESTED)) {
406911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BT_HDR* p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_bcb->xmit_q);
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
408911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (!p_buf) break;
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
410911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      L2CA_DataWrite(l2cap_cid, p_buf);
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
412911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
416ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
417ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_data_ind
418ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
419ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called when data is received from L2CAP.
420ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  if we are the originator of the connection, we are the SDP
4219ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  client, and the received message is queued for the client.
422ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
423ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  If we are the destination of the connection, we are the SDP
424ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  server, so the message is passed to the server processing
425ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  function.
426ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
427ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
428ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
429ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) {
431911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb;
432911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
433911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t rem_len = p_buf->len;
434911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t type, ctrl_type, ext_type = 0;
435911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool extension_present, fw_ext_present;
436911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t protocol = 0;
437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
438911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Find CCB based on CID */
439911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb = bnepu_find_bcb_by_cid(l2cap_cid);
440911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb == NULL) {
441911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_WARNING("BNEP - Rcvd L2CAP data, unknown CID: 0x%x", l2cap_cid);
442911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    osi_free(p_buf);
443911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
444911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
445911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
446911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Get the type and extension bits */
447911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  type = *p++;
448911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  extension_present = type >> 7;
449911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  type &= 0x7f;
45084e2ba5395bf168afe4a0154be3b7db2131ff30dMyles Watson  if (type >= sizeof(bnep_frame_hdr_sizes) / sizeof(bnep_frame_hdr_sizes[0])) {
45184e2ba5395bf168afe4a0154be3b7db2131ff30dMyles Watson    BNEP_TRACE_EVENT("BNEP - rcvd frame, bad type: 0x%02x", type);
45284e2ba5395bf168afe4a0154be3b7db2131ff30dMyles Watson    android_errorWriteLog(0x534e4554, "68818034");
45384e2ba5395bf168afe4a0154be3b7db2131ff30dMyles Watson    osi_free(p_buf);
45484e2ba5395bf168afe4a0154be3b7db2131ff30dMyles Watson    return;
45584e2ba5395bf168afe4a0154be3b7db2131ff30dMyles Watson  }
456911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((rem_len <= bnep_frame_hdr_sizes[type]) || (rem_len > BNEP_MTU_SIZE)) {
457911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - rcvd frame, bad len: %d  type: 0x%02x", p_buf->len,
458911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     type);
459911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    osi_free(p_buf);
460911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
461911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
462911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
463911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  rem_len--;
464911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
465911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
466911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)) &&
467911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (type != BNEP_FRAME_CONTROL)) {
468911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_WARNING(
469911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        "BNEP - Ignored L2CAP data while in state: %d, CID: 0x%x",
470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->con_state, l2cap_cid);
471911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
472911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (extension_present) {
473911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /*
474911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ** When there is no connection if a data packet is received
475911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ** with unknown control extension headers then those should be processed
476911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ** according to complain/ignore law
477911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      */
478911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      uint8_t ext, length;
479911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      uint16_t org_len, new_len;
480911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* parse the extension headers and process unknown control headers */
481911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      org_len = rem_len;
482911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      new_len = 0;
483911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      do {
4843eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang        if (org_len < 2) break;
485911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        ext = *p++;
486911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        length = *p++;
487911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p += length;
488911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
4893eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang        new_len = (length + 2);
4903eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang        if (new_len > org_len) break;
4913eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang
492911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if ((!(ext & 0x7F)) && (*p > BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG))
493911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          bnep_send_command_not_understood(p_bcb, *p);
494911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
4953eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang        org_len -= new_len;
496911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } while (ext & 0x80);
4973eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang      android_errorWriteLog(0x534e4554, "67863755");
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
500911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    osi_free(p_buf);
501911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
502911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
504911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (type > BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY) {
505911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - rcvd frame, unknown type: 0x%02x", type);
506911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    osi_free(p_buf);
507911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
508911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
510911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_DEBUG("BNEP - rcv frame, type: %d len: %d Ext: %d", type,
511911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_buf->len, extension_present);
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
513911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Initialize addresses to 'not supplied' */
5149e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski  const RawAddress *p_src_addr, *p_dst_addr;
515911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_src_addr = p_dst_addr = NULL;
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
517911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (type) {
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_GENERAL_ETHERNET:
5199e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski      p_dst_addr = (RawAddress*)p;
520911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += BD_ADDR_LEN;
5219e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski      p_src_addr = (RawAddress*)p;
522911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += BD_ADDR_LEN;
523911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(protocol, p);
524911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      rem_len -= 14;
525911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_CONTROL:
528911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ctrl_type = *p;
529911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = bnep_process_control_packet(p_bcb, p, &rem_len, false);
530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
531911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (ctrl_type == BNEP_SETUP_CONNECTION_REQUEST_MSG &&
532911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_bcb->con_state != BNEP_STATE_CONNECTED && extension_present && p &&
533911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          rem_len) {
5344982eb5df30cbcbee5c8b8807be95fdc6dfa63c5Pavlin Radoslavov        osi_free(p_bcb->p_pending_data);
535d88838a7237cd672d87b6b9cc8d56fff625fd1d5Pavlin Radoslavov        p_bcb->p_pending_data = (BT_HDR*)osi_malloc(rem_len + sizeof(BT_HDR));
536911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        memcpy((uint8_t*)(p_bcb->p_pending_data + 1), p, rem_len);
537911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->p_pending_data->len = rem_len;
538911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_bcb->p_pending_data->offset = 0;
539911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
540911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        while (extension_present && p && rem_len) {
541911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          ext_type = *p++;
5423eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang          rem_len--;
5433eb33a27c483f685be99eb327cbf9a05ffa12c58Hansong Zhang          android_errorWriteLog(0x534e4554, "69271284");
544911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          extension_present = ext_type >> 7;
545911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          ext_type &= 0x7F;
546911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
547911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          /* if unknown extension present stop processing */
548911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (ext_type) break;
549911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
550911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p = bnep_process_control_packet(p_bcb, p, &rem_len, true);
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
552911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
553911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      osi_free(p_buf);
554911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_COMPRESSED_ETHERNET:
557911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(protocol, p);
558911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      rem_len -= 2;
559911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY:
5629e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski      p_src_addr = (RawAddress*)p;
563911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += BD_ADDR_LEN;
564911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(protocol, p);
565911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      rem_len -= 8;
566911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY:
5699e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski      p_dst_addr = (RawAddress*)p;
570911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += BD_ADDR_LEN;
571911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_UINT16(protocol, p);
572911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      rem_len -= 8;
573911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
574911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
575911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
576911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Process the header extension if there is one */
577911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  while (extension_present && p && rem_len) {
578911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ext_type = *p;
579911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    extension_present = ext_type >> 7;
580911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ext_type &= 0x7F;
581911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
582911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* if unknown extension present stop processing */
583911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (ext_type) {
584911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BNEP_TRACE_EVENT("Data extension type 0x%x found", ext_type);
585911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
588911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p++;
589911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    rem_len--;
590911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = bnep_process_control_packet(p_bcb, p, &rem_len, true);
591911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
592911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
593911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset += p_buf->len - rem_len;
594911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = rem_len;
595911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
596911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Always give the upper layer MAC addresses */
597a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski  if (!p_src_addr) p_src_addr = &p_bcb->rem_bda;
598911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
599a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski  if (!p_dst_addr) p_dst_addr = controller_get_interface()->get_address();
600911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
601911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* check whether there are any extensions to be forwarded */
602911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (ext_type)
603911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    fw_ext_present = true;
604911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
605911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    fw_ext_present = false;
606911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
607911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (bnep_cb.p_data_buf_cb) {
608a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski    (*bnep_cb.p_data_buf_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol,
609911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             p_buf, fw_ext_present);
610911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (bnep_cb.p_data_ind_cb) {
611a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski    (*bnep_cb.p_data_ind_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol,
612a83ac12406eaa90e5f1f8a699b8b17e4440e2687Jakub Pawlowski                             p, rem_len, fw_ext_present);
613911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    osi_free(p_buf);
614911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
618ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
619ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_conn_timer_timeout
620ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
621ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function processes a timeout. If it is a startup
622ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  timeout, we check for reading our BD address. If it
623ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  is an L2CAP timeout, we send a disconnect req to L2CAP.
624ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
625ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
626ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
627ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
628911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnep_conn_timer_timeout(void* data) {
629911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBNEP_CONN* p_bcb = (tBNEP_CONN*)data;
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
631911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BNEP_TRACE_EVENT(
632911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      "BNEP - CCB timeout in state: %d  CID: 0x%x flags %x, re_transmit %d",
633911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->con_state, p_bcb->l2cap_cid, p_bcb->con_flags,
634911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_bcb->re_transmits);
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
636911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_state == BNEP_STATE_CONN_SETUP) {
637911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - CCB timeout in state: %d  CID: 0x%x",
638911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     p_bcb->con_state, p_bcb->l2cap_cid);
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
640911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!(p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) {
641911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      L2CA_DisconnectReq(p_bcb->l2cap_cid);
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
643911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_release_bcb(p_bcb);
644911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
647911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->re_transmits++ != BNEP_MAX_RETRANSMITS) {
648911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnep_send_conn_req(p_bcb);
64947616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski      alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
65047616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski                         bnep_conn_timer_timeout, p_bcb);
651911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
652911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      L2CA_DisconnectReq(p_bcb->l2cap_cid);
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
654911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) && (bnep_cb.p_conn_state_cb))
655911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
656911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   BNEP_CONN_FAILED, false);
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
658911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_release_bcb(p_bcb);
659911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
661911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_bcb->con_state != BNEP_STATE_CONNECTED) {
662911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BNEP_TRACE_EVENT("BNEP - CCB timeout in state: %d  CID: 0x%x",
663911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     p_bcb->con_state, p_bcb->l2cap_cid);
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
665911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    L2CA_DisconnectReq(p_bcb->l2cap_cid);
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
667911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Tell the user if he has a callback */
668911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) && (bnep_cb.p_conn_state_cb))
669911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
670911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                 BNEP_CONN_FAILED, false);
671911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
672911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bnepu_release_bcb(p_bcb);
673911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_bcb->con_flags & BNEP_FLAGS_FILTER_RESP_PEND) {
674911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->re_transmits++ != BNEP_MAX_RETRANSMITS) {
675911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_send_peer_our_filters(p_bcb);
67647616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski      alarm_set_on_mloop(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
67747616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski                         bnep_conn_timer_timeout, p_bcb);
678911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
679911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      L2CA_DisconnectReq(p_bcb->l2cap_cid);
680911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
681911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Tell the user if he has a callback */
682911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (bnep_cb.p_conn_state_cb)
683911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
684911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   BNEP_SET_FILTER_FAIL, false);
685911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
686911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_release_bcb(p_bcb);
687911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
689911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_bcb->con_flags & BNEP_FLAGS_MULTI_RESP_PEND) {
690911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_bcb->re_transmits++ != BNEP_MAX_RETRANSMITS) {
691911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_send_peer_our_multi_filters(p_bcb);
69247616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski      alarm_set_on_mloop(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
69347616530ceea2ea6432ffb35cd8a3fc0a56365b5Jakub Pawlowski                         bnep_conn_timer_timeout, p_bcb);
694911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
695911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      L2CA_DisconnectReq(p_bcb->l2cap_cid);
696911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
697911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Tell the user if he has a callback */
698911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (bnep_cb.p_conn_state_cb)
699911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
700911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   BNEP_SET_FILTER_FAIL, false);
701911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
702911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      bnepu_release_bcb(p_bcb);
703911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
705911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
709ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
710ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         bnep_connected
711ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
712ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called when a connection is established
713ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  (after config).
714ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
715ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
716ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
717ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
718911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid bnep_connected(tBNEP_CONN* p_bcb) {
719911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool is_role_change;
720911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
721911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
722911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    is_role_change = true;
723911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
724911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    is_role_change = false;
725911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
726911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_state = BNEP_STATE_CONNECTED;
727911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_flags |= BNEP_FLAGS_CONN_COMPLETED;
728911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
729911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
730911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Ensure timer is stopped */
731911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_cancel(p_bcb->conn_timer);
732911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_bcb->re_transmits = 0;
733911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
734911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Tell the upper layer, if he has a callback */
735911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (bnep_cb.p_conn_state_cb)
736911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda, BNEP_SUCCESS,
737911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                               is_role_change);
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
739