Example #1
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;
}
Example #2
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;
}