summaryrefslogtreecommitdiffstats
path: root/btif
diff options
context:
space:
mode:
authorzzy <zhenye@broadcom.com>2012-04-14 18:31:16 -0700
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:17 -0700
commit8e6e9356d5386501d5e0988ce23d0c9aaed31a64 (patch)
tree04f80006d3cdf0c3efe047677a317419eafcd802 /btif
parent2fe476a7b55eea667c854bb40e48648e8a0d5f1d (diff)
downloadexternal_bluetooth_bluedroid-8e6e9356d5386501d5e0988ce23d0c9aaed31a64.zip
external_bluetooth_bluedroid-8e6e9356d5386501d5e0988ce23d0c9aaed31a64.tar.gz
external_bluetooth_bluedroid-8e6e9356d5386501d5e0988ce23d0c9aaed31a64.tar.bz2
added bt pan profile
Diffstat (limited to 'btif')
-rw-r--r--btif/co/bta_pan_co.c360
-rw-r--r--btif/include/btif_pan.h64
-rw-r--r--btif/include/btif_pan_internal.h129
-rw-r--r--btif/src/bluetooth.c7
-rw-r--r--btif/src/btif_core.c11
-rw-r--r--btif/src/btif_pan.c652
-rw-r--r--btif/src/btif_sock_thread.c22
7 files changed, 1234 insertions, 11 deletions
diff --git a/btif/co/bta_pan_co.c b/btif/co/bta_pan_co.c
new file mode 100644
index 0000000..ec6d44e
--- /dev/null
+++ b/btif/co/bta_pan_co.c
@@ -0,0 +1,360 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2011 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+
+/************************************************************************************
+ *
+ * Filename: bta_pan_co.c
+ *
+ * Description: PAN stack callout api
+ *
+ *
+ ***********************************************************************************/
+#include "bta_api.h"
+#include "bta_pan_api.h"
+#include "bta_pan_ci.h"
+#include "bta_pan_co.h"
+#include "pan_api.h"
+#include "gki.h"
+//#include "btui.h"
+//#include "btui_int.h"
+#include <hardware/bluetooth.h>
+#include <hardware/bt_pan.h>
+#include "btif_pan_internal.h"
+#include "bd.h"
+
+
+#include <cutils/log.h>
+#define info(fmt, ...) LOGI ("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
+#define debug(fmt, ...) LOGD ("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
+#define warn(fmt, ...) LOGW ("## WARNING : %s: " fmt "##",__FUNCTION__, ## __VA_ARGS__)
+#define error(fmt, ...) LOGE ("## ERROR : %s: " fmt "##",__FUNCTION__, ## __VA_ARGS__)
+#define asrt(s) if(!(s)) LOGE ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
+
+
+
+
+/*******************************************************************************
+**
+** Function bta_pan_co_init
+**
+** Description
+**
+**
+** Returns Data flow mask.
+**
+*******************************************************************************/
+UINT8 bta_pan_co_init(UINT8 *q_level)
+{
+
+ LOGD("bta_pan_co_init");
+
+ /* set the q_level to 30 buffers */
+ *q_level = 30;
+
+ //return (BTA_PAN_RX_PULL | BTA_PAN_TX_PULL);
+ return (BTA_PAN_RX_PUSH_BUF | BTA_PAN_RX_PUSH | BTA_PAN_TX_PULL);
+}
+
+
+
+
+/*******************************************************************************
+**
+** Function bta_pan_co_open
+**
+** Description
+**
+**
+**
+**
+**
+** Returns void
+**
+*******************************************************************************/
+
+void bta_pan_co_open(UINT16 handle, UINT8 app_id, tBTA_PAN_ROLE local_role, tBTA_PAN_ROLE peer_role, BD_ADDR peer_addr)
+{
+ LOGD("bta_pan_co_open:app_id:%d, local_role:%d, peer_role:%d, handle:%d",
+ app_id, local_role, peer_role, handle);
+ btpan_conn_t* conn = btpan_find_conn_addr(peer_addr);
+ if(conn == NULL)
+ conn = btpan_new_conn(handle, peer_addr, local_role, peer_role);
+ if(conn)
+ {
+ LOGD("bta_pan_co_open:tap_fd:%d, open_count:%d, conn->handle:%d should = handle:%d, local_role:%d, remote_role:%d",
+ btpan_cb.tap_fd, btpan_cb.open_count, conn->handle, handle, conn->local_role, conn->remote_role);
+ //refresh the role & bt address
+
+ btpan_cb.open_count++;
+ conn->handle = handle;
+ //bdcpy(conn->peer, peer_addr);
+ if(btpan_cb.tap_fd < 0)
+ {
+ btpan_cb.tap_fd = btpan_tap_open();
+ if(btpan_cb.tap_fd >= 0)
+ create_tap_read_thread(btpan_cb.tap_fd);
+ }
+ if(btpan_cb.tap_fd >= 0)
+ {
+ conn->state = PAN_STATE_OPEN;
+ bta_pan_ci_rx_ready(handle);
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_pan_co_close
+**
+** Description This function is called by PAN when a connection to a
+** peer is closed.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pan_co_close(UINT16 handle, UINT8 app_id)
+{
+ LOGD("bta_pan_co_close:app_id:%d, handle:%d", app_id, handle);
+ btpan_conn_t* conn = btpan_find_conn_handle(handle);
+ if(conn && conn->state == PAN_STATE_OPEN)
+ {
+ LOGD("bta_pan_co_close");
+
+ // let bta close event reset this handle as it needs
+ // the handle to find the connection upon CLOSE
+ //conn->handle = -1;
+ conn->state = PAN_STATE_CLOSE;
+ btpan_cb.open_count--;
+
+ if(btpan_cb.open_count == 0)
+ {
+ destroy_tap_read_thread();
+ btpan_tap_close(btpan_cb.tap_fd);
+ btpan_cb.tap_fd = -1;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_pan_co_tx_path
+**
+** Description This function is called by PAN to transfer data on the
+** TX path; that is, data being sent from BTA to the phone.
+** This function is used when the TX data path is configured
+** to use the pull interface. The implementation of this
+** function will typically call Bluetooth stack functions
+** PORT_Read() or PORT_ReadData() to read data from RFCOMM
+** and then a platform-specific function to send data that
+** data to the phone.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pan_co_tx_path(UINT16 handle, UINT8 app_id)
+{
+ BT_HDR *p_buf;
+ UINT8 i;
+ BD_ADDR src;
+ BD_ADDR dst;
+ UINT16 protocol;
+ BOOLEAN ext;
+ BOOLEAN forward;
+
+ LOGD("bta_pan_co_tx_path, handle:%d, app_id:%d", handle, app_id);
+
+ btpan_conn_t* conn = btpan_find_conn_handle(handle);
+ if(conn && conn->state != PAN_STATE_OPEN)
+ {
+ LOGE("bta_pan_co_tx_path: cannot find pan connction or conn is not opened, conn:%p, conn->state:%d", conn, conn->state);
+ return;
+ }
+ do
+ {
+
+ /* read next data buffer from pan */
+ if ((p_buf = bta_pan_ci_readbuf(handle, src, dst, &protocol,
+ &ext, &forward)))
+ {
+ LOGD("bta_pan_co_tx_path, calling btapp_tap_send, p_buf->len:%d, offset:%d", p_buf->len, p_buf->offset);
+ if(is_empty_eth_addr(conn->eth_addr) && is_valid_bt_eth_addr(src))
+ {
+ LOGD("pan bt peer addr: %02x:%02x:%02x:%02x:%02x:%02x, update its ethernet addr: %02x:%02x:%02x:%02x:%02x:%02x",
+ conn->peer[0], conn->peer[1], conn->peer[2], conn->peer[3],conn->peer[4], conn->peer[5],
+ src[0], src[1], src[2], src[3],src[4], src[5]);
+ memcpy(conn->eth_addr, src, sizeof(conn->eth_addr));
+
+ }
+ btpan_tap_send(btpan_cb.tap_fd, src, dst, protocol, (char*)(p_buf + 1) + p_buf->offset, p_buf->len, ext, forward);
+ GKI_freebuf(p_buf);
+ }
+
+ } while (p_buf != NULL);
+
+}
+
+/*******************************************************************************
+**
+** Function bta_pan_co_rx_path
+**
+** Description
+**
+**
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pan_co_rx_path(UINT16 handle, UINT8 app_id)
+{
+
+
+ UINT8 i;
+
+ LOGD("bta_pan_co_rx_path not used");
+
+
+}
+
+/*******************************************************************************
+**
+** Function bta_pan_co_tx_write
+**
+** Description This function is called by PAN to send data to the phone
+** when the TX path is configured to use a push interface.
+** The implementation of this function must copy the data to
+** the phone's memory.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pan_co_tx_write(UINT16 handle, UINT8 app_id, BD_ADDR src, BD_ADDR dst, UINT16 protocol, UINT8 *p_data,
+ UINT16 len, BOOLEAN ext, BOOLEAN forward)
+{
+ LOGD("bta_pan_co_tx_write not used");
+
+}
+
+/*******************************************************************************
+**
+** Function bta_pan_co_tx_writebuf
+**
+** Description This function is called by PAN to send data to the phone
+** when the TX path is configured to use a push interface with
+** zero copy. The phone must free the buffer using function
+** GKI_freebuf() when it is through processing the buffer.
+**
+**
+** Returns TRUE if flow enabled
+**
+*******************************************************************************/
+void bta_pan_co_tx_writebuf(UINT16 handle, UINT8 app_id, BD_ADDR src, BD_ADDR dst, UINT16 protocol, BT_HDR *p_buf,
+ BOOLEAN ext, BOOLEAN forward)
+{
+
+ LOGD("bta_pan_co_tx_writebuf not used");
+
+
+}
+
+/*******************************************************************************
+**
+** Function bta_pan_co_rx_flow
+**
+** Description This function is called by PAN to enable or disable
+** data flow on the RX path when it is configured to use
+** a push interface. If data flow is disabled the phone must
+** not call bta_pan_ci_rx_write() or bta_pan_ci_rx_writebuf()
+** until data flow is enabled again.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pan_co_rx_flow(UINT16 handle, UINT8 app_id, BOOLEAN enable)
+{
+
+ LOGD("bta_pan_co_rx_flow, enabled:%d, not used", enable);
+
+}
+
+
+/*******************************************************************************
+**
+** Function bta_pan_co_filt_ind
+**
+** Description protocol filter indication from peer device
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pan_co_pfilt_ind(UINT16 handle, BOOLEAN indication, tBTA_PAN_STATUS result,
+ UINT16 len, UINT8 *p_filters)
+{
+ LOGD("bta_pan_co_pfilt_ind");
+
+}
+/*******************************************************************************
+**
+** Function bta_pan_co_mfilt_ind
+**
+** Description multicast filter indication from peer device
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pan_co_mfilt_ind(UINT16 handle, BOOLEAN indication, tBTA_PAN_STATUS result,
+ UINT16 len, UINT8 *p_filters)
+{
+
+ LOGD("bta_pan_co_mfilt_ind");
+}
+
diff --git a/btif/include/btif_pan.h b/btif/include/btif_pan.h
new file mode 100644
index 0000000..47635d7
--- /dev/null
+++ b/btif/include/btif_pan.h
@@ -0,0 +1,64 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2011 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+
+
+/************************************************************************************
+ *
+ * Filename: btif_pan.h
+ *
+ * Description: Bluetooth pan Interface
+ *
+ *
+ ***********************************************************************************/
+
+#ifndef btif_pan_h_
+#define btif_pan_h_
+#include <hardware/bt_pan.h>
+btpan_interface_t *btif_pan_interface();
+void btif_pan_init();
+void btif_pan_cleanup();
+#endif
diff --git a/btif/include/btif_pan_internal.h b/btif/include/btif_pan_internal.h
new file mode 100644
index 0000000..f4883bf
--- /dev/null
+++ b/btif/include/btif_pan_internal.h
@@ -0,0 +1,129 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2011 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+
+
+/************************************************************************************
+ *
+ * Filename: btif_pan_internal.h
+ *
+ * Description: Bluetooth pan internal
+ *
+ *
+ ***********************************************************************************/
+
+#ifndef btif_pan_internal_h_
+#define btif_pan_internal_h_
+#include "btif_pan.h"
+#include "bt_types.h"
+
+#define PAN_NAP_SERVICE_NAME "Android Network Access Point"
+#define PANU_SERVICE_NAME "Android Network User"
+#define TAP_IF_NAME "bt-pan"
+#define ETH_ADDR_LEN 6
+#ifndef PAN_SECURITY
+#define PAN_SECURITY BTM_SEC_NONE//(PAN_SEC_AUTHORIZE | PAN_SEC_AUTHENTICATE)// | PAN_SEC_ENCRYPT)
+#endif
+
+#define PAN_STATE_UNKNOWN 0
+#define PAN_STATE_OPEN 1
+#define PAN_STATE_CLOSE 2
+#ifndef PAN_ROLE_INACTIVE
+#define PAN_ROLE_INACTIVE 0
+#endif
+typedef struct eth_hdr
+{
+ unsigned char h_dest[ETH_ADDR_LEN];
+ unsigned char h_src[ETH_ADDR_LEN];
+ short h_proto;
+} tETH_HDR;
+typedef struct
+{
+ int handle;
+ int state;
+ UINT16 protocol;
+ BD_ADDR peer;
+ int local_role;
+ int remote_role;
+ unsigned char eth_addr[ETH_ADDR_LEN];
+} btpan_conn_t;
+
+typedef struct
+{
+ int btl_if_handle;
+ int btl_if_handle_panu;
+ int tap_fd;
+ int enabled;
+ int open_count;
+ btpan_conn_t conns[MAX_PAN_CONNS];
+} btpan_cb_t;
+extern btpan_cb_t btpan_cb;
+btpan_conn_t *btpan_new_conn(int handle, const BD_ADDR addr, int local_role, int peer_role);
+btpan_conn_t *btpan_find_conn_addr(const BD_ADDR addr);
+btpan_conn_t *btpan_find_conn_handle(UINT16 handle);
+int btpan_get_connected_count(void);
+int btpan_tap_open(void);
+void create_tap_read_thread(int tap_fd);
+void destroy_tap_read_thread(void);
+int btpan_tap_close(int tap_fd);
+int btpan_tap_send(int tap_fd, const BD_ADDR src, const BD_ADDR dst, UINT16 protocol,
+ const char* buff, UINT16 size, BOOLEAN ext, BOOLEAN forward);
+static inline int is_empty_eth_addr(const BD_ADDR addr)
+{
+ int i;
+ for(i = 0; i < BD_ADDR_LEN; i++)
+ if(addr[i] != 0)
+ return 0;
+ return 1;
+}
+static inline int is_valid_bt_eth_addr(const BD_ADDR addr)
+{
+ if(is_empty_eth_addr(addr))
+ return 0;
+ return addr[0] & 1 ? 0 : 1; //cannot be multicasting address
+}
+
+#endif
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c
index 5864eac..8e4ed0e 100644
--- a/btif/src/bluetooth.c
+++ b/btif/src/bluetooth.c
@@ -63,6 +63,7 @@
#include <hardware/bt_sock.h>
#include <hardware/bt_hh.h>
#include <hardware/bt_hl.h>
+#include <hardware/bt_pan.h>
#define LOG_NDDEBUG 0
#define LOG_TAG "bluedroid"
@@ -105,6 +106,8 @@ extern btsock_interface_t *btif_sock_get_interface();
extern bthh_interface_t *btif_hh_get_interface();
/* health device profile */
extern bthl_interface_t *btif_hl_get_interface();
+/*pan*/
+extern btpan_interface_t *btif_pan_get_interface();
/************************************************************************************
** Functions
@@ -329,6 +332,10 @@ static const void* get_profile_interface (const char *profile_id)
if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
return btif_sock_get_interface();
+
+ if (is_profile(profile_id, BT_PROFILE_PAN_ID))
+ return btif_pan_get_interface();
+
if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
return btif_av_get_interface();
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index f6f54f0..62541c8 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -70,7 +70,7 @@
#include "btif_storage.h"
#include "btif_util.h"
#include "btif_sock.h"
-
+#include "btif_pan.h"
/************************************************************************************
** Constants & Macros
************************************************************************************/
@@ -440,7 +440,10 @@ void btif_enable_bluetooth_evt(tBTA_STATUS status, BD_ADDR local_bd)
/* init rfcomm & l2cap api */
btif_sock_init();
-
+
+ /* init pan */
+ btif_pan_init();
+
/* load did configuration */
bte_load_did_conf(BTE_DID_CONF_FILE);
@@ -450,7 +453,7 @@ void btif_enable_bluetooth_evt(tBTA_STATUS status, BD_ADDR local_bd)
{
/* cleanup rfcomm & l2cap api */
btif_sock_cleanup();
-
+ btif_pan_cleanup();
btif_enabled = 0;
HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
@@ -483,7 +486,7 @@ bt_status_t btif_disable_bluetooth(void)
/* cleanup rfcomm & l2cap api */
btif_sock_cleanup();
-
+ btif_pan_cleanup();
status = BTA_DisableBluetooth();
if (status != BTA_SUCCESS)
diff --git a/btif/src/btif_pan.c b/btif/src/btif_pan.c
new file mode 100644
index 0000000..5b1e571
--- /dev/null
+++ b/btif/src/btif_pan.c
@@ -0,0 +1,652 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2011 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+
+/************************************************************************************
+ *
+ * Filename: btif_pan.c
+ *
+ * Description: PAN Profile Bluetooth Interface
+ *
+ *
+ ***********************************************************************************/
+#include <hardware/bluetooth.h>
+#include <hardware/bt_pan.h>
+#include <signal.h>
+#include <ctype.h>
+#include <sys/select.h>
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+#include <sys/prctl.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <linux/if_ether.h>
+
+#define LOG_TAG "BTIF_PAN"
+#include "btif_common.h"
+#include "btif_util.h"
+#include "btm_api.h"
+#include "bd.h"
+
+#include "bta_api.h"
+#include "bta_pan_api.h"
+#include "btif_sock_thread.h"
+#include "btif_sock_util.h"
+#include "btif_pan_internal.h"
+
+
+
+#include <cutils/log.h>
+#define info(fmt, ...) LOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define debug(fmt, ...) LOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define warn(fmt, ...) LOGW ("## WARNING : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define error(fmt, ...) LOGE ("## ERROR : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define asrt(s) if(!(s)) LOGE ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
+
+
+
+btpan_cb_t btpan_cb;
+
+BD_ADDR local_addr;
+
+static bt_status_t btpan_init(const btpan_callbacks_t* callbacks);
+static void btpan_cleanup();
+static bt_status_t btpan_connect(const bt_bdaddr_t *bd_addr, int local_role, int remote_role);
+static bt_status_t btpan_disconnect(const bt_bdaddr_t *bd_addr);
+static bt_status_t btpan_enable(int local_role);
+static int btpan_get_local_role(void);
+
+static void btpan_tap_fd_signaled(int fd, int type, int flags, uint32_t user_id);
+static void btpan_cleanup_conn(btpan_conn_t* conn);
+static void bta_pan_callback(tBTA_PAN_EVT event, tBTA_PAN *p_data);
+/*******************************************************************************
+ **
+ ** Function btpan_ini
+ **
+ ** Description initializes the bt socket interface
+ **
+ ** Returns bt_status_t
+ **
+ *******************************************************************************/
+static btpan_interface_t pan_if = {
+ sizeof(pan_if),
+ btpan_init,
+ btpan_enable,
+ btpan_get_local_role,
+ btpan_connect,
+ btpan_disconnect,
+ btpan_cleanup
+};
+btpan_interface_t *btif_pan_get_interface()
+{
+ return &pan_if;
+}
+void btif_pan_init()
+{
+ debug("in, btpan_cb.enabled:%d", btpan_cb.enabled);
+ //btif_enable_service(BTA_PANU_SERVICE_ID);
+ //btif_enable_service(BTA_NAP_SERVICE_ID);
+ if (!btpan_cb.enabled)
+ {
+ //btui_cfg.pan_security = PAN_SECURITY;
+ //strncpy(btui_cfg.pannap_service_name, PAN_NAP_SERVICE_NAME, sizeof(btui_cfg.pannap_service_name) - 1);
+ //btui_cfg.pannap_service_name[sizeof(btui_cfg.pannap_service_name) - 1] = 0;
+ //btui_cfg.p_sc_menu = NULL;
+ memset(&btpan_cb, 0, sizeof(btpan_cb));
+ btpan_cb.tap_fd = -1;
+ int i;
+ for(i = 0; i < MAX_PAN_CONNS; i++)
+ btpan_cleanup_conn(&btpan_cb.conns[i]);
+
+ BTA_PanEnable(bta_pan_callback);
+ btpan_cb.enabled = 1;
+ //panu by default
+ btpan_enable(BTPAN_ROLE_PANU);
+ //debug("set to BTPAN_ROLE_PANNAP for testing");
+ //btpan_enable(BTPAN_ROLE_PANNAP);
+ }
+}
+void btif_pan_cleanup()
+{
+ debug("in, bt is shuting down...");
+ //bt is shuting down, invalid all bta pan handles
+ int i;
+ for(i = 0; i < MAX_PAN_CONNS; i++)
+ {
+ btpan_cleanup_conn(&btpan_cb.conns[i]);
+ }
+ btpan_cleanup();
+}
+static btpan_callbacks_t callback;
+static bt_status_t btpan_init(const btpan_callbacks_t* callbacks)
+{
+ debug("in, btpan_cb.enabled:%d", btpan_cb.enabled);
+ static volatile int binit;
+ callback = *callbacks;
+ return BT_STATUS_SUCCESS;
+}
+static void btpan_cleanup()
+{
+ debug("in, btpan_cb.enabled:%d", btpan_cb.enabled);
+ if (btpan_cb.enabled)
+ {
+ btpan_cb.enabled = 0;
+ BTA_PanDisable();
+ if(btpan_cb.tap_fd != -1)
+ {
+ destroy_tap_read_thread();
+ btpan_tap_close(btpan_cb.tap_fd);
+ btpan_cb.tap_fd = -1;
+ }
+ }
+}
+static inline int bta_role_to_btpan(int bta_pan_role)
+{
+ int btpan_role = 0;
+ debug("bta_pan_role:0x%x", bta_pan_role);
+ if(bta_pan_role & PAN_ROLE_NAP_SERVER)
+ {
+ debug("BTPAN_ROLE_PANNAP");
+ btpan_role |= BTPAN_ROLE_PANNAP;
+ }
+ if(bta_pan_role & PAN_ROLE_CLIENT)
+ {
+ debug("BTPAN_ROLE_PANU");
+ btpan_role |= BTPAN_ROLE_PANU;
+ }
+ return btpan_role;
+}
+static inline int btpan_role_to_bta(int btpan_role)
+{
+ int bta_pan_role = PAN_ROLE_INACTIVE;
+ debug("btpan_role:0x%x", btpan_role);
+ if(btpan_role & BTPAN_ROLE_PANNAP)
+ {
+ debug("BTPAN_ROLE_PANNAP");
+ bta_pan_role |= PAN_ROLE_NAP_SERVER;
+ }
+ if(btpan_role & BTPAN_ROLE_PANU)
+ {
+ debug("BTPAN_ROLE_CLIENT");
+ bta_pan_role |= PAN_ROLE_CLIENT;
+ }
+ return bta_pan_role;
+}
+static volatile int btpan_dev_local_role;
+static tBTA_PAN_ROLE_INFO bta_panu_info = {PANU_SERVICE_NAME, 0, PAN_SECURITY};
+static tBTA_PAN_ROLE_INFO bta_pan_nap_info = {PAN_NAP_SERVICE_NAME, 0, PAN_SECURITY};
+
+static bt_status_t btpan_enable(int local_role)
+{
+ int bta_pan_role;
+ debug("local_role:%d", local_role);
+ bta_pan_role = btpan_role_to_bta(local_role);
+ BTA_PanSetRole(bta_pan_role, &bta_panu_info, NULL, &bta_pan_nap_info);
+ btpan_dev_local_role = local_role;
+ return BT_STATUS_SUCCESS;
+}
+static int btpan_get_local_role()
+{
+ debug("btpan_dev_local_role:%d", btpan_dev_local_role);
+ return btpan_dev_local_role;
+}
+static bt_status_t btpan_connect(const bt_bdaddr_t *bd_addr, int local_role, int remote_role)
+{
+ debug("local_role:%d, remote_role:%d", local_role, remote_role);
+ int bta_local_role = btpan_role_to_bta(local_role);
+ int bta_remote_role = btpan_role_to_bta(remote_role);
+ btpan_new_conn(-1, bd_addr->address, bta_local_role, bta_remote_role);
+ BTA_PanOpen((UINT8*)bd_addr->address, bta_local_role, bta_remote_role);
+ return BT_STATUS_SUCCESS;
+}
+static bt_status_t btpan_disconnect(const bt_bdaddr_t *bd_addr)
+{
+ debug("in");
+ btpan_conn_t* conn = btpan_find_conn_addr(bd_addr->address);
+ if(conn && conn->handle >= 0)
+ {
+ BTA_PanClose(conn->handle);
+ return BT_STATUS_SUCCESS;
+ }
+ return BT_STATUS_FAIL;
+}
+static int pth = -1;
+void create_tap_read_thread(int tap_fd)
+{
+ debug("in");
+ if(pth < 0)
+ {
+ pth = btsock_thread_create(btpan_tap_fd_signaled);
+ if(pth >= 0)
+ btsock_thread_add_fd(pth, tap_fd, 0, SOCK_THREAD_FD_RD, 0);
+ }
+}
+void destroy_tap_read_thread(void)
+{
+ if(pth >= 0)
+ {
+ btsock_thread_exit(pth);
+ pth = -1;
+ }
+}
+static int tap_if_up(const char *devname, BD_ADDR addr)
+{
+ struct ifreq ifr;
+ int sk, err;
+
+ sk = socket(AF_INET, SOCK_DGRAM, 0);
+
+ //set mac addr
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1);
+ err = ioctl(sk, SIOCGIFHWADDR, &ifr);
+ if(err < 0)
+ {
+ error("Could not get network hardware for interface:%s, errno:%s", devname, strerror(errno));
+ close(sk);
+ return -1;
+ }
+ debug("found mac address for interface:%s = %02x:%02x:%02x:%02x:%02x:%02x", devname,
+ ifr.ifr_hwaddr.sa_data[0], ifr.ifr_hwaddr.sa_data[1], ifr.ifr_hwaddr.sa_data[2],
+ ifr.ifr_hwaddr.sa_data[3], ifr.ifr_hwaddr.sa_data[4], ifr.ifr_hwaddr.sa_data[5]);
+ strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1);
+ memcpy(ifr.ifr_hwaddr.sa_data, addr, 6);
+ debug("setting bt address for interface:%s = %02x:%02x:%02x:%02x:%02x:%02x", devname,
+ ifr.ifr_hwaddr.sa_data[0], ifr.ifr_hwaddr.sa_data[1], ifr.ifr_hwaddr.sa_data[2],
+ ifr.ifr_hwaddr.sa_data[3], ifr.ifr_hwaddr.sa_data[4], ifr.ifr_hwaddr.sa_data[5]);
+
+ err = ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr);
+
+ if (err < 0) {
+ error("Could not set bt address for interface:%s, errno:%s", devname, strerror(errno));
+ close(sk);
+ return -1;
+ }
+
+ //bring it up
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);
+
+ ifr.ifr_flags |= IFF_UP;
+ ifr.ifr_flags |= IFF_MULTICAST;
+
+ err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
+
+
+ if (err < 0) {
+ error("Could not bring up network interface:%s, errno:%d", devname, errno);
+ close(sk);
+ return -1;
+ }
+ close(sk);
+ debug("network interface: %s is up", devname);
+ return 0;
+}
+
+static int tap_if_down(const char *devname)
+{
+ struct ifreq ifr;
+ int sk, err;
+
+ sk = socket(AF_INET, SOCK_DGRAM, 0);
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);
+
+ ifr.ifr_flags &= ~IFF_UP;
+
+ err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
+
+ close(sk);
+
+ return 0;
+}
+int btpan_tap_open()
+{
+ debug("in");
+ struct ifreq ifr;
+ int fd, err;
+ const char *clonedev = "/dev/tun";
+
+ /* open the clone device */
+
+ //system("insmod /system/lib/modules/tun.ko");
+ if( (fd = open(clonedev, O_RDWR)) < 0 ) {
+
+ debug("could not open %s, err:%d", clonedev, errno);
+ return fd;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+
+ strncpy(ifr.ifr_name, TAP_IF_NAME, IFNAMSIZ);
+
+ /* try to create the device */
+ if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 )//|| tap_setup_ip(TAP_IF_NAME) == FALSE)
+ {
+ debug("ioctl error:%d, errno:%s", err, strerror(errno));
+ close(fd);
+ return err;
+ }
+ BTM_GetLocalDeviceAddr (local_addr);
+ if(tap_if_up(TAP_IF_NAME, local_addr) == 0)
+ {
+ return fd;
+ }
+ error("can not bring up tap interface:%s", TAP_IF_NAME);
+ close(fd);
+ return -1;
+}
+int btpan_tap_send(int tap_fd, const BD_ADDR src, const BD_ADDR dst, UINT16 proto, const char* buf,
+ UINT16 len, BOOLEAN ext, BOOLEAN forward)
+{
+ debug("in");
+ debug("SRC ADDR = %02x:%02x:%02x:%02x:%02x:%02x",
+ src[0], src[1], src[2], src[3],
+ src[4], src[5]);
+ debug("DST ADDR = %02x:%02x:%02x:%02x:%02x:%02x",
+ dst[0], dst[1], dst[2], dst[3],
+ dst[4], dst[5]);
+
+ debug("Protocol = 0x%x", proto);
+ debug("Ext = 0x%x", ext);
+ debug("Forward = 0x%x", forward);
+ debug("Len = %d", len);
+ if(tap_fd != -1)
+ {
+ tETH_HDR eth_hdr;
+ //if(is_empty_eth_addr(dst))
+ // memcpy(&eth_hdr.h_dest, local_addr, ETH_ADDR_LEN);
+ //else
+ memcpy(&eth_hdr.h_dest, dst, ETH_ADDR_LEN);
+ memcpy(&eth_hdr.h_src, src, ETH_ADDR_LEN);
+ eth_hdr.h_proto = htons(proto);
+ char packet[2000];
+ memcpy(packet, &eth_hdr, sizeof(tETH_HDR));
+ if(len > 2000)
+ {
+ LOGE("btpan_tap_send eth packet size:%d is exceeded limit!", len);
+ return -1;
+ }
+ memcpy(packet + sizeof(tETH_HDR), buf, len);
+
+ /* Send data to network interface */
+ //btnet_send(btpan_cb.conn[i].sock.sock, &buffer, (len + sizeof(tETH_HDR)));
+ //dump_bin("packet to network", packet, len + sizeof(tETH_HDR));
+ int ret = write(tap_fd, packet, len + sizeof(tETH_HDR));
+ debug("ret:%d", ret);
+ return ret;
+ }
+ return -1;
+
+}
+int btpan_tap_close(int fd)
+{
+ debug("in");
+ tap_if_down(TAP_IF_NAME);
+ close(fd);
+ return 0;
+}
+btpan_conn_t * btpan_find_conn_handle(UINT16 handle)
+{
+ int i;
+ for(i = 0; i < MAX_PAN_CONNS; i++)
+ if(btpan_cb.conns[i].handle == handle)
+ return &btpan_cb.conns[i];
+ return NULL;
+}
+btpan_conn_t* btpan_find_conn_addr(const BD_ADDR addr)
+{
+ int i;
+ for(i = 0; i < MAX_PAN_CONNS; i++)
+ if(memcmp(btpan_cb.conns[i].peer, addr, sizeof(BD_ADDR)) == 0)
+ return &btpan_cb.conns[i];
+ return NULL;
+}
+static void btpan_cleanup_conn(btpan_conn_t* conn)
+{
+ if(conn)
+ {
+ conn->handle = -1;
+ conn->state = -1;
+ memset(&conn->peer, 0, sizeof(conn->peer));
+ memset(&conn->eth_addr, 0, sizeof(conn->eth_addr));
+ conn->local_role = conn->remote_role = 0;
+ }
+}
+btpan_conn_t* btpan_new_conn(int handle, const BD_ADDR addr, int local_role, int remote_role )
+{
+ int i;
+ debug("in");
+ for(i = 0; i < MAX_PAN_CONNS; i++)
+ {
+ debug("conns[%d]:%d", i, btpan_cb.conns[i].handle);
+ if(btpan_cb.conns[i].handle == -1)
+ {
+ debug("handle:%d, local_role:%d, remote_role:%d", handle, local_role, remote_role);
+
+ btpan_cb.conns[i].handle = handle;
+ bdcpy(btpan_cb.conns[i].peer, addr);
+ btpan_cb.conns[i].local_role = local_role;
+ btpan_cb.conns[i].remote_role = remote_role;
+ return &btpan_cb.conns[i];
+ }
+ }
+ debug("MAX_PAN_CONNS:%d exceeded, return NULL as failed", MAX_PAN_CONNS);
+ return NULL;
+}
+
+void btpan_close_handle(btpan_conn_t *p)
+{
+ debug("btpan_close_handle : close handle %d", p->handle);
+ p->handle = -1;
+ p->local_role = -1;
+ p->remote_role = -1;
+ memset(&p->peer, 0, 6);
+}
+static inline int should_forward(tETH_HDR* hdr)
+{
+ if(ntohs(hdr->h_proto) == ETH_P_IP || ntohs(hdr->h_proto) == ETH_P_ARP)
+ return TRUE;
+ debug("unknown proto:%x", ntohs(hdr->h_proto));
+ return FALSE;
+}
+extern void bta_pan_ci_rx_write(UINT16 handle, BD_ADDR dst, BD_ADDR src, UINT16 protocol,
+ UINT8 *p_data, UINT16 len, BOOLEAN ext);
+static void forward_bnep(tETH_HDR* eth_hdr, char * packet, int size)
+{
+ int broadcast = eth_hdr->h_dest[0] & 1;
+ int i;
+ for(i = 0; i < MAX_PAN_CONNS; i++)
+ {
+ UINT16 handle = btpan_cb.conns[i].handle;
+ if(handle != (UINT16)-1 &&
+ (broadcast || memcmp(btpan_cb.conns[i].eth_addr, eth_hdr->h_dest, sizeof(BD_ADDR)) == 0
+ || memcmp(btpan_cb.conns[i].peer, eth_hdr->h_dest, sizeof(BD_ADDR)) == 0))
+ {
+ debug("calling bta_pan_ci_rx_write, handle:%d", handle);
+ bta_pan_ci_rx_write(handle, eth_hdr->h_dest, eth_hdr->h_src,
+ ntohs(eth_hdr->h_proto), (UINT8*)packet, size, 0);
+ break;
+ }
+ }
+}
+
+static void bta_pan_callback_transfer(UINT16 event, char *p_param)
+{
+ tBTA_PAN *p_data = (tBTA_PAN *)p_param;
+ switch(event)
+ {
+ case BTA_PAN_ENABLE_EVT:
+ debug("BTA_PAN_ENABLE_EVT");
+ break;
+ case BTA_PAN_SET_ROLE_EVT:
+ {
+ int btpan_role = bta_role_to_btpan(p_data->set_role.role);
+ bt_status_t status = p_data->set_role.status == BTA_PAN_SUCCESS ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
+ btpan_control_state_t state = btpan_role == 0 ? BTPAN_STATE_DISABLED : BTPAN_STATE_ENABLED;
+ callback.control_state_cb(state, btpan_role, status, TAP_IF_NAME);
+ break;
+ }
+ case BTA_PAN_OPENING_EVT:
+ {
+ btpan_conn_t* conn;
+ bdstr_t bds;
+ bd2str((bt_bdaddr_t*)p_data->opening.bd_addr, &bds);
+ debug("BTA_PAN_OPENING_EVT handle %d, addr: %s", p_data->opening.handle, bds);
+ conn = btpan_find_conn_addr(p_data->opening.bd_addr);
+
+ asrt(conn != NULL);
+ if (conn)
+ {
+ conn->handle = p_data->opening.handle;
+ int btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
+ int btpan_remote_role = bta_role_to_btpan(conn->remote_role);
+ callback.connection_state_cb(BTPAN_STATE_CONNECTING, BT_STATUS_SUCCESS,
+ (const bt_bdaddr_t*)p_data->opening.bd_addr, btpan_conn_local_role, btpan_remote_role);
+ }
+ else
+ error("connection not found");
+ break;
+ }
+ case BTA_PAN_OPEN_EVT:
+ {
+ debug("BTA_PAN_OPEN_EVT, open status:%d, bd_addr = [%02X:%02X:%02X:%02X:%02X:%02X]",
+ p_data->open.status,
+ p_data->open.bd_addr[0], p_data->open.bd_addr[1], p_data->open.bd_addr[2],
+ p_data->open.bd_addr[3], p_data->open.bd_addr[4], p_data->open.bd_addr[5]);
+ btpan_connection_state_t state;
+ bt_status_t status;
+ if(p_data->open.status == BTA_PAN_SUCCESS)
+ {
+ state = BTPAN_STATE_CONNECTED;
+ status = BT_STATUS_SUCCESS;
+ }
+ else
+ {
+ state = BTPAN_STATE_DISCONNECTED;
+ status = BT_STATUS_FAIL;
+ }
+ btpan_conn_t* conn = btpan_find_conn_handle(p_data->open.handle);
+ debug("BTA_PAN_OPEN_EVT handle:%d, conn:%p", p_data->open.handle, conn);
+ debug("conn bta local_role:%d, bta remote role:%d", conn->local_role, conn->remote_role);
+ int btpan_conn_local_role = bta_role_to_btpan(p_data->open.local_role);
+ debug("bta local_role:%d, bta remote role:%d", p_data->open.local_role, p_data->open.peer_role);
+ int btpan_remote_role = bta_role_to_btpan(p_data->open.peer_role);
+ callback.connection_state_cb(state, status, (const bt_bdaddr_t*)p_data->open.bd_addr,
+ btpan_conn_local_role, btpan_remote_role);
+ break;
+ }
+ case BTA_PAN_CLOSE_EVT:
+ {
+ btpan_conn_t* conn = btpan_find_conn_handle(p_data->close.handle);
+
+ LOGI("%s: event = BTA_PAN_CLOSE_EVT handle %d", __FUNCTION__, p_data->close.handle);
+
+ if(conn && conn->handle >= 0)
+ {
+ debug("BTA_PAN_CLOSE_EVT, conn local_role:%d, remote_role:%d", conn->local_role, conn->remote_role);
+ int btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
+ int btpan_remote_role = bta_role_to_btpan(conn->remote_role);
+ callback.connection_state_cb(BTPAN_STATE_DISCONNECTED, 0, (const bt_bdaddr_t*)conn->peer,
+ btpan_conn_local_role, btpan_remote_role);
+ btpan_cleanup_conn(conn);
+ }
+ else
+ error("pan handle not found (%d)", p_data->close.handle);
+ break;
+ }
+ default:
+ debug("Unknown pan event %d", event);
+ break;
+ }
+}
+
+static void bta_pan_callback(tBTA_PAN_EVT event, tBTA_PAN *p_data)
+{
+ btif_transfer_context(bta_pan_callback_transfer, event, (char*)p_data, sizeof(tBTA_PAN), NULL);
+}
+#define MAX_PACKET_SIZE 2000
+static void btpan_tap_fd_signaled(int fd, int type, int flags, uint32_t user_id)
+{
+ char packet[MAX_PACKET_SIZE];
+ tETH_HDR eth_hdr;
+ if(flags & SOCK_THREAD_FD_EXCEPTION)
+ {
+ error("pan tap fd:%d exception", fd);
+ }
+ else if(flags & SOCK_THREAD_FD_RD)
+ {
+ debug("tab fd read trigged, data");
+ int size = read(fd, packet, MAX_PACKET_SIZE);
+ debug("tap fd read trigged, read size:%d", size);
+ memcpy(&eth_hdr, &packet, sizeof(tETH_HDR));
+ debug("eth src = %02x:%02x:%02x:%02x:%02x:%02x",
+ eth_hdr.h_src[0], eth_hdr.h_src[1], eth_hdr.h_src[2], eth_hdr.h_src[3],
+ eth_hdr.h_src[4], eth_hdr.h_src[5]);
+ debug("eth dest = %02x:%02x:%02x:%02x:%02x:%02x",
+ eth_hdr.h_dest[0], eth_hdr.h_dest[1], eth_hdr.h_dest[2], eth_hdr.h_dest[3],
+ eth_hdr.h_dest[4], eth_hdr.h_dest[5]);
+ //dump_bin("eth packet received", packet, size);
+ if(should_forward(&eth_hdr))
+ {
+ forward_bnep(&eth_hdr, packet + sizeof(tETH_HDR), size - sizeof(tETH_HDR));
+ }
+ btsock_thread_add_fd(pth, fd, 0, SOCK_THREAD_FD_RD | SOCK_THREAD_ADD_FD_SYNC, 0);
+ }
+}
+
+
diff --git a/btif/src/btif_sock_thread.c b/btif/src/btif_sock_thread.c
index 5bf014e..4ffe5ab 100644
--- a/btif/src/btif_sock_thread.c
+++ b/btif/src/btif_sock_thread.c
@@ -209,8 +209,14 @@ static int alloc_thread_slot()
int i;
//revserd order to save guard uninitialized access to 0 index
for(i = MAX_THREAD - 1; i >=0; i--)
+ {
+ debug("ts[%d].used:%d", i, ts[i].used);
if(!ts[i].used)
+ {
+ ts[i].used = 1;
return i;
+ }
+ }
error("execeeded max thread count");
return -1;
}
@@ -245,11 +251,13 @@ int btsock_thread_create(btsock_signaled_cb callback)
lock_slot(&thread_slot_lock);
int h = alloc_thread_slot();
unlock_slot(&thread_slot_lock);
+ debug("alloc_thread_slot ret:%d", h);
if(h >= 0)
{
init_poll(h);
if((ts[h].thread_id = create_thread(sock_poll_thread, (void*)h)) != -1)
{
+ debug("h:%d, thread id:%d", h, ts[h].thread_id);
ts[h].callback = callback;
}
else
@@ -310,7 +318,8 @@ int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
if(flags & SOCK_THREAD_ADD_FD_SYNC)
{
//must executed in socket poll thread
- asrt(ts[h].thread_id == gettid());
+ //debug("ts[%d].thread_id:%d, pthread self:%d", h, ts[h].thread_id, (int)pthread_self());
+ asrt(ts[h].thread_id == pthread_self());
//cleanup one-time flags
flags &= ~SOCK_THREAD_ADD_FD_SYNC;
add_poll(h, fd, type, flags, user_id);
@@ -362,7 +371,6 @@ int btsock_thread_exit(int h)
static void init_poll(int h)
{
int i;
- ts[h].used = 0;
ts[h].poll_count = 0;
ts[h].thread_id = -1;
ts[h].callback = NULL;
@@ -551,18 +559,18 @@ static void *sock_poll_thread(void *arg)
for(;;)
{
prepare_poll_fds(h, pfds);
- debug("call poll, thread handle:%d, cmd fd read:%d, ts[h].poll_count:%d",
+ debug("call poll, thread handle h:%d, cmd fd read:%d, ts[h].poll_count:%d",
h, ts[h].cmd_fdr, ts[h].poll_count);
int ret = poll(pfds, ts[h].poll_count, -1);
if(ret == -1)
{
error("poll ret -1, exit the thread, errno:%d, err:%s", errno, strerror(errno));
- debug("ts[h].poll_count:%d", ts[h].poll_count);
+ debug("ts[%d].poll_count:%d", h, ts[h].poll_count);
break;
}
if(ret != 0)
{
- debug("select wake up, ret:%d, ts[h].poll_count:%d", ret, ts[h].poll_count);
+ debug("select wake up, h:%d, ret:%d, ts[h].poll_count:%d", h, ret, ts[h].poll_count);
int need_process_data_fd = TRUE;
if(pfds[0].revents) //cmd fd always is the first one
{
@@ -572,7 +580,7 @@ static void *sock_poll_thread(void *arg)
asrt(pfds[0].fd == ts[h].cmd_fdr);
if(!process_cmd_sock(h))
{
- debug("process_cmd_sock failed, exit...");
+ debug("h:%d, process_cmd_sock failed, exit...", h);
break;
}
if(ret == 1)
@@ -585,7 +593,7 @@ static void *sock_poll_thread(void *arg)
else debug("no data, select ret: %d", ret);
}
ts[h].thread_id = -1;
- debug("socket poll thread exiting");
+ debug("socket poll thread exiting, h:%d", h);
return 0;
}