使用 jssc 获取 SerialPort 的设备描述符 [英] Get Device Descriptor of SerialPort using jssc
问题描述
如何使用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屋!