/* * exports the device on @busid to @host. * * few function calls. But error checking makes this function long and ugly. */ int export_busid_to_host(char *host, char *busid) { int ret; int sockfd; uint16_t code = OP_REP_EXPORT; struct usbip_exported_device *edev; /* * open stub driver */ ret = usbip_stub_driver_open(); if( ret != 0 ) { err( "could not open stub_driver"); return -1; } /* * get the relevant device */ edev = busid_to_edev(busid); if( edev == NULL ) { err( "no device found matching busid" ); goto exit_failure; } /* * Open connection and tell server* we want to export a device * * * server here means 'remote host', 'OS-Server', ... * This is the machine thats runs the virtual host controller */ sockfd = tcp_connect(host, USBAID_PORT_STRING); if( sockfd < 0 ) { err("tcp connection failed"); goto exit_failure; } dbg("tcp connection established"); /* * mark device as exported */ ret = usbip_stub_export_device(edev, sockfd); if( ret < 0 ) { err( "exporting of the device failed" ); goto exit_failure; } dbg("devices marked as exported"); /* * now, tell server */ ret = usbip_send_op_common( sockfd, OP_REQ_EXPORT, 0 ); if( ret < 0 ) { err( "sending OP_REQ_EXPORT failed" ); goto exit_failure; } dbg("export request (OP_COMMON) sent"); ret = send_request_export( sockfd, &(edev->udev) ); if( ret < 0 ) { err( "sending export request failed" ); goto exit_failure; } dbg("export request (device) sent"); dbg("device exported" ); /* * We do not wait for a status notification. see * usbaid.c::handle_export_query() for details. * * For now, we simply assume that the export was successfull */ usbip_stub_driver_close(); return 0; exit_failure: close(sockfd); usbip_stub_driver_close(); return -1; }
static int recv_request_import(int sockfd) { int ret; struct op_import_request req; struct op_common reply; struct usbip_exported_device *edev; int found = 0; int error = 0; bzero(&req, sizeof(req)); bzero(&reply, sizeof(reply)); ret = usbip_recv(sockfd, (void *) &req, sizeof(req)); if (ret < 0) { err("recv import request"); return -1; } PACK_OP_IMPORT_REQUEST(0, &req); dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) { if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { dbg("found requested device %s", req.busid); found = 1; break; } } if (found) { /* should set TCP_NODELAY for usbip */ usbip_set_nodelay(sockfd); /* export_device needs a TCP/IP socket descriptor */ ret = usbip_stub_export_device(edev, sockfd); if (ret < 0) error = 1; } else { info("not found requested device %s", req.busid); error = 1; } ret = usbip_send_op_common(sockfd, OP_REP_IMPORT, (!error ? ST_OK : ST_NA)); if (ret < 0) { err("send import reply"); return -1; } if (!error) { struct usb_device pdu_udev; memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); pack_usb_device(1, &pdu_udev); ret = usbip_send(sockfd, (void *) &pdu_udev, sizeof(pdu_udev)); if (ret < 0) { err("send devinfo"); return -1; } } return 0; }