|
@@ -149,14 +149,14 @@ char *_decode_udev_enc_dup(const char *s)
|
|
|
{
|
|
{
|
|
|
if (!s)
|
|
if (!s)
|
|
|
return NULL;
|
|
return NULL;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
char *o = malloc(strlen(s) + 1);
|
|
char *o = malloc(strlen(s) + 1);
|
|
|
if (!o)
|
|
if (!o)
|
|
|
{
|
|
{
|
|
|
applog(LOG_ERR, "Failed to malloc in _decode_udev_enc_dup");
|
|
applog(LOG_ERR, "Failed to malloc in _decode_udev_enc_dup");
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
_decode_udev_enc(o, s);
|
|
_decode_udev_enc(o, s);
|
|
|
return o;
|
|
return o;
|
|
|
}
|
|
}
|
|
@@ -182,11 +182,11 @@ void _vcom_devinfo_scan_udev(struct lowlevel_device_info ** const devinfo_list)
|
|
|
|
|
|
|
|
const char * const devpath = udev_device_get_devnode(device);
|
|
const char * const devpath = udev_device_get_devnode(device);
|
|
|
devinfo = _vcom_devinfo_findorcreate(devinfo_list, devpath);
|
|
devinfo = _vcom_devinfo_findorcreate(devinfo_list, devpath);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
BFGINIT(devinfo->manufacturer, _decode_udev_enc_dup(udev_device_get_property_value(device, "ID_VENDOR_ENC")));
|
|
BFGINIT(devinfo->manufacturer, _decode_udev_enc_dup(udev_device_get_property_value(device, "ID_VENDOR_ENC")));
|
|
|
BFGINIT(devinfo->product, _decode_udev_enc_dup(udev_device_get_property_value(device, "ID_MODEL_ENC")));
|
|
BFGINIT(devinfo->product, _decode_udev_enc_dup(udev_device_get_property_value(device, "ID_MODEL_ENC")));
|
|
|
BFGINIT(devinfo->serial, _decode_udev_enc_dup(udev_device_get_property_value(device, "ID_SERIAL_SHORT")));
|
|
BFGINIT(devinfo->serial, _decode_udev_enc_dup(udev_device_get_property_value(device, "ID_SERIAL_SHORT")));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
udev_device_unref(device);
|
|
udev_device_unref(device);
|
|
|
}
|
|
}
|
|
|
udev_enumerate_unref(enumerate);
|
|
udev_enumerate_unref(enumerate);
|
|
@@ -313,7 +313,7 @@ void _vcom_devinfo_scan_devserial(struct lowlevel_device_info ** const devinfo_l
|
|
|
char devpath[sizeof(udevdir) + 1 + NAME_MAX];
|
|
char devpath[sizeof(udevdir) + 1 + NAME_MAX];
|
|
|
char *devfile = devpath + sizeof(udevdir);
|
|
char *devfile = devpath + sizeof(udevdir);
|
|
|
struct lowlevel_device_info *devinfo;
|
|
struct lowlevel_device_info *devinfo;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
D = opendir(udevdir);
|
|
D = opendir(udevdir);
|
|
|
if (!D)
|
|
if (!D)
|
|
|
return;
|
|
return;
|
|
@@ -337,7 +337,7 @@ char *_sysfs_do_read(const char *devpath, char *devfile, const char *append)
|
|
|
{
|
|
{
|
|
|
char buf[0x40];
|
|
char buf[0x40];
|
|
|
FILE *F;
|
|
FILE *F;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
strcpy(devfile, append);
|
|
strcpy(devfile, append);
|
|
|
F = fopen(devpath, "r");
|
|
F = fopen(devpath, "r");
|
|
|
if (F)
|
|
if (F)
|
|
@@ -354,7 +354,7 @@ char *_sysfs_do_read(const char *devpath, char *devfile, const char *append)
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
buf[0] = '\0';
|
|
buf[0] = '\0';
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return buf[0] ? strdup(buf) : NULL;
|
|
return buf[0] ? strdup(buf) : NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -366,11 +366,11 @@ void _sysfs_find_tty(char *devpath, char *devfile, struct lowlevel_device_info *
|
|
|
struct dirent *de;
|
|
struct dirent *de;
|
|
|
char ttybuf[0x10] = "/dev/";
|
|
char ttybuf[0x10] = "/dev/";
|
|
|
char *mydevfile = strdup(devfile);
|
|
char *mydevfile = strdup(devfile);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
DT = opendir(devpath);
|
|
DT = opendir(devpath);
|
|
|
if (!DT)
|
|
if (!DT)
|
|
|
goto out;
|
|
goto out;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
while ( (de = readdir(DT)) )
|
|
while ( (de = readdir(DT)) )
|
|
|
{
|
|
{
|
|
|
if (strncmp(de->d_name, "tty", 3))
|
|
if (strncmp(de->d_name, "tty", 3))
|
|
@@ -384,7 +384,7 @@ void _sysfs_find_tty(char *devpath, char *devfile, struct lowlevel_device_info *
|
|
|
}
|
|
}
|
|
|
if (strncmp(&de->d_name[3], "USB", 3) && strncmp(&de->d_name[3], "ACM", 3))
|
|
if (strncmp(&de->d_name[3], "USB", 3) && strncmp(&de->d_name[3], "ACM", 3))
|
|
|
continue;
|
|
continue;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
strcpy(&ttybuf[5], de->d_name);
|
|
strcpy(&ttybuf[5], de->d_name);
|
|
|
devinfo = _vcom_devinfo_findorcreate(devinfo_list, ttybuf);
|
|
devinfo = _vcom_devinfo_findorcreate(devinfo_list, ttybuf);
|
|
|
if (!devinfo)
|
|
if (!devinfo)
|
|
@@ -394,7 +394,7 @@ void _sysfs_find_tty(char *devpath, char *devfile, struct lowlevel_device_info *
|
|
|
BFGINIT(devinfo->serial, _sysfs_do_read(devpath, devfile, "/serial"));
|
|
BFGINIT(devinfo->serial, _sysfs_do_read(devpath, devfile, "/serial"));
|
|
|
}
|
|
}
|
|
|
closedir(DT);
|
|
closedir(DT);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
out:
|
|
out:
|
|
|
free(mydevfile);
|
|
free(mydevfile);
|
|
|
}
|
|
}
|
|
@@ -409,7 +409,7 @@ void _vcom_devinfo_scan_sysfs(struct lowlevel_device_info ** const devinfo_list)
|
|
|
char devpath[sizeof(devroot) + (NAME_MAX * 3)];
|
|
char devpath[sizeof(devroot) + (NAME_MAX * 3)];
|
|
|
char *devfile, *upfile;
|
|
char *devfile, *upfile;
|
|
|
size_t len, len2;
|
|
size_t len, len2;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
D = opendir(devroot);
|
|
D = opendir(devroot);
|
|
|
if (!D)
|
|
if (!D)
|
|
|
return;
|
|
return;
|
|
@@ -421,22 +421,22 @@ void _vcom_devinfo_scan_sysfs(struct lowlevel_device_info ** const devinfo_list)
|
|
|
upfile = &devpath[devrootlen + 1];
|
|
upfile = &devpath[devrootlen + 1];
|
|
|
memcpy(upfile, de->d_name, len);
|
|
memcpy(upfile, de->d_name, len);
|
|
|
devfile = upfile + len;
|
|
devfile = upfile + len;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
devfile[0] = '\0';
|
|
devfile[0] = '\0';
|
|
|
DS = opendir(devpath);
|
|
DS = opendir(devpath);
|
|
|
if (!DS)
|
|
if (!DS)
|
|
|
continue;
|
|
continue;
|
|
|
devfile[0] = '/';
|
|
devfile[0] = '/';
|
|
|
++devfile;
|
|
++devfile;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
while ( (de = readdir(DS)) )
|
|
while ( (de = readdir(DS)) )
|
|
|
{
|
|
{
|
|
|
if (strncmp(de->d_name, upfile, len))
|
|
if (strncmp(de->d_name, upfile, len))
|
|
|
continue;
|
|
continue;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
len2 = strlen(de->d_name);
|
|
len2 = strlen(de->d_name);
|
|
|
memcpy(devfile, de->d_name, len2 + 1);
|
|
memcpy(devfile, de->d_name, len2 + 1);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
_sysfs_find_tty(devpath, devfile, devinfo_list);
|
|
_sysfs_find_tty(devpath, devfile, devinfo_list);
|
|
|
}
|
|
}
|
|
|
closedir(DS);
|
|
closedir(DS);
|
|
@@ -454,7 +454,7 @@ char *windows_usb_get_port_path(HANDLE hubh, const int portno)
|
|
|
{
|
|
{
|
|
|
size_t namesz;
|
|
size_t namesz;
|
|
|
ULONG rsz;
|
|
ULONG rsz;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
{
|
|
{
|
|
|
USB_NODE_CONNECTION_NAME pathinfo = {
|
|
USB_NODE_CONNECTION_NAME pathinfo = {
|
|
|
.ConnectionIndex = portno,
|
|
.ConnectionIndex = portno,
|
|
@@ -463,17 +463,17 @@ char *windows_usb_get_port_path(HANDLE hubh, const int portno)
|
|
|
applogfailinfor(NULL, LOG_ERR, "ioctl (1)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
applogfailinfor(NULL, LOG_ERR, "ioctl (1)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
namesz = pathinfo.ActualLength;
|
|
namesz = pathinfo.ActualLength;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const size_t bufsz = sizeof(USB_NODE_CONNECTION_NAME) + namesz;
|
|
const size_t bufsz = sizeof(USB_NODE_CONNECTION_NAME) + namesz;
|
|
|
uint8_t buf[bufsz];
|
|
uint8_t buf[bufsz];
|
|
|
USB_NODE_CONNECTION_NAME *path = (USB_NODE_CONNECTION_NAME *)buf;
|
|
USB_NODE_CONNECTION_NAME *path = (USB_NODE_CONNECTION_NAME *)buf;
|
|
|
*path = (USB_NODE_CONNECTION_NAME){
|
|
*path = (USB_NODE_CONNECTION_NAME){
|
|
|
.ConnectionIndex = portno,
|
|
.ConnectionIndex = portno,
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (!(DeviceIoControl(hubh, IOCTL_USB_GET_NODE_CONNECTION_NAME, path, bufsz, path, bufsz, &rsz, NULL) && rsz >= sizeof(*path)))
|
|
if (!(DeviceIoControl(hubh, IOCTL_USB_GET_NODE_CONNECTION_NAME, path, bufsz, path, bufsz, &rsz, NULL) && rsz >= sizeof(*path)))
|
|
|
applogfailinfor(NULL, LOG_ERR, "ioctl (2)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
applogfailinfor(NULL, LOG_ERR, "ioctl (2)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return ucs2_to_utf8_dup(path->NodeName, path->ActualLength);
|
|
return ucs2_to_utf8_dup(path->NodeName, path->ActualLength);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -482,11 +482,11 @@ char *windows_usb_get_string(HANDLE hubh, const int portno, const uint8_t descid
|
|
|
{
|
|
{
|
|
|
if (!descid)
|
|
if (!descid)
|
|
|
return NULL;
|
|
return NULL;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const size_t descsz_max = sizeof(USB_STRING_DESCRIPTOR) + MAXIMUM_USB_STRING_LENGTH;
|
|
const size_t descsz_max = sizeof(USB_STRING_DESCRIPTOR) + MAXIMUM_USB_STRING_LENGTH;
|
|
|
const size_t reqsz = sizeof(USB_DESCRIPTOR_REQUEST) + descsz_max;
|
|
const size_t reqsz = sizeof(USB_DESCRIPTOR_REQUEST) + descsz_max;
|
|
|
uint8_t buf[reqsz];
|
|
uint8_t buf[reqsz];
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
USB_DESCRIPTOR_REQUEST * const req = (USB_DESCRIPTOR_REQUEST *)buf;
|
|
USB_DESCRIPTOR_REQUEST * const req = (USB_DESCRIPTOR_REQUEST *)buf;
|
|
|
USB_STRING_DESCRIPTOR * const desc = (USB_STRING_DESCRIPTOR *)&req[1];
|
|
USB_STRING_DESCRIPTOR * const desc = (USB_STRING_DESCRIPTOR *)&req[1];
|
|
|
*req = (USB_DESCRIPTOR_REQUEST){
|
|
*req = (USB_DESCRIPTOR_REQUEST){
|
|
@@ -499,14 +499,14 @@ char *windows_usb_get_string(HANDLE hubh, const int portno, const uint8_t descid
|
|
|
};
|
|
};
|
|
|
// Need to explicitly zero the output memory
|
|
// Need to explicitly zero the output memory
|
|
|
memset(desc, '\0', descsz_max);
|
|
memset(desc, '\0', descsz_max);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
ULONG descsz;
|
|
ULONG descsz;
|
|
|
if (!DeviceIoControl(hubh, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, req, reqsz, req, reqsz, &descsz, NULL))
|
|
if (!DeviceIoControl(hubh, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, req, reqsz, req, reqsz, &descsz, NULL))
|
|
|
applogfailinfor(NULL, LOG_DEBUG, "ioctl", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
applogfailinfor(NULL, LOG_DEBUG, "ioctl", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (descsz < 2 || desc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE || desc->bLength > descsz - sizeof(USB_DESCRIPTOR_REQUEST) || desc->bLength % 2)
|
|
if (descsz < 2 || desc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE || desc->bLength > descsz - sizeof(USB_DESCRIPTOR_REQUEST) || desc->bLength % 2)
|
|
|
applogfailr(NULL, LOG_ERR, "sanity check");
|
|
applogfailr(NULL, LOG_ERR, "sanity check");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return ucs2_to_utf8_dup(desc->bString, desc->bLength);
|
|
return ucs2_to_utf8_dup(desc->bString, desc->bLength);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -519,16 +519,16 @@ void _vcom_devinfo_scan_windows__hubport(struct lowlevel_device_info ** const de
|
|
|
const size_t conninfosz = sizeof(USB_NODE_CONNECTION_INFORMATION) + (sizeof(USB_PIPE_INFO) * 30);
|
|
const size_t conninfosz = sizeof(USB_NODE_CONNECTION_INFORMATION) + (sizeof(USB_PIPE_INFO) * 30);
|
|
|
uint8_t buf[conninfosz];
|
|
uint8_t buf[conninfosz];
|
|
|
USB_NODE_CONNECTION_INFORMATION * const conninfo = (USB_NODE_CONNECTION_INFORMATION *)buf;
|
|
USB_NODE_CONNECTION_INFORMATION * const conninfo = (USB_NODE_CONNECTION_INFORMATION *)buf;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
conninfo->ConnectionIndex = portno;
|
|
conninfo->ConnectionIndex = portno;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
ULONG respsz;
|
|
ULONG respsz;
|
|
|
if (!DeviceIoControl(hubh, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, conninfo, conninfosz, conninfo, conninfosz, &respsz, NULL))
|
|
if (!DeviceIoControl(hubh, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, conninfo, conninfosz, conninfo, conninfosz, &respsz, NULL))
|
|
|
applogfailinfor(, LOG_ERR, "ioctl", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
applogfailinfor(, LOG_ERR, "ioctl", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (conninfo->ConnectionStatus != DeviceConnected)
|
|
if (conninfo->ConnectionStatus != DeviceConnected)
|
|
|
return;
|
|
return;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (conninfo->DeviceIsHub)
|
|
if (conninfo->DeviceIsHub)
|
|
|
{
|
|
{
|
|
|
const char * const hubpath = windows_usb_get_port_path(hubh, portno);
|
|
const char * const hubpath = windows_usb_get_port_path(hubh, portno);
|
|
@@ -536,7 +536,7 @@ void _vcom_devinfo_scan_windows__hubport(struct lowlevel_device_info ** const de
|
|
|
_vcom_devinfo_scan_windows__hub(devinfo_list, hubpath);
|
|
_vcom_devinfo_scan_windows__hub(devinfo_list, hubpath);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const USB_DEVICE_DESCRIPTOR * const devdesc = &conninfo->DeviceDescriptor;
|
|
const USB_DEVICE_DESCRIPTOR * const devdesc = &conninfo->DeviceDescriptor;
|
|
|
char * const serial = windows_usb_get_string(hubh, portno, devdesc->iSerialNumber);
|
|
char * const serial = windows_usb_get_string(hubh, portno, devdesc->iSerialNumber);
|
|
|
if (!serial)
|
|
if (!serial)
|
|
@@ -570,7 +570,7 @@ out:
|
|
|
applogfailinfor(, LOG_ERR, "get expected type for PortName registry key value", "%ld", (long)type);
|
|
applogfailinfor(, LOG_ERR, "get expected type for PortName registry key value", "%ld", (long)type);
|
|
|
goto out;
|
|
goto out;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
devinfo = _vcom_devinfo_findorcreate(devinfo_list, devpath);
|
|
devinfo = _vcom_devinfo_findorcreate(devinfo_list, devpath);
|
|
|
if (!devinfo)
|
|
if (!devinfo)
|
|
|
{
|
|
{
|
|
@@ -590,7 +590,7 @@ void _vcom_devinfo_scan_windows__hub(struct lowlevel_device_info ** const devinf
|
|
|
{
|
|
{
|
|
|
HANDLE hubh;
|
|
HANDLE hubh;
|
|
|
USB_NODE_INFORMATION nodeinfo;
|
|
USB_NODE_INFORMATION nodeinfo;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
{
|
|
{
|
|
|
char deviceName[4 + strlen(hubpath) + 1];
|
|
char deviceName[4 + strlen(hubpath) + 1];
|
|
|
sprintf(deviceName, "\\\\.\\%s", hubpath);
|
|
sprintf(deviceName, "\\\\.\\%s", hubpath);
|
|
@@ -598,15 +598,15 @@ void _vcom_devinfo_scan_windows__hub(struct lowlevel_device_info ** const devinf
|
|
|
if (hubh == INVALID_HANDLE_VALUE)
|
|
if (hubh == INVALID_HANDLE_VALUE)
|
|
|
applogr(, LOG_ERR, "Error opening USB hub device %s for autodetect: %s", deviceName, bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
applogr(, LOG_ERR, "Error opening USB hub device %s for autodetect: %s", deviceName, bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
ULONG nBytes;
|
|
ULONG nBytes;
|
|
|
if (!DeviceIoControl(hubh, IOCTL_USB_GET_NODE_INFORMATION, &nodeinfo, sizeof(nodeinfo), &nodeinfo, sizeof(nodeinfo), &nBytes, NULL))
|
|
if (!DeviceIoControl(hubh, IOCTL_USB_GET_NODE_INFORMATION, &nodeinfo, sizeof(nodeinfo), &nodeinfo, sizeof(nodeinfo), &nBytes, NULL))
|
|
|
applogfailinfor(, LOG_ERR, "ioctl", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
applogfailinfor(, LOG_ERR, "ioctl", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const int portcount = nodeinfo.u.HubInformation.HubDescriptor.bNumberOfPorts;
|
|
const int portcount = nodeinfo.u.HubInformation.HubDescriptor.bNumberOfPorts;
|
|
|
for (int i = 1; i <= portcount; ++i)
|
|
for (int i = 1; i <= portcount; ++i)
|
|
|
_vcom_devinfo_scan_windows__hubport(devinfo_list, hubh, i);
|
|
_vcom_devinfo_scan_windows__hubport(devinfo_list, hubh, i);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
CloseHandle(hubh);
|
|
CloseHandle(hubh);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -615,7 +615,7 @@ char *windows_usb_get_root_hub_path(HANDLE hcntlrh)
|
|
|
{
|
|
{
|
|
|
size_t namesz;
|
|
size_t namesz;
|
|
|
ULONG rsz;
|
|
ULONG rsz;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
{
|
|
{
|
|
|
USB_ROOT_HUB_NAME pathinfo;
|
|
USB_ROOT_HUB_NAME pathinfo;
|
|
|
if (!DeviceIoControl(hcntlrh, IOCTL_USB_GET_ROOT_HUB_NAME, 0, 0, &pathinfo, sizeof(pathinfo), &rsz, NULL))
|
|
if (!DeviceIoControl(hcntlrh, IOCTL_USB_GET_ROOT_HUB_NAME, 0, 0, &pathinfo, sizeof(pathinfo), &rsz, NULL))
|
|
@@ -624,14 +624,14 @@ char *windows_usb_get_root_hub_path(HANDLE hcntlrh)
|
|
|
applogfailinfor(NULL, LOG_ERR, "ioctl (1)", "Size too small (%d < %d)", (int)rsz, (int)sizeof(pathinfo));
|
|
applogfailinfor(NULL, LOG_ERR, "ioctl (1)", "Size too small (%d < %d)", (int)rsz, (int)sizeof(pathinfo));
|
|
|
namesz = pathinfo.ActualLength;
|
|
namesz = pathinfo.ActualLength;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const size_t bufsz = sizeof(USB_ROOT_HUB_NAME) + namesz;
|
|
const size_t bufsz = sizeof(USB_ROOT_HUB_NAME) + namesz;
|
|
|
uint8_t buf[bufsz];
|
|
uint8_t buf[bufsz];
|
|
|
USB_ROOT_HUB_NAME *hubpath = (USB_ROOT_HUB_NAME *)buf;
|
|
USB_ROOT_HUB_NAME *hubpath = (USB_ROOT_HUB_NAME *)buf;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (!(DeviceIoControl(hcntlrh, IOCTL_USB_GET_ROOT_HUB_NAME, NULL, 0, hubpath, bufsz, &rsz, NULL) && rsz >= sizeof(*hubpath)))
|
|
if (!(DeviceIoControl(hcntlrh, IOCTL_USB_GET_ROOT_HUB_NAME, NULL, 0, hubpath, bufsz, &rsz, NULL) && rsz >= sizeof(*hubpath)))
|
|
|
applogfailinfor(NULL, LOG_ERR, "ioctl (2)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
applogfailinfor(NULL, LOG_ERR, "ioctl (2)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return ucs2_to_utf8_dup(hubpath->RootHubName, hubpath->ActualLength);
|
|
return ucs2_to_utf8_dup(hubpath->RootHubName, hubpath->ActualLength);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -669,7 +669,7 @@ void _vcom_devinfo_scan_windows(struct lowlevel_device_info ** const devinfo_lis
|
|
|
SP_DEVINFO_DATA devinfodata = {
|
|
SP_DEVINFO_DATA devinfodata = {
|
|
|
.cbSize = sizeof(devinfodata),
|
|
.cbSize = sizeof(devinfodata),
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
for (int i = 0; SetupDiEnumDeviceInfo(devinfo, i, &devinfodata); ++i)
|
|
for (int i = 0; SetupDiEnumDeviceInfo(devinfo, i, &devinfodata); ++i)
|
|
|
_vcom_devinfo_scan_windows__hcntlr(devinfo_list, &devinfo, i);
|
|
_vcom_devinfo_scan_windows__hcntlr(devinfo_list, &devinfo, i);
|
|
|
SetupDiDestroyDeviceInfoList(devinfo);
|
|
SetupDiDestroyDeviceInfoList(devinfo);
|
|
@@ -716,7 +716,7 @@ void _vcom_devinfo_scan_ftdi(struct lowlevel_device_info ** const devinfo_list)
|
|
|
LOAD_SYM(FT_Open);
|
|
LOAD_SYM(FT_Open);
|
|
|
LOAD_SYM(FT_GetComPortNumber);
|
|
LOAD_SYM(FT_GetComPortNumber);
|
|
|
LOAD_SYM(FT_Close);
|
|
LOAD_SYM(FT_Close);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
ftStatus = FT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY);
|
|
ftStatus = FT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY);
|
|
|
if (ftStatus != FT_OK) {
|
|
if (ftStatus != FT_OK) {
|
|
|
applog(LOG_DEBUG, "FTDI device count failed, not using FTDI autodetect");
|
|
applog(LOG_DEBUG, "FTDI device count failed, not using FTDI autodetect");
|
|
@@ -735,11 +735,11 @@ void _vcom_devinfo_scan_ftdi(struct lowlevel_device_info ** const devinfo_list)
|
|
|
applog(LOG_DEBUG, "FTDI device list failed, not using FTDI autodetect");
|
|
applog(LOG_DEBUG, "FTDI device list failed, not using FTDI autodetect");
|
|
|
goto out;
|
|
goto out;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
for (i = numDevs; i > 0; ) {
|
|
for (i = numDevs; i > 0; ) {
|
|
|
--i;
|
|
--i;
|
|
|
bufptrs[i][64] = '\0';
|
|
bufptrs[i][64] = '\0';
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
FT_HANDLE ftHandle;
|
|
FT_HANDLE ftHandle;
|
|
|
if (FT_OK != FT_Open(i, &ftHandle))
|
|
if (FT_OK != FT_Open(i, &ftHandle))
|
|
|
continue;
|
|
continue;
|
|
@@ -748,10 +748,10 @@ void _vcom_devinfo_scan_ftdi(struct lowlevel_device_info ** const devinfo_list)
|
|
|
FT_Close(ftHandle);
|
|
FT_Close(ftHandle);
|
|
|
if (FT_OK != ftStatus || lComPortNumber < 0)
|
|
if (FT_OK != ftStatus || lComPortNumber < 0)
|
|
|
continue;
|
|
continue;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
applog(LOG_ERR, "FT_GetComPortNumber(%p (%ld), %ld)", ftHandle, (long)i, (long)lComPortNumber);
|
|
applog(LOG_ERR, "FT_GetComPortNumber(%p (%ld), %ld)", ftHandle, (long)i, (long)lComPortNumber);
|
|
|
sprintf(devpathnum, "%d", (int)lComPortNumber);
|
|
sprintf(devpathnum, "%d", (int)lComPortNumber);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
devinfo = _vcom_devinfo_findorcreate(devinfo_list, devpath);
|
|
devinfo = _vcom_devinfo_findorcreate(devinfo_list, devpath);
|
|
|
if (!devinfo)
|
|
if (!devinfo)
|
|
|
continue;
|
|
continue;
|
|
@@ -849,12 +849,12 @@ int _serial_autodetect(detectone_func_t detectone, ...)
|
|
|
va_list needles;
|
|
va_list needles;
|
|
|
char *needles_array[0x10];
|
|
char *needles_array[0x10];
|
|
|
int needlecount = 0;
|
|
int needlecount = 0;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
va_start(needles, detectone);
|
|
va_start(needles, detectone);
|
|
|
while ( (needles_array[needlecount++] = va_arg(needles, void *)) )
|
|
while ( (needles_array[needlecount++] = va_arg(needles, void *)) )
|
|
|
{}
|
|
{}
|
|
|
va_end(needles);
|
|
va_end(needles);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return _lowlevel_detect(_serial_autodetect_found_cb, NULL, (const char **)needles_array, detectone);
|
|
return _lowlevel_detect(_serial_autodetect_found_cb, NULL, (const char **)needles_array, detectone);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -864,7 +864,7 @@ struct lowlevel_device_info *vcom_devinfo_scan()
|
|
|
struct lowlevel_device_info *devinfo_hash = NULL;
|
|
struct lowlevel_device_info *devinfo_hash = NULL;
|
|
|
struct lowlevel_device_info *devinfo_list = NULL;
|
|
struct lowlevel_device_info *devinfo_list = NULL;
|
|
|
struct lowlevel_device_info *devinfo, *tmp;
|
|
struct lowlevel_device_info *devinfo, *tmp;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// All 3 USB Strings available:
|
|
// All 3 USB Strings available:
|
|
|
#ifndef WIN32
|
|
#ifndef WIN32
|
|
|
_vcom_devinfo_scan_sysfs(&devinfo_hash);
|
|
_vcom_devinfo_scan_sysfs(&devinfo_hash);
|
|
@@ -893,14 +893,14 @@ struct lowlevel_device_info *vcom_devinfo_scan()
|
|
|
_vcom_devinfo_scan_lsdev(&devinfo_hash);
|
|
_vcom_devinfo_scan_lsdev(&devinfo_hash);
|
|
|
#endif
|
|
#endif
|
|
|
_vcom_devinfo_scan_user(&devinfo_hash);
|
|
_vcom_devinfo_scan_user(&devinfo_hash);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Convert hash to simple list
|
|
// Convert hash to simple list
|
|
|
HASH_ITER(hh, devinfo_hash, devinfo, tmp)
|
|
HASH_ITER(hh, devinfo_hash, devinfo, tmp)
|
|
|
{
|
|
{
|
|
|
LL_PREPEND(devinfo_list, devinfo);
|
|
LL_PREPEND(devinfo_list, devinfo);
|
|
|
}
|
|
}
|
|
|
HASH_CLEAR(hh, devinfo_hash);
|
|
HASH_CLEAR(hh, devinfo_hash);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return devinfo_list;
|
|
return devinfo_list;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1066,7 +1066,7 @@ bool vcom_set_timeout_ms(const int fdDev, const unsigned timeout_ms)
|
|
|
return (SetCommTimeouts(hSerial, &cto) != 0);
|
|
return (SetCommTimeouts(hSerial, &cto) != 0);
|
|
|
#else
|
|
#else
|
|
|
struct termios my_termios;
|
|
struct termios my_termios;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
tcgetattr(fdDev, &my_termios);
|
|
tcgetattr(fdDev, &my_termios);
|
|
|
my_termios.c_cc[VTIME] = (cc_t)((timeout_ms + 99) / 100);
|
|
my_termios.c_cc[VTIME] = (cc_t)((timeout_ms + 99) / 100);
|
|
|
return (tcsetattr(fdDev, TCSANOW, &my_termios) == 0);
|
|
return (tcsetattr(fdDev, TCSANOW, &my_termios) == 0);
|
|
@@ -1135,7 +1135,7 @@ int serial_open(const char *devpath, unsigned long baud, uint8_t timeout, bool p
|
|
|
|
|
|
|
|
return _open_osfhandle((intptr_t)hSerial, 0);
|
|
return _open_osfhandle((intptr_t)hSerial, 0);
|
|
|
#else
|
|
#else
|
|
|
- int fdDev = open(devpath, O_RDWR | O_CLOEXEC | O_NOCTTY);
|
|
|
|
|
|
|
+ int fdDev = open(devpath, O_RDWR | O_CLOEXEC | O_NOCTTY | O_SYNC);
|
|
|
|
|
|
|
|
if (unlikely(fdDev == -1))
|
|
if (unlikely(fdDev == -1))
|
|
|
{
|
|
{
|
|
@@ -1146,7 +1146,7 @@ int serial_open(const char *devpath, unsigned long baud, uint8_t timeout, bool p
|
|
|
|
|
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
#if defined(LOCK_EX) && defined(LOCK_NB)
|
|
#if defined(LOCK_EX) && defined(LOCK_NB)
|
|
|
if (likely(!flock(fdDev, LOCK_EX | LOCK_NB)))
|
|
if (likely(!flock(fdDev, LOCK_EX | LOCK_NB)))
|
|
|
applog(LOG_DEBUG, "Acquired exclusive advisory lock on %s", devpath);
|
|
applog(LOG_DEBUG, "Acquired exclusive advisory lock on %s", devpath);
|
|
@@ -1181,10 +1181,11 @@ int serial_open(const char *devpath, unsigned long baud, uint8_t timeout, bool p
|
|
|
{
|
|
{
|
|
|
cfsetispeed(&my_termios, speed);
|
|
cfsetispeed(&my_termios, speed);
|
|
|
cfsetospeed(&my_termios, speed);
|
|
cfsetospeed(&my_termios, speed);
|
|
|
|
|
+ cfsetspeed(&my_termios, speed);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- my_termios.c_cflag &= ~(CSIZE | PARENB);
|
|
|
|
|
|
|
+ my_termios.c_cflag &= ~(CSIZE | PARENB | CSTOPB);
|
|
|
my_termios.c_cflag |= CS8;
|
|
my_termios.c_cflag |= CS8;
|
|
|
my_termios.c_cflag |= CREAD;
|
|
my_termios.c_cflag |= CREAD;
|
|
|
#ifdef USE_AVALON
|
|
#ifdef USE_AVALON
|
|
@@ -1224,6 +1225,60 @@ int serial_open(const char *devpath, unsigned long baud, uint8_t timeout, bool p
|
|
|
#endif
|
|
#endif
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+extern int serial_change_baud(int fd, unsigned long baud)
|
|
|
|
|
+{
|
|
|
|
|
+#ifdef WIN32
|
|
|
|
|
+ if (fd == -1)
|
|
|
|
|
+ return BGV_ERROR;
|
|
|
|
|
+ const HANDLE fh = (HANDLE)_get_osfhandle(fd);
|
|
|
|
|
+ if (fh == INVALID_HANDLE_VALUE)
|
|
|
|
|
+ return BGV_ERROR;
|
|
|
|
|
+
|
|
|
|
|
+ if (baud)
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ COMMCONFIG comCfg = {0};
|
|
|
|
|
+ comCfg.dwSize = sizeof(COMMCONFIG);
|
|
|
|
|
+ comCfg.wVersion = 1;
|
|
|
|
|
+ comCfg.dcb.DCBlength = sizeof(DCB);
|
|
|
|
|
+ comCfg.dcb.BaudRate = baud;
|
|
|
|
|
+ comCfg.dcb.fBinary = 1;
|
|
|
|
|
+ comCfg.dcb.fDtrControl = DTR_CONTROL_ENABLE;
|
|
|
|
|
+ comCfg.dcb.fRtsControl = RTS_CONTROL_ENABLE;
|
|
|
|
|
+ comCfg.dcb.ByteSize = 8;
|
|
|
|
|
+
|
|
|
|
|
+ if (!SetCommConfig(fh, &comCfg, sizeof(comCfg)))
|
|
|
|
|
+ // FIXME: We should probably be setting even if baud is clear (in which case, only LOG_DEBUG this)
|
|
|
|
|
+ applog(LOG_WARNING, "%s: %s failed: %s", devpath, "SetCommConfig", bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ #else
|
|
|
|
|
+
|
|
|
|
|
+ struct termios my_termios;
|
|
|
|
|
+
|
|
|
|
|
+ if (tcgetattr(fd, &my_termios))
|
|
|
|
|
+ applog(baud ? LOG_WARNING : LOG_DEBUG, "%s: %s failed: tcgetattr", bfg_strerror(errno, BST_ERRNO));
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ if (baud)
|
|
|
|
|
+ {
|
|
|
|
|
+ speed_t speed = tiospeed_t(baud);
|
|
|
|
|
+ if (speed == B0)
|
|
|
|
|
+ applog(LOG_WARNING, "Unrecognized baud rate: %lu", baud);
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ cfsetispeed(&my_termios, speed);
|
|
|
|
|
+ cfsetospeed(&my_termios, speed);
|
|
|
|
|
+ tcflush(fd, TCIOFLUSH);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ #endif
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
int serial_close(const int fd)
|
|
int serial_close(const int fd)
|
|
|
{
|
|
{
|
|
|
#if defined(LOCK_EX) && defined(LOCK_NB) && defined(LOCK_UN)
|
|
#if defined(LOCK_EX) && defined(LOCK_NB) && defined(LOCK_UN)
|
|
@@ -1270,7 +1325,7 @@ enum bfg_gpio_value _set_serial_cmflag(int fd, int flag, bool val)
|
|
|
return BGV_ERROR;
|
|
return BGV_ERROR;
|
|
|
|
|
|
|
|
ioctl(fd, TIOCMGET, &flags);
|
|
ioctl(fd, TIOCMGET, &flags);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (val)
|
|
if (val)
|
|
|
flags |= flag;
|
|
flags |= flag;
|
|
|
else
|
|
else
|
|
@@ -1313,20 +1368,20 @@ enum bfg_gpio_value _set_serial_cmflag(int fd, void (*setfunc)(DCB*, bool), bool
|
|
|
const HANDLE fh = (HANDLE)_get_osfhandle(fd);
|
|
const HANDLE fh = (HANDLE)_get_osfhandle(fd);
|
|
|
if (fh == INVALID_HANDLE_VALUE)
|
|
if (fh == INVALID_HANDLE_VALUE)
|
|
|
return BGV_ERROR;
|
|
return BGV_ERROR;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
DCB dcb;
|
|
DCB dcb;
|
|
|
if (!GetCommState(fh, &dcb))
|
|
if (!GetCommState(fh, &dcb))
|
|
|
applogr(BGV_ERROR, LOG_DEBUG, "Failed to %s"IN_FMT_FFL": %s",
|
|
applogr(BGV_ERROR, LOG_DEBUG, "Failed to %s"IN_FMT_FFL": %s",
|
|
|
"GetCommState", __FILE__, fname, __LINE__,
|
|
"GetCommState", __FILE__, fname, __LINE__,
|
|
|
bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
setfunc(&dcb, val);
|
|
setfunc(&dcb, val);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (!SetCommState(fh, &dcb))
|
|
if (!SetCommState(fh, &dcb))
|
|
|
applogr(BGV_ERROR, LOG_DEBUG, "Failed to %s"IN_FMT_FFL": %s",
|
|
applogr(BGV_ERROR, LOG_DEBUG, "Failed to %s"IN_FMT_FFL": %s",
|
|
|
"GetCommState", __FILE__, fname, __LINE__,
|
|
"GetCommState", __FILE__, fname, __LINE__,
|
|
|
bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
bfg_strerror(GetLastError(), BST_SYSTEM));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return val ? BGV_HIGH : BGV_LOW;
|
|
return val ? BGV_HIGH : BGV_LOW;
|
|
|
}
|
|
}
|
|
|
#define _set_serial_cmflag2(name, field, trueval, falseval) \
|
|
#define _set_serial_cmflag2(name, field, trueval, falseval) \
|