Reputation: 752
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?
Upvotes: 8
Views: 4159
Reputation: 116
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.
Upvotes: 1
Reputation: 10384
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.
Upvotes: 1
Reputation: 29150
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.
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.
To connect a Bluetooth enabled mobile phone:
Resource Link:
There are 7 ways to fix network connected issues:
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:
Upvotes: -1