如何使用 jssc 获取 SerialPort 的设备描述符( java-simple-serial-connector)
?
该getPortName()
方法提供端口名称 ( e.g. COM2
),但描述符会更有帮助。
如果需要修补此开源 API 以获取设备描述符,该怎么做?
如何使用 jssc 获取 SerialPort 的设备描述符( java-simple-serial-connector)
?
该getPortName()
方法提供端口名称 ( e.g. COM2
),但描述符会更有帮助。
如果需要修补此开源 API 以获取设备描述符,该怎么做?
查看gohai/java-simple-serial-connector,SerialPortList类有一个getPortProperties(String portName)方法来获取端口属性,遗憾的是尚未在 windows 上实现,但很容易实现并重新编译以使其工作.
我希望这有帮助。
在 zamanillo 的帮助下,我现在可以自己回答这个问题。jssc 2.8.0 无法做到这一点。
正在采取一些措施来扩展 jssc,但我不知道发布时间表,也不知道如何解决这个问题。扩展是方法
SerialPortList->getPortProperties(String portName)
实现在 jssc 2.8.0 for linux 和 mac 的修改版本中可用。Windows 实现更难(找到)。
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 的处理中找到了解决方案。
设备描述符是描述符树的根,包含基本的设备信息。唯一编号 idVendor 和 idProduct 标识连接的设备。Windows 操作系统使用这些数字来确定要加载的设备驱动程序。
idVendor
是分配给每家生产基于 USB 的设备的公司的编号。USB 实施者论坛负责管理供应商 ID 的分配。
这idProduct
是另一个 16 位字段,包含制造商分配的用于标识特定产品的编号。
从jantje的问题来看,
我需要的是 Windows 10 在连接的设备中显示的名称?
答:打开"Settings app"
并点击设备。单击设备将打开一个选项卡,您可以在其中调整所有打印机、连接设备、蓝牙设备、鼠标和触摸板、打字设置和自动播放设置的设置。此连接的设备选项卡显示连接到您的 PC 的硬件。单击添加设备,您的 PC 将自动扫描连接的设备。蓝牙选项卡很简单,只需简单的设置即可通过蓝牙将设备连接到您的 PC。单击蓝牙按钮,设备将自动开始扫描范围内的任何蓝牙设备。
如果显示设备或赠品不可用有任何问题,那么我们需要以下工作。
无法从您的蓝牙设备连接到计算机?确保您已允许蓝牙设备连接到您的计算机。请尝试以下步骤: 1. 进入控制面板。单击“硬件和声音”和“蓝牙设备”。2. 单击选项选项卡。3. 确保选中“允许蓝牙设备连接到这台计算机”复选框。
连接蓝牙手机:
资源链接:
有 7 种方法可以解决网络连接问题:
您的答案如何链接到 jssc?
我正在检查你的问题。我知道在 Windows 7 中它工作正常,在 Windows 10 中,有一些与硬件相关的问题会导致问题。
开发人员正在研究这个领域。但它还没有修复。问题#63和问题#85将澄清你。
/**
* 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()]);
}
我明白了,他们正在为各种操作系统使用一些模式。
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("");
建议: 仅使用官方和最新的驱动程序。
jSSC-2.8.0 发布版 (24.01.2014)
修复:重要!修复了端口处理潜在泄漏的错误。
此版本包含适用于 Windows(x86, x86-64), Linux(x86, x86-64, ARM soft & hard float), Solaris(x86, x86-64), Mac OS X(x86, x86-64, PPC) 的原生库, PPC64)。所有本机库都包含在 jssc.jar 文件中,您不需要手动管理本机库。
资源链接: