1/******************************************************************************
2 *
3 *  Copyright (C) 2009-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  Filename:      bta_pan_co.c
22 *
23 *  Description:   PAN stack callout api
24 *
25 *
26 ******************************************************************************/
27#include "bta_pan_co.h"
28#include <base/logging.h>
29#include <hardware/bluetooth.h>
30#include <hardware/bt_pan.h>
31#include <string.h>
32#include "bt_common.h"
33#include "bta_api.h"
34#include "bta_pan_api.h"
35#include "bta_pan_ci.h"
36#include "btif_pan_internal.h"
37#include "btif_sock_thread.h"
38#include "btif_util.h"
39#include "osi/include/osi.h"
40#include "pan_api.h"
41
42/*******************************************************************************
43 *
44 * Function         bta_pan_co_init
45 *
46 * Description
47 *
48 *
49 * Returns          Data flow mask.
50 *
51 ******************************************************************************/
52uint8_t bta_pan_co_init(uint8_t* q_level) {
53  BTIF_TRACE_API("bta_pan_co_init");
54
55  /* set the q_level to 30 buffers */
56  *q_level = 30;
57
58  // return (BTA_PAN_RX_PULL | BTA_PAN_TX_PULL);
59  return (BTA_PAN_RX_PUSH_BUF | BTA_PAN_RX_PUSH | BTA_PAN_TX_PULL);
60}
61
62/******************************************************************************
63 *
64 * Function         bta_pan_co_open
65 *
66 * Description
67 *
68 *
69 *
70 *
71 *
72 * Returns          void
73 *
74 ******************************************************************************/
75void bta_pan_co_open(uint16_t handle, uint8_t app_id, tBTA_PAN_ROLE local_role,
76                     tBTA_PAN_ROLE peer_role, const RawAddress& peer_addr) {
77  BTIF_TRACE_API(
78      "bta_pan_co_open:app_id:%d, local_role:%d, peer_role:%d, "
79      "handle:%d",
80      app_id, local_role, peer_role, handle);
81  btpan_conn_t* conn = btpan_find_conn_addr(peer_addr);
82  if (conn == NULL)
83    conn = btpan_new_conn(handle, peer_addr, local_role, peer_role);
84  if (conn) {
85    BTIF_TRACE_DEBUG(
86        "bta_pan_co_open:tap_fd:%d, open_count:%d, "
87        "conn->handle:%d should = handle:%d, local_role:%d, remote_role:%d",
88        btpan_cb.tap_fd, btpan_cb.open_count, conn->handle, handle,
89        conn->local_role, conn->remote_role);
90    // refresh the role & bt address
91
92    btpan_cb.open_count++;
93    conn->handle = handle;
94    // conn->peer = peer_addr;
95    if (btpan_cb.tap_fd < 0) {
96      btpan_cb.tap_fd = btpan_tap_open();
97      if (btpan_cb.tap_fd >= 0) create_tap_read_thread(btpan_cb.tap_fd);
98    }
99    if (btpan_cb.tap_fd >= 0) {
100      btpan_cb.flow = 1;
101      conn->state = PAN_STATE_OPEN;
102      bta_pan_ci_rx_ready(handle);
103    }
104  }
105}
106
107/*******************************************************************************
108 *
109 * Function         bta_pan_co_close
110 *
111 * Description      This function is called by PAN when a connection to a
112 *                  peer is closed.
113 *
114 *
115 * Returns          void
116 *
117 ******************************************************************************/
118void bta_pan_co_close(uint16_t handle, uint8_t app_id) {
119  BTIF_TRACE_API("bta_pan_co_close:app_id:%d, handle:%d", app_id, handle);
120  btpan_conn_t* conn = btpan_find_conn_handle(handle);
121  if (conn && conn->state == PAN_STATE_OPEN) {
122    BTIF_TRACE_DEBUG("bta_pan_co_close");
123
124    // let bta close event reset this handle as it needs
125    // the handle to find the connection upon CLOSE
126    // conn->handle = -1;
127    conn->state = PAN_STATE_CLOSE;
128    btpan_cb.open_count--;
129
130    if (btpan_cb.open_count == 0 && btpan_cb.tap_fd != -1) {
131      btpan_tap_close(btpan_cb.tap_fd);
132      btpan_cb.tap_fd = -1;
133    }
134  }
135}
136
137/*******************************************************************************
138 *
139 * Function         bta_pan_co_tx_path
140 *
141 * Description      This function is called by PAN to transfer data on the
142 *                  TX path; that is, data being sent from BTA to the phone.
143 *                  This function is used when the TX data path is configured
144 *                  to use the pull interface.  The implementation of this
145 *                  function will typically call Bluetooth stack functions
146 *                  PORT_Read() or PORT_ReadData() to read data from RFCOMM
147 *                  and then a platform-specific function to send data that
148 *                  data to the phone.
149 *
150 *
151 * Returns          void
152 *
153 ******************************************************************************/
154void bta_pan_co_tx_path(uint16_t handle, uint8_t app_id) {
155  BT_HDR* p_buf;
156  RawAddress src;
157  RawAddress dst;
158  uint16_t protocol;
159  bool ext;
160  bool forward;
161
162  BTIF_TRACE_API("%s, handle:%d, app_id:%d", __func__, handle, app_id);
163
164  btpan_conn_t* conn = btpan_find_conn_handle(handle);
165  if (!conn) {
166    BTIF_TRACE_ERROR("%s: cannot find pan connection", __func__);
167    return;
168  } else if (conn->state != PAN_STATE_OPEN) {
169    BTIF_TRACE_ERROR("%s: conn is not opened, conn:%p, conn->state:%d",
170                     __func__, conn, conn->state);
171    return;
172  }
173
174  do {
175    /* read next data buffer from pan */
176    p_buf = bta_pan_ci_readbuf(handle, src, dst, &protocol, &ext, &forward);
177    if (p_buf) {
178      BTIF_TRACE_DEBUG(
179          "%s, calling btapp_tap_send, "
180          "p_buf->len:%d, offset:%d",
181          __func__, p_buf->len, p_buf->offset);
182      if (is_empty_eth_addr(conn->eth_addr) && is_valid_bt_eth_addr(src)) {
183        VLOG(1) << __func__ << " pan bt peer addr: " << conn->peer
184                << " update its ethernet addr: " << src;
185        conn->eth_addr = src;
186      }
187      btpan_tap_send(btpan_cb.tap_fd, src, dst, protocol,
188                     (char*)(p_buf + 1) + p_buf->offset, p_buf->len, ext,
189                     forward);
190      osi_free(p_buf);
191    }
192
193  } while (p_buf != NULL);
194}
195
196/*******************************************************************************
197 *
198 * Function         bta_pan_co_rx_path
199 *
200 * Description
201 *
202 *
203 *
204 *
205 * Returns          void
206 *
207 ******************************************************************************/
208void bta_pan_co_rx_path(UNUSED_ATTR uint16_t handle,
209                        UNUSED_ATTR uint8_t app_id) {
210  BTIF_TRACE_API("bta_pan_co_rx_path not used");
211}
212
213/*******************************************************************************
214 *
215 * Function         bta_pan_co_tx_write
216 *
217 * Description      This function is called by PAN to send data to the phone
218 *                  when the TX path is configured to use a push interface.
219 *                  The implementation of this function must copy the data to
220 *                  the phone's memory.
221 *
222 *
223 * Returns          void
224 *
225 ******************************************************************************/
226void bta_pan_co_tx_write(UNUSED_ATTR uint16_t handle,
227                         UNUSED_ATTR uint8_t app_id,
228                         UNUSED_ATTR const RawAddress& src,
229                         UNUSED_ATTR const RawAddress& dst,
230                         UNUSED_ATTR uint16_t protocol,
231                         UNUSED_ATTR uint8_t* p_data, UNUSED_ATTR uint16_t len,
232                         UNUSED_ATTR bool ext, UNUSED_ATTR bool forward) {
233  BTIF_TRACE_API("bta_pan_co_tx_write not used");
234}
235
236/*******************************************************************************
237 *
238 * Function         bta_pan_co_tx_writebuf
239 *
240 * Description      This function is called by PAN to send data to the phone
241 *                  when the TX path is configured to use a push interface with
242 *                  zero copy.  The phone must free the buffer using function
243 *                  osi_free() when it is through processing the buffer.
244 *
245 *
246 * Returns          true if flow enabled
247 *
248 ******************************************************************************/
249void bta_pan_co_tx_writebuf(UNUSED_ATTR uint16_t handle,
250                            UNUSED_ATTR uint8_t app_id,
251                            UNUSED_ATTR const RawAddress& src,
252                            UNUSED_ATTR const RawAddress& dst,
253                            UNUSED_ATTR uint16_t protocol,
254                            UNUSED_ATTR BT_HDR* p_buf, UNUSED_ATTR bool ext,
255                            UNUSED_ATTR bool forward) {
256  BTIF_TRACE_API("bta_pan_co_tx_writebuf not used");
257}
258
259/*******************************************************************************
260 *
261 * Function         bta_pan_co_rx_flow
262 *
263 * Description      This function is called by PAN to enable or disable
264 *                  data flow on the RX path when it is configured to use
265 *                  a push interface.  If data flow is disabled the phone must
266 *                  not call bta_pan_ci_rx_write() or bta_pan_ci_rx_writebuf()
267 *                  until data flow is enabled again.
268 *
269 *
270 * Returns          void
271 *
272 ******************************************************************************/
273void bta_pan_co_rx_flow(UNUSED_ATTR uint16_t handle, UNUSED_ATTR uint8_t app_id,
274                        UNUSED_ATTR bool enable) {
275  BTIF_TRACE_API("bta_pan_co_rx_flow, enabled:%d, not used", enable);
276  btpan_conn_t* conn = btpan_find_conn_handle(handle);
277  if (!conn || conn->state != PAN_STATE_OPEN) return;
278  btpan_set_flow_control(enable);
279}
280
281/*******************************************************************************
282 *
283 * Function         bta_pan_co_filt_ind
284 *
285 * Description      protocol filter indication from peer device
286 *
287 * Returns          void
288 *
289 ******************************************************************************/
290void bta_pan_co_pfilt_ind(UNUSED_ATTR uint16_t handle,
291                          UNUSED_ATTR bool indication,
292                          UNUSED_ATTR tBTA_PAN_STATUS result,
293                          UNUSED_ATTR uint16_t len,
294                          UNUSED_ATTR uint8_t* p_filters) {
295  BTIF_TRACE_API("bta_pan_co_pfilt_ind");
296}
297
298/*******************************************************************************
299 *
300 * Function         bta_pan_co_mfilt_ind
301 *
302 * Description      multicast filter indication from peer device
303 *
304 * Returns          void
305 *
306 ******************************************************************************/
307void bta_pan_co_mfilt_ind(UNUSED_ATTR uint16_t handle,
308                          UNUSED_ATTR bool indication,
309                          UNUSED_ATTR tBTA_PAN_STATUS result,
310                          UNUSED_ATTR uint16_t len,
311                          UNUSED_ATTR uint8_t* p_filters) {
312  BTIF_TRACE_API("bta_pan_co_mfilt_ind");
313}
314