static int do_accept(JNIEnv* env, jobject object, int ag_fd,
                     jfieldID out_fd,
                     jfieldID out_address,
                     jfieldID out_channel) {

#if USE_ACCEPT_DIRECTLY==0
    if (set_nb(ag_fd, true) < 0)
        return -1;
#endif

    struct sockaddr_rc raddr;
    int alen = sizeof(raddr);
    int nsk = accept(ag_fd, (struct sockaddr *) &raddr, &alen);
    if (nsk < 0) {
        ALOGE("Error on accept from socket fd %d: %s (%d).",
             ag_fd,
             strerror(errno),
             errno);
#if USE_ACCEPT_DIRECTLY==0
        set_nb(ag_fd, false);
#endif
        return -1;
    }

    env->SetIntField(object, out_fd, nsk);
    env->SetIntField(object, out_channel, raddr.rc_channel);

    char addr[BTADDR_SIZE];
    get_bdaddr_as_string(&raddr.rc_bdaddr, addr);
    env->SetObjectField(object, out_address, env->NewStringUTF(addr));

    ALOGI("Successful accept() on AG socket %d: new socket %d, address %s, RFCOMM channel %d",
         ag_fd,
         nsk,
         addr,
         raddr.rc_channel);
#if USE_ACCEPT_DIRECTLY==0
    set_nb(ag_fd, false);
#endif
    return 0;
}
Exemple #2
0
static jobject acceptNative(JNIEnv *env, jobject obj, int timeout) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);

    int fd;
    jint type;
    struct sockaddr *addr;
    socklen_t addr_sz;
    jstring addr_jstr;
    char addr_cstr[BTADDR_SIZE];
    bdaddr_t *bdaddr;
    jboolean auth;
    jboolean encrypt;

    struct asocket *s = get_socketData(env, obj);

    if (!s)
        return NULL;

    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);
        bdaddr = &addr_rc.rc_bdaddr;
        memset(addr, 0, addr_sz);
        break;
    case TYPE_SCO:
        struct sockaddr_sco addr_sco;
        addr = (struct sockaddr *)&addr_sco;
        addr_sz = sizeof(addr_sco);
        bdaddr = &addr_sco.sco_bdaddr;
        memset(addr, 0, addr_sz);
        break;
    case TYPE_L2CAP:
    case TYPE_EL2CAP:
        struct sockaddr_l2 addr_l2;
        addr = (struct sockaddr *)&addr_l2;
        addr_sz = sizeof(addr_l2);
        bdaddr = &addr_l2.l2_bdaddr;
        memset(addr, 0, addr_sz);
        break;
    default:
        jniThrowIOException(env, ENOSYS);
        return NULL;
    }

    fd = asocket_accept(s, addr, &addr_sz, timeout);

    ALOGV("...accept(%d, %s) = %d (errno %d)",
            s->fd, TYPE_AS_STR(type), fd, errno);

    if (fd < 0) {
        jniThrowIOException(env, errno);
        return NULL;
    }

    /* Connected - return new BluetoothSocket */
    auth = env->GetBooleanField(obj, field_mAuth);
    encrypt = env->GetBooleanField(obj, field_mEncrypt);

    get_bdaddr_as_string(bdaddr, addr_cstr);

    addr_jstr = env->NewStringUTF(addr_cstr);
    return env->NewObject(class_BluetoothSocket, method_BluetoothSocket_ctor,
            type, fd, auth, encrypt, addr_jstr, -1);

#endif
    jniThrowIOException(env, ENOSYS);
    return NULL;
}