Example #1
0
static int tap_if_up(const char *devname, const bt_bdaddr_t *addr)
{
    struct ifreq ifr;
    int sk, err;

    sk = socket(AF_INET, SOCK_DGRAM, 0);
    if (sk < 0)
        return -1;

    //set mac addr
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1);
    err = ioctl(sk, SIOCGIFHWADDR, &ifr);
    if (err < 0)
    {
        BTIF_TRACE_ERROR("Could not get network hardware for interface:%s, errno:%s", devname, strerror(errno));
        close(sk);
        return -1;
    }

    strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1);
    memcpy(ifr.ifr_hwaddr.sa_data, addr->address, 6);

    /* 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) {
        BTIF_TRACE_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) {
        BTIF_TRACE_ERROR("Could not bring up network interface:%s, errno:%d", devname, errno);
        close(sk);
        return -1;
    }
    close(sk);
    BTIF_TRACE_DEBUG("network interface: %s is up", devname);
    return 0;
}
static void queue_int_add(connect_node_t *p_param) {
    connect_node_t *p_node = GKI_getbuf(sizeof(connect_node_t));
    ASSERTC(p_node != NULL, "Failed to allocate new list node", 0);
    if (p_node)
        memcpy(p_node, p_param, sizeof(connect_node_t));
    else
    {
        BTIF_TRACE_ERROR("%s, Failed to allocate new list node");
        return;
    }
    if (!connect_queue) {
        connect_queue = list_new(GKI_freebuf);
        ASSERTC(connect_queue != NULL, "Failed to allocate list", 0);
    }
    if (connect_queue)
        list_append(connect_queue, p_node);
    else
        BTIF_TRACE_ERROR("%s, Failed to allocate list");
}
Example #3
0
/*****************************************************************************
**
** Function     btif_sm_get_state
**
** Description  Fetches the current state of the state machine
**
** Returns      Current state
**
******************************************************************************/
btif_sm_state_t btif_sm_get_state(btif_sm_handle_t handle)
{
    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
    if (p_cb == NULL)
    {
        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
        return 0;
    }

    return p_cb->state;
}
Example #4
0
/*****************************************************************************
**
** Function     btif_sm_shutdown
**
** Description  Tears down the state machine
**
** Returns      None
**
******************************************************************************/
void btif_sm_shutdown(btif_sm_handle_t handle)
{
    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;

    if (p_cb == NULL)
    {
        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
        return;
    }
    osi_free(p_cb);
}
Example #5
0
/*****************************************************************************
**
** Function     btif_sm_dispatch
**
** Description  Dispatches the 'event' along with 'data' to the current state handler
**
** Returns      BT_STATUS_SUCCESS on success
**              BT_STATUS_UNHANDLED if event was not processed
**              BT_STATUS_FAIL otherwise
**
******************************************************************************/
bt_status_t btif_sm_dispatch(btif_sm_handle_t handle, btif_sm_event_t event,
                                void *data)
{
    bt_status_t status = BT_STATUS_SUCCESS;

    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;

    if (p_cb == NULL)
    {
        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
        return BT_STATUS_FAIL;
    }

    if (p_cb->p_handlers[p_cb->state](event, data, p_cb->index) == FALSE)
        return BT_STATUS_UNHANDLED;

    return status;
}
Example #6
0
btif_sm_handle_t btif_sm_init(const btif_sm_handler_t *p_handlers, btif_sm_state_t initial_state,
                            int index)
{
    btif_sm_cb_t *p_cb;

    if (p_handlers == NULL)
    {
        BTIF_TRACE_ERROR("%s : p_handlers is NULL", __FUNCTION__);
        return NULL;
    }

    p_cb = (btif_sm_cb_t *)osi_malloc(sizeof(btif_sm_cb_t));
    p_cb->state = initial_state;
    p_cb->p_handlers = (btif_sm_handler_t*)p_handlers;
    p_cb->index = index;

    /* Send BTIF_SM_ENTER_EVT to the initial state */
    p_cb->p_handlers[initial_state](BTIF_SM_ENTER_EVT, NULL, index);

    return (btif_sm_handle_t)p_cb;
}
int btpan_tap_open()
{
    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 ) {

        BTIF_TRACE_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)
    {
        BTIF_TRACE_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)
    {
        int flags = fcntl(fd, F_GETFL, 0);
        fcntl(fd, F_SETFL, flags | O_NONBLOCK);
        return fd;
    }
    BTIF_TRACE_ERROR("can not bring up tap interface:%s", TAP_IF_NAME);
    close(fd);
    return -1;
}
Example #8
0
/*****************************************************************************
**
** Function     btif_sm_change_state
**
** Description  Make a transition to the new 'state'. The 'BTIF_SM_EXIT_EVT'
**              shall be invoked before exiting the current state. The
**              'BTIF_SM_ENTER_EVT' shall be invoked before entering the new state
**
** Returns      BT_STATUS_SUCCESS on success
**              BT_STATUS_UNHANDLED if event was not processed
**              BT_STATUS_FAIL otherwise
**
******************************************************************************/
bt_status_t btif_sm_change_state(btif_sm_handle_t handle, btif_sm_state_t state)
{
    bt_status_t status = BT_STATUS_SUCCESS;
    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;

    if (p_cb == NULL)
    {
        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
        return BT_STATUS_FAIL;
    }

    /* Send exit event to the current state */
    if (p_cb->p_handlers[p_cb->state](BTIF_SM_EXIT_EVT, NULL, p_cb->index) == FALSE)
        status = BT_STATUS_UNHANDLED;

    /* Change to the new state */
    p_cb->state = state;

    /* Send enter event to the new state */
    if (p_cb->p_handlers[p_cb->state](BTIF_SM_ENTER_EVT, NULL, p_cb->index) == FALSE)
        status = BT_STATUS_UNHANDLED;

    return status;
}
Example #9
0
int btpan_tap_open()
{
    struct ifreq ifr;
    int fd, err;
    const char *clonedev = "/dev/tun";

    /* open the clone device */

    if ((fd = open(clonedev, O_RDWR)) < 0)
    {
        BTIF_TRACE_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)
    {
        BTIF_TRACE_DEBUG("ioctl error:%d, errno:%s", err, strerror(errno));
        close(fd);
        return err;
    }
    if (tap_if_up(TAP_IF_NAME, controller_get_interface()->get_address()) == 0)
    {
        int flags = fcntl(fd, F_GETFL, 0);
        fcntl(fd, F_SETFL, flags | O_NONBLOCK);
        return fd;
    }
    BTIF_TRACE_ERROR("can not bring up tap interface:%s", TAP_IF_NAME);
    close(fd);
    return INVALID_FD;
}
static void btu_exec_tap_fd_read(void *p_param) {
    struct pollfd ufd;
    int fd = (int)p_param;

    if (fd == -1 || fd != btpan_cb.tap_fd)
        return;

    // Don't occupy BTU context too long, avoid GKI buffer overruns and
    // give other profiles a chance to run by limiting the amount of memory
    // PAN can use from the shared pool buffer.
    for(int i = 0; i < PAN_POOL_MAX && btif_is_enabled() && btpan_cb.flow; i++) {
        BT_HDR *buffer = (BT_HDR *)GKI_getpoolbuf(PAN_POOL_ID);
        if (!buffer) {
            BTIF_TRACE_WARNING("%s unable to allocate buffer for packet.", __func__);
            break;
        }
        buffer->offset = PAN_MINIMUM_OFFSET;
        buffer->len = GKI_get_buf_size(buffer) - sizeof(BT_HDR) - buffer->offset;

        UINT8 *packet = (UINT8 *)buffer + sizeof(BT_HDR) + buffer->offset;

        // If we don't have an undelivered packet left over, pull one from the TAP driver.
        // We save it in the congest_packet right away in case we can't deliver it in this
        // attempt.
        if (!btpan_cb.congest_packet_size) {
            ssize_t ret = read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet));
            switch (ret) {
                case -1:
                    BTIF_TRACE_ERROR("%s unable to read from driver: %s", __func__, strerror(errno));
                    GKI_freebuf(buffer);
                    return;
                case 0:
                    BTIF_TRACE_WARNING("%s end of file reached.", __func__);
                    GKI_freebuf(buffer);
                    return;
                default:
                    btpan_cb.congest_packet_size = ret;
                    break;
            }
        }

        memcpy(packet, btpan_cb.congest_packet, MIN(btpan_cb.congest_packet_size, buffer->len));
        buffer->len = MIN(btpan_cb.congest_packet_size, buffer->len);

        if (buffer->len > sizeof(tETH_HDR) && should_forward((tETH_HDR *)packet)) {
            // Extract the ethernet header from the buffer since the PAN_WriteBuf inside
            // forward_bnep can't handle two pointers that point inside the same GKI buffer.
            tETH_HDR hdr;
            memcpy(&hdr, packet, sizeof(tETH_HDR));

            // Skip the ethernet header.
            buffer->len -= sizeof(tETH_HDR);
            buffer->offset += sizeof(tETH_HDR);
            if (forward_bnep(&hdr, buffer) != FORWARD_CONGEST)
                btpan_cb.congest_packet_size = 0;
        } else {
            BTIF_TRACE_WARNING("%s dropping packet of length %d", __func__, buffer->len);
            btpan_cb.congest_packet_size = 0;
            GKI_freebuf(buffer);
        }

        // Bail out of the loop if reading from the TAP fd would block.
        ufd.fd = fd;
        ufd.events = POLLIN;
        ufd.revents = 0;
        if(poll(&ufd, 1, 0) <= 0 || IS_EXCEPTION(ufd.revents)) {
            btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0);
            return;
        }
    }
}
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:
            BTIF_TRACE_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);
                BTIF_TRACE_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
                    BTIF_TRACE_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;
                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;
                    status = BT_STATUS_SUCCESS;
                }
                else
                {
                    state = BTPAN_STATE_DISCONNECTED;
                    status = BT_STATUS_FAIL;
                    btpan_cleanup_conn(conn);
                }
                /* 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);

                ALOGI("%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
                    BTIF_TRACE_ERROR("pan handle not found (%d)", p_data->close.handle);
                break;
            }
        default:
            BTIF_TRACE_WARNING("Unknown pan event %d", event);
            break;
    }
}