JNIEXPORT jlong JNICALL Java_com_intel_bluetooth_BluetoothStackBlueZ_l2RemoteAddress
  (JNIEnv* env, jobject peer, jlong handle) {
    struct sockaddr_l2 remoteAddr;
    socklen_t len = sizeof(remoteAddr);
    if (getpeername(handle, (struct sockaddr*)&remoteAddr, &len) < 0) {
        throwIOException(env, "Failed to get L2CAP (%i) peer name. [%d] %s", (int)handle, errno, strerror(errno));
        return -1;
    }
    return deviceAddrToLong(&remoteAddr.l2_bdaddr);
}
JNIEXPORT jlong JNICALL Java_com_intel_bluetooth_BluetoothStackBlueZDBus_getConnectionRfRemoteAddress
  (JNIEnv* env, jobject peer, jlong handle) {
    struct sockaddr_rc remoteAddr;
    memset(&remoteAddr, 0, sizeof(remoteAddr));
    socklen_t len = sizeof(remoteAddr);
    if (getpeername(handle, (struct sockaddr*)&remoteAddr, &len) < 0) {
        throwIOException(env, "Failed to get peer name. [%d] %s", errno, strerror(errno));
        return -1;
    }
    return deviceAddrToLong(&remoteAddr.rc_bdaddr);
}
JNIEXPORT jint JNICALL Java_com_intel_bluetooth_BluetoothStackBlueZ_runDeviceInquiryImpl
(JNIEnv *env, jobject peer, jobject inquiryRunnable, jobject startedNotify, jint deviceID, jint deviceDescriptor, jint accessCode, jint inquiryLength, jint maxResponses, jobject listener) {
    struct DeviceInquiryCallback callback;
    DeviceInquiryCallback_Init(&callback);
    if (!DeviceInquiryCallback_builDeviceInquiryCallbacks(env, &callback, inquiryRunnable, startedNotify)) {
        return INQUIRY_ERROR;
    }
    if (!DeviceInquiryCallback_callDeviceInquiryStartedCallback(env, &callback)) {
        return INQUIRY_ERROR;
    }
    int max_rsp = maxResponses;
    inquiry_info *ii = NULL;
    int num_rsp = hci_inquiry(deviceID, inquiryLength, max_rsp, NULL, &ii, accessCode);
    int rc = INQUIRY_COMPLETED;
    if (num_rsp < 0) {
        rc = INQUIRY_ERROR;
    } else {
        int i;
        for(i = 0; i < num_rsp; i++) {
            bdaddr_t* address = &(ii+i)->bdaddr;
            jlong addressLong = deviceAddrToLong(address);
            uint8_t *dev_class = (ii+i)->dev_class;
            int deviceClass = deviceClassBytesToInt(dev_class);

            jboolean paired = false; // TODO

            jstring name = NULL; // Names are stored in RemoteDeviceHelper and can be reused.

            if (!DeviceInquiryCallback_callDeviceDiscovered(env, &callback, listener, addressLong, deviceClass, name, paired)) {
                rc = INQUIRY_ERROR;
                break;
            }
        }
    }
    free(ii);
    return rc;
}