Get Device Descriptor of SerialPort using jssc

↘锁芯ラ 提交于 2021-02-17 22:20:30

问题


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

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

If it's necessary to patch this opensource API to get the Device Descriptor how can it be done?


回答1:


Look at gohai/java-simple-serial-connector, the SerialPortList class has a getPortProperties(String portName) method to get the port properties, unfortunately is not implemented yet for windows but is easy to do an implementation and recompile again to make it work.

I hope this helps.




回答2:


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.

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).

Here is the code for linux and mac taken from 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;
}

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




回答3:


The Device Descriptor is the root of the descriptor tree and contains basic device information. The unique numbers, idVendor and idProduct, identify the connected device. The Windows operating system uses these numbers to determine which device driver to load.

idVendor is the number assigned to each company producing USB-based devices. The USB Implementers’ Forum is responsible for administering the assignment of Vendor IDs.

The idProduct is another 16-bit field containing a number assigned by the manufacturer to identify a specific product.


From jantje's question,

What I need is what windows 10 shows as names in the connected devices?

Ans: Open the "Settings app" and click on Devices. Clicking on Devices will open a tab where you can adjust the settings for all your printers, connected devices, Bluetooth devices, mouse & touchpad, typing settings and autoplay settings. This connected devices tab shows the hardware connected to your PC. Click on Add a device and your PC will automatically scan for the connected devices. The Bluetooth tab is simple with simple settings for connecting a device to your PC via Bluetooth. Click on Bluetooth button and the device will automatically start scanning for any Bluetooth device in the range.

If there is any kind of problem for showing devices or gives not available, then we require following jobs.

  1. Scan the hardware and devices to find out the driver problems.
  2. Fix the corrupted, damaged, or incompatible Bluetooth driver.
  3. Update to the latest Bluetooth driver for Windows 10.
  4. Download and install the best-matched driver in Windows 10.

Top 2. Remove and Add the Bluetooth Devices

Top 3. Allow Bluetooth Devices to Connect to This Computer

Can’t connect to computer from your Bluetooth enabled device? Make sure you have allowed the Bluetooth devices to connect to your computer. Try the steps below: 1. Go to Control Panel. Click “Hardware and Sound” and “Bluetooth Devices”. 2. Click the Options tab. 3. Make sure the “Allow Bluetooth devices to connect to this computer” check box is selected.


How to Connect Bluetooth Devices to Your Windows 10 Computer?

To connect a Bluetooth enabled mobile phone:

  1. Go to the Start button and select “Settings”, “Devices” and “Bluetooth”. Click “Add”.
  2. Alternatively, go to Control Panel, click “Hardware and Sound” and “Bluetooth Devices”. Click “Add”.

Resource Link:

  1. Top 3 Ways to Fix Bluetooth Not Available after Windows 10 Update Issue
  2. http://windows.microsoft.com/en-gb/windows-10/getstarted-connect-to-bluetooth-devices

Fix network connection issues

There are 7 ways to fix network connected issues:

  1. Update the network adapter driver
  2. Roll back the network adapter driver
  3. Run the Network troubleshooter followed by networking commands
  4. Temporarily turn off firewalls
  5. Temporarily turn off any antivirus or malware-prevention software
  6. Uninstall the network adapter driver and restart
  7. Reinstall network devices using netcfg –d command

UPDATE:

How does your answer link to jssc?

I am checking for your issue. I got that in windows 7 it works fine and in windows 10, there are some hardware related issue which causes problem.

The developers are working on this area. But it is not fixed yet. The issue#63 and issue#85 will clarify you.

/**
 * Get serial port names in Windows
 *
 * @since 2.3.0
 */
private static String[] getWindowsPortNames(Pattern pattern, Comparator<String> comparator) {
    String[] portNames = serialInterface.getSerialPortNames();
    if(portNames == null){
        return new String[]{};
    }
    TreeSet<String> ports = new TreeSet<String>(comparator);
    for(String portName : portNames){
        if(pattern.matcher(portName).find()){
            ports.add(portName);
        }
    }
    return ports.toArray(new String[ports.size()]);
}

Here I got that, they are using some patterns for various OS.

OS_LINUX: Pattern.compile("(ttyS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO)[0-9]{1,3}"); 

OS_SOLARIS: Pattern.compile("[0-9]*|[a-z]*");

OS_MAC_OS_X: Pattern.compile("tty.(serial|usbserial|usbmodem).*"); 

OS_WINDOWS: Pattern.compile("");

Suggestions: use only official and latests drivers.

jSSC-2.8.0 Release version (24.01.2014)

Fixes: Important! Fixed bug with port handles potential leakage.

This version contains native libs for Windows(x86, x86-64), Linux(x86, x86-64, ARM soft & hard float), Solaris(x86, x86-64), Mac OS X(x86, x86-64, PPC, PPC64). All native libs contains in the jssc.jar file and you don't need manage native libs manually.

Resource Link:

  1. https://github.com/tcr/node-jssc/blob/master/jSSC-2.6.0-Release/src/src/jssc/SerialPortList.java


来源:https://stackoverflow.com/questions/33755211/get-device-descriptor-of-serialport-using-jssc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!