[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v4 5/5] usb-mtp: Advertise SendObjectInfo for wr
From: |
Daniel P . Berrangé |
Subject: |
Re: [Qemu-devel] [PATCH v4 5/5] usb-mtp: Advertise SendObjectInfo for write support |
Date: |
Wed, 21 Feb 2018 09:36:52 +0000 |
User-agent: |
Mutt/1.9.2 (2017-12-15) |
On Tue, Feb 20, 2018 at 05:59:04PM -0500, Bandan Das wrote:
> This patch implements a dummy ObjectInfo structure so that
> it's easy to typecast the incoming data. If the metadata is
> valid, write_pending is set. Also, the incoming filename
> is utf-16, so, instead of depending on external libraries, just
> implement a simple function to get the filename
>
> Signed-off-by: Bandan Das <address@hidden>
> ---
> hw/usb/dev-mtp.c | 132
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 130 insertions(+), 2 deletions(-)
>
> diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
> index 9b51708614..086296f415 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_INFO = 0x100c,
> CMD_SEND_OBJECT = 0x100d,
> CMD_GET_PARTIAL_OBJECT = 0x101b,
> CMD_GET_OBJECT_PROPS_SUPPORTED = 0x9801,
> @@ -67,8 +68,10 @@ enum mtp_code {
> RES_STORE_FULL = 0x200c,
> RES_STORE_READ_ONLY = 0x200e,
> RES_PARTIAL_DELETE = 0x2012,
> + RES_STORE_NOT_AVAILABLE = 0x2013,
> RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014,
> RES_INVALID_OBJECTINFO = 0x2015,
> + RES_DESTINATION_UNSUPPORTED = 0x2020,
> RES_INVALID_PARENT_OBJECT = 0x201a,
> RES_INVALID_PARAMETER = 0x201d,
> RES_SESSION_ALREADY_OPEN = 0x201e,
> @@ -196,6 +199,34 @@ struct MTPState {
> } dataset;
> };
>
> +/*
> + * ObjectInfo dataset received from initiator
> + * Fields we don't care about are ignored
> + */
> +typedef struct {
> + uint32_t storage_id; /*unused*/
> + uint16_t format;
> + uint16_t protection_status; /*unused*/
> + uint32_t size;
> + uint16_t thumb_format; /*unused*/
> + uint32_t thumb_comp_sz; /*unused*/
> + uint32_t thumb_pix_width; /*unused*/
> + uint32_t thumb_pix_height; /*unused*/
> + uint32_t image_pix_width; /*unused*/
> + uint32_t image_pix_height; /*unused*/
> + uint32_t image_bit_depth; /*unused*/
> + uint32_t parent; /*unused*/
> + uint16_t assoc_type;
> + uint32_t assoc_desc;
> + uint32_t seq_no; /*unused*/
> + uint8_t length; /*part of filename field*/
> + uint16_t filename[0];
> + char date_created[0]; /*unused*/
> + char date_modified[0]; /*unused*/
> + char keywords[0]; /*unused*/
> + /* string and other data follows */
> +} QEMU_PACKED ObjectInfo;
> +
> #define TYPE_USB_MTP "usb-mtp"
> #define USB_MTP(obj) OBJECT_CHECK(MTPState, (obj), TYPE_USB_MTP)
>
> @@ -437,7 +468,6 @@ static MTPObject *usb_mtp_add_child(MTPState *s,
> MTPObject *o,
> return child;
> }
>
> -#ifdef CONFIG_INOTIFY1
> static MTPObject *usb_mtp_object_lookup_name(MTPObject *parent,
> char *name, int len)
> {
> @@ -452,6 +482,7 @@ static MTPObject *usb_mtp_object_lookup_name(MTPObject
> *parent,
> return NULL;
> }
>
> +#ifdef CONFIG_INOTIFY1
> static MTPObject *usb_mtp_object_lookup_wd(MTPState *s, int wd)
> {
> MTPObject *iter;
> @@ -815,6 +846,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_INFO,
Same question about filtering this out for read-only devices,
and somewhere else in this patch validating it too.
> CMD_SEND_OBJECT,
> CMD_GET_OBJECT,
> CMD_GET_PARTIAL_OBJECT,
> @@ -1243,7 +1275,7 @@ static void usb_mtp_object_delete(MTPState *s, uint32_t
> handle,
> static void usb_mtp_command(MTPState *s, MTPControl *c)
> {
> MTPData *data_in = NULL;
> - MTPObject *o;
> + MTPObject *o = NULL;
> uint32_t nres = 0, res0 = 0;
>
> /* sanity checks */
> @@ -1390,6 +1422,37 @@ static void usb_mtp_command(MTPState *s, MTPControl *c)
> nres = 1;
> res0 = data_in->length;
> break;
> + case CMD_SEND_OBJECT_INFO:
> + /* First parameter points to storage id or is 0 */
> + if (c->argv[0] && (c->argv[0] != QEMU_STORAGE_ID)) {
> + usb_mtp_queue_result(s, RES_STORE_NOT_AVAILABLE, c->trans,
> + 0, 0, 0, 0);
> + } else if (c->argv[1] && !c->argv[0]) {
> + /* If second parameter is specified, first must also be
> specified */
> + usb_mtp_queue_result(s, RES_DESTINATION_UNSUPPORTED, c->trans,
> + 0, 0, 0, 0);
> + } else {
> + uint32_t handle = c->argv[1];
> + if (handle == 0xFFFFFFFF || handle == 0) {
> + /* root object */
> + o = QTAILQ_FIRST(&s->objects);
> + } else {
> + o = usb_mtp_object_lookup(s, handle);
> + }
> + if (o == NULL) {
> + usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, c->trans,
> + 0, 0, 0, 0);
> + }
> + if (o->format != FMT_ASSOCIATION) {
> + usb_mtp_queue_result(s, RES_INVALID_PARENT_OBJECT, c->trans,
> + 0, 0, 0, 0);
> + }
> + }
> + if (o) {
> + s->dataset.parent_handle = o->handle;
> + }
> + s->data_out = usb_mtp_data_alloc(c);
> + return;
> case CMD_SEND_OBJECT:
> if (!s->write_pending) {
> usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO,
> @@ -1492,6 +1555,19 @@ static void usb_mtp_cancel_packet(USBDevice *dev,
> USBPacket *p)
> fprintf(stderr, "%s\n", __func__);
> }
>
> +static void utf16_to_str(uint8_t len, uint16_t *arr, char *name)
> +{
> + int count;
> + wchar_t *wstr = g_new0(wchar_t, len);
> +
> + for (count = 0; count < len; count++) {
> + wstr[count] = (wchar_t)arr[count];
> + }
> +
> + wcstombs(name, wstr, len);
> + g_free(wstr);
> +}
> +
> static void usb_mtp_write_data(MTPState *s)
> {
> MTPData *d = s->data_out;
> @@ -1565,6 +1641,45 @@ free:
> s->write_pending = false;
> }
>
> +static void usb_mtp_write_metadata(MTPState *s)
> +{
> + MTPData *d = s->data_out;
> + ObjectInfo *dataset = (ObjectInfo *)d->data;
> + char *filename = g_new0(char, dataset->length);
> + MTPObject *o;
> + MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle);
> + uint32_t next_handle = s->next_handle;
> +
> + assert(!s->write_pending);
> +
> + utf16_to_str(dataset->length, dataset->filename, filename);
> +
> + o = usb_mtp_object_lookup_name(p, filename, dataset->length);
> + if (o != NULL) {
> + next_handle = o->handle;
> + }
> +
> + s->dataset.filename = filename;
> + s->dataset.format = dataset->format;
> + s->dataset.size = dataset->size;
> + s->dataset.filename = filename;
> + s->write_pending = true;
> +
> + if (s->dataset.format == FMT_ASSOCIATION) {
> + usb_mtp_write_data(s);
> + /* next_handle will be allocated to the newly created dir */
> + if (d->fd == -1) {
> + usb_mtp_queue_result(s, RES_STORE_FULL, d->trans,
> + 0, 0, 0, 0);
> + return;
> + }
> + d->fd = -1;
> + }
> +
> + usb_mtp_queue_result(s, RES_OK, d->trans, 3, QEMU_STORAGE_ID,
> + s->dataset.parent_handle, next_handle);
> +}
> +
> static void usb_mtp_get_data(MTPState *s, mtp_container *container,
> USBPacket *p)
> {
> @@ -1589,6 +1704,19 @@ static void usb_mtp_get_data(MTPState *s,
> mtp_container *container,
> }
>
> switch (d->code) {
> + case CMD_SEND_OBJECT_INFO:
> + usb_packet_copy(p, d->data + d->offset, dlen);
> + d->offset += dlen;
> + if (d->offset == d->length) {
> + /* The operation might have already failed */
> + if (!s->result) {
> + usb_mtp_write_metadata(s);
> + }
> + usb_mtp_data_free(s->data_out);
> + s->data_out = NULL;
> + return;
> + }
> + break;
> case CMD_SEND_OBJECT:
> usb_packet_copy(p, d->data + d->offset, dlen);
> d->offset += dlen;
> --
> 2.14.3
>
>
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 :|
- [Qemu-devel] [PATCH v4 0/5] Initial write support for MTP objects, Bandan Das, 2018/02/20
- [Qemu-devel] [PATCH v4 1/5] usb-mtp: Add one more argument when building results, Bandan Das, 2018/02/20
- [Qemu-devel] [PATCH v4 3/5] usb-mtp: Support delete of mtp objects, Bandan Das, 2018/02/20
- [Qemu-devel] [PATCH v4 5/5] usb-mtp: Advertise SendObjectInfo for write support, Bandan Das, 2018/02/20
- Re: [Qemu-devel] [PATCH v4 5/5] usb-mtp: Advertise SendObjectInfo for write support,
Daniel P . Berrangé <=
- [Qemu-devel] [PATCH v4 2/5] usb-mtp: print parent path in IN_IGNORED trace fn, Bandan Das, 2018/02/20