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 <hardware/bluetooth.h>
29 #include <hardware/bt_pan.h>
30 #include <string.h>
31 #include "bt_common.h"
32 #include "bta_api.h"
33 #include "bta_pan_api.h"
34 #include "bta_pan_ci.h"
35 #include "btcore/include/bdaddr.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  ******************************************************************************/
bta_pan_co_init(uint8_t * q_level)52 uint8_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  ******************************************************************************/
bta_pan_co_open(uint16_t handle,uint8_t app_id,tBTA_PAN_ROLE local_role,tBTA_PAN_ROLE peer_role,BD_ADDR peer_addr)75 void bta_pan_co_open(uint16_t handle, uint8_t app_id, tBTA_PAN_ROLE local_role,
76                      tBTA_PAN_ROLE peer_role, BD_ADDR 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     // bdcpy(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  ******************************************************************************/
bta_pan_co_close(uint16_t handle,uint8_t app_id)118 void 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  ******************************************************************************/
bta_pan_co_tx_path(uint16_t handle,uint8_t app_id)154 void bta_pan_co_tx_path(uint16_t handle, uint8_t app_id) {
155   BT_HDR* p_buf;
156   BD_ADDR src;
157   BD_ADDR 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       bdstr_t bdstr;
179       BTIF_TRACE_DEBUG(
180           "%s, calling btapp_tap_send, "
181           "p_buf->len:%d, offset:%d",
182           __func__, p_buf->len, p_buf->offset);
183       if (is_empty_eth_addr(conn->eth_addr) && is_valid_bt_eth_addr(src)) {
184         BTIF_TRACE_DEBUG(
185             "%s pan bt peer addr: %s", __func__,
186             bdaddr_to_string((bt_bdaddr_t*)conn->peer, bdstr, sizeof(bdstr)));
187         bdaddr_to_string((bt_bdaddr_t*)src, bdstr, sizeof(bdstr));
188         BTIF_TRACE_DEBUG(
189             "%s:     update its ethernet addr: %s", __func__,
190             bdaddr_to_string((bt_bdaddr_t*)src, bdstr, sizeof(bdstr)));
191         memcpy(conn->eth_addr, src, sizeof(conn->eth_addr));
192       }
193       btpan_tap_send(btpan_cb.tap_fd, src, dst, protocol,
194                      (char*)(p_buf + 1) + p_buf->offset, p_buf->len, ext,
195                      forward);
196       osi_free(p_buf);
197     }
198 
199   } while (p_buf != NULL);
200 }
201 
202 /*******************************************************************************
203  *
204  * Function         bta_pan_co_rx_path
205  *
206  * Description
207  *
208  *
209  *
210  *
211  * Returns          void
212  *
213  ******************************************************************************/
bta_pan_co_rx_path(UNUSED_ATTR uint16_t handle,UNUSED_ATTR uint8_t app_id)214 void bta_pan_co_rx_path(UNUSED_ATTR uint16_t handle,
215                         UNUSED_ATTR uint8_t app_id) {
216   BTIF_TRACE_API("bta_pan_co_rx_path not used");
217 }
218 
219 /*******************************************************************************
220  *
221  * Function         bta_pan_co_tx_write
222  *
223  * Description      This function is called by PAN to send data to the phone
224  *                  when the TX path is configured to use a push interface.
225  *                  The implementation of this function must copy the data to
226  *                  the phone's memory.
227  *
228  *
229  * Returns          void
230  *
231  ******************************************************************************/
bta_pan_co_tx_write(UNUSED_ATTR uint16_t handle,UNUSED_ATTR uint8_t app_id,UNUSED_ATTR BD_ADDR src,UNUSED_ATTR BD_ADDR dst,UNUSED_ATTR uint16_t protocol,UNUSED_ATTR uint8_t * p_data,UNUSED_ATTR uint16_t len,UNUSED_ATTR bool ext,UNUSED_ATTR bool forward)232 void bta_pan_co_tx_write(UNUSED_ATTR uint16_t handle,
233                          UNUSED_ATTR uint8_t app_id, UNUSED_ATTR BD_ADDR src,
234                          UNUSED_ATTR BD_ADDR dst, UNUSED_ATTR uint16_t protocol,
235                          UNUSED_ATTR uint8_t* p_data, UNUSED_ATTR uint16_t len,
236                          UNUSED_ATTR bool ext, UNUSED_ATTR bool forward) {
237   BTIF_TRACE_API("bta_pan_co_tx_write not used");
238 }
239 
240 /*******************************************************************************
241  *
242  * Function         bta_pan_co_tx_writebuf
243  *
244  * Description      This function is called by PAN to send data to the phone
245  *                  when the TX path is configured to use a push interface with
246  *                  zero copy.  The phone must free the buffer using function
247  *                  osi_free() when it is through processing the buffer.
248  *
249  *
250  * Returns          true if flow enabled
251  *
252  ******************************************************************************/
bta_pan_co_tx_writebuf(UNUSED_ATTR uint16_t handle,UNUSED_ATTR uint8_t app_id,UNUSED_ATTR BD_ADDR src,UNUSED_ATTR BD_ADDR dst,UNUSED_ATTR uint16_t protocol,UNUSED_ATTR BT_HDR * p_buf,UNUSED_ATTR bool ext,UNUSED_ATTR bool forward)253 void bta_pan_co_tx_writebuf(UNUSED_ATTR uint16_t handle,
254                             UNUSED_ATTR uint8_t app_id, UNUSED_ATTR BD_ADDR src,
255                             UNUSED_ATTR BD_ADDR dst,
256                             UNUSED_ATTR uint16_t protocol,
257                             UNUSED_ATTR BT_HDR* p_buf, UNUSED_ATTR bool ext,
258                             UNUSED_ATTR bool forward) {
259   BTIF_TRACE_API("bta_pan_co_tx_writebuf not used");
260 }
261 
262 /*******************************************************************************
263  *
264  * Function         bta_pan_co_rx_flow
265  *
266  * Description      This function is called by PAN to enable or disable
267  *                  data flow on the RX path when it is configured to use
268  *                  a push interface.  If data flow is disabled the phone must
269  *                  not call bta_pan_ci_rx_write() or bta_pan_ci_rx_writebuf()
270  *                  until data flow is enabled again.
271  *
272  *
273  * Returns          void
274  *
275  ******************************************************************************/
bta_pan_co_rx_flow(UNUSED_ATTR uint16_t handle,UNUSED_ATTR uint8_t app_id,UNUSED_ATTR bool enable)276 void bta_pan_co_rx_flow(UNUSED_ATTR uint16_t handle, UNUSED_ATTR uint8_t app_id,
277                         UNUSED_ATTR bool enable) {
278   BTIF_TRACE_API("bta_pan_co_rx_flow, enabled:%d, not used", enable);
279   btpan_conn_t* conn = btpan_find_conn_handle(handle);
280   if (!conn || conn->state != PAN_STATE_OPEN) return;
281   btpan_set_flow_control(enable);
282 }
283 
284 /*******************************************************************************
285  *
286  * Function         bta_pan_co_filt_ind
287  *
288  * Description      protocol filter indication from peer device
289  *
290  * Returns          void
291  *
292  ******************************************************************************/
bta_pan_co_pfilt_ind(UNUSED_ATTR uint16_t handle,UNUSED_ATTR bool indication,UNUSED_ATTR tBTA_PAN_STATUS result,UNUSED_ATTR uint16_t len,UNUSED_ATTR uint8_t * p_filters)293 void bta_pan_co_pfilt_ind(UNUSED_ATTR uint16_t handle,
294                           UNUSED_ATTR bool indication,
295                           UNUSED_ATTR tBTA_PAN_STATUS result,
296                           UNUSED_ATTR uint16_t len,
297                           UNUSED_ATTR uint8_t* p_filters) {
298   BTIF_TRACE_API("bta_pan_co_pfilt_ind");
299 }
300 
301 /*******************************************************************************
302  *
303  * Function         bta_pan_co_mfilt_ind
304  *
305  * Description      multicast filter indication from peer device
306  *
307  * Returns          void
308  *
309  ******************************************************************************/
bta_pan_co_mfilt_ind(UNUSED_ATTR uint16_t handle,UNUSED_ATTR bool indication,UNUSED_ATTR tBTA_PAN_STATUS result,UNUSED_ATTR uint16_t len,UNUSED_ATTR uint8_t * p_filters)310 void bta_pan_co_mfilt_ind(UNUSED_ATTR uint16_t handle,
311                           UNUSED_ATTR bool indication,
312                           UNUSED_ATTR tBTA_PAN_STATUS result,
313                           UNUSED_ATTR uint16_t len,
314                           UNUSED_ATTR uint8_t* p_filters) {
315   BTIF_TRACE_API("bta_pan_co_mfilt_ind");
316 }
317