root/tools/usb/usbip/libsrc/usbip_common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usbip_status_string
  2. usbip_speed_string
  3. usbip_op_common_status_string
  4. dump_usb_interface
  5. dump_usb_device
  6. read_attr_value
  7. read_attr_speed
  8. read_usb_device
  9. read_usb_interface
  10. usbip_names_init
  11. usbip_names_free
  12. usbip_names_get_product
  13. usbip_names_get_class

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2005-2007 Takahiro Hirofuchi
   4  */
   5 
   6 #include <libudev.h>
   7 #include "usbip_common.h"
   8 #include "names.h"
   9 
  10 #undef  PROGNAME
  11 #define PROGNAME "libusbip"
  12 
  13 int usbip_use_syslog;
  14 int usbip_use_stderr;
  15 int usbip_use_debug;
  16 
  17 extern struct udev *udev_context;
  18 
  19 struct speed_string {
  20         int num;
  21         char *speed;
  22         char *desc;
  23 };
  24 
  25 static const struct speed_string speed_strings[] = {
  26         { USB_SPEED_UNKNOWN, "unknown", "Unknown Speed"},
  27         { USB_SPEED_LOW,  "1.5", "Low Speed(1.5Mbps)"  },
  28         { USB_SPEED_FULL, "12",  "Full Speed(12Mbps)" },
  29         { USB_SPEED_HIGH, "480", "High Speed(480Mbps)" },
  30         { USB_SPEED_WIRELESS, "53.3-480", "Wireless"},
  31         { USB_SPEED_SUPER, "5000", "Super Speed(5000Mbps)" },
  32         { 0, NULL, NULL }
  33 };
  34 
  35 struct portst_string {
  36         int num;
  37         char *desc;
  38 };
  39 
  40 static struct portst_string portst_strings[] = {
  41         { SDEV_ST_AVAILABLE,    "Device Available" },
  42         { SDEV_ST_USED,         "Device in Use" },
  43         { SDEV_ST_ERROR,        "Device Error"},
  44         { VDEV_ST_NULL,         "Port Available"},
  45         { VDEV_ST_NOTASSIGNED,  "Port Initializing"},
  46         { VDEV_ST_USED,         "Port in Use"},
  47         { VDEV_ST_ERROR,        "Port Error"},
  48         { 0, NULL}
  49 };
  50 
  51 const char *usbip_status_string(int32_t status)
  52 {
  53         for (int i = 0; portst_strings[i].desc != NULL; i++)
  54                 if (portst_strings[i].num == status)
  55                         return portst_strings[i].desc;
  56 
  57         return "Unknown Status";
  58 }
  59 
  60 const char *usbip_speed_string(int num)
  61 {
  62         for (int i = 0; speed_strings[i].speed != NULL; i++)
  63                 if (speed_strings[i].num == num)
  64                         return speed_strings[i].desc;
  65 
  66         return "Unknown Speed";
  67 }
  68 
  69 struct op_common_status_string {
  70         int num;
  71         char *desc;
  72 };
  73 
  74 static struct op_common_status_string op_common_status_strings[] = {
  75         { ST_OK,        "Request Completed Successfully" },
  76         { ST_NA,        "Request Failed" },
  77         { ST_DEV_BUSY,  "Device busy (exported)" },
  78         { ST_DEV_ERR,   "Device in error state" },
  79         { ST_NODEV,     "Device not found" },
  80         { ST_ERROR,     "Unexpected response" },
  81         { 0, NULL}
  82 };
  83 
  84 const char *usbip_op_common_status_string(int status)
  85 {
  86         for (int i = 0; op_common_status_strings[i].desc != NULL; i++)
  87                 if (op_common_status_strings[i].num == status)
  88                         return op_common_status_strings[i].desc;
  89 
  90         return "Unknown Op Common Status";
  91 }
  92 
  93 #define DBG_UDEV_INTEGER(name)\
  94         dbg("%-20s = %x", to_string(name), (int) udev->name)
  95 
  96 #define DBG_UINF_INTEGER(name)\
  97         dbg("%-20s = %x", to_string(name), (int) uinf->name)
  98 
  99 void dump_usb_interface(struct usbip_usb_interface *uinf)
 100 {
 101         char buff[100];
 102 
 103         usbip_names_get_class(buff, sizeof(buff),
 104                         uinf->bInterfaceClass,
 105                         uinf->bInterfaceSubClass,
 106                         uinf->bInterfaceProtocol);
 107         dbg("%-20s = %s", "Interface(C/SC/P)", buff);
 108 }
 109 
 110 void dump_usb_device(struct usbip_usb_device *udev)
 111 {
 112         char buff[100];
 113 
 114         dbg("%-20s = %s", "path",  udev->path);
 115         dbg("%-20s = %s", "busid", udev->busid);
 116 
 117         usbip_names_get_class(buff, sizeof(buff),
 118                         udev->bDeviceClass,
 119                         udev->bDeviceSubClass,
 120                         udev->bDeviceProtocol);
 121         dbg("%-20s = %s", "Device(C/SC/P)", buff);
 122 
 123         DBG_UDEV_INTEGER(bcdDevice);
 124 
 125         usbip_names_get_product(buff, sizeof(buff),
 126                         udev->idVendor,
 127                         udev->idProduct);
 128         dbg("%-20s = %s", "Vendor/Product", buff);
 129 
 130         DBG_UDEV_INTEGER(bNumConfigurations);
 131         DBG_UDEV_INTEGER(bNumInterfaces);
 132 
 133         dbg("%-20s = %s", "speed",
 134                         usbip_speed_string(udev->speed));
 135 
 136         DBG_UDEV_INTEGER(busnum);
 137         DBG_UDEV_INTEGER(devnum);
 138 }
 139 
 140 
 141 int read_attr_value(struct udev_device *dev, const char *name,
 142                     const char *format)
 143 {
 144         const char *attr;
 145         int num = 0;
 146         int ret;
 147 
 148         attr = udev_device_get_sysattr_value(dev, name);
 149         if (!attr) {
 150                 err("udev_device_get_sysattr_value failed");
 151                 goto err;
 152         }
 153 
 154         /* The client chooses the device configuration
 155          * when attaching it so right after being bound
 156          * to usbip-host on the server the device will
 157          * have no configuration.
 158          * Therefore, attributes such as bConfigurationValue
 159          * and bNumInterfaces will not exist and sscanf will
 160          * fail. Check for these cases and don't treat them
 161          * as errors.
 162          */
 163 
 164         ret = sscanf(attr, format, &num);
 165         if (ret < 1) {
 166                 if (strcmp(name, "bConfigurationValue") &&
 167                                 strcmp(name, "bNumInterfaces")) {
 168                         err("sscanf failed for attribute %s", name);
 169                         goto err;
 170                 }
 171         }
 172 
 173 err:
 174 
 175         return num;
 176 }
 177 
 178 
 179 int read_attr_speed(struct udev_device *dev)
 180 {
 181         const char *speed;
 182 
 183         speed = udev_device_get_sysattr_value(dev, "speed");
 184         if (!speed) {
 185                 err("udev_device_get_sysattr_value failed");
 186                 goto err;
 187         }
 188 
 189         for (int i = 0; speed_strings[i].speed != NULL; i++) {
 190                 if (!strcmp(speed, speed_strings[i].speed))
 191                         return speed_strings[i].num;
 192         }
 193 
 194 err:
 195 
 196         return USB_SPEED_UNKNOWN;
 197 }
 198 
 199 #define READ_ATTR(object, type, dev, name, format)                            \
 200         do {                                                                  \
 201                 (object)->name = (type) read_attr_value(dev, to_string(name), \
 202                                                         format);              \
 203         } while (0)
 204 
 205 
 206 int read_usb_device(struct udev_device *sdev, struct usbip_usb_device *udev)
 207 {
 208         uint32_t busnum, devnum;
 209         const char *path, *name;
 210 
 211         READ_ATTR(udev, uint8_t,  sdev, bDeviceClass,           "%02x\n");
 212         READ_ATTR(udev, uint8_t,  sdev, bDeviceSubClass,        "%02x\n");
 213         READ_ATTR(udev, uint8_t,  sdev, bDeviceProtocol,        "%02x\n");
 214 
 215         READ_ATTR(udev, uint16_t, sdev, idVendor,               "%04x\n");
 216         READ_ATTR(udev, uint16_t, sdev, idProduct,              "%04x\n");
 217         READ_ATTR(udev, uint16_t, sdev, bcdDevice,              "%04x\n");
 218 
 219         READ_ATTR(udev, uint8_t,  sdev, bConfigurationValue,    "%02x\n");
 220         READ_ATTR(udev, uint8_t,  sdev, bNumConfigurations,     "%02x\n");
 221         READ_ATTR(udev, uint8_t,  sdev, bNumInterfaces,         "%02x\n");
 222 
 223         READ_ATTR(udev, uint8_t,  sdev, devnum,                 "%d\n");
 224         udev->speed = read_attr_speed(sdev);
 225 
 226         path = udev_device_get_syspath(sdev);
 227         name = udev_device_get_sysname(sdev);
 228 
 229         strncpy(udev->path,  path,  SYSFS_PATH_MAX - 1);
 230         udev->path[SYSFS_PATH_MAX - 1] = '\0';
 231         strncpy(udev->busid, name, SYSFS_BUS_ID_SIZE - 1);
 232         udev->busid[SYSFS_BUS_ID_SIZE - 1] = '\0';
 233 
 234         sscanf(name, "%u-%u", &busnum, &devnum);
 235         udev->busnum = busnum;
 236 
 237         return 0;
 238 }
 239 
 240 int read_usb_interface(struct usbip_usb_device *udev, int i,
 241                        struct usbip_usb_interface *uinf)
 242 {
 243         char busid[SYSFS_BUS_ID_SIZE];
 244         int size;
 245         struct udev_device *sif;
 246 
 247         size = snprintf(busid, sizeof(busid), "%s:%d.%d",
 248                         udev->busid, udev->bConfigurationValue, i);
 249         if (size < 0 || (unsigned int)size >= sizeof(busid)) {
 250                 err("busid length %i >= %lu or < 0", size,
 251                     (long unsigned)sizeof(busid));
 252                 return -1;
 253         }
 254 
 255         sif = udev_device_new_from_subsystem_sysname(udev_context, "usb", busid);
 256         if (!sif) {
 257                 err("udev_device_new_from_subsystem_sysname %s failed", busid);
 258                 return -1;
 259         }
 260 
 261         READ_ATTR(uinf, uint8_t,  sif, bInterfaceClass,         "%02x\n");
 262         READ_ATTR(uinf, uint8_t,  sif, bInterfaceSubClass,      "%02x\n");
 263         READ_ATTR(uinf, uint8_t,  sif, bInterfaceProtocol,      "%02x\n");
 264 
 265         return 0;
 266 }
 267 
 268 int usbip_names_init(char *f)
 269 {
 270         return names_init(f);
 271 }
 272 
 273 void usbip_names_free(void)
 274 {
 275         names_free();
 276 }
 277 
 278 void usbip_names_get_product(char *buff, size_t size, uint16_t vendor,
 279                              uint16_t product)
 280 {
 281         const char *prod, *vend;
 282 
 283         prod = names_product(vendor, product);
 284         if (!prod)
 285                 prod = "unknown product";
 286 
 287 
 288         vend = names_vendor(vendor);
 289         if (!vend)
 290                 vend = "unknown vendor";
 291 
 292         snprintf(buff, size, "%s : %s (%04x:%04x)", vend, prod, vendor, product);
 293 }
 294 
 295 void usbip_names_get_class(char *buff, size_t size, uint8_t class,
 296                            uint8_t subclass, uint8_t protocol)
 297 {
 298         const char *c, *s, *p;
 299 
 300         if (class == 0 && subclass == 0 && protocol == 0) {
 301                 snprintf(buff, size, "(Defined at Interface level) (%02x/%02x/%02x)", class, subclass, protocol);
 302                 return;
 303         }
 304 
 305         p = names_protocol(class, subclass, protocol);
 306         if (!p)
 307                 p = "unknown protocol";
 308 
 309         s = names_subclass(class, subclass);
 310         if (!s)
 311                 s = "unknown subclass";
 312 
 313         c = names_class(class);
 314         if (!c)
 315                 c = "unknown class";
 316 
 317         snprintf(buff, size, "%s / %s / %s (%02x/%02x/%02x)", c, s, p, class, subclass, protocol);
 318 }

/* [<][>][^][v][top][bottom][index][help] */