├── CMakeLists.txt ├── driver-libusb ├── stub.h ├── stub_common.c ├── stub_common.h ├── stub_event.c ├── stub_main.c ├── stub_rx.c ├── stub_tx.c └── usbip_host_driver.c ├── include ├── list.h ├── usbip.h ├── usbip_config.h ├── usbip_debug.h ├── usbip_host_driver.h └── usbip_network.h └── src ├── names.c ├── names.h ├── usbip_debug.c ├── usbip_network.c ├── usbipd.c ├── usbipd_requests.c └── usbipd_requests.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | project(usbip_libusb C) 3 | 4 | set(CMAKE_C_STANDARD 11) 5 | 6 | find_path(LIBUSB_INCLUDE_DIR NAMES libusb.h PATH_SUFFIXES "include" "libusb" "libusb-1.0") 7 | find_library(LIBUSB_LIBRARY NAMES usb-1.0 PATH_SUFFIXES "lib" "lib32" "lib64") 8 | if(NOT LIBUSB_INCLUDE_DIR OR NOT LIBUSB_LIBRARY) 9 | error("libusb not found") 10 | endif() 11 | 12 | include_directories(include libsrc) 13 | 14 | add_definitions(-DDEBUG) 15 | 16 | add_executable(${PROJECT_NAME} 17 | include/usbip.h 18 | include/list.h 19 | src/names.c 20 | src/names.h 21 | src/usbip_network.c 22 | include/usbip_network.h 23 | src/usbipd_requests.c 24 | src/usbipd.c 25 | src/usbipd_requests.h 26 | driver-libusb/stub.h 27 | driver-libusb/stub_common.c 28 | driver-libusb/stub_common.h 29 | driver-libusb/usbip_host_driver.c 30 | driver-libusb/stub_event.c 31 | driver-libusb/stub_main.c 32 | driver-libusb/stub_rx.c 33 | driver-libusb/stub_tx.c include/usbip_host_driver.h include/usbip_debug.h src/usbip_debug.c) 34 | target_include_directories(${PROJECT_NAME} PRIVATE ${LIBUSB_INCLUDE_DIR}) 35 | target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBUSB_LIBRARY} pthread) -------------------------------------------------------------------------------- /driver-libusb/stub.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | /* 3 | * Copyright (C) 2003-2008 Takahiro Hirofuchi 4 | */ 5 | 6 | #ifndef __USBIP_STUB_H 7 | #define __USBIP_STUB_H 8 | 9 | #include "usbip_config.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #ifndef USBIP_OS_NO_PTHREAD_H 15 | #include 16 | #endif 17 | #include 18 | #include "usbip_host_driver.h" 19 | #include "stub_common.h" 20 | #include "list.h" 21 | 22 | struct stub_interface { 23 | struct usbip_usb_interface uinf; 24 | uint8_t detached; 25 | uint8_t claimed; 26 | }; 27 | 28 | struct stub_endpoint { 29 | uint8_t nr; 30 | uint8_t dir; /* LIBUSB_ENDPOINT_IN || LIBUSB_ENDPOINT_OUT */ 31 | uint8_t type; /* LIBUSB_TRANSFER_TYPE_ */ 32 | }; 33 | 34 | struct stub_device { 35 | libusb_device *dev; 36 | libusb_device_handle *dev_handle; 37 | struct usbip_usb_device udev; 38 | struct usbip_device ud; 39 | uint32_t devid; 40 | int num_eps; 41 | struct stub_endpoint *eps; 42 | 43 | pthread_t tx, rx; 44 | 45 | /* 46 | * stub_priv preserves private data of each urb. 47 | * It is allocated as stub_priv_cache and assigned to urb->context. 48 | * 49 | * stub_priv is always linked to any one of 3 lists; 50 | * priv_init: linked to this until the comletion of a urb. 51 | * priv_tx : linked to this after the completion of a urb. 52 | * priv_free: linked to this after the sending of the result. 53 | * 54 | * Any of these list operations should be locked by priv_lock. 55 | */ 56 | pthread_mutex_t priv_lock; 57 | struct list_head priv_init; 58 | struct list_head priv_tx; 59 | struct list_head priv_free; 60 | 61 | /* see comments for unlinking in stub_rx.c */ 62 | struct list_head unlink_tx; 63 | struct list_head unlink_free; 64 | 65 | pthread_mutex_t tx_waitq; 66 | int should_stop; 67 | 68 | struct stub_interface ifs[]; 69 | }; 70 | 71 | /* private data into urb->priv */ 72 | struct stub_priv { 73 | unsigned long seqnum; 74 | struct list_head list; 75 | struct stub_device *sdev; 76 | struct libusb_transfer *trx; 77 | 78 | uint8_t dir; 79 | uint8_t unlinking; 80 | }; 81 | 82 | struct stub_unlink { 83 | unsigned long seqnum; 84 | struct list_head list; 85 | enum libusb_transfer_status status; 86 | }; 87 | 88 | struct stub_edev_data { 89 | libusb_device *dev; 90 | struct stub_device *sdev; 91 | int num_eps; 92 | struct stub_endpoint eps[]; 93 | }; 94 | 95 | /* stub_rx.c */ 96 | void *stub_rx_loop(void *data); 97 | 98 | /* stub_tx.c */ 99 | void stub_enqueue_ret_unlink(struct stub_device *sdev, uint32_t seqnum, 100 | enum libusb_transfer_status status); 101 | void LIBUSB_CALL stub_complete(struct libusb_transfer *trx); 102 | void *stub_tx_loop(void *data); 103 | 104 | /* for libusb */ 105 | extern libusb_context *stub_libusb_ctx; 106 | uint8_t stub_get_transfer_type(struct stub_device *sdev, uint8_t ep); 107 | uint8_t stub_endpoint_dir(struct stub_device *sdev, uint8_t ep); 108 | int stub_endpoint_dir_out(struct stub_device *sdev, uint8_t ep); 109 | uint8_t stub_get_transfer_flags(uint32_t in); 110 | 111 | /* from stub_main.c */ 112 | void stub_device_cleanup_transfers(struct stub_device *sdev); 113 | void stub_device_cleanup_unlinks(struct stub_device *sdev); 114 | 115 | #endif /* __USBIP_STUB_H */ 116 | -------------------------------------------------------------------------------- /driver-libusb/stub_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi 3 | * Copyright (C) 2015-2016 Nobuo Iwata 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "stub.h" 25 | 26 | #include 27 | 28 | static const char *s_trx_type_cont = "cont"; 29 | static const char *s_trx_type_isoc = "isoc"; 30 | static const char *s_trx_type_bulk = "bulk"; 31 | static const char *s_trx_type_intr = "intr"; 32 | static const char *s_trx_type_blks = "blks"; 33 | static const char *s_trx_type_unknown = "????"; 34 | 35 | static const char *get_trx_type_str(uint8_t type) 36 | { 37 | switch (type) { 38 | case LIBUSB_TRANSFER_TYPE_CONTROL: 39 | return s_trx_type_cont; 40 | case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 41 | return s_trx_type_isoc; 42 | case LIBUSB_TRANSFER_TYPE_BULK: 43 | return s_trx_type_bulk; 44 | case LIBUSB_TRANSFER_TYPE_INTERRUPT: 45 | return s_trx_type_intr; 46 | case LIBUSB_TRANSFER_TYPE_BULK_STREAM: 47 | return s_trx_type_blks; 48 | } 49 | return s_trx_type_unknown; 50 | } 51 | 52 | static void get_endpoint_descs(struct libusb_config_descriptor *config, 53 | const struct libusb_endpoint_descriptor *in[], 54 | const struct libusb_endpoint_descriptor *out[], int max) 55 | { 56 | int i, j, k; 57 | const struct libusb_interface *intf; 58 | const struct libusb_interface_descriptor *desc; 59 | const struct libusb_endpoint_descriptor *ep; 60 | uint8_t dir; 61 | int num_in = 0; 62 | int num_out = 0; 63 | 64 | for (k = 0; k < max; k++) { 65 | in[k] = NULL; 66 | out[k] = NULL; 67 | } 68 | for (i = 0; i < config->bNumInterfaces; i++) { 69 | intf = config->interface + i; 70 | for (j = 0; j < intf->num_altsetting; j++) { 71 | desc = intf->altsetting + j; 72 | for (k = 0; k < desc->bNumEndpoints; k++) { 73 | ep = desc->endpoint + k; 74 | dir = ep->bEndpointAddress & 0x80; 75 | if (dir == LIBUSB_ENDPOINT_IN 76 | && num_in < max) { 77 | in[num_in++] = ep; 78 | } else if (dir == LIBUSB_ENDPOINT_OUT 79 | && num_out < max) { 80 | out[num_out++] = ep; 81 | } 82 | } 83 | } 84 | } 85 | } 86 | 87 | static void usbip_dump_ep_max(const struct libusb_endpoint_descriptor *ep[], 88 | char *buf) 89 | { 90 | int i; 91 | 92 | for (i = 0; i < 16; i++) { 93 | sprintf(buf+(3*i), " %2u", (ep[i]) ? 94 | libusb_le16_to_cpu(ep[i]->wMaxPacketSize) : 0); 95 | } 96 | } 97 | 98 | static void usbip_dump_usb_device(struct libusb_device *dev) 99 | { 100 | struct libusb_device_descriptor desc; 101 | struct libusb_config_descriptor *config; 102 | int config_acquired = 0; 103 | const struct libusb_endpoint_descriptor *in[16], *out[16]; 104 | char buf[3*16+1]; 105 | 106 | if (libusb_get_device_descriptor(dev, &desc)) 107 | dev_err(dev, "fail to get desc"); 108 | 109 | if (libusb_get_active_config_descriptor(dev, &config) == 0) 110 | config_acquired = 1; 111 | 112 | dev_dbg(dev, "addr(%d)", 113 | libusb_get_device_address(dev)); 114 | /* TODO: device number, device path */ 115 | /* TODO: Transaction Translator info, tt */ 116 | 117 | /* TODO: Toggle */ 118 | 119 | if (config_acquired) { 120 | get_endpoint_descs(config, in, out, 16); 121 | usbip_dump_ep_max(in, buf); 122 | dev_dbg(dev, "epmaxp_in :%s", buf); 123 | usbip_dump_ep_max(out, buf); 124 | dev_dbg(dev, "epmaxp_out :%s", buf); 125 | } 126 | 127 | /* TODO: bus pointer */ 128 | dev_dbg(dev, "parent %p", 129 | libusb_get_parent(dev)); 130 | 131 | /* TODO: all configs pointer, raw descs */ 132 | dev_dbg(dev, "vendor:0x%x product:0x%x actconfig:%p", 133 | desc.idVendor, desc.idProduct, config); 134 | 135 | /* TODO: have_lang, have_langid */ 136 | 137 | /* TODO: maxchild */ 138 | 139 | if (config_acquired) 140 | libusb_free_config_descriptor(config); 141 | } 142 | 143 | static const char *s_recipient_device = "DEVC"; 144 | static const char *s_recipient_interface = "INTF"; 145 | static const char *s_recipient_endpoint = "ENDP"; 146 | static const char *s_recipient_other = "OTHR"; 147 | static const char *s_recipient_unknown = "????"; 148 | 149 | static const char *get_request_recipient_str(uint8_t rt) 150 | { 151 | uint8_t recip = get_recipient(rt); 152 | 153 | switch (recip) { 154 | case LIBUSB_RECIPIENT_DEVICE: 155 | return s_recipient_device; 156 | case LIBUSB_RECIPIENT_INTERFACE: 157 | return s_recipient_interface; 158 | case LIBUSB_RECIPIENT_ENDPOINT: 159 | return s_recipient_endpoint; 160 | case LIBUSB_RECIPIENT_OTHER: 161 | return s_recipient_other; 162 | } 163 | return s_recipient_unknown; 164 | } 165 | 166 | static const char *s_request_get_status = "GET_STATUS"; 167 | static const char *s_request_clear_feature = "CLEAR_FEAT"; 168 | static const char *s_request_set_feature = "SET_FEAT "; 169 | static const char *s_request_set_address = "SET_ADDRRS"; 170 | static const char *s_request_get_descriptor = "GET_DESCRI"; 171 | static const char *s_request_set_descriptor = "SET_DESCRI"; 172 | static const char *s_request_get_config = "GET_CONFIG"; 173 | static const char *s_request_set_config = "SET_CONFIG"; 174 | static const char *s_request_get_interface = "GET_INTERF"; 175 | static const char *s_request_set_interface = "SET_INTERF"; 176 | static const char *s_request_sync_frame = "SYNC_FRAME"; 177 | static const char *s_request_unknown = "???? "; 178 | 179 | static const char *get_request_str(uint8_t req) 180 | { 181 | switch (req) { 182 | case LIBUSB_REQUEST_GET_STATUS: 183 | return s_request_get_status; 184 | case LIBUSB_REQUEST_CLEAR_FEATURE: 185 | return s_request_clear_feature; 186 | case LIBUSB_REQUEST_SET_FEATURE: 187 | return s_request_set_feature; 188 | case LIBUSB_REQUEST_SET_ADDRESS: 189 | return s_request_set_address; 190 | case LIBUSB_REQUEST_GET_DESCRIPTOR: 191 | return s_request_get_descriptor; 192 | case LIBUSB_REQUEST_SET_DESCRIPTOR: 193 | return s_request_set_descriptor; 194 | case LIBUSB_REQUEST_GET_CONFIGURATION: 195 | return s_request_get_config; 196 | case LIBUSB_REQUEST_SET_CONFIGURATION: 197 | return s_request_set_config; 198 | case LIBUSB_REQUEST_GET_INTERFACE: 199 | return s_request_get_interface; 200 | case LIBUSB_REQUEST_SET_INTERFACE: 201 | return s_request_set_interface; 202 | case LIBUSB_REQUEST_SYNCH_FRAME: 203 | return s_request_sync_frame; 204 | } 205 | return s_request_unknown; 206 | } 207 | 208 | static void usbip_dump_usb_ctrlrequest(struct libusb_device *dev, 209 | struct libusb_transfer *trx) 210 | { 211 | struct libusb_control_setup *cmd = 212 | libusb_control_transfer_get_setup(trx); 213 | 214 | if (!cmd) { 215 | dev_dbg(dev, "null control"); 216 | return; 217 | } 218 | 219 | dev_dbg(dev, "bRequestType(%02X) bRequest(%02X) ", 220 | cmd->bmRequestType, cmd->bRequest); 221 | dev_dbg(dev, "wValue(%04X) wIndex(%04X) wLength(%04X)", 222 | cmd->wValue, cmd->wIndex, cmd->wLength); 223 | 224 | switch (cmd->bmRequestType & USB_TYPE_MASK) { 225 | case LIBUSB_REQUEST_TYPE_STANDARD: 226 | dev_dbg(dev, "STANDARD %s %s", 227 | get_request_str(cmd->bRequest), 228 | get_request_recipient_str(cmd->bmRequestType)); 229 | break; 230 | case LIBUSB_REQUEST_TYPE_CLASS: 231 | dev_dbg(dev, "CLASS"); 232 | break; 233 | case LIBUSB_REQUEST_TYPE_VENDOR: 234 | dev_dbg(dev, "VENDOR"); 235 | break; 236 | case LIBUSB_REQUEST_TYPE_RESERVED: 237 | dev_dbg(dev, "RESERVED"); 238 | break; 239 | } 240 | } 241 | 242 | void usbip_dump_trx(struct libusb_transfer *trx) 243 | { 244 | struct libusb_device *dev; 245 | 246 | if (!trx) { 247 | dbg("trx: null pointer!!"); 248 | return; 249 | } 250 | 251 | if (!trx->dev_handle) { 252 | dbg("trx->dev_handle: null pointer!!"); 253 | return; 254 | } 255 | 256 | dev = libusb_get_device(trx->dev_handle); 257 | 258 | dev_dbg(dev, " trx :%p", trx); 259 | dev_dbg(dev, " dev_handle :%p", trx->dev_handle); 260 | dev_dbg(dev, " trx_type :%s", get_trx_type_str(trx->type)); 261 | dev_dbg(dev, " endpoint :%08x", trx->endpoint); 262 | dev_dbg(dev, " status :%d", trx->status); 263 | dev_dbg(dev, " trx_flags :%08X", trx->flags); 264 | dev_dbg(dev, " buffer :%p", trx->buffer); 265 | dev_dbg(dev, " buffer_length:%d", trx->length); 266 | dev_dbg(dev, " actual_length:%d", trx->actual_length); 267 | dev_dbg(dev, " num_packets :%d", trx->num_iso_packets); 268 | dev_dbg(dev, " context :%p", trx->user_data); 269 | dev_dbg(dev, " complete :%p", trx->callback); 270 | 271 | if (trx->type == LIBUSB_TRANSFER_TYPE_CONTROL) 272 | usbip_dump_usb_ctrlrequest(dev, trx); 273 | 274 | usbip_dump_usb_device(dev); 275 | } 276 | 277 | void usbip_dump_header(struct usbip_header *pdu) 278 | { 279 | dbg("BASE: cmd %u seq %u devid %u dir %u ep %u", 280 | pdu->base.command, 281 | pdu->base.seqnum, 282 | pdu->base.devid, 283 | pdu->base.direction, 284 | pdu->base.ep); 285 | 286 | switch (pdu->base.command) { 287 | case USBIP_CMD_SUBMIT: 288 | dbg("USBIP_CMD_SUBMIT: xflg %x xln %u sf %x #p %d iv %d", 289 | pdu->u.cmd_submit.transfer_flags, 290 | pdu->u.cmd_submit.transfer_buffer_length, 291 | pdu->u.cmd_submit.start_frame, 292 | pdu->u.cmd_submit.number_of_packets, 293 | pdu->u.cmd_submit.interval); 294 | break; 295 | case USBIP_CMD_UNLINK: 296 | dbg("USBIP_CMD_UNLINK: seq %u", 297 | pdu->u.cmd_unlink.seqnum); 298 | break; 299 | case USBIP_RET_SUBMIT: 300 | dbg("USBIP_RET_SUBMIT: st %d al %u sf %x #p %d ec %d", 301 | pdu->u.ret_submit.status, 302 | pdu->u.ret_submit.actual_length, 303 | pdu->u.ret_submit.start_frame, 304 | pdu->u.ret_submit.number_of_packets, 305 | pdu->u.ret_submit.error_count); 306 | break; 307 | case USBIP_RET_UNLINK: 308 | dbg("USBIP_RET_UNLINK: status %d", 309 | pdu->u.ret_unlink.status); 310 | break; 311 | case USBIP_NOP: 312 | dbg("USBIP_NOP"); 313 | break; 314 | default: 315 | /* NOT REACHED */ 316 | err("unknown command"); 317 | break; 318 | } 319 | } 320 | 321 | /* Send data over TCP/IP. */ 322 | int usbip_sendmsg(struct usbip_device *ud, struct iovec *vec, size_t num) { 323 | if (usbip_dbg_flag_xmit) { 324 | size_t i; 325 | for (i = 0; i < num; i++) { 326 | dbg("sending, idx %zd size %zd", i, vec[i].iov_len); 327 | usbip_dump_buffer(vec[i].iov_base, vec[i].iov_len); 328 | } 329 | } 330 | return writev(ud->sock_fd, vec, num); 331 | } 332 | 333 | /* Receive data over TCP/IP. */ 334 | int usbip_recv(struct usbip_device *ud, void *buf, int size) { 335 | int result; 336 | int total = 0; 337 | 338 | /* for blocks of if (usbip_dbg_flag_xmit) */ 339 | char *bp = (char *)buf; 340 | int osize = size; 341 | 342 | if (!ud->sock_fd || !buf || !size) { 343 | err("invalid arg, sock %d buff %p size %d", 344 | ud->sock_fd, buf, size); 345 | errno = EINVAL; 346 | return -1; 347 | } 348 | 349 | do { 350 | usbip_dbg_xmit("receiving %d", size); 351 | result = recv(ud->sock_fd, bp, size, 0); 352 | 353 | if (result < 0) { 354 | if (errno == EAGAIN || errno == EINTR) { 355 | result = 0; // Try more 356 | } else { 357 | err("receive error %d (errno %d)", result, errno); 358 | goto out; 359 | } 360 | } else if (result == 0) { 361 | info("connection closed, releasing the device..."); 362 | goto out; 363 | } 364 | 365 | size -= result; 366 | bp += result; 367 | total += result; 368 | } while (size > 0); 369 | 370 | if (usbip_dbg_flag_xmit) { 371 | dbg("received, osize %d ret %d size %d total %d", 372 | osize, result, size, total); 373 | usbip_dump_buffer((char *)buf, osize); 374 | } 375 | 376 | return total; 377 | 378 | out: 379 | return result; 380 | } 381 | 382 | static int trxstat2error(enum libusb_transfer_status trxstat) 383 | { 384 | switch (trxstat) { 385 | case LIBUSB_TRANSFER_COMPLETED: 386 | return 0; 387 | case LIBUSB_TRANSFER_CANCELLED: 388 | return -ECONNRESET; 389 | case LIBUSB_TRANSFER_ERROR: 390 | case LIBUSB_TRANSFER_STALL: 391 | case LIBUSB_TRANSFER_TIMED_OUT: 392 | case LIBUSB_TRANSFER_OVERFLOW: 393 | return -EPIPE; 394 | case LIBUSB_TRANSFER_NO_DEVICE: 395 | return -ESHUTDOWN; 396 | } 397 | return -ENOENT; 398 | } 399 | 400 | static enum libusb_transfer_status error2trxstat(int e) 401 | { 402 | switch (e) { 403 | case 0: 404 | return LIBUSB_TRANSFER_COMPLETED; 405 | case -ENOENT: 406 | return LIBUSB_TRANSFER_ERROR; 407 | case -ECONNRESET: 408 | return LIBUSB_TRANSFER_CANCELLED; 409 | case -ETIMEDOUT: 410 | return LIBUSB_TRANSFER_TIMED_OUT; 411 | case -EPIPE: 412 | return LIBUSB_TRANSFER_STALL; 413 | case -ESHUTDOWN: 414 | return LIBUSB_TRANSFER_NO_DEVICE; 415 | case -EOVERFLOW: 416 | return LIBUSB_TRANSFER_OVERFLOW; 417 | } 418 | return LIBUSB_TRANSFER_ERROR; 419 | } 420 | 421 | void usbip_pack_ret_submit(struct usbip_header *pdu, 422 | struct libusb_transfer *trx) 423 | { 424 | struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit; 425 | 426 | rpdu->status = trxstat2error(trx->status); 427 | rpdu->actual_length = trx->actual_length; 428 | rpdu->start_frame = 0; 429 | rpdu->number_of_packets = trx->num_iso_packets; 430 | rpdu->error_count = 0; 431 | } 432 | 433 | void usbip_pack_ret_unlink(struct usbip_header *pdu, 434 | struct stub_unlink *unlink) 435 | { 436 | struct usbip_header_ret_unlink *rpdu = &pdu->u.ret_unlink; 437 | 438 | rpdu->status = trxstat2error(unlink->status); 439 | } 440 | 441 | static void correct_endian_basic(struct usbip_header_basic *base, int send) 442 | { 443 | if (send) { 444 | base->command = htonl(base->command); 445 | base->seqnum = htonl(base->seqnum); 446 | base->devid = htonl(base->devid); 447 | base->direction = htonl(base->direction); 448 | base->ep = htonl(base->ep); 449 | } else { 450 | base->command = ntohl(base->command); 451 | base->seqnum = ntohl(base->seqnum); 452 | base->devid = ntohl(base->devid); 453 | base->direction = ntohl(base->direction); 454 | base->ep = ntohl(base->ep); 455 | } 456 | } 457 | 458 | static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu, 459 | int send) 460 | { 461 | if (send) { 462 | pdu->transfer_flags = htonl(pdu->transfer_flags); 463 | 464 | pdu->transfer_buffer_length = 465 | (int32_t)htonl(pdu->transfer_buffer_length); 466 | pdu->start_frame = (int32_t)htonl(pdu->start_frame); 467 | pdu->number_of_packets = (int32_t)htonl(pdu->number_of_packets); 468 | pdu->interval = (int32_t)htonl(pdu->interval); 469 | } else { 470 | pdu->transfer_flags = ntohl(pdu->transfer_flags); 471 | 472 | pdu->transfer_buffer_length = 473 | (int32_t)ntohl(pdu->transfer_buffer_length); 474 | pdu->start_frame = (int32_t)ntohl(pdu->start_frame); 475 | pdu->number_of_packets = (int32_t)ntohl(pdu->number_of_packets); 476 | pdu->interval = (int32_t)ntohl(pdu->interval); 477 | } 478 | } 479 | 480 | static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, 481 | int send) 482 | { 483 | if (send) { 484 | pdu->status = (int32_t)htonl(pdu->status); 485 | pdu->actual_length = (int32_t)htonl(pdu->actual_length); 486 | pdu->start_frame = (int32_t)htonl(pdu->start_frame); 487 | pdu->number_of_packets = (int32_t)htonl(pdu->number_of_packets); 488 | pdu->error_count = (int32_t)htonl(pdu->error_count); 489 | } else { 490 | pdu->status = (int32_t)ntohl(pdu->status); 491 | pdu->actual_length = (int32_t)ntohl(pdu->actual_length); 492 | pdu->start_frame = (int32_t)ntohl(pdu->start_frame); 493 | pdu->number_of_packets = (int32_t)ntohl(pdu->number_of_packets); 494 | pdu->error_count = (int32_t)ntohl(pdu->error_count); 495 | } 496 | } 497 | 498 | static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu, 499 | int send) 500 | { 501 | if (send) 502 | pdu->seqnum = htonl(pdu->seqnum); 503 | else 504 | pdu->seqnum = ntohl(pdu->seqnum); 505 | } 506 | 507 | static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu, 508 | int send) 509 | { 510 | if (send) 511 | pdu->status = (int32_t)htonl(pdu->status); 512 | else 513 | pdu->status = ntohl(pdu->status); 514 | } 515 | 516 | void usbip_header_correct_endian(struct usbip_header *pdu, int send) 517 | { 518 | uint32_t cmd = 0; 519 | 520 | if (send) 521 | cmd = pdu->base.command; 522 | 523 | correct_endian_basic(&pdu->base, send); 524 | 525 | if (!send) 526 | cmd = pdu->base.command; 527 | 528 | switch (cmd) { 529 | case USBIP_CMD_SUBMIT: 530 | correct_endian_cmd_submit(&pdu->u.cmd_submit, send); 531 | break; 532 | case USBIP_RET_SUBMIT: 533 | correct_endian_ret_submit(&pdu->u.ret_submit, send); 534 | break; 535 | case USBIP_CMD_UNLINK: 536 | correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send); 537 | break; 538 | case USBIP_RET_UNLINK: 539 | correct_endian_ret_unlink(&pdu->u.ret_unlink, send); 540 | break; 541 | case USBIP_NOP: 542 | break; 543 | default: 544 | /* NOT REACHED */ 545 | err("unknown command"); 546 | break; 547 | } 548 | } 549 | 550 | static void usbip_iso_packet_correct_endian( 551 | struct usbip_iso_packet_descriptor *iso, int send) 552 | { 553 | /* does not need all members. but copy all simply. */ 554 | if (send) { 555 | iso->offset = htonl(iso->offset); 556 | iso->length = htonl(iso->length); 557 | iso->status = htonl(iso->status); 558 | iso->actual_length = htonl(iso->actual_length); 559 | } else { 560 | iso->offset = ntohl(iso->offset); 561 | iso->length = ntohl(iso->length); 562 | iso->status = ntohl(iso->status); 563 | iso->actual_length = ntohl(iso->actual_length); 564 | } 565 | } 566 | 567 | static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso, 568 | struct libusb_iso_packet_descriptor *uiso, 569 | int offset, int pack) 570 | { 571 | if (pack) { 572 | iso->offset = offset; 573 | iso->length = uiso->length; 574 | iso->status = trxstat2error(uiso->status); 575 | iso->actual_length = uiso->actual_length; 576 | } else { 577 | /* ignore iso->offset; */ 578 | uiso->length = iso->length; 579 | uiso->status = error2trxstat(iso->status); 580 | uiso->actual_length = iso->actual_length; 581 | } 582 | } 583 | 584 | /* must free buffer */ 585 | struct usbip_iso_packet_descriptor* 586 | usbip_alloc_iso_desc_pdu(struct libusb_transfer *trx, ssize_t *bufflen) 587 | { 588 | struct usbip_iso_packet_descriptor *iso; 589 | int np = trx->num_iso_packets; 590 | ssize_t size = np * sizeof(*iso); 591 | int i, offset = 0; 592 | 593 | iso = (struct usbip_iso_packet_descriptor *)malloc(size); 594 | if (!iso) 595 | return NULL; 596 | 597 | for (i = 0; i < np; i++) { 598 | usbip_pack_iso(&iso[i], &trx->iso_packet_desc[i], offset, 1); 599 | usbip_iso_packet_correct_endian(&iso[i], 1); 600 | offset += trx->iso_packet_desc[i].length; 601 | } 602 | 603 | *bufflen = size; 604 | 605 | return iso; 606 | } 607 | 608 | /* some members of urb must be substituted before. */ 609 | int usbip_recv_iso(struct usbip_device *ud, struct libusb_transfer *trx) 610 | { 611 | void *buff; 612 | struct usbip_iso_packet_descriptor *iso; 613 | int np = trx->num_iso_packets; 614 | int size = np * sizeof(*iso); 615 | int i; 616 | int ret; 617 | int total_length = 0; 618 | 619 | /* my Bluetooth dongle gets ISO URBs which are np = 0 */ 620 | if (np == 0) 621 | return 0; 622 | 623 | buff = malloc(size); 624 | if (!buff) { 625 | errno = ENOMEM; 626 | return -1; 627 | } 628 | 629 | ret = usbip_recv(ud, buff, size); 630 | if (ret != size) { 631 | dev_err(libusb_get_device(trx->dev_handle), 632 | "recv iso_frame_descriptor, %d", ret); 633 | free(buff); 634 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 635 | errno = EPIPE; 636 | return -1; 637 | } 638 | 639 | iso = (struct usbip_iso_packet_descriptor *) buff; 640 | for (i = 0; i < np; i++) { 641 | usbip_iso_packet_correct_endian(&iso[i], 0); 642 | usbip_pack_iso(&iso[i], &trx->iso_packet_desc[i], 0, 0); 643 | total_length += trx->iso_packet_desc[i].actual_length; 644 | } 645 | 646 | free(buff); 647 | 648 | if (total_length != trx->actual_length) { 649 | dev_err(libusb_get_device(trx->dev_handle), "total length of iso packets %d not equal to actual ", total_length); 650 | dev_err(libusb_get_device(trx->dev_handle), "length of buffer %d", trx->actual_length); 651 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 652 | errno = EPIPE; 653 | return -1; 654 | } 655 | 656 | return ret; 657 | } 658 | 659 | /* some members of urb must be substituted before. */ 660 | int usbip_recv_xbuff(struct usbip_device *ud, struct libusb_transfer *trx, 661 | int offset) 662 | { 663 | int ret; 664 | int size; 665 | 666 | size = trx->length - offset; 667 | 668 | /* no need to recv xbuff */ 669 | if (!(size > 0)) 670 | return 0; 671 | 672 | /* 673 | * Take offset for CONTROL setup 674 | */ 675 | ret = usbip_recv(ud, trx->buffer + offset, size); 676 | if (ret != size) { 677 | dev_err(libusb_get_device(trx->dev_handle), "recv xbuf, %d", ret); 678 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 679 | } 680 | 681 | return ret; 682 | } 683 | -------------------------------------------------------------------------------- /driver-libusb/stub_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi 3 | * Copyright (C) 2015-2016 Nobuo Iwata 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef __STUB_COMMON_H 20 | #define __STUB_COMMON_H 21 | 22 | #include "usbip_config.h" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | /* alternate of kthread_should_stop */ 30 | #define stub_should_stop(sdev) ((sdev)->should_stop) 31 | 32 | /* 33 | * See also from include/uapi/linux/usb/ch9.h 34 | */ 35 | #define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ 36 | 37 | #define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ 38 | #define USB_ENDPOINT_DIR_MASK 0x80 39 | 40 | #define USB_DIR_OUT 0 /* to device */ 41 | #define USB_DIR_IN 0x80 /* to host */ 42 | 43 | #ifndef USB_TYPE_MASK 44 | #define USB_TYPE_MASK 0x60 45 | #endif 46 | 47 | #define USB_RECIP_MASK 0x1f 48 | 49 | #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ 50 | #define URB_ISO_ASAP 0x0002 /* iso-only; use the first unexpired */ 51 | /* slot in the schedule */ 52 | #define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */ 53 | #define URB_NO_FSBR 0x0020 /* UHCI-specific */ 54 | #define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */ 55 | #define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt */ 56 | /* needed */ 57 | #define URB_FREE_BUFFER 0x0100 58 | 59 | #define USB_CLASS_HUB 9 60 | 61 | static inline uint8_t get_request_dir(uint8_t rt) 62 | { 63 | return (rt & USB_ENDPOINT_DIR_MASK); 64 | } 65 | 66 | static inline uint8_t get_request_type(uint8_t rt) 67 | { 68 | return (rt & USB_TYPE_MASK); 69 | } 70 | 71 | static inline uint8_t get_recipient(uint8_t rt) 72 | { 73 | return (rt & USB_RECIP_MASK); 74 | } 75 | 76 | #define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ 77 | #define USB_ENDPOINT_XFER_CONTROL 0 78 | #define USB_ENDPOINT_XFER_ISOC 1 79 | #define USB_ENDPOINT_XFER_BULK 2 80 | #define USB_ENDPOINT_XFER_INT 3 81 | #define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 82 | 83 | /* 84 | * See also from include/uapi/linux/usb/ch11.h 85 | */ 86 | 87 | #define USB_RT_HUB \ 88 | (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE) 89 | #define USB_RT_PORT \ 90 | (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER) 91 | 92 | /* 93 | * Port feature numbers 94 | * See USB 2.0 spec Table 11-17 95 | */ 96 | #define USB_PORT_FEAT_CONNECTION 0 97 | #define USB_PORT_FEAT_ENABLE 1 98 | #define USB_PORT_FEAT_SUSPEND 2 /* L2 suspend */ 99 | #define USB_PORT_FEAT_OVER_CURRENT 3 100 | #define USB_PORT_FEAT_RESET 4 101 | #define USB_PORT_FEAT_L1 5 /* L1 suspend */ 102 | #define USB_PORT_FEAT_POWER 8 103 | #define USB_PORT_FEAT_LOWSPEED 9 /* Should never be used */ 104 | #define USB_PORT_FEAT_C_CONNECTION 16 105 | #define USB_PORT_FEAT_C_ENABLE 17 106 | #define USB_PORT_FEAT_C_SUSPEND 18 107 | #define USB_PORT_FEAT_C_OVER_CURRENT 19 108 | #define USB_PORT_FEAT_C_RESET 20 109 | #define USB_PORT_FEAT_TEST 21 110 | #define USB_PORT_FEAT_INDICATOR 22 111 | #define USB_PORT_FEAT_C_PORT_L1 23 112 | 113 | 114 | /* 115 | * USB/IP request headers 116 | * 117 | * Each request is transferred across the network to its counterpart, which 118 | * facilitates the normal USB communication. The values contained in the headers 119 | * are basically the same as in a URB. Currently, four request types are 120 | * defined: 121 | * 122 | * - USBIP_CMD_SUBMIT: a USB request block, corresponds to usb_submit_urb() 123 | * (client to server) 124 | * 125 | * - USBIP_RET_SUBMIT: the result of USBIP_CMD_SUBMIT 126 | * (server to client) 127 | * 128 | * - USBIP_CMD_UNLINK: an unlink request of a pending USBIP_CMD_SUBMIT, 129 | * corresponds to usb_unlink_urb() 130 | * (client to server) 131 | * 132 | * - USBIP_RET_UNLINK: the result of USBIP_CMD_UNLINK 133 | * (server to client) 134 | * 135 | */ 136 | #define USBIP_NOP 0x0000 137 | #define USBIP_CMD_SUBMIT 0x0001 138 | #define USBIP_CMD_UNLINK 0x0002 139 | #define USBIP_RET_SUBMIT 0x0003 140 | #define USBIP_RET_UNLINK 0x0004 141 | 142 | #define USBIP_DIR_OUT 0x00 143 | #define USBIP_DIR_IN 0x01 144 | 145 | /** 146 | * struct usbip_header_basic - data pertinent to every request 147 | * @command: the usbip request type 148 | * @seqnum: sequential number that identifies requests; incremented per 149 | * connection 150 | * @devid: specifies a remote USB device uniquely instead of busnum and devnum; 151 | * in the stub driver, this value is ((busnum << 16) | devnum) 152 | * @direction: direction of the transfer 153 | * @ep: endpoint number 154 | */ 155 | struct usbip_header_basic { 156 | uint32_t command; 157 | uint32_t seqnum; 158 | uint32_t devid; 159 | uint32_t direction; 160 | uint32_t ep; 161 | } __attribute__((packed)); 162 | 163 | /** 164 | * struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header 165 | * @transfer_flags: URB flags 166 | * @transfer_buffer_length: the data size for (in) or (out) transfer 167 | * @start_frame: initial frame for isochronous or interrupt transfers 168 | * @number_of_packets: number of isochronous packets 169 | * @interval: maximum time for the request on the server-side host controller 170 | * @setup: setup data for a control request 171 | */ 172 | struct usbip_header_cmd_submit { 173 | uint32_t transfer_flags; 174 | int32_t transfer_buffer_length; 175 | 176 | /* it is difficult for usbip to sync frames (reserved only?) */ 177 | int32_t start_frame; 178 | int32_t number_of_packets; 179 | int32_t interval; 180 | 181 | unsigned char setup[8]; 182 | } __attribute__((packed)); 183 | 184 | /** 185 | * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header 186 | * @status: return status of a non-iso request 187 | * @actual_length: number of bytes transferred 188 | * @start_frame: initial frame for isochronous or interrupt transfers 189 | * @number_of_packets: number of isochronous packets 190 | * @error_count: number of errors for isochronous transfers 191 | */ 192 | struct usbip_header_ret_submit { 193 | int32_t status; 194 | int32_t actual_length; 195 | int32_t start_frame; 196 | int32_t number_of_packets; 197 | int32_t error_count; 198 | } __attribute__((packed)); 199 | 200 | /** 201 | * struct usbip_header_cmd_unlink - USBIP_CMD_UNLINK packet header 202 | * @seqnum: the URB seqnum to unlink 203 | */ 204 | struct usbip_header_cmd_unlink { 205 | uint32_t seqnum; 206 | } __attribute__((packed)); 207 | 208 | /** 209 | * struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header 210 | * @status: return status of the request 211 | */ 212 | struct usbip_header_ret_unlink { 213 | uint32_t status; 214 | } __attribute__((packed)); 215 | 216 | /** 217 | * struct usbip_header - common header for all usbip packets 218 | * @base: the basic header 219 | * @u: packet type dependent header 220 | */ 221 | struct usbip_header { 222 | struct usbip_header_basic base; 223 | 224 | union { 225 | struct usbip_header_cmd_submit cmd_submit; 226 | struct usbip_header_ret_submit ret_submit; 227 | struct usbip_header_cmd_unlink cmd_unlink; 228 | struct usbip_header_ret_unlink ret_unlink; 229 | } u; 230 | } __attribute__((packed)); 231 | 232 | /* 233 | * This is the same as usb_iso_packet_descriptor but packed for pdu. 234 | */ 235 | struct usbip_iso_packet_descriptor { 236 | uint32_t offset; 237 | uint32_t length; /* expected length */ 238 | uint32_t actual_length; 239 | uint32_t status; 240 | } __attribute__((packed)); 241 | 242 | /* event handler */ 243 | #define USBIP_EH_SHUTDOWN (1 << 0) 244 | #define USBIP_EH_BYE (1 << 1) 245 | #define USBIP_EH_RESET (1 << 2) 246 | #define USBIP_EH_UNUSABLE (1 << 3) 247 | 248 | #define SDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE) 249 | #define SDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) 250 | #define SDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) 251 | #define SDEV_EVENT_ERROR_SUBMIT (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) 252 | #define SDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) 253 | 254 | /* a common structure for stub_device and vhci_device */ 255 | struct usbip_device { 256 | enum usbip_device_status status; 257 | 258 | /* lock for status */ 259 | pthread_mutex_t lock; 260 | 261 | int sock_fd; 262 | 263 | unsigned long event; 264 | pthread_t eh; 265 | pthread_mutex_t eh_waitq; 266 | int eh_should_stop; 267 | 268 | struct eh_ops { 269 | void (*shutdown)(struct usbip_device *); 270 | void (*reset)(struct usbip_device *); 271 | void (*unusable)(struct usbip_device *); 272 | } eh_ops; 273 | }; 274 | 275 | /* usbip_common.c */ 276 | void usbip_dump_trx(struct libusb_transfer *trx); 277 | void usbip_dump_header(struct usbip_header *pdu); 278 | 279 | int usbip_sendmsg(struct usbip_device *ud, struct iovec *vec, size_t num); 280 | int usbip_recv(struct usbip_device *ud, void *buf, int size); 281 | 282 | struct stub_unlink; 283 | 284 | void usbip_pack_ret_submit(struct usbip_header *pdu, 285 | struct libusb_transfer *trx); 286 | void usbip_pack_ret_unlink(struct usbip_header *pdu, 287 | struct stub_unlink *unlink); 288 | void usbip_header_correct_endian(struct usbip_header *pdu, int send); 289 | 290 | struct usbip_iso_packet_descriptor* 291 | usbip_alloc_iso_desc_pdu(struct libusb_transfer *trx, ssize_t *bufflen); 292 | 293 | /* some members of urb must be substituted before. */ 294 | int usbip_recv_iso(struct usbip_device *ud, struct libusb_transfer *trx); 295 | void usbip_pad_iso(struct usbip_device *ud, struct libusb_transfer *trx); 296 | int usbip_recv_xbuff(struct usbip_device *ud, struct libusb_transfer *trx, 297 | int offset); 298 | 299 | /* usbip_event.c */ 300 | int usbip_start_eh(struct usbip_device *ud); 301 | void usbip_stop_eh(struct usbip_device *ud); 302 | void usbip_join_eh(struct usbip_device *ud); 303 | void usbip_event_add(struct usbip_device *ud, unsigned long event); 304 | int usbip_event_happened(struct usbip_device *ud); 305 | 306 | #endif /* __STUB_COMMON_H */ 307 | -------------------------------------------------------------------------------- /driver-libusb/stub_event.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi 3 | * Copyright (C) 2015 Nobuo Iwata 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "stub.h" 20 | 21 | #include 22 | 23 | static unsigned long event_get(struct usbip_device *ud) 24 | { 25 | unsigned long event; 26 | 27 | pthread_mutex_lock(&ud->lock); 28 | event = ud->event; 29 | ud->event = 0; 30 | pthread_mutex_unlock(&ud->lock); 31 | 32 | return event; 33 | } 34 | 35 | static int event_handler(struct usbip_device *ud) 36 | { 37 | unsigned long event = event_get(ud); 38 | 39 | usbip_dbg_eh("enter event_handler"); 40 | 41 | /* 42 | * Events are handled by only this thread. 43 | */ 44 | usbip_dbg_eh("pending event %lx", event); 45 | 46 | /* 47 | * NOTE: shutdown must come first. 48 | * Shutdown the device. 49 | */ 50 | if (event & USBIP_EH_SHUTDOWN) 51 | ud->eh_ops.shutdown(ud); 52 | 53 | /* Reset the device. */ 54 | if (event & USBIP_EH_RESET) 55 | ud->eh_ops.reset(ud); 56 | 57 | /* Mark the device as unusable. */ 58 | if (event & USBIP_EH_UNUSABLE) 59 | ud->eh_ops.unusable(ud); 60 | 61 | /* Stop the error handler. */ 62 | if (event & USBIP_EH_BYE) 63 | return -1; 64 | 65 | return 0; 66 | } 67 | 68 | static void *event_handler_loop(void *data) 69 | { 70 | struct usbip_device *ud = (struct usbip_device *)data; 71 | 72 | while (!ud->eh_should_stop) { 73 | pthread_mutex_lock(&ud->eh_waitq); 74 | usbip_dbg_eh("wakeup"); 75 | 76 | if (event_handler(ud) < 0) 77 | break; 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | int usbip_start_eh(struct usbip_device *ud) 84 | { 85 | pthread_mutex_init(&ud->eh_waitq, NULL); 86 | ud->eh_should_stop = 0; 87 | ud->event = 0; 88 | 89 | if (pthread_create(&ud->eh, NULL, event_handler_loop, ud)) { 90 | warn("Unable to start control thread"); 91 | return -1; 92 | } 93 | return 0; 94 | } 95 | 96 | void usbip_stop_eh(struct usbip_device *ud) 97 | { 98 | usbip_dbg_eh("finishing usbip_eh"); 99 | ud->eh_should_stop = 1; 100 | pthread_mutex_unlock(&ud->eh_waitq); 101 | } 102 | 103 | void usbip_join_eh(struct usbip_device *ud) 104 | { 105 | pthread_join(ud->eh, NULL); 106 | pthread_mutex_destroy(&ud->eh_waitq); 107 | } 108 | 109 | void usbip_event_add(struct usbip_device *ud, unsigned long event) 110 | { 111 | pthread_mutex_lock(&ud->lock); 112 | ud->event |= event; 113 | pthread_mutex_unlock(&ud->lock); 114 | pthread_mutex_unlock(&ud->eh_waitq); 115 | } 116 | 117 | int usbip_event_happened(struct usbip_device *ud) 118 | { 119 | int happened = 0; 120 | 121 | pthread_mutex_lock(&ud->lock); 122 | if (ud->event != 0) 123 | happened = 1; 124 | pthread_mutex_unlock(&ud->lock); 125 | 126 | return happened; 127 | } 128 | -------------------------------------------------------------------------------- /driver-libusb/stub_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi 3 | * Copyright (C) 2015-2016 Nobuo Iwata 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "stub.h" 20 | #include 21 | 22 | static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead) 23 | { 24 | struct list_head *pos, *tmp; 25 | struct stub_priv *priv; 26 | 27 | list_for_each_safe(pos, tmp, listhead) { 28 | priv = list_entry(pos, struct stub_priv, list); 29 | warn("Found pending trx %p.", priv->trx); 30 | } 31 | 32 | return NULL; 33 | } 34 | 35 | static struct stub_priv *stub_priv_pop(struct stub_device *sdev) 36 | { 37 | struct stub_priv *priv; 38 | 39 | pthread_mutex_lock(&sdev->priv_lock); 40 | 41 | priv = stub_priv_pop_from_listhead(&sdev->priv_init); 42 | if (priv) 43 | goto done; 44 | 45 | priv = stub_priv_pop_from_listhead(&sdev->priv_tx); 46 | if (priv) 47 | goto done; 48 | 49 | priv = stub_priv_pop_from_listhead(&sdev->priv_free); 50 | 51 | done: 52 | pthread_mutex_unlock(&sdev->priv_lock); 53 | return priv; 54 | } 55 | 56 | void stub_device_cleanup_transfers(struct stub_device *sdev) 57 | { 58 | struct stub_priv *priv; 59 | struct libusb_transfer *trx; 60 | 61 | dev_dbg(sdev->dev, "free sdev %p", sdev); 62 | 63 | while (1) { 64 | priv = stub_priv_pop(sdev); 65 | if (!priv) 66 | break; 67 | 68 | trx = priv->trx; 69 | libusb_cancel_transfer(trx); 70 | 71 | dev_dbg(sdev->dev, "free trx %p", trx); 72 | free(priv); 73 | free(trx->buffer); 74 | libusb_free_transfer(trx); 75 | } 76 | } 77 | 78 | void stub_device_cleanup_unlinks(struct stub_device *sdev) 79 | { 80 | /* derived from stub_shutdown_connection */ 81 | struct list_head *pos, *tmp; 82 | struct stub_unlink *unlink; 83 | 84 | pthread_mutex_lock(&sdev->priv_lock); 85 | list_for_each_safe(pos, tmp, &sdev->unlink_tx) { 86 | unlink = list_entry(pos, struct stub_unlink, list); 87 | list_del(&unlink->list); 88 | free(unlink); 89 | } 90 | list_for_each_safe(pos, tmp, &sdev->unlink_free) { 91 | unlink = list_entry(pos, struct stub_unlink, list); 92 | list_del(&unlink->list); 93 | free(unlink); 94 | } 95 | pthread_mutex_unlock(&sdev->priv_lock); 96 | } 97 | -------------------------------------------------------------------------------- /driver-libusb/stub_rx.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | /* 3 | * Copyright (C) 2003-2008 Takahiro Hirofuchi 4 | * Copyright (C) 2015-2016 Nobuo Iwata 5 | */ 6 | 7 | #include "stub.h" 8 | #include 9 | #include 10 | #include 11 | 12 | static int is_clear_halt_cmd(struct libusb_transfer *trx) 13 | { 14 | struct libusb_control_setup *req = 15 | libusb_control_transfer_get_setup(trx); 16 | uint8_t recip = get_recipient(req->bmRequestType); 17 | 18 | return (req->bRequest == LIBUSB_REQUEST_CLEAR_FEATURE) && 19 | (recip == LIBUSB_RECIPIENT_ENDPOINT) && 20 | (req->wValue == USB_ENDPOINT_HALT); 21 | } 22 | 23 | static int is_set_interface_cmd(struct libusb_transfer *trx) 24 | { 25 | struct libusb_control_setup *req = 26 | libusb_control_transfer_get_setup(trx); 27 | uint8_t recip = get_recipient(req->bmRequestType); 28 | 29 | return (req->bRequest == LIBUSB_REQUEST_SET_INTERFACE) && 30 | (recip == LIBUSB_RECIPIENT_INTERFACE); 31 | } 32 | 33 | static int is_set_configuration_cmd(struct libusb_transfer *trx) 34 | { 35 | struct libusb_control_setup *req = 36 | libusb_control_transfer_get_setup(trx); 37 | uint8_t recip = get_recipient(req->bmRequestType); 38 | 39 | return (req->bRequest == LIBUSB_REQUEST_SET_CONFIGURATION) && 40 | (recip == LIBUSB_RECIPIENT_DEVICE); 41 | } 42 | 43 | static int is_reset_device_cmd(struct libusb_transfer *trx) 44 | { 45 | struct libusb_control_setup *req = 46 | libusb_control_transfer_get_setup(trx); 47 | uint8_t request_type = get_request_type(req->bmRequestType); 48 | uint8_t recip = get_recipient(req->bmRequestType); 49 | uint16_t value; 50 | uint16_t index; 51 | 52 | value = libusb_cpu_to_le16(req->wValue); 53 | index = libusb_cpu_to_le16(req->wIndex); 54 | 55 | if ((req->bRequest == LIBUSB_REQUEST_SET_FEATURE) && 56 | (request_type == LIBUSB_REQUEST_TYPE_CLASS) && 57 | (recip == LIBUSB_RECIPIENT_OTHER) && 58 | (value == USB_PORT_FEAT_RESET)) { 59 | usbip_dbg_stub_rx("reset_device_cmd, port %u", index); 60 | return 1; 61 | } 62 | return 0; 63 | } 64 | 65 | static int tweak_clear_halt_cmd(struct libusb_transfer *trx) 66 | { 67 | struct libusb_control_setup *req = libusb_control_transfer_get_setup(trx); 68 | unsigned char target_endp; 69 | int ret; 70 | 71 | /* 72 | * The stalled endpoint is specified in the wIndex value. The endpoint 73 | * of the urb is the target of this clear_halt request (i.e., control 74 | * endpoint). 75 | * 76 | * NOTE: endpoint value must be with direction for libusb. 77 | */ 78 | target_endp = libusb_le16_to_cpu(req->wIndex); 79 | 80 | ret = libusb_clear_halt(trx->dev_handle, target_endp); 81 | if (ret) 82 | dev_err(libusb_get_device(trx->dev_handle), 83 | "usb_clear_halt error: endp %d ret %d", 84 | target_endp, ret); 85 | else 86 | dev_info(libusb_get_device(trx->dev_handle), 87 | "usb_clear_halt done: endp %d", 88 | target_endp); 89 | 90 | return ret; 91 | } 92 | 93 | static int tweak_set_interface_cmd(struct libusb_transfer *trx) 94 | { 95 | struct libusb_control_setup *req; 96 | uint16_t alternate; 97 | uint16_t interface; 98 | int ret; 99 | 100 | req = libusb_control_transfer_get_setup(trx); 101 | alternate = libusb_le16_to_cpu(req->wValue); 102 | interface = libusb_le16_to_cpu(req->wIndex); 103 | 104 | usbip_dbg_stub_rx("set_interface: inf %u alt %u", 105 | interface, alternate); 106 | 107 | ret = libusb_set_interface_alt_setting(trx->dev_handle, 108 | interface, alternate); 109 | if (ret) 110 | dev_err(libusb_get_device(trx->dev_handle), 111 | "usb_set_interface error: inf %u alt %u ret %d", 112 | interface, alternate, ret); 113 | else 114 | dev_info(libusb_get_device(trx->dev_handle), 115 | "usb_set_interface done: inf %u alt %u", 116 | interface, alternate); 117 | 118 | return ret; 119 | } 120 | 121 | static int tweak_set_configuration_cmd(struct libusb_transfer *trx) 122 | { 123 | struct libusb_control_setup *req; 124 | uint16_t config; 125 | 126 | req = libusb_control_transfer_get_setup(trx); 127 | config = libusb_le16_to_cpu(req->wValue); 128 | 129 | /* 130 | * I have never seen a multi-config device. Very rare. 131 | * For most devices, this will be called to choose a default 132 | * configuration only once in an initialization phase. 133 | * 134 | * set_configuration may change a device configuration and its device 135 | * drivers will be unbound and assigned for a new device configuration. 136 | * This means this usbip driver will be also unbound when called, then 137 | * eventually reassigned to the device as far as driver matching 138 | * condition is kept. 139 | * 140 | * Unfortunately, an existing usbip connection will be dropped 141 | * due to this driver unbinding. So, skip here. 142 | * A user may need to set a special configuration value before 143 | * exporting the device. 144 | */ 145 | //TODO not sure if it is the point here 146 | dev_info(libusb_get_device(trx->dev_handle), 147 | "usb_set_configuration %d ... skip!", 148 | config); 149 | 150 | return -1; 151 | } 152 | 153 | static int tweak_reset_device_cmd(struct libusb_transfer *trx) 154 | { 155 | struct stub_priv *priv = (struct stub_priv *) trx->user_data; 156 | struct stub_device *sdev = priv->sdev; 157 | 158 | dev_info(libusb_get_device(trx->dev_handle), "usb_queue_reset_device"); 159 | 160 | /* 161 | * With the implementation of pre_reset and post_reset the driver no 162 | * longer unbinds. This allows the use of synchronous reset. 163 | */ 164 | //libusb_reset_device(sdev->dev_handle); 165 | return 0; 166 | } 167 | 168 | /* 169 | * clear_halt, set_interface, and set_configuration require special tricks. 170 | */ 171 | static int tweak_special_requests(struct libusb_transfer *trx) { 172 | struct libusb_control_setup *req; 173 | 174 | if (!trx) 175 | return -1; 176 | 177 | req = libusb_control_transfer_get_setup(trx); 178 | if (!req) 179 | return -1; 180 | 181 | if (trx->type != LIBUSB_TRANSFER_TYPE_CONTROL) 182 | return -1; 183 | 184 | if (is_clear_halt_cmd(trx)) 185 | return tweak_clear_halt_cmd(trx); 186 | 187 | else if (is_set_interface_cmd(trx)) 188 | return tweak_set_interface_cmd(trx); 189 | 190 | else if (is_set_configuration_cmd(trx)) 191 | return tweak_set_configuration_cmd(trx); 192 | 193 | else if (is_reset_device_cmd(trx)) 194 | return tweak_reset_device_cmd(trx); 195 | else 196 | usbip_dbg_stub_rx("no need to tweak"); 197 | 198 | return -1; 199 | } 200 | 201 | /* 202 | * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb(). 203 | * By unlinking the urb asynchronously, stub_rx can continuously 204 | * process coming urbs. Even if the urb is unlinked, its completion 205 | * handler will be called and stub_tx will send a return pdu. 206 | * 207 | * See also comments about unlinking strategy in vhci_hcd.c. 208 | */ 209 | static int stub_recv_cmd_unlink(struct stub_device *sdev, 210 | struct usbip_header *pdu) 211 | { 212 | int ret; 213 | struct list_head *pos; 214 | struct stub_priv *priv; 215 | 216 | pthread_mutex_lock(&sdev->priv_lock); 217 | 218 | list_for_each(pos, &sdev->priv_init) { 219 | priv = list_entry(pos, struct stub_priv, list); 220 | if (priv->seqnum != pdu->u.cmd_unlink.seqnum) 221 | continue; 222 | 223 | dev_info(libusb_get_device(priv->trx->dev_handle), "unlink urb %p", priv->trx); 224 | 225 | /* 226 | * This matched urb is not completed yet (i.e., be in 227 | * flight in usb hcd hardware/driver). Now we are 228 | * cancelling it. The unlinking flag means that we are 229 | * now not going to return the normal result pdu of a 230 | * submission request, but going to return a result pdu 231 | * of the unlink request. 232 | */ 233 | priv->unlinking = 1; 234 | 235 | /* 236 | * In the case that unlinking flag is on, prev->seqnum 237 | * is changed from the seqnum of the cancelling urb to 238 | * the seqnum of the unlink request. This will be used 239 | * to make the result pdu of the unlink request. 240 | */ 241 | priv->seqnum = pdu->base.seqnum; 242 | 243 | pthread_mutex_unlock(&sdev->priv_lock); 244 | 245 | /* 246 | * usb_unlink_urb() is now out of spinlocking to avoid 247 | * spinlock recursion since stub_complete() is 248 | * sometimes called in this context but not in the 249 | * interrupt context. If stub_complete() is executed 250 | * before we call usb_unlink_urb(), usb_unlink_urb() 251 | * will return an error value. In this case, stub_tx 252 | * will return the result pdu of this unlink request 253 | * though submission is completed and actual unlinking 254 | * is not executed. OK? 255 | */ 256 | /* In the above case, urb->status is not -ECONNRESET, 257 | * so a driver in a client host will know the failure 258 | * of the unlink request ? 259 | */ 260 | ret = libusb_cancel_transfer(priv->trx); 261 | if (ret == LIBUSB_ERROR_NOT_FOUND) { 262 | dev_err(libusb_get_device(priv->trx->dev_handle), 263 | "failed to unlink a urb completed urb%p", 264 | priv->trx); 265 | } else if (ret) { 266 | dev_err(libusb_get_device(priv->trx->dev_handle), 267 | "failed to unlink a urb %p, ret %d", 268 | priv->trx, ret); 269 | } 270 | return 0; 271 | } 272 | 273 | usbip_dbg_stub_rx("seqnum %d is not pending", 274 | pdu->u.cmd_unlink.seqnum); 275 | 276 | /* 277 | * The urb of the unlink target is not found in priv_init queue. It was 278 | * already completed and its results is/was going to be sent by a 279 | * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only 280 | * return the completeness of this unlink request to vhci_hcd. 281 | */ 282 | stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0); 283 | 284 | pthread_mutex_unlock(&sdev->priv_lock); 285 | 286 | return 0; 287 | } 288 | 289 | /* 290 | static int valid_request(struct stub_device *sdev, struct usbip_header *pdu) 291 | { 292 | struct usbip_device *ud = &sdev->ud; 293 | int valid = 0; 294 | 295 | if (pdu->base.devid == sdev->devid) { 296 | pthread_mutex_lock(&ud->lock); 297 | if (ud->status == SDEV_ST_USED) { 298 | */ 299 | /* A request is valid. *//* 300 | 301 | valid = 1; 302 | } 303 | pthread_mutex_unlock(&ud->lock); 304 | } 305 | if (!valid) { 306 | dev_err(sdev->dev, "invalid request %08x:%08x(%d)", 307 | pdu->base.devid, sdev->devid, ud->status); 308 | } 309 | return valid; 310 | } 311 | */ 312 | 313 | static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, 314 | struct usbip_header *pdu) 315 | { 316 | struct stub_priv *priv; 317 | struct usbip_device *ud = &sdev->ud; 318 | 319 | pthread_mutex_lock(&sdev->priv_lock); 320 | 321 | priv = (struct stub_priv *)calloc(1, sizeof(struct stub_priv)); 322 | if (!priv) { 323 | dev_err(sdev->dev, "alloc stub_priv"); 324 | pthread_mutex_unlock(&sdev->priv_lock); 325 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); 326 | return NULL; 327 | } 328 | 329 | priv->seqnum = pdu->base.seqnum; 330 | priv->dir = pdu->base.direction; 331 | priv->sdev = sdev; 332 | 333 | /* 334 | * After a stub_priv is linked to a list_head, 335 | * our error handler can free allocated data. 336 | */ 337 | list_add(&priv->list, sdev->priv_init.prev); 338 | 339 | pthread_mutex_unlock(&sdev->priv_lock); 340 | 341 | return priv; 342 | } 343 | 344 | static void masking_bogus_flags(struct libusb_transfer *trx) 345 | { 346 | struct stub_priv *priv = (struct stub_priv *)trx->user_data; 347 | struct stub_device *sdev = priv->sdev; 348 | int is_out; 349 | unsigned int allowed = 0; 350 | 351 | if (!trx || !trx->callback) /* FIXME: omit hcpriv */ 352 | return; 353 | /* FIXME: ignore dev->state */ 354 | 355 | if (trx->type == LIBUSB_TRANSFER_TYPE_CONTROL) { 356 | struct libusb_control_setup *setup = 357 | libusb_control_transfer_get_setup(trx); 358 | 359 | if (!setup) 360 | return; 361 | is_out = !(setup->bmRequestType & USB_DIR_IN) || 362 | !setup->wLength; 363 | } else { 364 | is_out = stub_endpoint_dir_out(sdev, trx->endpoint); 365 | } 366 | 367 | /* enforce simple/standard policy */ 368 | switch (trx->type) { 369 | case LIBUSB_TRANSFER_TYPE_BULK: 370 | if (is_out) 371 | allowed |= LIBUSB_TRANSFER_ADD_ZERO_PACKET; 372 | /* FALLTHROUGH */ 373 | case LIBUSB_TRANSFER_TYPE_CONTROL: 374 | /*allowed |= URB_NO_FSBR; */ /* only affects UHCI */ 375 | /* FALLTHROUGH */ 376 | default: /* all non-iso endpoints */ 377 | if (!is_out) 378 | allowed |= LIBUSB_TRANSFER_SHORT_NOT_OK; 379 | break; 380 | } 381 | trx->flags &= allowed; 382 | } 383 | 384 | static void stub_recv_cmd_submit(struct stub_device *sdev, 385 | struct usbip_header *pdu) 386 | { 387 | int ret; 388 | struct stub_priv *priv; 389 | struct usbip_device *ud = &sdev->ud; 390 | struct libusb_device_handle *dev_handle = sdev->dev_handle; 391 | unsigned char endpoint = pdu->base.ep; 392 | unsigned char trx_type = stub_get_transfer_type(sdev, pdu->base.ep); 393 | uint8_t trx_flags = stub_get_transfer_flags( 394 | pdu->u.cmd_submit.transfer_flags); 395 | int num_iso_packets = 0; 396 | struct libusb_transfer *trx; 397 | unsigned char *buf = NULL; 398 | int buflen = 0; 399 | int offset = 0; 400 | 401 | if (trx_type > LIBUSB_TRANSFER_TYPE_MASK) 402 | return; 403 | if (pdu->base.direction == USBIP_DIR_IN) 404 | endpoint |= USB_DIR_IN; 405 | 406 | priv = stub_priv_alloc(sdev, pdu); 407 | if (!priv) 408 | return; 409 | 410 | /* setup a urb */ 411 | if (trx_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) 412 | num_iso_packets = pdu->u.cmd_submit.number_of_packets; 413 | trx = libusb_alloc_transfer(num_iso_packets); 414 | if (!trx) { 415 | dev_err(sdev->dev, "malloc trx"); 416 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); 417 | return; 418 | } 419 | priv->trx = trx; 420 | 421 | /* allocate urb transfer buffer, if needed */ 422 | if (trx_type == LIBUSB_TRANSFER_TYPE_CONTROL) { 423 | buflen = 8; 424 | offset = 8; 425 | } 426 | 427 | if (pdu->u.cmd_submit.transfer_buffer_length > 0) 428 | buflen += pdu->u.cmd_submit.transfer_buffer_length; 429 | 430 | if (buflen > 0) { 431 | buf = (unsigned char *)calloc(1, buflen); 432 | if (!buf) { 433 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); 434 | return; 435 | } 436 | } 437 | 438 | /* copy urb setup packet */ 439 | if (trx_type == LIBUSB_TRANSFER_TYPE_CONTROL) 440 | memcpy(buf, pdu->u.cmd_submit.setup, 8); 441 | 442 | /* set members from the base header of pdu */ 443 | trx->dev_handle = dev_handle; 444 | trx->flags = trx_flags; 445 | trx->endpoint = endpoint; 446 | trx->type = trx_type; 447 | trx->timeout = 0; 448 | trx->buffer = buf; 449 | trx->length = buflen; 450 | trx->num_iso_packets = num_iso_packets; 451 | trx->user_data = priv; 452 | trx->callback = stub_complete; 453 | 454 | if (pdu->base.direction != USBIP_DIR_IN) { 455 | if (usbip_recv_xbuff(ud, trx, offset) < 0) 456 | return; 457 | } 458 | 459 | if (usbip_recv_iso(ud, trx) < 0) 460 | return; 461 | 462 | /* no need to submit an intercepted request, but harmless? */ 463 | ret = tweak_special_requests(trx); 464 | if (ret < 0) { 465 | masking_bogus_flags(trx); 466 | 467 | /* urb is now ready to submit */ 468 | ret = libusb_submit_transfer(priv->trx); 469 | } else { 470 | priv->trx->status = LIBUSB_TRANSFER_COMPLETED; 471 | priv->trx->actual_length = 0; 472 | pthread_mutex_unlock(&sdev->priv_lock); 473 | list_del(&priv->list); 474 | list_add(&priv->list, sdev->priv_tx.prev); 475 | pthread_mutex_unlock(&sdev->priv_lock); 476 | pthread_mutex_unlock(&sdev->tx_waitq); //wakeup sleepy 477 | ret = 0; 478 | } 479 | 480 | if (ret == 0) 481 | usbip_dbg_stub_rx("submit_urb ok %p seq %u", trx, pdu->base.seqnum); 482 | else { 483 | dev_err(sdev->dev, "submit_urb error, %d seq %u", ret, pdu->base.seqnum); 484 | dev_err(sdev->dev, "ERRNO: %s", strerror(errno)); 485 | usbip_dump_header(pdu); 486 | usbip_dump_trx(trx); 487 | libusb_free_transfer(trx); 488 | 489 | /* 490 | * Pessimistic. 491 | * This connection will be discarded. 492 | */ 493 | usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT); 494 | } 495 | } 496 | 497 | /* recv a pdu */ 498 | static void stub_rx_pdu(struct usbip_device *ud) 499 | { 500 | int ret; 501 | struct usbip_header pdu; 502 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); 503 | 504 | again: 505 | memset(&pdu, 0, sizeof(pdu)); 506 | 507 | /* receive a pdu header */ 508 | ret = usbip_recv(ud, &pdu, sizeof(pdu)); 509 | 510 | if (ret != sizeof(pdu)) { 511 | if (ret != 0) { 512 | dev_err(sdev->dev, "recv a header, %d", ret); 513 | } else { 514 | dev_info(sdev->dev, "disconnect from client"); 515 | } 516 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 517 | return; 518 | } 519 | 520 | usbip_header_correct_endian(&pdu, 0); 521 | 522 | if (usbip_dbg_flag_stub_rx) 523 | usbip_dump_header(&pdu); 524 | 525 | if (pdu.base.command == USBIP_NOP) { 526 | usbip_dbg_stub_rx("nop command"); 527 | goto again; 528 | } 529 | 530 | /* 531 | if (!valid_request(sdev, &pdu)) { 532 | dev_err(sdev->dev, "recv invalid request"); 533 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 534 | return; 535 | } 536 | */ 537 | 538 | switch (pdu.base.command) { 539 | case USBIP_CMD_UNLINK: 540 | stub_recv_cmd_unlink(sdev, &pdu); 541 | break; 542 | case USBIP_CMD_SUBMIT: 543 | stub_recv_cmd_submit(sdev, &pdu); 544 | break; 545 | default: 546 | /* NOTREACHED */ 547 | dev_err(sdev->dev, "unknown pdu"); 548 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 549 | break; 550 | } 551 | } 552 | 553 | void *stub_rx_loop(void *data) 554 | { 555 | struct stub_device *sdev = (struct stub_device *)data; 556 | struct usbip_device *ud = &sdev->ud; 557 | 558 | while (!stub_should_stop(sdev)) { 559 | if (usbip_event_happened(ud)) 560 | break; 561 | 562 | stub_rx_pdu(ud); 563 | } 564 | usbip_dbg_stub_rx("end of stub_rx_loop"); 565 | return NULL; 566 | } 567 | -------------------------------------------------------------------------------- /driver-libusb/stub_tx.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0+ 2 | /* 3 | * Copyright (C) 2003-2008 Takahiro Hirofuchi 4 | * Copyright (C) 2015-2016 Nobuo Iwata 5 | */ 6 | 7 | #include "stub.h" 8 | #include 9 | 10 | static void stub_free_priv_and_trx(struct stub_priv *priv) 11 | { 12 | struct libusb_transfer *trx = priv->trx; 13 | 14 | free(trx->buffer); 15 | list_del(&priv->list); 16 | free(priv); 17 | usbip_dbg_stub_tx("freeing trx %p", trx); 18 | libusb_free_transfer(trx); 19 | } 20 | 21 | /* be in spin_lock_irqsave(&sdev->priv_lock, flags) */ 22 | void stub_enqueue_ret_unlink(struct stub_device *sdev, uint32_t seqnum, 23 | enum libusb_transfer_status status) 24 | { 25 | struct stub_unlink *unlink; 26 | 27 | unlink = (struct stub_unlink *)calloc(1, sizeof(struct stub_unlink)); 28 | if (!unlink) { 29 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC); 30 | return; 31 | } 32 | 33 | unlink->seqnum = seqnum; 34 | unlink->status = status; 35 | 36 | list_add(&unlink->list, sdev->unlink_tx.prev); 37 | } 38 | 39 | /** 40 | * stub_complete - completion handler of a usbip urb 41 | * @urb: pointer to the urb completed 42 | * 43 | * When a urb has completed, the USB core driver calls this function mostly in 44 | * the interrupt context. To return the result of a urb, the completed urb is 45 | * linked to the pending list of returning. 46 | * 47 | */ 48 | void LIBUSB_CALL stub_complete(struct libusb_transfer *trx) 49 | { 50 | struct stub_priv *priv = (struct stub_priv *) trx->user_data; 51 | struct stub_device *sdev = priv->sdev; 52 | 53 | usbip_dbg_stub_tx("complete %p! status %d", trx, trx->status); 54 | 55 | switch (trx->status) { 56 | case LIBUSB_TRANSFER_COMPLETED: 57 | /* OK */ 58 | break; 59 | case LIBUSB_TRANSFER_ERROR: 60 | if (!(trx->flags & LIBUSB_TRANSFER_SHORT_NOT_OK)) { 61 | dev_info(sdev->dev, "error on endpoint %d", trx->endpoint); 62 | } else { 63 | //Tweaking status to complete as we received data, but all 64 | trx->status = LIBUSB_TRANSFER_COMPLETED; 65 | } 66 | break; 67 | case LIBUSB_TRANSFER_CANCELLED: 68 | dev_info(sdev->dev, "unlinked by a call to usb_unlink_urb()"); 69 | break; 70 | case LIBUSB_TRANSFER_STALL: 71 | dev_err(sdev->dev, "endpoint %d is stalled", trx->endpoint); 72 | break; 73 | case LIBUSB_TRANSFER_NO_DEVICE: 74 | dev_info(sdev->dev, "device removed?"); 75 | break; 76 | default: 77 | dev_err(sdev->dev, "urb completion with unknown status %d", trx->status); 78 | break; 79 | } 80 | 81 | /* link a urb to the queue of tx. */ 82 | pthread_mutex_lock(&sdev->priv_lock); 83 | if (!sdev->ud.sock_fd) { 84 | dev_info(sdev->dev, 85 | "urb discarded in closed connection"); 86 | } else if (priv->unlinking) { 87 | stub_enqueue_ret_unlink(sdev, priv->seqnum, trx->status); 88 | stub_free_priv_and_trx(priv); 89 | } else { 90 | list_del(&priv->list); 91 | list_add(&priv->list, sdev->priv_tx.prev); 92 | } 93 | pthread_mutex_unlock(&sdev->priv_lock); 94 | 95 | /* wake up tx_thread */ 96 | pthread_mutex_unlock(&sdev->tx_waitq); 97 | } 98 | 99 | static inline void setup_base_pdu(struct usbip_header_basic *base, 100 | uint32_t command, uint32_t seqnum) 101 | { 102 | base->command = command; 103 | base->seqnum = seqnum; 104 | base->devid = 0; 105 | base->ep = 0; 106 | base->direction = 0; 107 | } 108 | 109 | static void setup_ret_submit_pdu(struct usbip_header *rpdu, 110 | struct libusb_transfer *trx) 111 | { 112 | struct stub_priv *priv = (struct stub_priv *) trx->user_data; 113 | 114 | setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum); 115 | usbip_pack_ret_submit(rpdu, trx); 116 | } 117 | 118 | static void setup_ret_unlink_pdu(struct usbip_header *rpdu, 119 | struct stub_unlink *unlink) 120 | { 121 | setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum); 122 | usbip_pack_ret_unlink(rpdu, unlink); 123 | } 124 | 125 | static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev) 126 | { 127 | struct list_head *pos, *tmp; 128 | struct stub_priv *priv; 129 | 130 | pthread_mutex_lock(&sdev->priv_lock); 131 | 132 | list_for_each_safe(pos, tmp, &sdev->priv_tx) { 133 | priv = list_entry(pos, struct stub_priv, list); 134 | list_del(&priv->list); 135 | list_add(&priv->list, sdev->priv_free.prev); 136 | pthread_mutex_unlock(&sdev->priv_lock); 137 | return priv; 138 | } 139 | 140 | pthread_mutex_unlock(&sdev->priv_lock); 141 | 142 | return NULL; 143 | } 144 | 145 | static void fixup_actual_length(struct libusb_transfer *trx) 146 | { 147 | int i, len = 0; 148 | 149 | for (i = 0; i < trx->num_iso_packets; i++) 150 | len += trx->iso_packet_desc[i].actual_length; 151 | 152 | trx->actual_length = len; 153 | } 154 | 155 | static int stub_send_ret_submit(struct stub_device *sdev) 156 | { 157 | struct list_head *pos, *tmp; 158 | struct stub_priv *priv; 159 | size_t total_size = 0; 160 | 161 | while ((priv = dequeue_from_priv_tx(sdev)) != NULL) { 162 | size_t sent; 163 | struct libusb_transfer *trx = priv->trx; 164 | struct usbip_header pdu_header; 165 | struct usbip_iso_packet_descriptor *iso_buffer = NULL; 166 | struct iovec iov[2 + trx->num_iso_packets]; 167 | int iovnum = 0; 168 | int offset = 0; 169 | size_t txsize = 0; 170 | 171 | memset(&pdu_header, 0, sizeof(pdu_header)); 172 | 173 | if (trx->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { 174 | fixup_actual_length(trx); 175 | } 176 | 177 | /* 1. setup usbip_header */ 178 | setup_ret_submit_pdu(&pdu_header, trx); 179 | usbip_dbg_stub_tx("setup txdata seqnum: %d trx: %p actl: %d", 180 | pdu_header.base.seqnum, trx, trx->actual_length); 181 | usbip_header_correct_endian(&pdu_header, 1); 182 | 183 | iov[iovnum].iov_base = &pdu_header; 184 | iov[iovnum].iov_len = sizeof(pdu_header); 185 | iovnum++; 186 | txsize += sizeof(pdu_header); 187 | 188 | /* 2. setup transfer buffer */ 189 | if (priv->dir == USBIP_DIR_IN && 190 | trx->type != LIBUSB_TRANSFER_TYPE_ISOCHRONOUS && 191 | trx->actual_length > 0) { 192 | if (trx->type == LIBUSB_TRANSFER_TYPE_CONTROL) 193 | offset = 8; 194 | iov[iovnum].iov_base = trx->buffer + offset; 195 | iov[iovnum].iov_len = trx->actual_length; 196 | iovnum++; 197 | txsize += trx->actual_length; 198 | } else if (priv->dir == USBIP_DIR_IN && 199 | trx->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { 200 | /* 201 | * For isochronous packets: actual length is the sum of 202 | * the actual length of the individual, packets, but as 203 | * the packet offsets are not changed there will be 204 | * padding between the packets. To optimally use the 205 | * bandwidth the padding is not transmitted. 206 | */ 207 | int i; 208 | 209 | for (i = 0; i < trx->num_iso_packets; i++) { 210 | iov[iovnum].iov_base = trx->buffer + offset; 211 | iov[iovnum].iov_len = 212 | trx->iso_packet_desc[i].actual_length; 213 | iovnum++; 214 | offset += trx->iso_packet_desc[i].length; 215 | txsize += trx->iso_packet_desc[i].actual_length; 216 | } 217 | 218 | if (txsize != sizeof(pdu_header) + trx->actual_length) { 219 | dev_err(sdev->dev, 220 | "actual length of urb %d does not ", 221 | trx->actual_length); 222 | dev_err(sdev->dev, 223 | "match iso packet sizes %zu", 224 | txsize-sizeof(pdu_header)); 225 | usbip_event_add(&sdev->ud, 226 | SDEV_EVENT_ERROR_TCP); 227 | return -1; 228 | } 229 | } 230 | 231 | /* 3. setup iso_packet_descriptor */ 232 | if (trx->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { 233 | ssize_t len = 0; 234 | 235 | iso_buffer = usbip_alloc_iso_desc_pdu(trx, &len); 236 | if (!iso_buffer) { 237 | usbip_event_add(&sdev->ud, 238 | SDEV_EVENT_ERROR_MALLOC); 239 | return -1; 240 | } 241 | 242 | iov[iovnum].iov_base = iso_buffer; 243 | iov[iovnum].iov_len = len; 244 | txsize += len; 245 | iovnum++; 246 | } 247 | 248 | sent = usbip_sendmsg(&sdev->ud, iov, iovnum); 249 | if (sent != txsize) { 250 | dev_err(sdev->dev, 251 | "sendmsg failed!, retval %zd for %zd", 252 | sent, txsize); 253 | free(iso_buffer); 254 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); 255 | return -1; 256 | } 257 | 258 | if (iso_buffer) 259 | free(iso_buffer); 260 | 261 | total_size += txsize; 262 | } 263 | 264 | pthread_mutex_lock(&sdev->priv_lock); 265 | list_for_each_safe(pos, tmp, &sdev->priv_free) { 266 | priv = list_entry(pos, struct stub_priv, list); 267 | stub_free_priv_and_trx(priv); 268 | } 269 | pthread_mutex_unlock(&sdev->priv_lock); 270 | 271 | return total_size; 272 | } 273 | 274 | static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev) 275 | { 276 | struct list_head *pos, *tmp; 277 | struct stub_unlink *unlink; 278 | 279 | pthread_mutex_lock(&sdev->priv_lock); 280 | 281 | list_for_each_safe(pos, tmp, &sdev->unlink_tx) { 282 | unlink = list_entry(pos, struct stub_unlink, list); 283 | list_del(&unlink->list); 284 | list_add(&unlink->list, sdev->unlink_free.prev); 285 | pthread_mutex_unlock(&sdev->priv_lock); 286 | return unlink; 287 | } 288 | 289 | pthread_mutex_unlock(&sdev->priv_lock); 290 | 291 | return NULL; 292 | } 293 | 294 | static int stub_send_ret_unlink(struct stub_device *sdev) 295 | { 296 | struct list_head *pos, *tmp; 297 | struct stub_unlink *unlink; 298 | struct iovec iov[1]; 299 | size_t txsize; 300 | size_t total_size = 0; 301 | 302 | while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) { 303 | size_t sent; 304 | struct usbip_header pdu_header; 305 | 306 | txsize = 0; 307 | memset(&pdu_header, 0, sizeof(pdu_header)); 308 | memset(&iov, 0, sizeof(iov)); 309 | 310 | usbip_dbg_stub_tx("setup ret unlink %lu", unlink->seqnum); 311 | 312 | /* 1. setup usbip_header */ 313 | setup_ret_unlink_pdu(&pdu_header, unlink); 314 | usbip_header_correct_endian(&pdu_header, 1); 315 | 316 | iov[0].iov_base = &pdu_header; 317 | iov[0].iov_len = sizeof(pdu_header); 318 | txsize += sizeof(pdu_header); 319 | 320 | sent = usbip_sendmsg(&sdev->ud, iov, 1); 321 | if (sent != txsize) { 322 | dev_err(sdev->dev, 323 | "sendmsg failed!, retval %zd for %zd", 324 | sent, txsize); 325 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); 326 | return -1; 327 | } 328 | 329 | usbip_dbg_stub_tx("send txdata"); 330 | total_size += txsize; 331 | } 332 | 333 | pthread_mutex_lock(&sdev->priv_lock); 334 | 335 | list_for_each_safe(pos, tmp, &sdev->unlink_free) { 336 | unlink = list_entry(pos, struct stub_unlink, list); 337 | list_del(&unlink->list); 338 | free(unlink); 339 | } 340 | 341 | pthread_mutex_unlock(&sdev->priv_lock); 342 | 343 | return total_size; 344 | } 345 | 346 | static void poll_events_and_complete(struct stub_device *sdev) 347 | { 348 | struct timeval tv = {0, 0}; 349 | int ret; 350 | 351 | // ret = libusb_handle_events(stub_libusb_ctx); //TODO redo, performance hit here 352 | ret = libusb_handle_events_timeout(stub_libusb_ctx, &tv); 353 | if (ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) 354 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_SUBMIT); 355 | } 356 | 357 | void *stub_tx_loop(void *data) 358 | { 359 | struct stub_device *sdev = (struct stub_device *)data; 360 | int ret_submit, ret_unlink; 361 | 362 | while (!stub_should_stop(sdev)) { 363 | poll_events_and_complete(sdev); 364 | 365 | if (usbip_event_happened(&sdev->ud)) 366 | break; 367 | 368 | /* 369 | * send_ret_submit comes earlier than send_ret_unlink. stub_rx 370 | * looks at only priv_init queue. If the completion of a URB is 371 | * earlier than the receive of CMD_UNLINK, priv is moved to 372 | * priv_tx queue and stub_rx does not find the target priv. In 373 | * this case, vhci_rx receives the result of the submit request 374 | * and then receives the result of the unlink request. The 375 | * result of the submit is given back to the usbcore as the 376 | * completion of the unlink request. The request of the 377 | * unlink is ignored. This is ok because a driver who calls 378 | * usb_unlink_urb() understands the unlink was too late by 379 | * getting the status of the given-backed URB which has the 380 | * status of usb_submit_urb(). 381 | */ 382 | ret_submit = stub_send_ret_submit(sdev); 383 | if (ret_submit < 0) 384 | break; 385 | 386 | ret_unlink = stub_send_ret_unlink(sdev); 387 | if (ret_unlink < 0) 388 | break; 389 | 390 | } 391 | usbip_dbg_stub_tx("end of stub_tx_loop"); 392 | return NULL; 393 | } 394 | -------------------------------------------------------------------------------- /driver-libusb/usbip_host_driver.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi 3 | * Copyright (C) 2015-2016 Nobuo Iwata 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "stub.h" 23 | 24 | #include 25 | 26 | libusb_context *stub_libusb_ctx; 27 | 28 | static struct stub_endpoint *get_endpoint(struct stub_device *sdev, uint8_t ep) 29 | { 30 | int i; 31 | uint8_t ep_nr = ep & USB_ENDPOINT_NUMBER_MASK; 32 | 33 | for (i = 0; i < sdev->num_eps; i++) { 34 | if ((sdev->eps + i)->nr == ep_nr) 35 | return sdev->eps + i; 36 | } 37 | return NULL; 38 | } 39 | 40 | uint8_t stub_get_transfer_type(struct stub_device *sdev, uint8_t ep) 41 | { 42 | struct stub_endpoint *epp; 43 | 44 | if (ep == 0) 45 | return LIBUSB_TRANSFER_TYPE_CONTROL; 46 | 47 | epp = get_endpoint(sdev, ep); 48 | if (epp == NULL) { 49 | dbg("Unknown endpoint %d", ep); 50 | return 0xff; 51 | } 52 | return epp->type; 53 | } 54 | 55 | uint8_t stub_endpoint_dir(struct stub_device *sdev, uint8_t ep) 56 | { 57 | struct stub_endpoint *epp; 58 | 59 | epp = get_endpoint(sdev, ep); 60 | if (epp == NULL) { 61 | dbg("Direction for %d is undetermined", ep); 62 | return 0; 63 | } 64 | return epp->dir; 65 | } 66 | 67 | int stub_endpoint_dir_out(struct stub_device *sdev, uint8_t ep) 68 | { 69 | uint8_t dir = stub_endpoint_dir(sdev, ep); 70 | 71 | if (dir == LIBUSB_ENDPOINT_OUT) 72 | return 1; 73 | return 0; 74 | } 75 | 76 | uint8_t stub_get_transfer_flags(uint32_t in) 77 | { 78 | uint8_t flags = 0; 79 | 80 | if (in & URB_SHORT_NOT_OK) 81 | flags |= LIBUSB_TRANSFER_SHORT_NOT_OK; 82 | if (in & URB_ZERO_PACKET) 83 | flags |= LIBUSB_TRANSFER_ADD_ZERO_PACKET; 84 | 85 | /* 86 | * URB_FREE_BUFFER is turned off to free by stub_free_priv_and_trx() 87 | * 88 | * URB_ISO_ASAP, URB_NO_TRANSFER_DMA_MAP, URB_NO_FSBR and 89 | * URB_NO_INTERRUPT are ignored because unsupported by libusb. 90 | */ 91 | return flags; 92 | } 93 | 94 | int usbip_driver_open(void) { 95 | return libusb_init(&stub_libusb_ctx); 96 | } 97 | 98 | void usbip_driver_close(void) { 99 | libusb_exit(stub_libusb_ctx); 100 | } 101 | 102 | static void get_busid(libusb_device *dev, char *buf) 103 | { 104 | snprintf(buf, SYSFS_BUS_ID_SIZE, "%d-%d", 105 | libusb_get_bus_number(dev), 106 | libusb_get_port_number(dev) 107 | //libusb_get_device_address(dev) 108 | ); 109 | } 110 | 111 | static uint32_t get_device_speed(libusb_device *dev) 112 | { 113 | int speed = libusb_get_device_speed(dev); 114 | 115 | switch (speed) { 116 | case LIBUSB_SPEED_LOW: 117 | return USB_SPEED_LOW; 118 | case LIBUSB_SPEED_FULL: 119 | return USB_SPEED_FULL; 120 | case LIBUSB_SPEED_HIGH: 121 | return USB_SPEED_HIGH; 122 | case LIBUSB_SPEED_SUPER: 123 | return USB_SPEED_SUPER; 124 | default: 125 | dbg("unknown speed enum %d", speed); 126 | } 127 | return USB_SPEED_UNKNOWN; 128 | } 129 | 130 | static void __fill_usb_device(struct usbip_usb_device *udev, 131 | libusb_device *dev, 132 | struct libusb_device_descriptor *desc, 133 | struct libusb_config_descriptor *config) 134 | { 135 | char busid[SYSFS_BUS_ID_SIZE]; 136 | 137 | get_busid(dev, busid); 138 | 139 | memset((char *)udev, 0, sizeof(struct usbip_usb_device)); 140 | strncpy(udev->busid, busid, SYSFS_BUS_ID_SIZE); 141 | udev->busnum = libusb_get_bus_number(dev); 142 | udev->devnum = libusb_get_port_number(dev); 143 | udev->speed = get_device_speed(dev); 144 | udev->idVendor = desc->idVendor; 145 | udev->idProduct = desc->idProduct; 146 | udev->bcdDevice = desc->bcdDevice; 147 | udev->bDeviceClass = desc->bDeviceClass; 148 | udev->bDeviceSubClass = desc->bDeviceSubClass; 149 | udev->bDeviceProtocol = desc->bDeviceProtocol; 150 | udev->bConfigurationValue = config->bConfigurationValue; 151 | udev->bNumConfigurations = desc->bNumConfigurations; 152 | udev->bNumInterfaces = config->bNumInterfaces; 153 | } 154 | 155 | #define FILL_SKIPPED 1 156 | 157 | static int fill_usb_device(struct usbip_usb_device *udev, libusb_device *dev) 158 | { 159 | struct libusb_device_descriptor desc; 160 | struct libusb_config_descriptor *config; 161 | char busid[SYSFS_BUS_ID_SIZE]; 162 | 163 | if (libusb_get_device_descriptor(dev, &desc)) { 164 | get_busid(dev, busid); 165 | err("get device desc %s", busid); 166 | return -1; 167 | } 168 | 169 | if (desc.bDeviceClass == USB_CLASS_HUB) { 170 | get_busid(dev, busid); 171 | dbg("skip hub to fill udev %s", busid); 172 | return FILL_SKIPPED; 173 | } 174 | 175 | if (libusb_get_active_config_descriptor(dev, &config)) { 176 | get_busid(dev, busid); 177 | err("get device config %s", busid); 178 | return -1; 179 | } 180 | 181 | __fill_usb_device(udev, dev, &desc, config); 182 | 183 | libusb_free_config_descriptor(config); 184 | return 0; 185 | } 186 | 187 | static void fill_usb_interfaces(struct usbip_usb_interface *uinf, 188 | struct libusb_config_descriptor *config) 189 | { 190 | int i; 191 | const struct libusb_interface_descriptor *intf; 192 | 193 | for (i = 0; i < config->bNumInterfaces; i++) { 194 | intf = (config->interface + i)->altsetting; 195 | (uinf + i)->bInterfaceClass = intf->bInterfaceClass; 196 | (uinf + i)->bInterfaceSubClass = intf->bInterfaceSubClass; 197 | (uinf + i)->bInterfaceProtocol = intf->bInterfaceProtocol; 198 | (uinf + i)->bInterfaceNumber = intf->bInterfaceNumber; 199 | } 200 | } 201 | 202 | static void fill_stub_endpoint(struct stub_endpoint *ep, 203 | const struct libusb_endpoint_descriptor *desc) 204 | { 205 | ep->nr = desc->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK; 206 | ep->dir = desc->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK; 207 | ep->type = desc->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK; 208 | } 209 | 210 | static void fill_stub_endpoints(struct stub_endpoint *ep, 211 | struct libusb_config_descriptor *config) 212 | { 213 | int i, j, k, num = 0; 214 | const struct libusb_interface *intf; 215 | const struct libusb_interface_descriptor *idesc; 216 | 217 | for (i = 0; i < config->bNumInterfaces; i++) { 218 | intf = config->interface + i; 219 | for (j = 0; j < intf->num_altsetting; j++) { 220 | idesc = intf->altsetting + j; 221 | for (k = 0; k < idesc->bNumEndpoints; k++) { 222 | fill_stub_endpoint(ep + num, 223 | idesc->endpoint + k); 224 | num++; 225 | } 226 | } 227 | } 228 | } 229 | 230 | static inline 231 | int edev2num_ifs(struct usbip_exported_device *edev) 232 | { 233 | return edev->udev.bNumInterfaces; 234 | } 235 | 236 | static inline 237 | struct stub_edev_data *edev2edev_data(struct usbip_exported_device *edev) 238 | { 239 | return (struct stub_edev_data *)(edev->uinf + edev2num_ifs(edev)); 240 | } 241 | 242 | static inline 243 | int edev2num_eps(struct usbip_exported_device *edev) 244 | { 245 | struct stub_edev_data *edev_data = edev2edev_data(edev); 246 | 247 | return edev_data->num_eps; 248 | } 249 | 250 | static int count_endpoints(struct libusb_config_descriptor *config) 251 | { 252 | int i, j, num = 0; 253 | const struct libusb_interface *intf; 254 | const struct libusb_interface_descriptor *idesc; 255 | 256 | for (i = 0; i < config->bNumInterfaces; i++) { 257 | intf = config->interface + i; 258 | for (j = 0; j < intf->num_altsetting; j++) { 259 | idesc = intf->altsetting + j; 260 | num += idesc->bNumEndpoints; 261 | } 262 | } 263 | return num; 264 | } 265 | 266 | static struct usbip_exported_device *exported_device_new( 267 | libusb_device *dev, 268 | struct libusb_device_descriptor *desc) 269 | { 270 | struct libusb_config_descriptor *config; 271 | struct usbip_exported_device *edev; 272 | struct stub_edev_data *edev_data; 273 | int num_eps; 274 | int ret; 275 | 276 | ret = libusb_get_active_config_descriptor(dev, &config); 277 | if (ret != LIBUSB_SUCCESS) { 278 | err("get device config: %d", ret); 279 | goto err_out; 280 | } 281 | 282 | num_eps = count_endpoints(config); 283 | 284 | edev = (struct usbip_exported_device *)calloc(1, 285 | sizeof(struct usbip_exported_device) + 286 | (config->bNumInterfaces * 287 | sizeof(struct usbip_usb_interface)) + 288 | sizeof(struct stub_edev_data) + 289 | (num_eps * 290 | sizeof(struct stub_endpoint))); 291 | if (!edev) { 292 | err("alloc edev"); 293 | goto err_free_config; 294 | } 295 | /* 296 | edev_data = 297 | (struct stub_edev_data *)(edev->uinf + config->bNumInterfaces); 298 | */ 299 | 300 | __fill_usb_device(&edev->udev, dev, desc, config); 301 | fill_usb_interfaces(edev->uinf, config); 302 | edev_data = edev2edev_data(edev); 303 | edev_data->dev = dev; 304 | edev_data->num_eps = num_eps; 305 | fill_stub_endpoints(edev_data->eps, config); 306 | 307 | libusb_free_config_descriptor(config); 308 | return edev; 309 | 310 | err_free_config: 311 | libusb_free_config_descriptor(config); 312 | err_out: 313 | return NULL; 314 | } 315 | 316 | static void stub_device_delete(struct stub_device *sdev); 317 | 318 | static void exported_device_delete(struct usbip_exported_device *edev) 319 | { 320 | struct stub_edev_data *edev_data = edev2edev_data(edev); 321 | 322 | if (edev_data->sdev) 323 | stub_device_delete(edev_data->sdev); 324 | free(edev); 325 | } 326 | 327 | int usbip_refresh_device_list(struct usbip_exported_devices *edevs) { 328 | int num, i; 329 | libusb_device **devs, *dev; 330 | struct usbip_exported_device *edev; 331 | struct libusb_device_descriptor desc; 332 | char busid[SYSFS_BUS_ID_SIZE]; 333 | 334 | edevs->ndevs = 0; 335 | INIT_LIST_HEAD(&edevs->edev_list); 336 | edevs->data = NULL; 337 | 338 | num = libusb_get_device_list(stub_libusb_ctx, &devs); 339 | if (num < 0) { 340 | err("get device list"); 341 | goto err_out; 342 | } 343 | 344 | for (i = 0; i < num; i++) { 345 | dev = *(devs + i); 346 | get_busid(dev, busid); 347 | 348 | if (libusb_get_device_descriptor(dev, &desc)) { 349 | err("get device desc %s", busid); 350 | goto err_free_list; 351 | } 352 | if (desc.bDeviceClass == USB_CLASS_HUB) { 353 | dbg("skip hub to fill udev %s", busid); 354 | continue; 355 | } 356 | edev = exported_device_new(dev, &desc); 357 | if (!edev) { 358 | info("Unable to get device configuration for %s, skip", busid); 359 | continue; 360 | } 361 | list_add(&edev->node, &edevs->edev_list); 362 | edevs->ndevs++; 363 | } 364 | 365 | edevs->data = (void *)devs; 366 | return 0; 367 | 368 | err_free_list: 369 | libusb_free_device_list(devs, 1); 370 | err_out: 371 | return -1; 372 | } 373 | 374 | int usbip_free_device_list(struct usbip_exported_devices *edevs) { 375 | libusb_device **devs = (libusb_device **)edevs->data; 376 | struct list_head *i, *tmp; 377 | struct usbip_exported_device *edev; 378 | 379 | if (devs) 380 | libusb_free_device_list(devs, 1); 381 | 382 | list_for_each_safe(i, tmp, &edevs->edev_list) { 383 | edev = list_entry(i, struct usbip_exported_device, node); 384 | list_del(i); 385 | exported_device_delete(edev); 386 | } 387 | return 0; 388 | } 389 | 390 | struct usbip_exported_device *usbip_get_device(struct usbip_exported_devices *edevs, const char *busid) { 391 | struct list_head *i; 392 | struct usbip_exported_device *edev; 393 | 394 | list_for_each(i, &edevs->edev_list) { 395 | edev = list_entry(i, struct usbip_exported_device, node); 396 | if (!strncmp(busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) 397 | return edev; 398 | } 399 | 400 | return NULL; 401 | } 402 | 403 | static void stub_shutdown(struct usbip_device *ud) 404 | { 405 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); 406 | 407 | sdev->should_stop = 1; 408 | usbip_stop_eh(&sdev->ud); 409 | pthread_mutex_unlock(&sdev->tx_waitq); 410 | /* rx will exit by disconnect */ 411 | } 412 | 413 | static void stub_device_reset(struct usbip_device *ud) 414 | { 415 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); 416 | int ret; 417 | 418 | /* try to reset the device */ 419 | ret = libusb_reset_device(sdev->dev_handle); 420 | 421 | pthread_mutex_lock(&ud->lock); 422 | if (ret) { 423 | dev_err(sdev->dev, "device reset: %d", ret); 424 | ud->status = SDEV_ST_ERROR; 425 | } else { 426 | dev_info(sdev->dev, "device reset"); 427 | ud->status = SDEV_ST_AVAILABLE; 428 | } 429 | pthread_mutex_unlock(&ud->lock); 430 | } 431 | 432 | static void stub_device_unusable(struct usbip_device *ud) 433 | { 434 | pthread_mutex_lock(&ud->lock); 435 | ud->status = SDEV_ST_ERROR; 436 | pthread_mutex_unlock(&ud->lock); 437 | } 438 | 439 | static void init_usbip_device(struct usbip_device *ud) 440 | { 441 | ud->status = SDEV_ST_AVAILABLE; 442 | pthread_mutex_init(&ud->lock, NULL); 443 | 444 | ud->eh_ops.shutdown = stub_shutdown; 445 | ud->eh_ops.reset = stub_device_reset; 446 | ud->eh_ops.unusable = stub_device_unusable; 447 | } 448 | 449 | static void clear_usbip_device(struct usbip_device *ud) 450 | { 451 | pthread_mutex_destroy(&ud->lock); 452 | } 453 | 454 | static inline uint32_t get_devid(libusb_device *dev) 455 | { 456 | uint32_t bus_number = libusb_get_bus_number(dev); 457 | uint32_t dev_addr = libusb_get_port_number(dev); //libusb_get_device_address(dev); 458 | 459 | return (bus_number << 16) | dev_addr; 460 | } 461 | 462 | static inline struct stub_device *edev2sdev(struct usbip_exported_device *edev) 463 | { 464 | struct stub_edev_data *edev_data = edev2edev_data(edev); 465 | 466 | return edev_data->sdev; 467 | } 468 | 469 | static struct stub_device *stub_device_new(struct usbip_exported_device *edev) 470 | { 471 | struct stub_device *sdev; 472 | struct stub_edev_data *edev_data = edev2edev_data(edev); 473 | int num_ifs = edev2num_ifs(edev); 474 | int num_eps = edev2num_eps(edev); 475 | int i; 476 | 477 | sdev = (struct stub_device *)calloc(1, 478 | sizeof(struct stub_device) + 479 | (sizeof(struct stub_interface) * num_ifs) + 480 | (sizeof(struct stub_endpoint) * num_eps)); 481 | if (!sdev) { 482 | err("alloc sdev"); 483 | return NULL; 484 | } 485 | 486 | sdev->dev = edev_data->dev; 487 | memcpy(&sdev->udev, &edev->udev, sizeof(struct usbip_usb_device)); 488 | init_usbip_device(&sdev->ud); 489 | sdev->devid = get_devid(edev_data->dev); 490 | for (i = 0; i < num_ifs; i++) 491 | memcpy(&((sdev->ifs + i)->uinf), edev->uinf + i, sizeof(struct usbip_usb_interface)); 492 | sdev->num_eps = num_eps; 493 | 494 | sdev->eps = (struct stub_endpoint *)(sdev->ifs + num_ifs); 495 | for (i = 0; i < num_eps; i++) 496 | memcpy(sdev->eps + i, edev_data->eps + i, 497 | sizeof(struct stub_endpoint)); 498 | 499 | pthread_mutex_init(&sdev->priv_lock, NULL); 500 | INIT_LIST_HEAD(&sdev->priv_init); 501 | INIT_LIST_HEAD(&sdev->priv_tx); 502 | INIT_LIST_HEAD(&sdev->priv_free); 503 | INIT_LIST_HEAD(&sdev->unlink_tx); 504 | INIT_LIST_HEAD(&sdev->unlink_free); 505 | pthread_mutex_init(&sdev->tx_waitq, NULL); 506 | pthread_mutex_lock(&sdev->tx_waitq); 507 | 508 | return sdev; 509 | } 510 | 511 | static void stub_device_delete(struct stub_device *sdev) 512 | { 513 | clear_usbip_device(&sdev->ud); 514 | pthread_mutex_destroy(&sdev->priv_lock); 515 | pthread_mutex_destroy(&sdev->tx_waitq); 516 | free(sdev); 517 | } 518 | 519 | static void release_interface(libusb_device_handle *dev_handle, 520 | struct stub_interface *intf, int force) 521 | { 522 | int nr = intf->uinf.bInterfaceNumber; 523 | int ret; 524 | 525 | if (force || intf->claimed) { 526 | ret = libusb_release_interface(dev_handle, nr); 527 | if (ret == LIBUSB_SUCCESS) 528 | intf->claimed = 0; 529 | else 530 | dbg("failed to release interface %d by %d", nr, ret); 531 | } 532 | if (force || intf->detached) { 533 | ret = libusb_attach_kernel_driver(dev_handle, nr); 534 | 535 | if (ret == LIBUSB_SUCCESS || ret == LIBUSB_ERROR_NOT_FOUND || ret == LIBUSB_ERROR_NOT_SUPPORTED) 536 | intf->detached = 0; 537 | else 538 | err("failed to attach interface %d by %d", nr, ret); 539 | } 540 | } 541 | 542 | static void release_interfaces(libusb_device_handle *dev_handle, int num_ifs, 543 | struct stub_interface *intfs, int force) 544 | { 545 | int i; 546 | 547 | for (i = 0; i < num_ifs; i++) 548 | release_interface(dev_handle, intfs + i, force); 549 | } 550 | 551 | static int claim_interface(libusb_device_handle *dev_handle, 552 | struct stub_interface *intf) 553 | { 554 | int nr = intf->uinf.bInterfaceNumber; 555 | int ret; 556 | 557 | ret = libusb_detach_kernel_driver(dev_handle, nr); 558 | if (!(ret == 0 || ret == LIBUSB_ERROR_NOT_FOUND)) { 559 | dbg("failed to detach interface %d by %d", nr, ret); 560 | /* ignore error, because some platform doesn't support */ 561 | } else { 562 | intf->detached = 1; 563 | } 564 | 565 | dbg("claiming interface %d", nr); 566 | ret = libusb_claim_interface(dev_handle, nr); 567 | if (ret) { 568 | dbg("failed to claim interface %d by %d", nr, ret); 569 | release_interface(dev_handle, intf, 0); 570 | return -1; 571 | } 572 | intf->claimed = 1; 573 | return 0; 574 | } 575 | 576 | static int claim_interfaces(libusb_device_handle *dev_handle, int num_ifs, 577 | struct stub_interface *intfs) 578 | { 579 | int i; 580 | 581 | for (i = 0; i < num_ifs; i++) { 582 | if (claim_interface(dev_handle, intfs + i)) 583 | return -1; 584 | } 585 | return 0; 586 | } 587 | int usbip_export_device(struct usbip_exported_device *edev, int sock_fd) { 588 | struct stub_device *sdev; 589 | struct stub_edev_data *edev_data = edev2edev_data(edev); 590 | int ret; 591 | 592 | sdev = stub_device_new(edev); 593 | if (!sdev) 594 | goto err_out; 595 | 596 | edev_data->sdev = sdev; 597 | 598 | ret = libusb_open(sdev->dev, &sdev->dev_handle); 599 | if (ret) { 600 | if (ret == LIBUSB_ERROR_ACCESS) 601 | err("access denied to open device %s", edev->udev.busid); 602 | else 603 | err("failed to open device %s by %d", edev->udev.busid, ret); 604 | 605 | goto err_out; 606 | } 607 | 608 | if (claim_interfaces(sdev->dev_handle, sdev->udev.bNumInterfaces, sdev->ifs)) { 609 | err("claim interfaces %s", edev->udev.busid); 610 | goto err_close_lib; 611 | } 612 | 613 | sdev->ud.sock_fd = sock_fd; 614 | 615 | return 0; 616 | 617 | err_close_lib: 618 | libusb_close(sdev->dev_handle); 619 | sdev->dev_handle = NULL; 620 | err_out: 621 | return -1; 622 | } 623 | 624 | void stub_unexport_device(struct stub_device *sdev) 625 | { 626 | release_interfaces(sdev->dev_handle, sdev->udev.bNumInterfaces, 627 | sdev->ifs, 0); 628 | libusb_close(sdev->dev_handle); 629 | sdev->dev_handle = NULL; 630 | } 631 | 632 | static int stub_start(struct stub_device *sdev) 633 | { 634 | if (sdev == NULL) 635 | return 0; 636 | 637 | if (usbip_start_eh(&sdev->ud)) { 638 | err("start event handler"); 639 | return -1; 640 | } 641 | if (pthread_create(&sdev->rx, NULL, stub_rx_loop, sdev)) { 642 | err("start recv thread"); 643 | return -1; 644 | } 645 | if (pthread_create(&sdev->tx, NULL, stub_tx_loop, sdev)) { 646 | err("start send thread"); 647 | return -1; 648 | } 649 | pthread_mutex_lock(&sdev->ud.lock); 650 | sdev->ud.status = SDEV_ST_USED; 651 | pthread_mutex_unlock(&sdev->ud.lock); 652 | dbg("successfully started libusb transmission"); 653 | return 0; 654 | } 655 | 656 | static void stub_join(struct stub_device *sdev) 657 | { 658 | if (sdev == NULL) 659 | return; 660 | dbg("waiting on libusb transmission threads"); 661 | usbip_join_eh(&sdev->ud); 662 | pthread_join(sdev->tx, NULL); 663 | pthread_join(sdev->rx, NULL); 664 | } 665 | 666 | int usbip_try_transfer(struct usbip_exported_device *edev, int sock_fd) { 667 | struct stub_device *sdev = edev2sdev(edev); 668 | 669 | if (stub_start(sdev)) { 670 | err("start driver-libusb"); 671 | return -1; 672 | } 673 | stub_join(sdev); 674 | stub_device_cleanup_transfers(sdev); 675 | stub_device_cleanup_unlinks(sdev); 676 | stub_unexport_device(sdev); 677 | 678 | return 0; 679 | } 680 | 681 | 682 | -------------------------------------------------------------------------------- /include/list.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIST_H 2 | #define _LIST_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | /* Stripped down implementation of linked list taken 9 | * from the Linux Kernel. 10 | */ 11 | 12 | /* 13 | * Simple doubly linked list implementation. 14 | * 15 | * Some of the internal functions ("__xxx") are useful when 16 | * manipulating whole lists rather than single entries, as 17 | * sometimes we already know the next/prev entries and we can 18 | * generate better code by using them directly rather than 19 | * using the generic single-entry routines. 20 | */ 21 | 22 | struct list_head { 23 | struct list_head *next, *prev; 24 | }; 25 | 26 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 27 | 28 | #define LIST_HEAD(name) \ 29 | struct list_head name = LIST_HEAD_INIT(name) 30 | 31 | static inline void INIT_LIST_HEAD(struct list_head *list) 32 | { 33 | list->next = list; 34 | list->prev = list; 35 | } 36 | 37 | /* 38 | * Insert a new entry between two known consecutive entries. 39 | * 40 | * This is only for internal list manipulation where we know 41 | * the prev/next entries already! 42 | */ 43 | static inline void __list_add(struct list_head *neo, 44 | struct list_head *prev, 45 | struct list_head *next) 46 | { 47 | next->prev = neo; 48 | neo->next = next; 49 | neo->prev = prev; 50 | prev->next = neo; 51 | } 52 | 53 | /** 54 | * list_add - add a new entry 55 | * @new: new entry to be added 56 | * @head: list head to add it after 57 | * 58 | * Insert a new entry after the specified head. 59 | * This is good for implementing stacks. 60 | */ 61 | static inline void list_add(struct list_head *neo, struct list_head *head) 62 | { 63 | __list_add(neo, head, head->next); 64 | } 65 | 66 | /* 67 | * Delete a list entry by making the prev/next entries 68 | * point to each other. 69 | * 70 | * This is only for internal list manipulation where we know 71 | * the prev/next entries already! 72 | */ 73 | static inline void __list_del(struct list_head * prev, struct list_head * next) 74 | { 75 | next->prev = prev; 76 | prev->next = next; 77 | } 78 | 79 | #define POISON_POINTER_DELTA 0 80 | #define LIST_POISON1 ((char *) 0x00100100 + POISON_POINTER_DELTA) 81 | #define LIST_POISON2 ((char *) 0x00200200 + POISON_POINTER_DELTA) 82 | 83 | /** 84 | * list_del - deletes entry from list. 85 | * @entry: the element to delete from the list. 86 | * Note: list_empty() on entry does not return true after this, the entry is 87 | * in an undefined state. 88 | */ 89 | static inline void __list_del_entry(struct list_head *entry) 90 | { 91 | __list_del(entry->prev, entry->next); 92 | } 93 | 94 | static inline void list_del(struct list_head *entry) 95 | { 96 | __list_del(entry->prev, entry->next); 97 | entry->next = (struct list_head *)LIST_POISON1; 98 | entry->prev = (struct list_head *)LIST_POISON2; 99 | } 100 | 101 | /** 102 | * list_entry - get the struct for this entry 103 | * @ptr: the &struct list_head pointer. 104 | * @type: the type of the struct this is embedded in. 105 | * @member: the name of the list_head within the struct. 106 | */ 107 | #define list_entry(ptr, type, member) \ 108 | container_of(ptr, type, member) 109 | /** 110 | * list_for_each - iterate over a list 111 | * @pos: the &struct list_head to use as a loop cursor. 112 | * @head: the head for your list. 113 | */ 114 | #define list_for_each(pos, head) \ 115 | for (pos = (head)->next; pos != (head); pos = pos->next) 116 | 117 | /** 118 | * list_for_each_safe - iterate over a list safe against removal of list entry 119 | * @pos: the &struct list_head to use as a loop cursor. 120 | * @n: another &struct list_head to use as temporary storage 121 | * @head: the head for your list. 122 | */ 123 | #define list_for_each_safe(pos, n, head) \ 124 | for (pos = (head)->next, n = pos->next; pos != (head); \ 125 | pos = n, n = pos->next) 126 | 127 | /** 128 | * container_of - cast a member of a structure out to the containing structure 129 | * @ptr: the pointer to the member. 130 | * @type: the type of the container struct this is embedded in. 131 | * @member: the name of the member within the struct. 132 | * 133 | */ 134 | #ifndef USBIP_OS_HAVE_CONTAINER_OF 135 | #define container_of(ptr, type, member) ({ \ 136 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 137 | (type *)( (char *)__mptr - offsetof(type,member) );}) 138 | #endif 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /include/usbip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * usbip.h 3 | * 4 | * USBIP uapi defines and function prototypes etc. 5 | */ 6 | 7 | #ifndef _UAPI_LINUX_USBIP_H 8 | #define _UAPI_LINUX_USBIP_H 9 | 10 | 11 | /* usbip device status - exported in usbip device sysfs status */ 12 | enum usbip_device_status { 13 | /* sdev is available. */ 14 | SDEV_ST_AVAILABLE = 0x01, 15 | /* sdev is now used. */ 16 | SDEV_ST_USED, 17 | /* sdev is unusable because of a fatal error. */ 18 | SDEV_ST_ERROR, 19 | }; 20 | 21 | #endif /* _UAPI_LINUX_USBIP_H */ 22 | -------------------------------------------------------------------------------- /include/usbip_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2016 Nobuo Iwata 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef __USBIP_CONFIG_H 19 | #define __USBIP_CONFIG_H 20 | 21 | /* binary-coded decimal version number */ 22 | #define USBIP_VERSION 0x00000111 23 | 24 | /* Version number of package */ 25 | #define VERSION "2.0" 26 | 27 | /* Define to the full name and version of this package. */ 28 | #define PACKAGE_STRING "usbip-libusb 2.0" 29 | #define PACKAGE "usbipd" 30 | 31 | #define USBIDS_FILE "/usr/share/hwdata/usb.ids" 32 | #define DEFAULT_PID_FILE "/var/run/" PACKAGE ".pid" 33 | 34 | #define USBIP_OS_NO_DAEMON 35 | //#define USBIP_OS_HAVE_CONTAINER_OF // list.h config 36 | #define USBIP_OS_NO_FORK 37 | //#define USBIP_OS_NO_PTHREAD_H //TODO Just removes includes, doesn't switch anything else, might be useful in future 38 | //#define USBIP_OS_NO_POLL_H //TODO Just removes includes, doesn't switch anything else, might be useful in future 39 | //#define USBIP_OS_NO_SYS_SOCKET 40 | #define CONFIG_USBIP_DEBUG //Enable all liubusb debug messages 41 | 42 | 43 | #endif /* !__USBIP_CONFIG_H */ 44 | -------------------------------------------------------------------------------- /include/usbip_debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __USBIP_DEBUG_H__ 2 | #define __USBIP_DEBUG_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | extern int usbip_use_debug; 10 | extern unsigned long usbip_stub_debug_flags; 11 | 12 | 13 | #ifndef USBIP_OS_NO_NR_ARGS 14 | #define pr_fmt(lvl, fmt) lvl ": " fmt "\n" 15 | #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) 16 | #define dbg_fmt(lvl, fmt) pr_fmt(lvl, "%s:%d/%s: " fmt), __FILENAME__, __LINE__, __func__ 17 | 18 | #define dbg(fmt, args...) \ 19 | if (usbip_use_debug) fprintf(stdout, dbg_fmt("", fmt), ##args) 20 | 21 | #define info(fmt, args...) \ 22 | fprintf(stdout, dbg_fmt("", fmt), ##args) 23 | 24 | #define warn(fmt, args...) \ 25 | fprintf(stderr, dbg_fmt("", fmt), ##args) 26 | 27 | #define err(fmt, args...) \ 28 | fprintf(stderr, dbg_fmt("", fmt), ##args) 29 | #endif /* !USBIP_OS_NO_NR_ARGS */ 30 | 31 | #ifndef USBIP_OS_NO_NR_ARGS 32 | #define dev_pfmt(dev, lvl, fmt) dbg_fmt(lvl, ": %d-%d: " fmt), libusb_get_bus_number(dev), libusb_get_port_number(dev) 33 | 34 | #define dev_dbg(dev, fmt, args...) \ 35 | fprintf(stdout, dev_pfmt(dev, "", fmt), ##args) 36 | #define dev_info(dev, fmt, args...) \ 37 | fprintf(stdout, dev_pfmt(dev, "", fmt), ##args) 38 | #define dev_err(dev, fmt, args...) \ 39 | fprintf(stderr, dev_pfmt(dev, "", fmt), ##args) 40 | 41 | enum { 42 | usbip_debug_xmit = (1U << 0U), 43 | usbip_debug_eh = (1U << 1U), 44 | usbip_debug_stub_rx = (1U << 2U), 45 | usbip_debug_stub_tx = (1U << 3U), 46 | }; 47 | 48 | #define usbip_dbg_flag_xmit (usbip_stub_debug_flags & (unsigned)usbip_debug_xmit) 49 | #define usbip_dbg_flag_stub_rx (usbip_stub_debug_flags & usbip_debug_stub_rx) 50 | #define usbip_dbg_flag_stub_tx (usbip_debug_flag & usbip_debug_stub_tx) 51 | 52 | 53 | #define usbip_dbg_with_flag(flag, fmt, args...) \ 54 | do { \ 55 | if ((unsigned)flag & usbip_stub_debug_flags) \ 56 | dbg(fmt, ##args); \ 57 | } while (0) 58 | 59 | #define usbip_dbg_xmit(fmt, args...) \ 60 | usbip_dbg_with_flag(usbip_debug_xmit, fmt, ##args) 61 | #define usbip_dbg_eh(fmt, args...) \ 62 | usbip_dbg_with_flag(usbip_debug_eh, fmt, ##args) 63 | 64 | #define usbip_dbg_stub_rx(fmt, args...) \ 65 | usbip_dbg_with_flag(usbip_debug_stub_rx, fmt, ##args) 66 | #define usbip_dbg_stub_tx(fmt, args...) \ 67 | usbip_dbg_with_flag(usbip_debug_stub_tx, fmt, ##args) 68 | #endif /*! USBIP_OS_NO_NR_ARGS */ 69 | 70 | 71 | 72 | void dump_usb_interface(struct usbip_usb_interface *); 73 | void dump_usb_device(struct usbip_usb_device *); 74 | const char *usbip_speed_string(int num); 75 | 76 | void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, 77 | uint16_t product); 78 | 79 | void usbip_names_get_class(char *buff, size_t size, uint8_t clazz, 80 | uint8_t subclass, uint8_t protocol); 81 | 82 | void usbip_dump_buffer(void *buf, int size); 83 | 84 | #endif //__USBIP_DEBUG_H__ 85 | -------------------------------------------------------------------------------- /include/usbip_host_driver.h: -------------------------------------------------------------------------------- 1 | #ifndef __STUB_DRIVER_H__ 2 | #define __STUB_DRIVER_H__ 3 | 4 | #include 5 | #include 6 | 7 | struct usbip_exported_devices { 8 | int ndevs; 9 | struct list_head edev_list; 10 | void *data; 11 | }; 12 | 13 | struct usbip_exported_device { 14 | int32_t status; 15 | struct usbip_usb_device udev; 16 | struct list_head node; 17 | struct usbip_usb_interface uinf[]; 18 | }; 19 | 20 | /* API to be implemented by the driver */ 21 | int usbip_refresh_device_list(struct usbip_exported_devices *edevs); 22 | 23 | int usbip_free_device_list(struct usbip_exported_devices *edevs); 24 | 25 | struct usbip_exported_device *usbip_get_device(struct usbip_exported_devices *edevs, const char *busid); 26 | 27 | int usbip_export_device(struct usbip_exported_device *edev, int sock_fd); 28 | 29 | int usbip_try_transfer(struct usbip_exported_device *edev, int sock_fd); 30 | 31 | int usbip_driver_open(void); 32 | void usbip_driver_close(void); 33 | 34 | 35 | #endif //__STUB_DRIVER_H__ -------------------------------------------------------------------------------- /include/usbip_network.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2007 Takahiro Hirofuchi 3 | */ 4 | 5 | #ifndef __USBIP_NETWORK_H 6 | #define __USBIP_NETWORK_H 7 | 8 | #include "usbip_config.h" 9 | 10 | #include 11 | 12 | #include 13 | 14 | extern int usbip_port; 15 | extern char *usbip_port_string; 16 | void usbip_setup_port_number(char *arg); 17 | 18 | #ifdef __linux__ 19 | #include 20 | #elif __APPLE__ 21 | // Copied from linux/usb/ch9.h 22 | enum usb_device_speed { 23 | USB_SPEED_UNKNOWN = 0, /* enumerating */ 24 | USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ 25 | USB_SPEED_HIGH, /* usb 2.0 */ 26 | USB_SPEED_WIRELESS, /* wireless (usb 2.5) */ 27 | USB_SPEED_SUPER, /* usb 3.0 */ 28 | }; 29 | #endif 30 | 31 | #include 32 | 33 | #define SYSFS_PATH_MAX 256 34 | #define SYSFS_BUS_ID_SIZE 32 35 | 36 | struct usbip_usb_interface { 37 | uint8_t bInterfaceClass; 38 | uint8_t bInterfaceSubClass; 39 | uint8_t bInterfaceProtocol; 40 | uint8_t bInterfaceNumber; //TODO in original implementation: uint8_t padding; /* alignment */ 41 | } __attribute__((packed)); 42 | 43 | struct usbip_usb_device { 44 | char path[SYSFS_PATH_MAX]; 45 | char busid[SYSFS_BUS_ID_SIZE]; 46 | 47 | uint32_t busnum; 48 | uint32_t devnum; 49 | uint32_t speed; 50 | 51 | uint16_t idVendor; 52 | uint16_t idProduct; 53 | uint16_t bcdDevice; 54 | 55 | uint8_t bDeviceClass; 56 | uint8_t bDeviceSubClass; 57 | uint8_t bDeviceProtocol; 58 | uint8_t bConfigurationValue; 59 | uint8_t bNumConfigurations; 60 | uint8_t bNumInterfaces; 61 | } __attribute__((packed)); 62 | 63 | 64 | /* ---------------------------------------------------------------------- */ 65 | /* Common header for all the kinds of PDUs. */ 66 | struct op_common { 67 | uint16_t version; 68 | uint16_t code; 69 | uint32_t status; /* op_code status (for reply) */ 70 | } __attribute__((packed)); 71 | 72 | #define OP_REQUEST (0x80 << 8) 73 | #define OP_REPLY (0x00 << 8) 74 | 75 | /* add more error code */ 76 | #define ST_OK 0x00 77 | #define ST_NA 0x01 78 | #define ST_NO_FREE_PORT 0x02 79 | #define ST_DEVICE_NOT_FOUND 0x03 80 | 81 | /* ---------------------------------------------------------------------- */ 82 | /* Dummy Code */ 83 | #define OP_UNSPEC 0x00 84 | 85 | /* ---------------------------------------------------------------------- */ 86 | /* Import a remote USB device. */ 87 | #define OP_IMPORT 0x03 88 | #define OP_REQ_IMPORT (OP_REQUEST | OP_IMPORT) 89 | #define OP_REP_IMPORT (OP_REPLY | OP_IMPORT) 90 | 91 | struct op_import_request { 92 | char busid[SYSFS_BUS_ID_SIZE]; 93 | } __attribute__((packed)); 94 | 95 | 96 | #define PACK_OP_IMPORT_REQUEST(pack, request) do {\ 97 | } while (0) 98 | 99 | #define PACK_OP_IMPORT_REPLY(pack, reply) do {\ 100 | if (pack) { \ 101 | reply.busnum = htonl(reply.busnum); \ 102 | reply.devnum = htonl(reply.devnum); \ 103 | reply.speed = htonl(reply.speed); \ 104 | reply.idVendor = htons(reply.idVendor); \ 105 | reply.idProduct = htons(reply.idProduct); \ 106 | reply.bcdDevice = htons(reply.bcdDevice); \ 107 | } else { \ 108 | reply.busnum = ntohl(reply.busnum); \ 109 | reply.devnum = ntohl(reply.devnum); \ 110 | reply.speed = ntohl(reply.speed); \ 111 | reply.idVendor = ntohs(reply.idVendor); \ 112 | reply.idProduct = ntohs(reply.idProduct); \ 113 | reply.bcdDevice = ntohs(reply.bcdDevice); \ 114 | } \ 115 | } while (0) 116 | 117 | 118 | /* ---------------------------------------------------------------------- */ 119 | /* Retrieve the list of exported USB devices. */ 120 | #define OP_DEVLIST 0x05 121 | #define OP_REQ_DEVLIST (OP_REQUEST | OP_DEVLIST) 122 | #define OP_REP_DEVLIST (OP_REPLY | OP_DEVLIST) 123 | 124 | struct op_devlist_reply { 125 | uint32_t ndev; 126 | /* followed by op_devlist_reply_extra[] */ 127 | } __attribute__((packed)); 128 | 129 | /* 130 | struct op_devlist_reply_extra { 131 | struct usbip_usb_device udev; 132 | struct usbip_usb_interface uinf[]; 133 | } __attribute__((packed)); 134 | */ 135 | 136 | 137 | ssize_t usbip_net_recv(int sock_fd, void *buff, size_t bufflen); 138 | ssize_t usbip_net_send(int sock_fd, void *buff, size_t bufflen); 139 | int usbip_net_send_op_common(int sock_fd, uint32_t code, uint32_t status); 140 | int usbip_net_recv_op_common(int sock_fd, uint16_t *code); 141 | int usbip_net_set_reuseaddr(int sockfd); 142 | int usbip_net_set_nodelay(int sockfd); 143 | int usbip_net_set_keepalive(int sockfd); 144 | int usbip_net_set_v6only(int sockfd); 145 | const char *usbip_net_gai_strerror(int errcode); 146 | 147 | #endif /* __USBIP_NETWORK_H */ 148 | -------------------------------------------------------------------------------- /src/names.c: -------------------------------------------------------------------------------- 1 | /* 2 | * names.c -- USB name database manipulation routines 3 | * 4 | * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * 20 | * 21 | * 22 | * 23 | * 24 | * Copyright (C) 2005 Takahiro Hirofuchi 25 | * - names_deinit() is added. 26 | * 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #include "names.h" 39 | 40 | struct vendor { 41 | struct vendor *next; 42 | u_int16_t vendorid; 43 | char name[1]; 44 | }; 45 | 46 | struct product { 47 | struct product *next; 48 | u_int16_t vendorid, productid; 49 | char name[1]; 50 | }; 51 | 52 | struct clazz { 53 | struct clazz *next; 54 | u_int8_t classid; 55 | char name[1]; 56 | }; 57 | 58 | struct subclass { 59 | struct subclass *next; 60 | u_int8_t classid, subclassid; 61 | char name[1]; 62 | }; 63 | 64 | struct protocol { 65 | struct protocol *next; 66 | u_int8_t classid, subclassid, protocolid; 67 | char name[1]; 68 | }; 69 | 70 | struct genericstrtable { 71 | struct genericstrtable *next; 72 | unsigned int num; 73 | char name[1]; 74 | }; 75 | 76 | 77 | #define HASH1 0x10 78 | #define HASH2 0x02 79 | #define HASHSZ 16 80 | 81 | static unsigned int hashnum(unsigned int num) 82 | { 83 | unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27; 84 | 85 | for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1) 86 | if (num & mask1) 87 | num ^= mask2; 88 | return num & (HASHSZ-1); 89 | } 90 | 91 | 92 | static struct vendor *vendors[HASHSZ] = { NULL, }; 93 | static struct product *products[HASHSZ] = { NULL, }; 94 | static struct clazz *classes[HASHSZ] = { NULL, }; 95 | static struct subclass *subclasses[HASHSZ] = { NULL, }; 96 | static struct protocol *protocols[HASHSZ] = { NULL, }; 97 | 98 | const char *names_vendor(u_int16_t vendorid) 99 | { 100 | struct vendor *v; 101 | 102 | v = vendors[hashnum(vendorid)]; 103 | for (; v; v = v->next) 104 | if (v->vendorid == vendorid) 105 | return v->name; 106 | return NULL; 107 | } 108 | 109 | const char *names_product(u_int16_t vendorid, u_int16_t productid) 110 | { 111 | struct product *p; 112 | 113 | p = products[hashnum((vendorid << 16) | productid)]; 114 | for (; p; p = p->next) 115 | if (p->vendorid == vendorid && p->productid == productid) 116 | return p->name; 117 | return NULL; 118 | } 119 | 120 | const char *names_class(u_int8_t classid) 121 | { 122 | struct clazz *c; 123 | 124 | c = classes[hashnum(classid)]; 125 | for (; c; c = c->next) 126 | if (c->classid == classid) 127 | return c->name; 128 | return NULL; 129 | } 130 | 131 | const char *names_subclass(u_int8_t classid, u_int8_t subclassid) 132 | { 133 | struct subclass *s; 134 | 135 | s = subclasses[hashnum((classid << 8) | subclassid)]; 136 | for (; s; s = s->next) 137 | if (s->classid == classid && s->subclassid == subclassid) 138 | return s->name; 139 | return NULL; 140 | } 141 | 142 | const char *names_protocol(u_int8_t classid, u_int8_t subclassid, 143 | u_int8_t protocolid) 144 | { 145 | struct protocol *p; 146 | 147 | p = protocols[hashnum((classid << 16) | (subclassid << 8) 148 | | protocolid)]; 149 | for (; p; p = p->next) 150 | if (p->classid == classid && p->subclassid == subclassid && 151 | p->protocolid == protocolid) 152 | return p->name; 153 | return NULL; 154 | } 155 | 156 | /* add a cleanup function by takahiro */ 157 | struct pool { 158 | struct pool *next; 159 | void *mem; 160 | }; 161 | 162 | static struct pool *pool_head; 163 | 164 | static void *my_malloc(size_t size) 165 | { 166 | struct pool *p; 167 | 168 | p = calloc(1, sizeof(struct pool)); 169 | if (!p) 170 | return NULL; 171 | 172 | p->mem = calloc(1, size); 173 | if (!p->mem) { 174 | free(p); 175 | return NULL; 176 | } 177 | 178 | p->next = pool_head; 179 | pool_head = p; 180 | 181 | return p->mem; 182 | } 183 | 184 | void names_free(void) 185 | { 186 | struct pool *pool; 187 | 188 | if (!pool_head) 189 | return; 190 | 191 | for (pool = pool_head; pool != NULL; ) { 192 | struct pool *tmp; 193 | 194 | if (pool->mem) 195 | free(pool->mem); 196 | 197 | tmp = pool; 198 | pool = pool->next; 199 | free(tmp); 200 | } 201 | } 202 | 203 | static int new_vendor(const char *name, u_int16_t vendorid) 204 | { 205 | struct vendor *v; 206 | unsigned int h = hashnum(vendorid); 207 | 208 | v = vendors[h]; 209 | for (; v; v = v->next) 210 | if (v->vendorid == vendorid) 211 | return -1; 212 | v = my_malloc(sizeof(struct vendor) + strlen(name)); 213 | if (!v) 214 | return -1; 215 | strcpy(v->name, name); 216 | v->vendorid = vendorid; 217 | v->next = vendors[h]; 218 | vendors[h] = v; 219 | return 0; 220 | } 221 | 222 | static int new_product(const char *name, u_int16_t vendorid, 223 | u_int16_t productid) 224 | { 225 | struct product *p; 226 | unsigned int h = hashnum((vendorid << 16) | productid); 227 | 228 | p = products[h]; 229 | for (; p; p = p->next) 230 | if (p->vendorid == vendorid && p->productid == productid) 231 | return -1; 232 | p = my_malloc(sizeof(struct product) + strlen(name)); 233 | if (!p) 234 | return -1; 235 | strcpy(p->name, name); 236 | p->vendorid = vendorid; 237 | p->productid = productid; 238 | p->next = products[h]; 239 | products[h] = p; 240 | return 0; 241 | } 242 | 243 | static int new_class(const char *name, u_int8_t classid) 244 | { 245 | struct clazz *c; 246 | unsigned int h = hashnum(classid); 247 | 248 | c = classes[h]; 249 | for (; c; c = c->next) 250 | if (c->classid == classid) 251 | return -1; 252 | c = my_malloc(sizeof(struct clazz) + strlen(name)); 253 | if (!c) 254 | return -1; 255 | strcpy(c->name, name); 256 | c->classid = classid; 257 | c->next = classes[h]; 258 | classes[h] = c; 259 | return 0; 260 | } 261 | 262 | static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid) 263 | { 264 | struct subclass *s; 265 | unsigned int h = hashnum((classid << 8) | subclassid); 266 | 267 | s = subclasses[h]; 268 | for (; s; s = s->next) 269 | if (s->classid == classid && s->subclassid == subclassid) 270 | return -1; 271 | s = my_malloc(sizeof(struct subclass) + strlen(name)); 272 | if (!s) 273 | return -1; 274 | strcpy(s->name, name); 275 | s->classid = classid; 276 | s->subclassid = subclassid; 277 | s->next = subclasses[h]; 278 | subclasses[h] = s; 279 | return 0; 280 | } 281 | 282 | static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, 283 | u_int8_t protocolid) 284 | { 285 | struct protocol *p; 286 | unsigned int h = hashnum((classid << 16) | (subclassid << 8) 287 | | protocolid); 288 | 289 | p = protocols[h]; 290 | for (; p; p = p->next) 291 | if (p->classid == classid && p->subclassid == subclassid 292 | && p->protocolid == protocolid) 293 | return -1; 294 | p = my_malloc(sizeof(struct protocol) + strlen(name)); 295 | if (!p) 296 | return -1; 297 | strcpy(p->name, name); 298 | p->classid = classid; 299 | p->subclassid = subclassid; 300 | p->protocolid = protocolid; 301 | p->next = protocols[h]; 302 | protocols[h] = p; 303 | return 0; 304 | } 305 | 306 | static void parse(FILE *f) 307 | { 308 | char buf[512], *cp; 309 | unsigned int linectr = 0; 310 | int lastvendor = -1; 311 | int lastclass = -1; 312 | int lastsubclass = -1; 313 | int lasthut = -1; 314 | int lastlang = -1; 315 | unsigned int u; 316 | 317 | while (fgets(buf, sizeof(buf), f)) { 318 | linectr++; 319 | /* remove line ends */ 320 | cp = strchr(buf, '\r'); 321 | if (cp) 322 | *cp = 0; 323 | cp = strchr(buf, '\n'); 324 | if (cp) 325 | *cp = 0; 326 | if (buf[0] == '#' || !buf[0]) 327 | continue; 328 | cp = buf; 329 | if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && 330 | buf[3] == 'S' && buf[4] == 'D' && 331 | buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ 332 | buf[7] == ' ') { 333 | continue; 334 | } 335 | if (buf[0] == 'P' && buf[1] == 'H' && 336 | buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') { 337 | continue; 338 | } 339 | if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && 340 | buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') { 341 | continue; 342 | } 343 | if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') { 344 | lasthut = lastclass = lastvendor = lastsubclass = -1; 345 | /* 346 | * set 1 as pseudo-id to indicate that the parser is 347 | * in a `L' section. 348 | */ 349 | lastlang = 1; 350 | continue; 351 | } 352 | if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') { 353 | /* class spec */ 354 | cp = buf+2; 355 | while (isspace(*cp)) 356 | cp++; 357 | if (!isxdigit(*cp)) { 358 | err("Invalid class spec at line %u", linectr); 359 | continue; 360 | } 361 | u = strtoul(cp, &cp, 16); 362 | while (isspace(*cp)) 363 | cp++; 364 | if (!*cp) { 365 | err("Invalid class spec at line %u", linectr); 366 | continue; 367 | } 368 | if (new_class(cp, u)) 369 | err("Duplicate class spec at line %u class %04x %s", 370 | linectr, u, cp); 371 | dbg("line %5u class %02x %s", linectr, u, cp); 372 | lasthut = lastlang = lastvendor = lastsubclass = -1; 373 | lastclass = u; 374 | continue; 375 | } 376 | if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) { 377 | /* audio terminal type spec */ 378 | continue; 379 | } 380 | if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' 381 | && isspace(buf[3])) { 382 | /* HID Descriptor bCountryCode */ 383 | continue; 384 | } 385 | if (isxdigit(*cp)) { 386 | /* vendor */ 387 | u = strtoul(cp, &cp, 16); 388 | while (isspace(*cp)) 389 | cp++; 390 | if (!*cp) { 391 | err("Invalid vendor spec at line %u", linectr); 392 | continue; 393 | } 394 | if (new_vendor(cp, u)) 395 | err("Duplicate vendor spec at line %u vendor %04x %s", 396 | linectr, u, cp); 397 | dbg("line %5u vendor %04x %s", linectr, u, cp); 398 | lastvendor = u; 399 | lasthut = lastlang = lastclass = lastsubclass = -1; 400 | continue; 401 | } 402 | if (buf[0] == '\t' && isxdigit(buf[1])) { 403 | /* product or subclass spec */ 404 | u = strtoul(buf+1, &cp, 16); 405 | while (isspace(*cp)) 406 | cp++; 407 | if (!*cp) { 408 | err("Invalid product/subclass spec at line %u", 409 | linectr); 410 | continue; 411 | } 412 | if (lastvendor != -1) { 413 | if (new_product(cp, lastvendor, u)) 414 | err("Duplicate product spec at line %u product %04x:%04x %s", 415 | linectr, lastvendor, u, cp); 416 | dbg("line %5u product %04x:%04x %s", linectr, 417 | lastvendor, u, cp); 418 | continue; 419 | } 420 | if (lastclass != -1) { 421 | if (new_subclass(cp, lastclass, u)) 422 | err("Duplicate subclass spec at line %u class %02x:%02x %s", 423 | linectr, lastclass, u, cp); 424 | dbg("line %5u subclass %02x:%02x %s", linectr, 425 | lastclass, u, cp); 426 | lastsubclass = u; 427 | continue; 428 | } 429 | if (lasthut != -1) { 430 | /* do not store hut */ 431 | continue; 432 | } 433 | if (lastlang != -1) { 434 | /* do not store langid */ 435 | continue; 436 | } 437 | err("Product/Subclass spec without prior Vendor/Class spec at line %u", 438 | linectr); 439 | continue; 440 | } 441 | if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) { 442 | /* protocol spec */ 443 | u = strtoul(buf+2, &cp, 16); 444 | while (isspace(*cp)) 445 | cp++; 446 | if (!*cp) { 447 | err("Invalid protocol spec at line %u", 448 | linectr); 449 | continue; 450 | } 451 | if (lastclass != -1 && lastsubclass != -1) { 452 | if (new_protocol(cp, lastclass, lastsubclass, 453 | u)) 454 | err("Duplicate protocol spec at line %u class %02x:%02x:%02x %s", 455 | linectr, lastclass, lastsubclass, 456 | u, cp); 457 | dbg("line %5u protocol %02x:%02x:%02x %s", 458 | linectr, lastclass, lastsubclass, u, cp); 459 | continue; 460 | } 461 | err("Protocol spec without prior Class and Subclass spec at line %u", 462 | linectr); 463 | continue; 464 | } 465 | if (buf[0] == 'H' && buf[1] == 'I' && 466 | buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') { 467 | continue; 468 | } 469 | if (buf[0] == 'H' && buf[1] == 'U' && 470 | buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') { 471 | lastlang = lastclass = lastvendor = lastsubclass = -1; 472 | /* 473 | * set 1 as pseudo-id to indicate that the parser is 474 | * in a `HUT' section. 475 | */ 476 | lasthut = 1; 477 | continue; 478 | } 479 | if (buf[0] == 'R' && buf[1] == ' ') 480 | continue; 481 | 482 | if (buf[0] == 'V' && buf[1] == 'T') 483 | continue; 484 | 485 | err("Unknown line at line %u", linectr); 486 | } 487 | } 488 | 489 | 490 | int names_init(char *n) 491 | { 492 | FILE *f; 493 | 494 | f = fopen(n, "r"); 495 | if (!f) 496 | return errno; 497 | 498 | parse(f); 499 | fclose(f); 500 | return 0; 501 | } 502 | -------------------------------------------------------------------------------- /src/names.h: -------------------------------------------------------------------------------- 1 | /* 2 | * names.h -- USB name database manipulation routines 3 | * 4 | * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * 20 | * 21 | * 22 | * Copyright (C) 2005 Takahiro Hirofuchi 23 | * - names_free() is added. 24 | */ 25 | 26 | #ifndef _NAMES_H 27 | #define _NAMES_H 28 | 29 | #include 30 | 31 | /* used by usbip_common.c */ 32 | extern const char *names_vendor(u_int16_t vendorid); 33 | extern const char *names_product(u_int16_t vendorid, u_int16_t productid); 34 | extern const char *names_class(u_int8_t classid); 35 | extern const char *names_subclass(u_int8_t classid, u_int8_t subclassid); 36 | extern const char *names_protocol(u_int8_t classid, u_int8_t subclassid, 37 | u_int8_t protocolid); 38 | extern int names_init(char *n); 39 | extern void names_free(void); 40 | 41 | #endif /* _NAMES_H */ 42 | -------------------------------------------------------------------------------- /src/usbip_debug.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "names.h" 5 | 6 | #include 7 | #include 8 | 9 | 10 | int usbip_use_debug; 11 | 12 | #ifdef CONFIG_USBIP_DEBUG 13 | unsigned long usbip_stub_debug_flags; 14 | #else 15 | unsigned long usbip_stub_debug_flags; 16 | #endif 17 | 18 | #define to_string(s) #s 19 | 20 | struct speed_string { 21 | int num; 22 | char *speed; 23 | char *desc; 24 | }; 25 | 26 | static const struct speed_string speed_strings[] = { 27 | { USB_SPEED_UNKNOWN, "unknown", "Unknown Speed"}, 28 | { USB_SPEED_LOW, "1.5", "Low Speed(1.5Mbps)" }, 29 | { USB_SPEED_FULL, "12", "Full Speed(12Mbps)" }, 30 | { USB_SPEED_HIGH, "480", "High Speed(480Mbps)" }, 31 | { USB_SPEED_WIRELESS, "53.3-480", "Wireless"}, 32 | { USB_SPEED_SUPER, "5000", "Super Speed(5000Mbps)" }, 33 | { 0, NULL, NULL } 34 | }; 35 | 36 | 37 | const char *usbip_speed_string(int num) 38 | { 39 | int i; 40 | 41 | for (i = 0; speed_strings[i].speed != NULL; i++) 42 | if (speed_strings[i].num == num) 43 | return speed_strings[i].desc; 44 | 45 | return "Unknown Speed"; 46 | } 47 | 48 | 49 | #define DBG_UDEV_INTEGER(name)\ 50 | dbg("%-20s = %x", to_string(name), (int) udev->name) 51 | 52 | #define DBG_UINF_INTEGER(name)\ 53 | dbg("%-20s = %x", to_string(name), (int) uinf->name) 54 | 55 | void dump_usb_interface(struct usbip_usb_interface *uinf) 56 | { 57 | char buff[100]; 58 | 59 | usbip_names_get_class(buff, sizeof(buff), 60 | uinf->bInterfaceClass, 61 | uinf->bInterfaceSubClass, 62 | uinf->bInterfaceProtocol); 63 | dbg("%-20s = %s", "Interface(C/SC/P)", buff); 64 | } 65 | 66 | void dump_usb_device(struct usbip_usb_device *udev) 67 | { 68 | char buff[100]; 69 | 70 | dbg("%-20s = %s", "path", udev->path); 71 | dbg("%-20s = %s", "busid", udev->busid); 72 | 73 | usbip_names_get_class(buff, sizeof(buff), 74 | udev->bDeviceClass, 75 | udev->bDeviceSubClass, 76 | udev->bDeviceProtocol); 77 | dbg("%-20s = %s", "Device(C/SC/P)", buff); 78 | 79 | DBG_UDEV_INTEGER(bcdDevice); 80 | 81 | usbip_names_get_product(buff, sizeof(buff), 82 | udev->idVendor, 83 | udev->idProduct); 84 | dbg("%-20s = %s", "Vendor/Product", buff); 85 | 86 | DBG_UDEV_INTEGER(bNumConfigurations); 87 | DBG_UDEV_INTEGER(bNumInterfaces); 88 | 89 | dbg("%-20s = %s", "speed", 90 | usbip_speed_string(udev->speed)); 91 | 92 | DBG_UDEV_INTEGER(busnum); 93 | DBG_UDEV_INTEGER(devnum); 94 | } 95 | 96 | void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, 97 | uint16_t product) 98 | { 99 | const char *prod, *vend; 100 | 101 | prod = names_product(vendor, product); 102 | if (!prod) 103 | prod = "unknown product"; 104 | 105 | 106 | vend = names_vendor(vendor); 107 | if (!vend) 108 | vend = "unknown vendor"; 109 | 110 | snprintf(buff, size, "%s : %s (%04x:%04x)", vend, prod, vendor, product); 111 | } 112 | 113 | void usbip_names_get_class(char *buff, size_t size, uint8_t clazz, 114 | uint8_t subclass, uint8_t protocol) 115 | { 116 | const char *c, *s, *p; 117 | 118 | if (clazz == 0 && subclass == 0 && protocol == 0) { 119 | snprintf(buff, size, 120 | "(Defined at Interface level) (%02x/%02x/%02x)", clazz, subclass, protocol); 121 | return; 122 | } 123 | 124 | p = names_protocol(clazz, subclass, protocol); 125 | if (!p) 126 | p = "unknown protocol"; 127 | 128 | s = names_subclass(clazz, subclass); 129 | if (!s) 130 | s = "unknown subclass"; 131 | 132 | c = names_class(clazz); 133 | if (!c) 134 | c = "unknown class"; 135 | 136 | snprintf(buff, size, "%s / %s / %s (%02x/%02x/%02x)", c, s, p, clazz, subclass, protocol); 137 | } 138 | 139 | 140 | void usbip_dump_buffer(void *buf, int size){ 141 | unsigned i, j, k; 142 | unsigned char *pbuf = buf; 143 | 144 | for (i=0; i 126)) { 158 | printf("."); 159 | } else { 160 | printf("%c", pbuf[i + j]); 161 | } 162 | } 163 | } 164 | } 165 | printf("\n" ); 166 | } -------------------------------------------------------------------------------- /src/usbip_network.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * Copyright (C) 2015-2016 Nobuo Iwata 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "usbip_config.h" 29 | 30 | #include "usbip_network.h" 31 | 32 | int usbip_port = 3240; 33 | char *usbip_port_string = "3240"; 34 | 35 | void usbip_setup_port_number(char *arg) 36 | { 37 | char *end; 38 | unsigned long int port = strtoul(arg, &end, 10); 39 | 40 | dbg("parsing port arg '%s'", arg); 41 | if (end == arg) { 42 | err("port: could not parse '%s' as a decimal integer", arg); 43 | return; 44 | } 45 | 46 | if (*end != '\0') { 47 | err("port: garbage at end of '%s'", arg); 48 | return; 49 | } 50 | 51 | if (port > UINT16_MAX) { 52 | err("port: %s too high (max=%d)", 53 | arg, UINT16_MAX); 54 | return; 55 | } 56 | 57 | usbip_port = port; 58 | usbip_port_string = arg; 59 | info("using port %d (\"%s\")", usbip_port, usbip_port_string); 60 | } 61 | 62 | ssize_t usbip_net_recv(int sock_fd, void *buff, size_t bufflen) { 63 | size_t recvd = 0; 64 | 65 | while(recvd != bufflen) { 66 | int ret = recv(sock_fd, (char *)buff + recvd, bufflen - recvd, MSG_WAITALL); 67 | if (ret <= 0) { 68 | return ret; 69 | } 70 | 71 | recvd += ret; 72 | } 73 | 74 | return recvd; 75 | } 76 | 77 | ssize_t usbip_net_send(int sock_fd, void *buff, size_t bufflen) { 78 | ssize_t total = 0; 79 | 80 | while (bufflen > 0) { 81 | ssize_t ret = send(sock_fd, buff, bufflen, 0); 82 | 83 | if (ret <= 0) { 84 | return -1; 85 | } 86 | 87 | buff = (void *)((intptr_t) buff + ret); 88 | bufflen -= ret; 89 | total += ret; 90 | } 91 | 92 | return total; 93 | } 94 | 95 | int usbip_net_send_op_common(int sock_fd, 96 | uint32_t code, uint32_t status) 97 | { 98 | struct op_common op_common; 99 | int rc; 100 | 101 | memset(&op_common, 0, sizeof(op_common)); 102 | 103 | op_common.version = htons(USBIP_VERSION); 104 | op_common.code = htons(code); 105 | op_common.status = htonl(status); 106 | 107 | rc = usbip_net_send(sock_fd, &op_common, sizeof(op_common)); 108 | if (rc < 0) { 109 | dbg("usbip_net_send failed: %d", rc); 110 | return -1; 111 | } 112 | 113 | return 0; 114 | } 115 | 116 | struct op_common_error { 117 | uint32_t status; 118 | const char *str; 119 | }; 120 | 121 | struct op_common_error op_common_errors[] = { 122 | {ST_NA, "not available"}, 123 | {ST_NO_FREE_PORT, "no free port"}, 124 | {ST_DEVICE_NOT_FOUND, "device not found"}, 125 | {0, NULL} 126 | }; 127 | 128 | static const char *op_common_strerror(uint32_t status) 129 | { 130 | struct op_common_error *err; 131 | 132 | for (err = op_common_errors; err->str != NULL; err++) { 133 | if (err->status == status) 134 | return err->str; 135 | } 136 | return "unknown error"; 137 | } 138 | 139 | int usbip_net_recv_op_common(int sock_fd, uint16_t *code) 140 | { 141 | struct op_common op_common; 142 | int rc; 143 | 144 | memset(&op_common, 0, sizeof(op_common)); 145 | 146 | rc = usbip_net_recv(sock_fd, &op_common, sizeof(op_common)); 147 | if (rc < 0) { 148 | dbg("usbip_net_recv failed: %d", rc); 149 | goto err; 150 | } 151 | 152 | op_common.version = ntohs(op_common.version); 153 | op_common.code = ntohs(op_common.code); 154 | op_common.status = ntohl(op_common.status); 155 | 156 | if (op_common.version != USBIP_VERSION) { 157 | dbg("version mismatch: %d %d", op_common.version, USBIP_VERSION); 158 | goto err; 159 | } 160 | 161 | switch (*code) { 162 | case OP_UNSPEC: 163 | break; 164 | default: 165 | if (op_common.code != *code) { 166 | dbg("unexpected pdu %#0x for %#0x", op_common.code, 167 | *code); 168 | goto err; 169 | } 170 | } 171 | 172 | if (op_common.status != ST_OK) { 173 | dbg("request failed at peer: %s", 174 | op_common_strerror(op_common.status)); 175 | goto err; 176 | } 177 | 178 | *code = op_common.code; 179 | 180 | return 0; 181 | err: 182 | return -1; 183 | } 184 | 185 | int usbip_net_set_reuseaddr(int sockfd) 186 | { 187 | const int val = 1; 188 | int ret; 189 | 190 | ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 191 | if (ret < 0) 192 | dbg("setsockopt: SO_REUSEADDR"); 193 | 194 | return ret; 195 | } 196 | 197 | int usbip_net_set_nodelay(int sockfd) 198 | { 199 | const int val = 1; 200 | int ret; 201 | 202 | ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); 203 | if (ret < 0) 204 | dbg("setsockopt: TCP_NODELAY"); 205 | 206 | return ret; 207 | } 208 | 209 | int usbip_net_set_keepalive(int sockfd) 210 | { 211 | const int val = 1; 212 | int ret; 213 | 214 | ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); 215 | if (ret < 0) 216 | dbg("setsockopt: SO_KEEPALIVE"); 217 | 218 | return ret; 219 | } 220 | 221 | int usbip_net_set_v6only(int sockfd) 222 | { 223 | const int val = 1; 224 | int ret; 225 | 226 | ret = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &val, 227 | sizeof(val)); 228 | if (ret < 0) 229 | dbg("setsockopt: IPV6_V6ONLY"); 230 | 231 | return ret; 232 | } 233 | 234 | 235 | static const char *gai_unknown_error = "?"; 236 | 237 | const char *usbip_net_gai_strerror(int errcode) 238 | { 239 | const char *s; 240 | 241 | s = gai_strerror(errcode); 242 | if (s == NULL) 243 | return gai_unknown_error; 244 | return s; 245 | } 246 | -------------------------------------------------------------------------------- /src/usbipd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * Copyright (C) 2015-2016 Samsung Electronics 5 | * Igor Kotrasinski 6 | * Krzysztof Opasiak 7 | * Copyright (C) 2015-2016 Nobuo Iwata 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | */ 22 | 23 | #include "usbip_config.h" 24 | 25 | #define _GNU_SOURCE // Reqired for ppoll(..) 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | #ifndef USBIP_OS_NO_POLL_H 38 | 39 | #include 40 | 41 | #endif 42 | 43 | #ifndef USBIP_OS_NO_PTHREAD_H 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #endif 51 | 52 | #include "usbip_network.h" 53 | #include "usbipd_requests.h" 54 | #include "list.h" 55 | #include "names.h" 56 | 57 | #define MAXSOCKFD 20 58 | 59 | #define MAIN_LOOP_TIMEOUT 10 60 | 61 | static const char usbipd_help_string[] = 62 | "usage: " PACKAGE " [options]\n" 63 | "\n" 64 | " -4, --ipv4\n" 65 | " Bind to IPv4. Default is both.\n" 66 | "\n" 67 | " -6, --ipv6\n" 68 | " Bind to IPv6. Default is both.\n" 69 | #ifndef USBIP_DAEMON_APP 70 | "\n" 71 | " -e, --device\n" 72 | " Run in device mode.\n" 73 | " Rather than drive an attached device, create\n" 74 | " a virtual UDC to bind gadgets to.\n" 75 | #endif 76 | "\n" 77 | " -D, --daemon\n" 78 | " Run as a daemon process.\n" 79 | "\n" 80 | " -d, --debug\n" 81 | " Print debugging information.\n" 82 | "\n" 83 | " -fHEX, --debug-flags HEX\n" 84 | " Print flags for driver-libusb debugging.\n" 85 | "\n" 86 | " -PFILE, --pid FILE\n" 87 | " Write process id to FILE.\n" 88 | " If no FILE specified, use " DEFAULT_PID_FILE ".\n" 89 | "\n" 90 | " -tPORT, --tcp-port PORT\n" 91 | " Listen on TCP/IP port PORT.\n" 92 | "\n" 93 | " -h, --help\n" 94 | " Print this help.\n" 95 | "\n" 96 | " -v, --version\n" 97 | " Show version.\n"; 98 | 99 | static void usbipd_help(void) { 100 | printf(usbipd_help_string); 101 | } 102 | 103 | int usbipd_recv_pdu(int sock_fd, const char *host, const char *port) { 104 | uint16_t code = OP_UNSPEC; 105 | int ret; 106 | struct usbipd_recv_pdu_op *op; 107 | 108 | ret = usbip_net_recv_op_common(sock_fd, &code); 109 | if (ret < 0) { 110 | dbg("could not receive opcode: %#0x", code); 111 | return -1; 112 | } 113 | 114 | info("received request: %#0x(%d)", code, sock_fd); 115 | for (op = usbipd_recv_pdu_ops; op->code != OP_UNSPEC; op++) { 116 | if (op->code == code) { 117 | if (op->proc) 118 | ret = (*(op->proc))(sock_fd, host, port); 119 | else { 120 | err("received an unsupported opcode: %#0x", 121 | code); 122 | ret = -1; 123 | } 124 | break; 125 | } 126 | } 127 | if (op->code == OP_UNSPEC) { 128 | err("received an unknown opcode: %#0x", code); 129 | ret = -1; 130 | } 131 | 132 | if (ret == 0) 133 | info("request %#0x(%d): complete", code, sock_fd); 134 | else 135 | info("request %#0x(%d): failed", code, sock_fd); 136 | 137 | return ret; 138 | } 139 | 140 | static int do_accept(int listenfd, char *host, int host_len, 141 | char *port, int port_len) { 142 | int connfd; 143 | struct sockaddr_storage ss; 144 | socklen_t len = sizeof(ss); 145 | int rc; 146 | 147 | memset(&ss, 0, sizeof(ss)); 148 | 149 | connfd = accept(listenfd, (struct sockaddr *) &ss, &len); 150 | if (connfd < 0) { 151 | err("failed to accept connection"); 152 | return -1; 153 | } 154 | 155 | rc = getnameinfo((struct sockaddr *) &ss, len, host, host_len, 156 | port, port_len, NI_NUMERICHOST | NI_NUMERICSERV); 157 | if (rc) 158 | err("getnameinfo: %s", usbip_net_gai_strerror(rc)); 159 | 160 | info("connection from %s:%s", host, port); 161 | 162 | /* should set TCP_NODELAY for usbip */ 163 | usbip_net_set_nodelay(connfd); 164 | 165 | return connfd; 166 | } 167 | 168 | #ifdef USBIP_OS_NO_FORK 169 | struct request_data { 170 | int connfd; 171 | char host[NI_MAXHOST], port[NI_MAXSERV]; 172 | }; 173 | 174 | static void *__process_request(void *arg) { 175 | struct request_data *data = (struct request_data *) arg; 176 | 177 | usbipd_recv_pdu(data->connfd, data->host, data->port); 178 | close(data->connfd); 179 | free(data); 180 | pthread_exit(NULL); 181 | } 182 | 183 | int process_request(int listenfd) { 184 | pthread_t thread; 185 | struct request_data *data; 186 | 187 | data = (struct request_data *) calloc(1, sizeof(struct request_data)); 188 | if (!data) 189 | return -1; 190 | 191 | data->connfd = do_accept(listenfd, data->host, sizeof(data->host), 192 | data->port, sizeof(data->port)); 193 | if (data->connfd < 0) { 194 | free(data); 195 | return -1; 196 | } 197 | if (pthread_create(&thread, NULL, __process_request, data)) { 198 | free(data); 199 | return -1; 200 | } 201 | return 0; 202 | } 203 | 204 | #else 205 | int process_request(int listenfd) 206 | { 207 | pid_t childpid; 208 | int connfd; 209 | struct usbip_sock sock; 210 | char host[NI_MAXHOST], port[NI_MAXSERV]; 211 | 212 | connfd = do_accept(listenfd, host, NI_MAXHOST, port, NI_MAXSERV); 213 | if (connfd < 0) 214 | return -1; 215 | childpid = fork(); 216 | if (childpid == 0) { 217 | close(listenfd); 218 | usbip_sock_init(&sock, connfd, NULL, NULL, NULL, NULL); 219 | usbipd_recv_pdu(&sock, host, port); 220 | socket_close(connfd); 221 | exit(0); 222 | } 223 | socket_close(connfd); 224 | return 0; 225 | } 226 | #endif /* !USBIP_OS_NO_FORK */ 227 | 228 | static void addrinfo_to_text(struct addrinfo *ai, char buf[], 229 | const size_t buf_size) { 230 | char hbuf[NI_MAXHOST]; 231 | char sbuf[NI_MAXSERV]; 232 | int rc; 233 | 234 | buf[0] = '\0'; 235 | 236 | rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), 237 | sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); 238 | if (rc) 239 | err("getnameinfo: %s", usbip_net_gai_strerror(rc)); 240 | 241 | snprintf(buf, buf_size, "%s:%s", hbuf, sbuf); 242 | } 243 | 244 | static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[], 245 | int maxsockfd) { 246 | struct addrinfo *ai; 247 | int ret, nsockfd = 0; 248 | const size_t ai_buf_size = NI_MAXHOST + NI_MAXSERV + 2; 249 | char ai_buf[NI_MAXHOST + NI_MAXSERV + 2]; 250 | 251 | for (ai = ai_head; ai && nsockfd < maxsockfd; ai = ai->ai_next) { 252 | int sock; 253 | 254 | addrinfo_to_text(ai, ai_buf, ai_buf_size); 255 | dbg("opening %s", ai_buf); 256 | sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 257 | if (sock < 0) { 258 | err("socket: %s: %d (%s)", 259 | ai_buf, errno, strerror(errno)); 260 | continue; 261 | } 262 | 263 | usbip_net_set_reuseaddr(sock); 264 | usbip_net_set_nodelay(sock); 265 | /* We use seperate sockets for IPv4 and IPv6 266 | * (see do_standalone_mode()) */ 267 | if (ai->ai_family != AF_INET) { 268 | usbip_net_set_v6only(sock); 269 | } 270 | 271 | ret = bind(sock, ai->ai_addr, ai->ai_addrlen); 272 | if (ret < 0) { 273 | err("bind: %s: %d (%s)", 274 | ai_buf, errno, strerror(errno)); 275 | close(sock); 276 | continue; 277 | } 278 | 279 | ret = listen(sock, SOMAXCONN); 280 | if (ret < 0) { 281 | err("listen: %s: %d (%s)", 282 | ai_buf, errno, strerror(errno)); 283 | close(sock); 284 | continue; 285 | } 286 | 287 | info("listening on %s", ai_buf); 288 | sockfdlist[nsockfd++] = sock; 289 | } 290 | 291 | return nsockfd; 292 | } 293 | 294 | static struct addrinfo *do_getaddrinfo(const char *host, int ai_family) { 295 | struct addrinfo hints, *ai_head; 296 | int rc; 297 | 298 | memset(&hints, 0, sizeof(hints)); 299 | hints.ai_family = ai_family; 300 | hints.ai_socktype = SOCK_STREAM; 301 | hints.ai_flags = AI_PASSIVE; 302 | 303 | rc = getaddrinfo(host, usbip_port_string, &hints, &ai_head); 304 | if (rc) { 305 | err("failed to get a network address %s: %s", usbip_port_string, 306 | usbip_net_gai_strerror(rc)); 307 | return NULL; 308 | } 309 | 310 | return ai_head; 311 | } 312 | 313 | static void signal_handler(int i) { 314 | dbg("received '%s' signal", strsignal(i)); 315 | } 316 | 317 | static void set_signal(void) { 318 | struct sigaction act; 319 | 320 | memset(&act, 0, sizeof(act)); 321 | act.sa_handler = signal_handler; 322 | sigemptyset(&act.sa_mask); 323 | sigaction(SIGTERM, &act, NULL); 324 | sigaction(SIGINT, &act, NULL); 325 | act.sa_handler = SIG_IGN; 326 | sigaction(SIGCHLD, &act, NULL); 327 | } 328 | 329 | static const char *pid_file; 330 | 331 | static void write_pid_file(void) { 332 | FILE *fp; 333 | 334 | if (pid_file) { 335 | dbg("creating pid file %s", pid_file); 336 | 337 | fp = fopen(pid_file, "w"); 338 | if (!fp) { 339 | err("pid_file: %s: %d (%s)", 340 | pid_file, errno, strerror(errno)); 341 | return; 342 | } 343 | fprintf(fp, "%d\n", getpid()); 344 | fclose(fp); 345 | } 346 | } 347 | 348 | static void remove_pid_file(void) { 349 | if (pid_file) { 350 | dbg("removing pid file %s", pid_file); 351 | unlink(pid_file); 352 | } 353 | } 354 | 355 | static int do_standalone_mode(int daemonize, int ipv4, int ipv6) { 356 | struct addrinfo *ai_head; 357 | int sockfdlist[MAXSOCKFD]; 358 | int nsockfd, family; 359 | int i, terminate; 360 | struct pollfd *fds; 361 | 362 | sigset_t sigmask; 363 | sigset_t origmask; 364 | 365 | if (usbip_driver_open()) 366 | goto err_out; 367 | 368 | if (daemonize) { 369 | #ifndef USBIP_OS_NO_DAEMON 370 | if (daemon(0, 0) < 0) { 371 | err("daemonizing failed: %s", strerror(errno)); 372 | goto err_driver_close; 373 | } 374 | umask(0); 375 | usbip_use_syslog = 1; 376 | #endif 377 | } 378 | set_signal(); 379 | write_pid_file(); 380 | 381 | info("starting %s (%s)", PACKAGE, PACKAGE_STRING); 382 | 383 | /* 384 | * To suppress warnings on systems with bindv6only disabled 385 | * (default), we use seperate sockets for IPv6 and IPv4 and set 386 | * IPV6_V6ONLY on the IPv6 sockets. 387 | */ 388 | if (ipv4 && ipv6) 389 | family = AF_UNSPEC; 390 | else if (ipv4) 391 | family = AF_INET; 392 | else 393 | family = AF_INET6; 394 | 395 | ai_head = do_getaddrinfo(NULL, family); 396 | if (!ai_head) 397 | goto err_socket_stop; 398 | 399 | nsockfd = listen_all_addrinfo(ai_head, sockfdlist, 400 | sizeof(sockfdlist) / sizeof(*sockfdlist)); 401 | freeaddrinfo(ai_head); 402 | if (nsockfd <= 0) { 403 | err("failed to open a listening socket"); 404 | goto err_socket_stop; 405 | } 406 | 407 | dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es"); 408 | 409 | fds = (struct pollfd *) calloc(nsockfd, sizeof(struct pollfd)); 410 | for (i = 0; i < nsockfd; i++) { 411 | fds[i].fd = sockfdlist[i]; 412 | fds[i].events = POLLIN; 413 | } 414 | 415 | sigfillset(&sigmask); 416 | sigdelset(&sigmask, SIGTERM); 417 | sigdelset(&sigmask, SIGINT); 418 | 419 | terminate = 0; 420 | while (!terminate) { 421 | int r; 422 | 423 | pthread_sigmask(SIG_SETMASK, &sigmask, &origmask); 424 | r = poll(fds, nsockfd, MAIN_LOOP_TIMEOUT * 1000); 425 | pthread_sigmask(SIG_SETMASK, &origmask, NULL); 426 | 427 | if (r < 0) { 428 | dbg("%s", strerror(errno)); 429 | terminate = 1; 430 | } else if (r) { 431 | for (i = 0; i < nsockfd; i++) { 432 | if (fds[i].revents & POLLIN) { 433 | dbg("read event on fd[%d]=%d", 434 | i, sockfdlist[i]); 435 | process_request(sockfdlist[i]); 436 | } 437 | } 438 | } else { 439 | dbg("heartbeat timeout on ppoll()"); 440 | } 441 | } 442 | 443 | info("shutting down %s", PACKAGE); 444 | free(fds); 445 | usbip_driver_close(); 446 | 447 | return 0; 448 | 449 | err_socket_stop: 450 | err_driver_close: 451 | usbip_driver_close(); 452 | err_out: 453 | return -1; 454 | } 455 | 456 | int main(int argc, char *argv[]) { 457 | static const struct option longopts[] = { 458 | {"ipv4", no_argument, NULL, '4'}, 459 | {"ipv6", no_argument, NULL, '6'}, 460 | {"daemon", no_argument, NULL, 'D'}, 461 | {"debug", no_argument, NULL, 'd'}, 462 | {"debug-flags", required_argument, NULL, 'f'}, 463 | #ifndef USBIP_DAEMON_APP 464 | {"device", no_argument, NULL, 'e'}, 465 | #endif 466 | {"pid", optional_argument, NULL, 'P'}, 467 | {"tcp-port", required_argument, NULL, 't'}, 468 | {"help", no_argument, NULL, 'h'}, 469 | {"version", no_argument, NULL, 'v'}, 470 | {NULL, 0, NULL, 0} 471 | }; 472 | 473 | enum { 474 | cmd_standalone_mode = 1, 475 | cmd_help, 476 | cmd_version 477 | } cmd; 478 | 479 | int daemonize = 0; 480 | int ipv4 = 0, ipv6 = 0; 481 | int opt, rc = -1; 482 | 483 | pid_file = NULL; 484 | 485 | cmd = cmd_standalone_mode; 486 | 487 | for (;;) { 488 | opt = getopt_long(argc, argv, "46Dd" 489 | "f:" 490 | #ifndef USBIP_DAEMON_APP 491 | "e" 492 | #endif 493 | "P::t:hv", longopts, NULL); 494 | 495 | if (opt == -1) 496 | break; 497 | 498 | switch (opt) { 499 | case '4': 500 | ipv4 = 1; 501 | break; 502 | case '6': 503 | ipv6 = 1; 504 | break; 505 | case 'D': 506 | daemonize = 1; 507 | break; 508 | case 'd': 509 | usbip_use_debug = 1; 510 | break; 511 | case 'f': 512 | usbip_stub_debug_flags = strtoul(optarg, NULL, 0); 513 | break; 514 | case 'h': 515 | cmd = cmd_help; 516 | break; 517 | case 'P': 518 | pid_file = optarg ? optarg : DEFAULT_PID_FILE; 519 | break; 520 | case 't': 521 | usbip_setup_port_number(optarg); 522 | break; 523 | case 'v': 524 | cmd = cmd_version; 525 | break; 526 | case '?': 527 | usbipd_help(); 528 | default: 529 | goto err_out; 530 | } 531 | } 532 | 533 | if (!ipv4 && !ipv6) { 534 | ipv4 = 1; 535 | ipv6 = 0; 536 | } 537 | 538 | if (usbip_use_debug) { 539 | if (names_init(USBIDS_FILE)) { 540 | err("Unable to open names file: " USBIDS_FILE); 541 | } 542 | } 543 | 544 | switch (cmd) { 545 | case cmd_standalone_mode: 546 | rc = do_standalone_mode(daemonize, ipv4, ipv6); 547 | remove_pid_file(); 548 | break; 549 | case cmd_version: 550 | printf("%s (%s)\n", PACKAGE, PACKAGE_STRING); 551 | rc = 0; 552 | break; 553 | case cmd_help: 554 | default: 555 | usbipd_help(); 556 | rc = 0; 557 | break; 558 | } 559 | 560 | err_out: 561 | return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE); 562 | } -------------------------------------------------------------------------------- /src/usbipd_requests.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * Copyright (C) 2015-2016 Nobuo Iwata 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | #include "list.h" 26 | #include "usbip_host_driver.h" 27 | #include "usbip_network.h" 28 | #include 29 | 30 | #include "usbipd_requests.h" 31 | 32 | 33 | static int recv_request_attach(int sock_fd, 34 | const char *host, const char *port) 35 | { 36 | struct usbip_exported_devices edevs; 37 | struct usbip_exported_device *edev; 38 | struct op_import_request req; 39 | struct usbip_usb_device pdu_udev; 40 | int found = 0; 41 | int error = 0; 42 | int rc; 43 | 44 | (void)host; 45 | (void)port; 46 | 47 | rc = usbip_refresh_device_list(&edevs); 48 | if (rc < 0) { 49 | dbg("could not refresh device list: %d", rc); 50 | goto err_out; 51 | } 52 | 53 | memset(&req, 0, sizeof(req)); 54 | 55 | rc = usbip_net_recv(sock_fd, &req, sizeof(req)); 56 | if (rc < 0) { 57 | dbg("usbip_net_recv failed: import request"); 58 | goto err_free_edevs; 59 | } 60 | PACK_OP_IMPORT_REQUEST(0, &req); 61 | 62 | edev = usbip_get_device(&edevs, req.busid); 63 | if (edev) { 64 | info("found requested device: %s", req.busid); 65 | found = 1; 66 | } 67 | 68 | if (found) { 69 | /* export device needs a TCP/IP socket descriptor */ 70 | rc = usbip_export_device(edev, sock_fd); 71 | if (rc < 0) 72 | error = 1; 73 | } else { 74 | info("requested device not found: %s", req.busid); 75 | error = 1; 76 | } 77 | 78 | rc = usbip_net_send_op_common(sock_fd, OP_REP_IMPORT, (!error ? ST_OK : ST_NA)); 79 | if (rc < 0) { 80 | dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT); 81 | goto err_free_edevs; 82 | } 83 | 84 | if (error) { 85 | dbg("import request busid %s: failed: %d", req.busid, error); 86 | goto err_free_edevs; 87 | } 88 | 89 | memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); 90 | PACK_OP_IMPORT_REPLY(1, pdu_udev); 91 | 92 | rc = usbip_net_send(sock_fd, &pdu_udev, sizeof(pdu_udev)); 93 | if (rc < 0) { 94 | dbg("usbip_net_send failed: devinfo"); 95 | goto err_free_edevs; 96 | } 97 | 98 | dbg("import request busid %s: complete", req.busid); 99 | 100 | rc = usbip_try_transfer(edev, sock_fd); 101 | if (rc < 0) { 102 | err("try transfer"); 103 | goto err_free_edevs; 104 | } 105 | 106 | usbip_free_device_list(&edevs); 107 | 108 | return 0; 109 | err_free_edevs: 110 | usbip_free_device_list(&edevs); 111 | err_out: 112 | return -1; 113 | } 114 | 115 | static int recv_request_devlist(int sock_fd, 116 | const char *host, const char *port) 117 | { 118 | struct usbip_exported_devices edevs; 119 | struct usbip_exported_device *edev; 120 | struct usbip_usb_device pdu_udev; 121 | struct usbip_usb_interface pdu_uinf; 122 | struct op_devlist_reply reply; 123 | struct list_head *j; 124 | int rc, i; 125 | 126 | rc = usbip_refresh_device_list(&edevs); 127 | if (rc < 0) { 128 | dbg("could not refresh device list: %d", rc); 129 | goto err_out; 130 | } 131 | 132 | reply.ndev = edevs.ndevs; 133 | info("importable devices: %d", reply.ndev); 134 | 135 | rc = usbip_net_send_op_common(sock_fd, OP_REP_DEVLIST, ST_OK); 136 | if (rc < 0) { 137 | dbg("usbip_net_send_op_common failed: %#0x", OP_REP_DEVLIST); 138 | goto err_free_edevs; 139 | } 140 | 141 | reply.ndev = htonl(reply.ndev); 142 | 143 | rc = usbip_net_send(sock_fd, &reply, sizeof(reply)); 144 | if (rc < 0) { 145 | dbg("usbip_net_send failed: %#0x", OP_REP_DEVLIST); 146 | goto err_free_edevs; 147 | } 148 | 149 | list_for_each(j, &edevs.edev_list) { 150 | edev = list_entry(j, struct usbip_exported_device, node); 151 | dump_usb_device(&edev->udev); 152 | memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); 153 | PACK_OP_IMPORT_REPLY(1, pdu_udev); 154 | 155 | rc = usbip_net_send(sock_fd, &pdu_udev, sizeof(pdu_udev)); 156 | if (rc < 0) { 157 | dbg("usbip_net_send failed: pdu_udev"); 158 | goto err_free_edevs; 159 | } 160 | 161 | for (i = 0; i < edev->udev.bNumInterfaces; i++) { 162 | dump_usb_interface(&edev->uinf[i]); 163 | memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf)); 164 | 165 | rc = usbip_net_send(sock_fd, &pdu_uinf, 166 | sizeof(pdu_uinf)); 167 | if (rc < 0) { 168 | err("usbip_net_send failed: pdu_uinf"); 169 | goto err_free_edevs; 170 | } 171 | } 172 | } 173 | 174 | usbip_free_device_list(&edevs); 175 | 176 | return 0; 177 | err_free_edevs: 178 | usbip_free_device_list(&edevs); 179 | err_out: 180 | return -1; 181 | } 182 | 183 | struct usbipd_recv_pdu_op usbipd_recv_pdu_ops[] = { 184 | {OP_REQ_DEVLIST, recv_request_devlist}, 185 | {OP_REQ_IMPORT, recv_request_attach}, 186 | {OP_UNSPEC, NULL} 187 | }; 188 | -------------------------------------------------------------------------------- /src/usbipd_requests.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * Copyright (C) 2015-2016 Nobuo Iwata 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef __USBIPD_H 21 | #define __USBIPD_H 22 | 23 | 24 | struct usbipd_recv_pdu_op { 25 | uint16_t code; 26 | int (*proc)(int sock_fd, const char *host, const char *port); 27 | }; 28 | 29 | extern struct usbipd_recv_pdu_op usbipd_recv_pdu_ops[]; 30 | 31 | #endif /* __USBIPD_H */ 32 | --------------------------------------------------------------------------------