On Tue, Feb 20, 2018 at 05:59:03PM -0500, Bandan Das wrote: > Allow write operations on behalf of the initiator. The > precursor to write is the sending of the write metadata > that consists of the ObjectInfo dataset. This patch introduces > a flag that is set when the responder is ready to receive > write data based on a previous SendObjectInfo operation by > the initiator (The SendObjectInfo implementation is in a > later patch) > > Signed-off-by: Bandan Das <b...@redhat.com> > --- > hw/usb/dev-mtp.c | 152 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 150 insertions(+), 2 deletions(-) > > diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c > index 5ef77f3e9f..9b51708614 100644 > --- a/hw/usb/dev-mtp.c > +++ b/hw/usb/dev-mtp.c > @@ -47,6 +47,7 @@ enum mtp_code { > CMD_GET_OBJECT_INFO = 0x1008, > CMD_GET_OBJECT = 0x1009, > CMD_DELETE_OBJECT = 0x100b, > + CMD_SEND_OBJECT = 0x100d, > CMD_GET_PARTIAL_OBJECT = 0x101b, > CMD_GET_OBJECT_PROPS_SUPPORTED = 0x9801, > CMD_GET_OBJECT_PROP_DESC = 0x9802, > @@ -63,9 +64,11 @@ enum mtp_code { > RES_INVALID_STORAGE_ID = 0x2008, > RES_INVALID_OBJECT_HANDLE = 0x2009, > RES_INVALID_OBJECT_FORMAT_CODE = 0x200b, > + RES_STORE_FULL = 0x200c, > RES_STORE_READ_ONLY = 0x200e, > RES_PARTIAL_DELETE = 0x2012, > RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014, > + RES_INVALID_OBJECTINFO = 0x2015, > RES_INVALID_PARENT_OBJECT = 0x201a, > RES_INVALID_PARAMETER = 0x201d, > RES_SESSION_ALREADY_OPEN = 0x201e, > @@ -183,6 +186,14 @@ struct MTPState { > int inotifyfd; > QTAILQ_HEAD(events, MTPMonEntry) events; > #endif > + /* Responder is expecting a write operation */ > + bool write_pending; > + struct { > + uint32_t parent_handle; > + uint16_t format; > + uint32_t size; > + char *filename; > + } dataset; > }; > > #define TYPE_USB_MTP "usb-mtp" > @@ -804,6 +815,7 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, > MTPControl *c) > CMD_GET_OBJECT_HANDLES, > CMD_GET_OBJECT_INFO, > CMD_DELETE_OBJECT, > + CMD_SEND_OBJECT,
Seems we should not advertize this for readonly devices. > CMD_GET_OBJECT, > CMD_GET_PARTIAL_OBJECT, > CMD_GET_OBJECT_PROPS_SUPPORTED, > @@ -1378,6 +1390,14 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) > nres = 1; > res0 = data_in->length; > break; > + case CMD_SEND_OBJECT: > + if (!s->write_pending) { > + usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, > + c->trans, 0, 0, 0, 0); > + return; > + } > + s->data_out = usb_mtp_data_alloc(c); > + return; > case CMD_GET_OBJECT_PROPS_SUPPORTED: > if (c->argv[0] != FMT_UNDEFINED_OBJECT && > c->argv[0] != FMT_ASSOCIATION) { > @@ -1472,12 +1492,126 @@ static void usb_mtp_cancel_packet(USBDevice *dev, > USBPacket *p) > fprintf(stderr, "%s\n", __func__); > } > > +static void usb_mtp_write_data(MTPState *s) > +{ > + MTPData *d = s->data_out; > + MTPObject *parent = > + usb_mtp_object_lookup(s, s->dataset.parent_handle); > + char *path = NULL; > + int rc = -1; > + mode_t mask = 0644; > + > + assert(d != NULL); > + Somewhere in here should surely be validating the "readonly" flag. > + if (parent == NULL || !s->write_pending) { > + usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, d->trans, > + 0, 0, 0, 0); > + return; > + } > + Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|