#define BTA_PAN_TX_MASK 0xF0
/*******************************************************************************
+ **
+ ** Function bta_pan_pm_conn_busy
+ **
+ ** Description set pan pm connection busy state
+ **
+ ** Params p_scb: state machine control block of pan connection
+ **
+ ** Returns void
+ **
+ *******************************************************************************/
+static void bta_pan_pm_conn_busy(tBTA_PAN_SCB *p_scb)
+{
+ if ((p_scb != NULL) && (p_scb->state != BTA_PAN_IDLE_ST))
+ bta_sys_busy(BTA_ID_PAN, p_scb->app_id, p_scb->bd_addr);
+}
+
+/*******************************************************************************
+ **
+ ** Function bta_pan_pm_conn_idle
+ **
+ ** Description set pan pm connection idle state
+ **
+ ** Params p_scb: state machine control block of pan connection
+ **
+ ** Returns void
+ **
+ *******************************************************************************/
+static void bta_pan_pm_conn_idle(tBTA_PAN_SCB *p_scb)
+{
+ if ((p_scb != NULL) && (p_scb->state != BTA_PAN_IDLE_ST))
+ bta_sys_idle(BTA_ID_PAN, p_scb->app_id, p_scb->bd_addr);
+}
+
+/*******************************************************************************
**
** Function bta_pan_conn_state_cback
**
status = PAN_Connect (p_data->api_open.bd_addr, p_data->api_open.local_role, p_data->api_open.peer_role,
&p_scb->handle);
-
+ APPL_TRACE_DEBUG("%s pan connect status: %d", __func__, status);
if(status == PAN_SUCCESS)
{
bta_pan_scb_dealloc(p_scb);
bdcpy(data.bd_addr, p_data->api_open.bd_addr);
data.status = BTA_PAN_FAIL;
+ data.local_role = p_data->api_open.local_role;
+ data.peer_role = p_data->api_open.peer_role;
bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);
}
tBTA_PAN_OPEN data;
+ APPL_TRACE_DEBUG("%s pan connection result: %d", __func__, p_data->conn.result);
+
bdcpy(data.bd_addr, p_scb->bd_addr);
data.handle = p_scb->handle;
data.local_role = p_scb->local_role;
{
data.status = BTA_PAN_SUCCESS;
bta_pan_co_open(p_scb->handle, p_scb->app_id, p_scb->local_role, p_scb->peer_role, p_scb->bd_addr);
-
+ p_scb->pan_flow_enable = TRUE;
+ p_scb->app_flow_enable = TRUE;
+ bta_sys_conn_open(BTA_ID_PAN ,p_scb->app_id, p_scb->bd_addr);
}
else
{
data.status = BTA_PAN_FAIL;
}
- p_scb->pan_flow_enable = TRUE;
- p_scb->app_flow_enable = TRUE;
-
- bta_sys_conn_open( BTA_ID_PAN ,p_scb->app_id, p_scb->bd_addr);
-
bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);
/* if data path configured for tx pull */
if ((bta_pan_cb.flow_mask & BTA_PAN_TX_MASK) == BTA_PAN_TX_PULL)
{
+ bta_pan_pm_conn_busy(p_scb);
/* call application callout function for tx path */
bta_pan_co_tx_path(p_scb->handle, p_scb->app_id);
/* free data that exceeds queue level */
while(p_scb->data_queue.count > bta_pan_cb.q_level)
GKI_freebuf(GKI_dequeue(&p_scb->data_queue));
+ bta_pan_pm_conn_idle(p_scb);
}
/* if configured for zero copy push */
else if ((bta_pan_cb.flow_mask & BTA_PAN_TX_MASK) == BTA_PAN_TX_PUSH_BUF)
{
if ((bta_pan_cb.flow_mask & BTA_PAN_RX_MASK) == BTA_PAN_RX_PUSH_BUF)
{
+ bta_pan_pm_conn_busy(p_scb);
PAN_WriteBuf (p_scb->handle,
((tBTA_PAN_DATA_PARAMS *)p_data)->dst,
((tBTA_PAN_DATA_PARAMS *)p_data)->protocol,
(BT_HDR *)p_data,
((tBTA_PAN_DATA_PARAMS *)p_data)->ext);
+ bta_pan_pm_conn_idle(p_scb);
}
}
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 tBTA_PAN_ROLE_INFO bta_pan_nap_info = {PAN_NAP_SERVICE_NAME, 1, PAN_SECURITY};
static bt_status_t btpan_enable(int local_role)
{
int bta_pan_role;
BTIF_TRACE_DEBUG("local_role:%d", local_role);
bta_pan_role = btpan_role_to_bta(local_role);
+#if BTA_PAN_INCLUDED == TRUE
BTA_PanSetRole(bta_pan_role, &bta_panu_info, NULL, &bta_pan_nap_info);
btpan_dev_local_role = local_role;
return BT_STATUS_SUCCESS;
+#else
+ return BT_STATUS_FAIL;
+#endif
}
static int btpan_get_local_role()
/* 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]); */
+ /* The IEEE has specified that the most significant bit of the most significant byte is used to
+ * determine a multicast address. If its a 1, that means multicast, 0 means unicast.
+ * Kernel returns an error if we try to set a multicast address for the tun-tap ethernet interface.
+ * Mask this bit to avoid any issue with auto generated address.
+ */
+ if (ifr.ifr_hwaddr.sa_data[0] & 0x01) {
+ BTIF_TRACE_WARNING("Not a unicast MAC address, force multicast bit flipping");
+ ifr.ifr_hwaddr.sa_data[0] &= ~0x01;
+ }
+
err = ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr);
if (err < 0) {
/* 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;
+ btpan_conn_t *conn = btpan_find_conn_handle(p_data->open.handle);
+
+ ALOGV("%s pan connection open status: %d", __func__, p_data->open.status);
if(p_data->open.status == BTA_PAN_SUCCESS)
{
state = BTPAN_STATE_CONNECTED;
{
state = BTPAN_STATE_DISCONNECTED;
status = BT_STATUS_FAIL;
+ btpan_cleanup_conn(conn);
}
- 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);