Ejemplo n.º 1
0
/* 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;
}
Ejemplo n.º 2
0
static int send_reply_devlist(int sockfd)
{
	int ret;
	struct usbip_exported_device *edev;
	struct op_devlist_reply reply;


	reply.ndev = 0;

	/* how many devices are exported ? */
	dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
		reply.ndev += 1;
	}

	dbg("%d devices are exported", reply.ndev);

	ret = usbip_send_op_common(sockfd, OP_REP_DEVLIST,  ST_OK);
	if (ret < 0) {
		err("send op_common");
		return ret;
	}

	PACK_OP_DEVLIST_REPLY(1, &reply);

	ret = usbip_send(sockfd, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		err("send op_devlist_reply");
		return ret;
	}

	dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
		struct usb_device pdu_udev;

		dump_usb_device(&edev->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 pdu_udev");
			return ret;
		}

		for (int i=0; i < edev->udev.bNumInterfaces; i++) {
			struct usb_interface pdu_uinf;

			dump_usb_interface(&edev->uinf[i]);
			memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf));
			pack_usb_interface(1, &pdu_uinf);

			ret = usbip_send(sockfd, (void *) &pdu_uinf, sizeof(pdu_uinf));
			if (ret < 0) {
				err("send pdu_uinf");
				return ret;
			}
		}
	}

	return 0;
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
/*
 * 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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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;
}