/* call at unbound state */ static int bind_to_usbip(char *busid) { int fd; struct op_export_request req; uint16_t code = OP_REP_EXPORT; int ret; fd = tcp_connect("127.0.0.1", USBIP_PORT_STRING); if(fd < 0){ err("connect"); return -1; } ret = usbip_send_op_common(fd, OP_REQ_EXPORT, 0); if (ret < 0) { close(fd); err("send op_common"); return -1; } snprintf(req.udev.busid, sizeof(req.udev.busid), "%s", busid); ret = usbip_send(fd, &req, sizeof(req)); if(ret!=sizeof(req)){ close(fd); err("send"); return -1; } ret = usbip_recv_op_common(fd, &code); close(fd); if(ret<0){ err("recv reply"); return -1; } return 0; }
static int query_import_device(int sockfd, char *busid) { int ret; struct op_import_request request; struct op_import_reply reply; uint16_t code = OP_REP_IMPORT; bzero(&request, sizeof(request)); bzero(&reply, sizeof(reply)); /* send a request */ ret = usbip_send_op_common(sockfd, OP_REQ_IMPORT, 0); if (ret < 0) { err("send op_common"); return -1; } strncpy(request.busid, busid, SYSFS_BUS_ID_SIZE-1); PACK_OP_IMPORT_REQUEST(0, &request); ret = usbip_send(sockfd, (void *) &request, sizeof(request)); if (ret < 0) { err("send op_import_request"); return -1; } /* recieve a reply */ ret = usbip_recv_op_common(sockfd, &code); if (ret < 0) { err("recv op_common"); return -1; } ret = usbip_recv(sockfd, (void *) &reply, sizeof(reply)); if (ret < 0) { err("recv op_import_reply"); return -1; } PACK_OP_IMPORT_REPLY(0, &reply); /* check the reply */ if (strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) { err("recv different busid %s", reply.udev.busid); return -1; } /* import a device */ return import_device(sockfd, &reply.udev); }
static int attach_exported_devices(char *host, int sockfd) { int ret; struct op_devlist_reply rep; uint16_t code = OP_REP_DEVLIST; bzero(&rep, sizeof(rep)); ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0); if(ret < 0) { err("send op_common"); return -1; } ret = usbip_recv_op_common(sockfd, &code); if(ret < 0) { err("recv op_common"); return -1; } ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep)); if(ret < 0) { err("recv op_devlist"); return -1; } PACK_OP_DEVLIST_REPLY(0, &rep); dbg("exportable %d devices", rep.ndev); for(unsigned int i=0; i < rep.ndev; i++) { char product_name[100]; char class_name[100]; struct usb_device udev; bzero(&udev, sizeof(udev)); ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev)); if(ret < 0) { err("recv usb_device[%d]", i); return -1; } pack_usb_device(0, &udev); usbip_names_get_product(product_name, sizeof(product_name), udev.idVendor, udev.idProduct); usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass, udev.bDeviceSubClass, udev.bDeviceProtocol); dbg("Attaching usb port %s from host %s on usbip, with deviceid: %s", udev.busid, host, product_name); attach_device(host, udev.busid); } return rep.ndev; }
static int query_import_device(int sockfd, char *busid, struct usb_interface *uinf0, HANDLE * fd) { int ret; struct op_import_request request; struct op_import_reply reply; uint16_t code = OP_REP_IMPORT; memset(&request, 0, sizeof(request)); memset(&reply, 0, sizeof(reply)); /* send a request */ ret = usbip_send_op_common(sockfd, OP_REQ_IMPORT, 0); if (ret < 0) { err("send op_common"); return -1; } strncpy(request.busid, busid, sizeof(request.busid)); request.busid[sizeof(request.busid)-1]=0; PACK_OP_IMPORT_REQUEST(0, &request); ret = usbip_send(sockfd, (void *) &request, sizeof(request)); if (ret < 0) { err("send op_import_request"); return -1; } /* recieve a reply */ ret = usbip_recv_op_common(sockfd, &code); if (ret < 0) { err("recv op_common"); return -1; } ret = usbip_recv(sockfd, (void *) &reply, sizeof(reply)); if (ret < 0) { err("recv op_import_reply"); return -1; } PACK_OP_IMPORT_REPLY(0, &reply); /* check the reply */ if (strncmp(reply.udev.busid, busid, sizeof(reply.udev.busid))) { err("recv different busid %s", reply.udev.busid); return -1; } /* import a device */ return import_device(sockfd, &reply.udev, uinf0, fd); }
static int recv_pdu(int sockfd) { int ret; uint16_t code = OP_UNSPEC; ret = usbip_recv_op_common(sockfd, &code); if (ret < 0) { err("recv op_common, %d", ret); return ret; } ret = usbip_stub_refresh_device_list(); if (ret < 0) return -1; switch(code) { case OP_REQ_DEVLIST: ret = recv_request_devlist(sockfd); break; case OP_REQ_IMPORT: ret = recv_request_import(sockfd); break; case OP_REQ_DEVINFO: case OP_REQ_CRYPKEY: default: err("unknown op_code, %d", code); ret = -1; } return ret; }
int unexport_busid_from_host(char *host, char *busid) { int ret; int sockfd; uint16_t code = OP_REP_UNEXPORT; 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 unexport a device */ sockfd = tcp_connect(host, USBAID_PORT_STRING); if( sockfd < 0 ) { err("tcp connection failed"); goto exit_failure; } dbg("tcp connection established"); /* * now, tell server */ ret = usbip_send_op_common( sockfd, OP_REQ_UNEXPORT, 0 ); if( ret < 0 ) { err( "sending OP_REQ_UNEXPORT failed" ); goto exit_failure; } dbg("unexport request (OP_COMMON) sent"); ret = send_request_unexport( sockfd, &(edev->udev) ); if( ret < 0 ) { err( "sending unexport request failed" ); goto exit_failure; } dbg("unexport request (device) sent"); /* * mark device as no longer exported */ /*XXX There seems to be no action on the 'client' side neccessary. * The server needs to be told, that it should detach the device. * On the client side, the device is 'unexported' by releasing it from * the usbip driver. */ /* receive status message from server */ ret = usbip_recv_op_common(sockfd, &code); if( ret < 0 ) { err( "receiving op_common failed" ); goto exit_failure; } usbip_stub_driver_close(); return 0; exit_failure: usbip_stub_driver_close(); return -1; }
static int query_exported_devices(int sockfd) { int ret; struct op_devlist_reply rep; uint16_t code = OP_REP_DEVLIST; bzero(&rep, sizeof(rep)); ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0); if (ret < 0) { err("send op_common"); return -1; } ret = usbip_recv_op_common(sockfd, &code); if (ret < 0) { err("recv op_common"); return -1; } ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep)); if (ret < 0) { err("recv op_devlist"); return -1; } PACK_OP_DEVLIST_REPLY(0, &rep); dbg("exportable %d devices", rep.ndev); for (unsigned int i=0; i < rep.ndev; i++) { char product_name[100]; char class_name[100]; struct usb_device udev; bzero(&udev, sizeof(udev)); ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev)); if (ret < 0) { err("recv usb_device[%d]", i); return -1; } pack_usb_device(0, &udev); usbip_names_get_product(product_name, sizeof(product_name), udev.idVendor, udev.idProduct); usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass, udev.bDeviceSubClass, udev.bDeviceProtocol); info("%8s: %s", udev.busid, product_name); info("%8s: %s", " ", udev.path); info("%8s: %s", " ", class_name); for (int j=0; j < udev.bNumInterfaces; j++) { struct usb_interface uinf; ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf)); if (ret < 0) { err("recv usb_interface[%d]", j); return -1; } pack_usb_interface(0, &uinf); usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass, uinf.bInterfaceSubClass, uinf.bInterfaceProtocol); info("%8s: %2d - %s", " ", j, class_name); } info(" "); } return rep.ndev; }
static int query_interface0(SOCKET sockfd, char * busid, struct usb_interface * uinf0) { int ret; struct op_devlist_reply rep; uint16_t code = OP_REP_DEVLIST; uint32_t i,j; char product_name[100]; char class_name[100]; struct usb_device udev; struct usb_interface uinf; int found=0; memset(&rep, 0, sizeof(rep)); ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0); if (ret < 0) { err("send op_common"); return -1; } ret = usbip_recv_op_common(sockfd, &code); if (ret < 0) { err("recv op_common"); return -1; } ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep)); if (ret < 0) { err("recv op_devlist"); return -1; } PACK_OP_DEVLIST_REPLY(0, &rep); dbg("exportable %d devices", rep.ndev); for (i=0; i < rep.ndev; i++) { memset(&udev, 0, sizeof(udev)); ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev)); if (ret < 0) { err("recv usb_device[%d]", i); return -1; } pack_usb_device(0, &udev); usbip_names_get_product(product_name, sizeof(product_name), udev.idVendor, udev.idProduct); usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass, udev.bDeviceSubClass, udev.bDeviceProtocol); dbg("%8s: %s", udev.busid, product_name); dbg("%8s: %s", " ", udev.path); dbg("%8s: %s", " ", class_name); for (j=0; j < udev.bNumInterfaces; j++) { ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf)); if (ret < 0) { err("recv usb_interface[%d]", j); return -1; } pack_usb_interface(0, &uinf); if(!strcmp(udev.busid, busid)&&j==0){ memcpy(uinf0, &uinf, sizeof(uinf)); found=1; } usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass, uinf.bInterfaceSubClass, uinf.bInterfaceProtocol); dbg("%8s: %2d - %s", " ", j, class_name); } dbg(" "); } if(found) return 0; return -1; }