static int setup_listening_socket(int dev, int channel) {
    struct sockaddr_rc laddr;
    int sk, lm;

    sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
    if (sk < 0) {
        ALOGE("Can't create RFCOMM socket");
        return -1;
    }

    if (debug_no_encrypt()) {
        lm = RFCOMM_LM_AUTH;
    } else {
        lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
    }

    if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
        ALOGE("Can't set RFCOMM link mode");
        close(sk);
        return -1;
    }

    laddr.rc_family = AF_BLUETOOTH;
    bdaddr_t any = android_bluetooth_bdaddr_any();
    memcpy(&laddr.rc_bdaddr, &any, sizeof(bdaddr_t));
    laddr.rc_channel = channel;

    if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
        ALOGE("Can't bind RFCOMM socket");
        close(sk);
        return -1;
    }

    listen(sk, 10);
    return sk;
}
Beispiel #2
0
/* Returns errno instead of throwing, so java can check errno */
static int bindListenNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);

    jint type;
    socklen_t addr_sz;
    struct sockaddr *addr;
    bdaddr_t bdaddr = android_bluetooth_bdaddr_any();
    struct asocket *s = get_socketData(env, obj);

    if (!s)
        return EINVAL;

    type = env->GetIntField(obj, field_mType);

    switch (type) {
    case TYPE_RFCOMM:
        struct sockaddr_rc addr_rc;
        addr = (struct sockaddr *)&addr_rc;
        addr_sz = sizeof(addr_rc);

        memset(addr, 0, addr_sz);
        addr_rc.rc_family = AF_BLUETOOTH;
        addr_rc.rc_channel = env->GetIntField(obj, field_mPort);
        memcpy(&addr_rc.rc_bdaddr, &bdaddr, sizeof(bdaddr_t));
        break;
    case TYPE_SCO:
        struct sockaddr_sco addr_sco;
        addr = (struct sockaddr *)&addr_sco;
        addr_sz = sizeof(addr_sco);

        memset(addr, 0, addr_sz);
        addr_sco.sco_family = AF_BLUETOOTH;
        memcpy(&addr_sco.sco_bdaddr, &bdaddr, sizeof(bdaddr_t));
        break;
    case TYPE_L2CAP:
    case TYPE_EL2CAP:
        struct sockaddr_l2 addr_l2;
        addr = (struct sockaddr *)&addr_l2;
        addr_sz = sizeof(addr_l2);

        memset(addr, 0, addr_sz);
        addr_l2.l2_family = AF_BLUETOOTH;
        addr_l2.l2_psm = env->GetIntField(obj, field_mPort);
        memcpy(&addr_l2.l2_bdaddr, &bdaddr, sizeof(bdaddr_t));
        break;
    default:
        return ENOSYS;
    }

    if (bind(s->fd, addr, addr_sz)) {
        ALOGV("...bind(%d) gave errno %d", s->fd, errno);
        return errno;
    }

    if (listen(s->fd, 1)) {
        ALOGV("...listen(%d) gave errno %d", s->fd, errno);
        return errno;
    }

    ALOGV("...bindListenNative(%d) success", s->fd);

    return 0;

#endif
    return ENOSYS;
}