使用 jssc 获取 SerialPort 的设备描述符 [英] Get Device Descriptor of SerialPort using jssc

查看:164
本文介绍了使用 jssc 获取 SerialPort 的设备描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用jssc(java-simple-serial-connector)获取SerialPort的设备描述符?

How to get the Device Descriptor of a SerialPort using jssc ( java-simple-serial-connector)?

getPortName() 方法给出端口名称(例如 COM2),但描述符会更有帮助.

The getPortName() method gives port name (e.g. COM2), but descriptor would be more helpful.

如果有必要修补这个开源 API 以获得设备描述符怎么做?

推荐答案

在 zamanillo 的帮助下,我现在可以自己回答这个问题.jssc 2.8.0 无法做到这一点.

With the help from zamanillo his input I can now answer this myself. it is not possible to do it with jssc 2.8.0.

正在进行扩展 jssc 的行动,但我不知道发布时间表,也不知道要解决这个问题.扩展是方法<代码>SerialPortList->getPortProperties(String portName)在 jssc 2.8.0 的 linux 和 mac 修改版本中提供了实现.Windows 实现更难(很难找到).

There are actions underway to extend jssc but I don't know the release schedule nor drive to get this fixed. The extension is the method SerialPortList->getPortProperties(String portName) Implementations are available in modified versions of jssc 2.8.0 for linux and mac. Windows implementations are harder (to find).

这里是从 https://github.com/gohai/java-simple-serial-connector/blob/processing/src/cpp/_nix_based/jssc.cpp

JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties
  (JNIEnv *env, jclass cls, jstring portName) {
    const char* portNameChar = (const char*)env->GetStringUTFChars(portName, NULL);
    jclass stringClass = env->FindClass("Ljava/lang/String;");
    jobjectArray ret = env->NewObjectArray(5, stringClass, NULL);

#ifdef __APPLE__

    // this code is based on QtSerialPort
    CFMutableDictionaryRef matching = IOServiceMatching(kIOSerialBSDServiceValue);
    io_iterator_t iter = 0;
    kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iter);
    if (kr != kIOReturnSuccess) {
        env->ReleaseStringUTFChars(portName, portNameChar);
        return ret;
    }

    io_registry_entry_t service;
    while ((service = IOIteratorNext(iter))) {

        // compare portName against cu and tty devices
        bool found = false;

        CFTypeRef cu = 0;
        cu = IORegistryEntrySearchCFProperty(service, kIOServicePlane, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
        if (cu) {
            char buffer[MAXPATHLEN];
            CFStringGetCString(CFStringRef(cu), buffer, sizeof(buffer), kCFStringEncodingUTF8);
            //fprintf(stdout, "getPortProperties: %s\n", buffer);
            //fflush(stdout);
            if (strcmp(portNameChar, buffer) == 0) {
                found = true;
            }
            CFRelease(cu);
        }

        CFTypeRef tty = 0;
        tty = IORegistryEntrySearchCFProperty(service, kIOServicePlane, CFSTR(kIODialinDeviceKey), kCFAllocatorDefault, 0);
        if (tty) {
            char buffer[MAXPATHLEN];
            CFStringGetCString(CFStringRef(tty), buffer, sizeof(buffer), kCFStringEncodingUTF8);
            //fprintf(stdout, "getPortProperties: %s\n", buffer);
            //fflush(stdout);
            if (strcmp(portNameChar, buffer) == 0) {
                found = true;
            }
            CFRelease(tty);
        }

        if (!found) {
            // not port we're looking for
            //fprintf(stderr, "getPortProperties: %s not found", portNameChar);
            //fflush(stderr);
            IOObjectRelease(service);
            continue;
        }

        io_registry_entry_t entry = service;
        do {
            int val = 0;
            char buffer[255];

            CFTypeRef idProduct = 0;
            idProduct = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBProductID), kCFAllocatorDefault, 0);
            if (idProduct && !env->GetObjectArrayElement(ret, 0)) {
                CFNumberGetValue(CFNumberRef(idProduct), kCFNumberIntType, &val);
                sprintf(buffer, "%04x", val);
                jstring tmp = env->NewStringUTF(buffer);
                env->SetObjectArrayElement(ret, 0, tmp);
                env->DeleteLocalRef(tmp);
                CFRelease(idProduct);
            }

            CFTypeRef idVendor = 0;
            idVendor = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBVendorID), kCFAllocatorDefault, 0);
            if (idVendor && !env->GetObjectArrayElement(ret, 1)) {
                CFNumberGetValue(CFNumberRef(idVendor), kCFNumberIntType, &val);
                sprintf(buffer, "%04x", val);
                jstring tmp = env->NewStringUTF(buffer);
                env->SetObjectArrayElement(ret, 1, tmp);
                env->DeleteLocalRef(tmp);
                CFRelease(idVendor);
            }

            CFTypeRef manufacturer = 0;
            manufacturer = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBVendorString), kCFAllocatorDefault, 0);
            if (manufacturer && !env->GetObjectArrayElement(ret, 2)) {
                CFStringGetCString(CFStringRef(manufacturer), buffer, sizeof(buffer), kCFStringEncodingUTF8);
                jstring tmp = env->NewStringUTF(buffer);
                env->SetObjectArrayElement(ret, 2, tmp);
                env->DeleteLocalRef(tmp);
                CFRelease(manufacturer);
            }

            CFTypeRef product = 0;
            product = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBProductString), kCFAllocatorDefault, 0);
            if (product && !env->GetObjectArrayElement(ret, 3)) {
                CFStringGetCString(CFStringRef(product), buffer, sizeof(buffer), kCFStringEncodingUTF8);
                jstring tmp = env->NewStringUTF(buffer);
                env->SetObjectArrayElement(ret, 3, tmp);
                env->DeleteLocalRef(tmp);
                CFRelease(product);
            }

            CFTypeRef serial = 0;
            serial = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBSerialNumberString), kCFAllocatorDefault, 0);
            if (serial && !env->GetObjectArrayElement(ret, 4)) {
                CFStringGetCString(CFStringRef(serial), buffer, sizeof(buffer), kCFStringEncodingUTF8);
                jstring tmp = env->NewStringUTF(buffer);
                env->SetObjectArrayElement(ret, 4, tmp);
                env->DeleteLocalRef(tmp);
                CFRelease(serial);
            }

            kr = IORegistryEntryGetParentEntry(entry, kIOServicePlane, &entry);
        } while (kr == kIOReturnSuccess);

        IOObjectRelease(entry);

        IOObjectRelease(service);
    }

    IOObjectRelease(iter);

#endif  // __APPLE__

    env->ReleaseStringUTFChars(portName, portNameChar);
    return ret;
}

对于 Windows,我只找到了使用自定义 dll 进行处理的解决方案.

For windows I only found a solution in processing where a custom dll is used.

这篇关于使用 jssc 获取 SerialPort 的设备描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆