***********************************************************************************/
#define LOG_TAG "BTIF_HL"
+#include <assert.h>
+#include <ctype.h>
+#include <cutils/log.h>
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <hardware/bluetooth.h>
+#include <hardware/bt_hl.h>
+#include <pthread.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
-#include <errno.h>
#include <string.h>
-#include <sys/types.h>
+#include <sys/poll.h>
+#include <sys/select.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <sys/un.h>
#include <time.h>
-#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include "gki.h"
#include "bta_api.h"
#include "bta_hl_api.h"
-#include "mca_api.h"
+#include "btif_common.h"
#include "btif_hl.h"
#include "btif_storage.h"
+#include "btif_util.h"
#include "btu.h"
+#include "gki.h"
+#include "list.h"
+#include "mca_api.h"
#define MAX_DATATYPE_SUPPORTED 8
static int connected_s = -1;
static int select_thread_id = -1;
static int signal_fds[2] = { -1, -1 };
-static BUFFER_Q soc_queue;
+static list_t *soc_queue;
static int reg_counter;
static inline int btif_hl_select_wakeup(void);
** Returns int
**
*******************************************************************************/
-int btif_hl_update_maxfd( int max_org_s){
- btif_hl_soc_cb_t *p_scb = NULL;
- int maxfd=0;
+int btif_hl_update_maxfd(int max_org_s) {
+ int maxfd = max_org_s;
BTIF_TRACE_DEBUG("btif_hl_update_maxfd max_org_s= %d", max_org_s);
-
- maxfd = max_org_s;
- if (!GKI_queue_is_empty(&soc_queue))
- {
- p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
- if (maxfd < p_scb->max_s)
- {
+ for (const list_node_t *node = list_begin(soc_queue);
+ node != list_end(soc_queue); node = list_next(node)) {
+ btif_hl_soc_cb_t *p_scb = list_node(node);
+ if (maxfd < p_scb->max_s) {
maxfd = p_scb->max_s;
- BTIF_TRACE_DEBUG("btif_hl_update_maxfd 1 maxfd=%d", maxfd);
- }
- while (p_scb != NULL)
- {
- if (maxfd < p_scb->max_s)
- {
- maxfd = p_scb->max_s;
- BTIF_TRACE_DEBUG("btif_hl_update_maxfd 2 maxfd=%d", maxfd);
- }
- p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
+ BTIF_TRACE_DEBUG("btif_hl_update_maxfd maxfd=%d", maxfd);
}
}
memcpy(p_scb->bd_addr, p_mcb->bd_addr,sizeof(BD_ADDR));
btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_ADD);
p_scb->max_s = p_scb->socket_id[1];
- GKI_enqueue(&soc_queue, (void *) p_scb);
+ list_append(soc_queue, (void *)p_scb);
btif_hl_select_wakeup();
status = TRUE;
}
** Returns void
**
*******************************************************************************/
-void btif_hl_add_socket_to_set( fd_set *p_org_set){
- btif_hl_soc_cb_t *p_scb = NULL;
+void btif_hl_add_socket_to_set(fd_set *p_org_set) {
btif_hl_mdl_cb_t *p_dcb = NULL;
btif_hl_mcl_cb_t *p_mcb = NULL;
btif_hl_app_cb_t *p_acb = NULL;
BTIF_TRACE_DEBUG("entering %s",__FUNCTION__);
- if (!GKI_queue_is_empty(&soc_queue))
- {
- p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
+ for (const list_node_t *node = list_begin(soc_queue);
+ node != list_end(soc_queue); node = list_next(node)) {
+ btif_hl_soc_cb_t *p_scb = list_node(node);
+
BTIF_TRACE_DEBUG("btif_hl_add_socket_to_set first p_scb=0x%x", p_scb);
- while (p_scb != NULL)
- {
- if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_ADD)
- {
- btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_READ);
- FD_SET(p_scb->socket_id[1], p_org_set);
- BTIF_TRACE_DEBUG("found and set socket_id=%d is_set=%d", p_scb->socket_id[1], FD_ISSET(p_scb->socket_id[1], p_org_set));
- p_mcb = BTIF_HL_GET_MCL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx);
- p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
- p_acb = BTIF_HL_GET_APP_CB_PTR(p_scb->app_idx);
- if (p_mcb && p_dcb)
- {
- btif_hl_stop_timer_using_handle(p_mcb->mcl_handle);
- evt_param.chan_cb.app_id = p_acb->app_id;
- memcpy(evt_param.chan_cb.bd_addr, p_mcb->bd_addr, sizeof(BD_ADDR));
- evt_param.chan_cb.channel_id = p_dcb->channel_id;
- evt_param.chan_cb.fd = p_scb->socket_id[0];
- evt_param.chan_cb.mdep_cfg_index = (int ) p_dcb->local_mdep_cfg_idx;
- evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING;
- len = sizeof(btif_hl_send_chan_state_cb_t);
- status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_SEND_CONNECTED_CB,
- (char*) &evt_param, len, NULL);
- ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
- }
+ if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_ADD) {
+ btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_READ);
+ FD_SET(p_scb->socket_id[1], p_org_set);
+ BTIF_TRACE_DEBUG("found and set socket_id=%d is_set=%d",
+ p_scb->socket_id[1], FD_ISSET(p_scb->socket_id[1], p_org_set));
+ p_mcb = BTIF_HL_GET_MCL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx);
+ p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
+ p_acb = BTIF_HL_GET_APP_CB_PTR(p_scb->app_idx);
+ if (p_mcb && p_dcb) {
+ btif_hl_stop_timer_using_handle(p_mcb->mcl_handle);
+ evt_param.chan_cb.app_id = p_acb->app_id;
+ memcpy(evt_param.chan_cb.bd_addr, p_mcb->bd_addr, sizeof(BD_ADDR));
+ evt_param.chan_cb.channel_id = p_dcb->channel_id;
+ evt_param.chan_cb.fd = p_scb->socket_id[0];
+ evt_param.chan_cb.mdep_cfg_index = (int ) p_dcb->local_mdep_cfg_idx;
+ evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING;
+ len = sizeof(btif_hl_send_chan_state_cb_t);
+ status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_SEND_CONNECTED_CB,
+ (char*) &evt_param, len, NULL);
+ ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
}
- p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
- BTIF_TRACE_DEBUG("next p_scb=0x%x", p_scb);
}
}
-
BTIF_TRACE_DEBUG("leaving %s",__FUNCTION__);
}
+
/*******************************************************************************
**
** Function btif_hl_close_socket
**
*******************************************************************************/
void btif_hl_close_socket( fd_set *p_org_set){
- btif_hl_soc_cb_t *p_scb = NULL;
- BOOLEAN element_removed = FALSE;
- btif_hl_mdl_cb_t *p_dcb = NULL ;
- btif_hl_app_cb_t *p_acb = NULL ;
- btif_hl_evt_cb_t evt_param;
- int len;
- int app_idx;
- bt_status_t status;
-
BTIF_TRACE_DEBUG("entering %s",__FUNCTION__);
- if (!GKI_queue_is_empty(&soc_queue))
- {
- p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
- while (p_scb != NULL)
- {
- if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_REL)
- {
- BTIF_TRACE_DEBUG("app_idx=%d mcl_id=%d, mdl_idx=%d",
- p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
- btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_IDLE);
- if (p_scb->socket_id[1] != -1)
- {
- FD_CLR(p_scb->socket_id[1] , p_org_set);
- shutdown(p_scb->socket_id[1], SHUT_RDWR);
- close(p_scb->socket_id[1]);
-
- evt_param.chan_cb.app_id = (int) btif_hl_get_app_id(p_scb->channel_id);
- memcpy(evt_param.chan_cb.bd_addr, p_scb->bd_addr, sizeof(BD_ADDR));
- evt_param.chan_cb.channel_id = p_scb->channel_id;
- evt_param.chan_cb.fd = p_scb->socket_id[0];
- evt_param.chan_cb.mdep_cfg_index = (int ) p_scb->mdep_cfg_idx;
- evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_DISCONNECTED_PENDING;
- len = sizeof(btif_hl_send_chan_state_cb_t);
- status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_SEND_DISCONNECTED_CB,
- (char*) &evt_param, len, NULL);
- ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
-
-
- }
+ for (const list_node_t *node = list_begin(soc_queue);
+ node != list_end(soc_queue); node = list_next(node)) {
+ btif_hl_soc_cb_t *p_scb = list_node(node);
+ if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_REL) {
+ BTIF_TRACE_DEBUG("app_idx=%d mcl_id=%d, mdl_idx=%d",
+ p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
+ btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_IDLE);
+ if (p_scb->socket_id[1] != -1) {
+ FD_CLR(p_scb->socket_id[1] , p_org_set);
+ shutdown(p_scb->socket_id[1], SHUT_RDWR);
+ close(p_scb->socket_id[1]);
+
+ btif_hl_evt_cb_t evt_param;
+ evt_param.chan_cb.app_id = (int) btif_hl_get_app_id(p_scb->channel_id);
+ memcpy(evt_param.chan_cb.bd_addr, p_scb->bd_addr, sizeof(BD_ADDR));
+ evt_param.chan_cb.channel_id = p_scb->channel_id;
+ evt_param.chan_cb.fd = p_scb->socket_id[0];
+ evt_param.chan_cb.mdep_cfg_index = (int ) p_scb->mdep_cfg_idx;
+ evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_DISCONNECTED_PENDING;
+ int len = sizeof(btif_hl_send_chan_state_cb_t);
+ bt_status_t status = btif_transfer_context (btif_hl_proc_cb_evt,
+ BTIF_HL_SEND_DISCONNECTED_CB,
+ (char*) &evt_param, len, NULL);
+ ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
}
- p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
- BTIF_TRACE_DEBUG("while loop next p_scb=0x%x", p_scb);
}
+ }
- p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
- while (p_scb != NULL)
- {
- if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_IDLE)
- {
- p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
- BTIF_TRACE_DEBUG("idle socket app_idx=%d mcl_id=%d, mdl_idx=%d p_dcb->in_use=%d",
- p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx, p_dcb->in_use);
- GKI_remove_from_queue((void *)&soc_queue, p_scb);
- btif_hl_free_buf((void **)&p_scb);
- p_dcb->p_scb = NULL;
- element_removed = TRUE;
- }
- BTIF_TRACE_DEBUG("element_removed=%d p_scb=0x%x", element_removed, p_scb);
- if (element_removed)
- {
- element_removed = FALSE;
- p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
- }
- else
- p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
-
- BTIF_TRACE_DEBUG("while loop p_scb=0x%x", p_scb);
+ for (const list_node_t *node = list_begin(soc_queue);
+ node != list_end(soc_queue); ) {
+ // We may mutate this list so we need keep track of
+ // the current node and only remove items behind.
+ btif_hl_soc_cb_t *p_scb = list_node(node);
+ node = list_next(node);
+ if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_IDLE) {
+ btif_hl_mdl_cb_t *p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx,
+ p_scb->mcl_idx, p_scb->mdl_idx);
+ BTIF_TRACE_DEBUG("idle socket app_idx=%d mcl_id=%d, mdl_idx=%d p_dcb->in_use=%d",
+ p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx, p_dcb->in_use);
+ list_remove(soc_queue, p_scb);
+ btif_hl_free_buf((void **)&p_scb);
+ p_dcb->p_scb = NULL;
}
+ BTIF_TRACE_DEBUG("p_scb=0x%x", p_scb);
}
BTIF_TRACE_DEBUG("leaving %s",__FUNCTION__);
}
+
/*******************************************************************************
**
** Function btif_hl_select_wakeup_callback
** Returns void
**
*******************************************************************************/
-void btif_hl_select_monitor_callback( fd_set *p_cur_set , fd_set *p_org_set){
- btif_hl_soc_cb_t *p_scb = NULL;
- btif_hl_mdl_cb_t *p_dcb = NULL;
- int r;
+void btif_hl_select_monitor_callback(fd_set *p_cur_set ,fd_set *p_org_set) {
UNUSED(p_org_set);
BTIF_TRACE_DEBUG("entering %s",__FUNCTION__);
- if (!GKI_queue_is_empty(&soc_queue))
- {
- p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
- BTIF_TRACE_DEBUG(" GKI queue is not empty ");
- while (p_scb != NULL)
- {
- if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_READ)
- {
- if (FD_ISSET(p_scb->socket_id[1], p_cur_set))
- {
- BTIF_TRACE_DEBUG("read data");
- BTIF_TRACE_DEBUG("state= BTIF_HL_SOC_STATE_W4_READ");
- p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
- if (p_dcb->p_tx_pkt)
- {
- BTIF_TRACE_ERROR("Rcv new pkt but the last pkt is still not been sent tx_size=%d", p_dcb->tx_size);
- btif_hl_free_buf((void **) &p_dcb->p_tx_pkt);
- }
- p_dcb->p_tx_pkt = btif_hl_get_buf (p_dcb->mtu);
- if (p_dcb )
- {
- //do
- // {
- // r = recv(p_scb->socket_id[1], p_dcb->p_tx_pkt, p_dcb->mtu , MSG_DONTWAIT));
- // } while (r == SOCKET_ERROR && errno == EINTR);
-
- if ((r = (int)recv(p_scb->socket_id[1], p_dcb->p_tx_pkt, p_dcb->mtu , MSG_DONTWAIT)) > 0)
- {
- BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data r =%d", r);
- p_dcb->tx_size = r;
- BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data tx_size=%d", p_dcb->tx_size );
- BTA_HlSendData(p_dcb->mdl_handle, p_dcb->tx_size );
- }
-
- if (r <= 0 )
- {
- BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback receive failed r=%d",r);
- BTA_HlDchClose(p_dcb->mdl_handle );
- }
+ for (const list_node_t *node = list_begin(soc_queue);
+ node != list_end(soc_queue); node = list_next(node)) {
+ btif_hl_soc_cb_t *p_scb = list_node(node);
+ if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_READ) {
+ if (FD_ISSET(p_scb->socket_id[1], p_cur_set)) {
+ BTIF_TRACE_DEBUG("read data state= BTIF_HL_SOC_STATE_W4_READ");
+ btif_hl_mdl_cb_t *p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx,
+ p_scb->mcl_idx, p_scb->mdl_idx);
+ assert(p_dcb != NULL);
+ if (p_dcb->p_tx_pkt) {
+ BTIF_TRACE_ERROR("Rcv new pkt but the last pkt is still not been"
+ " sent tx_size=%d", p_dcb->tx_size);
+ btif_hl_free_buf((void **) &p_dcb->p_tx_pkt);
+ }
+ p_dcb->p_tx_pkt = btif_hl_get_buf (p_dcb->mtu);
+ if (p_dcb) {
+ int r = (int)recv(p_scb->socket_id[1], p_dcb->p_tx_pkt,
+ p_dcb->mtu, MSG_DONTWAIT);
+ if (r > 0) {
+ BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data r =%d", r);
+ p_dcb->tx_size = r;
+ BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data tx_size=%d", p_dcb->tx_size );
+ BTA_HlSendData(p_dcb->mdl_handle, p_dcb->tx_size);
+ } else {
+ BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback receive failed r=%d",r);
+ BTA_HlDchClose(p_dcb->mdl_handle);
}
}
}
- p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
}
}
- else
- {
+
+ if (list_is_empty(soc_queue))
BTIF_TRACE_DEBUG("btif_hl_select_monitor_queue is empty");
- }
+
BTIF_TRACE_DEBUG("leaving %s",__FUNCTION__);
}
+
/*******************************************************************************
**
** Function btif_hl_select_wakeup_init
select_thread_id = -1;
}
}
+ list_free(soc_queue);
return result;
}
*******************************************************************************/
void btif_hl_soc_thread_init(void){
BTIF_TRACE_DEBUG("%s", __FUNCTION__);
- GKI_init_q(&soc_queue);
+ soc_queue = list_new(NULL);
+ if (soc_queue == NULL)
+ ALOGE("%s unable to allocate resources for thread", __func__);
select_thread_id = create_thread(btif_hl_select_thread, NULL);
}
/*******************************************************************************