|
From: Alistair B. <a.j...@gm...> - 2017-12-09 18:02:38
|
Hi, me again. I am trying to implement sending files to my responder. Sending whole files works. But if I open a text file using gfvs, edit it, and then try to save it directly back, I get "operation not supported". I by a process of elimination I identified the missing operation to be "get object properties list". So I implemented it, and then sent back an empty list of properties. This caused gvfs to crash. What properties do I need to implement in order to make this work? -- Alistair Buxton a.j...@gm... |
|
From: Alistair B. <a.j...@gm...> - 2017-12-09 19:31:11
|
I have implemented the following operations and properties and it
still doesn't work:
Supported operations:
1001: Get device info
1002: Open session
1003: Close session
1004: Get storage IDs
1005: Get storage info
1006: Get number of objects
1007: Get object handles
1008: Get object info
1009: Get object
100b: Delete object
100c: Send object info
100d: Send object
1014: Get device property description
1015: Get device property value
1016: Set device property value
1017: Reset device property value
101b: Get partial object
95c1: Get Partial Object (64bit Offset)
95c2: Send Partial Object
95c3: Truncate Object
95c4: Begin Edit Object
95c5: End Edit Object
9801: Get object properties supported
9802: Get object property description
9803: Get object property value
9804: Set object property value
9810: Get object references
9811: Set object references
Events supported:
0x4002 ((null))
0x4003 ((null))
0x4004 ((null))
0x4005 ((null))
0x4007 ((null))
0x4008 ((null))
0x400a ((null))
0x400b ((null))
0x400c ((null))
0x400e ((null))
Device Properties Supported:
0xd401: Synchronization Partner
0xd402: Friendly Device Name
Playable File (Object) Types and Object Properties Supported:
3000: Undefined Type
dc01: Storage ID UINT32 data type ANY 32BIT VALUE form GET/SET
dc02: Object Format UINT16 data type ANY 16BIT VALUE form GET/SET
dc03: Protection Status UINT16 data type ANY 16BIT VALUE form GET/SET
dc04: Object Size UINT64 data type GET/SET
dc07: Object File Name STRING data type GET/SET
dc09: Date Modified STRING data type GET/SET
dc0b: Parent Object UINT32 data type ANY 32BIT VALUE form GET/SET
dc44: Name STRING data type GET/SET
3001: Association/Directory
dc01: Storage ID UINT32 data type ANY 32BIT VALUE form GET/SET
dc02: Object Format UINT16 data type ANY 16BIT VALUE form GET/SET
dc03: Protection Status UINT16 data type ANY 16BIT VALUE form GET/SET
dc04: Object Size UINT64 data type GET/SET
dc07: Object File Name STRING data type GET/SET
dc09: Date Modified STRING data type GET/SET
dc0b: Parent Object UINT32 data type ANY 32BIT VALUE form GET/SET
dc44: Name STRING data type GET/SET
This is the tail of gvfs debug output:
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (I) do_query_info
(filename = /Files/pi-tftp/tftpboot-old/config.txt)
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (III)
get_cache_entry: /Files/pi-tftp/tftpboot-old/config.txt
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (III)
get_cache_entry done: 0x7f46ac017ac0
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (II) get_file_info: 107
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (II) get_file_info done.
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]:
send_reply(0x7f46c4002a00), failed=0 ()
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (I) do_query_info done.
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]:
backend_dbus_handler org.gtk.vfs.Mount:OpenForWriteFlags
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: Queued new job
0x7f46ac00b040 (GVfsJobOpenForWrite)
Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]:
send_reply(0x7f46ac00b040), failed=1 (Operation unsupported)
And this is the tail of debug log from my side:
DEBUG:mtp.responder:Operation: GET_OBJECT_PROPS_SUPPORTED 0x3001 0x0 0x0 0x0 0x0
WARNING:mtp.responder:format 0x3001
DEBUG:mtp.responder:Response: OK None None None None None
DEBUG:mtp.responder:Operation: GET_OBJECT_PROP_VALUE 0x10c 0xdc04 0x0 0x0 0x0
DEBUG:mtp.responder:Response: OK None None None None None
DEBUG:mtp.responder:Operation: GET_OBJECT_PROPS_SUPPORTED 0x3001 0x0 0x0 0x0 0x0
WARNING:mtp.responder:format 0x3001
DEBUG:mtp.responder:Response: OK None None None None None
DEBUG:mtp.responder:Operation: GET_OBJECT_PROP_VALUE 0x10b 0xdc04 0x0 0x0 0x0
DEBUG:mtp.responder:Response: OK None None None None None
DEBUG:mtp.responder:Operation: GET_OBJECT_PROPS_SUPPORTED 0x3000 0x0 0x0 0x0 0x0
WARNING:mtp.responder:format 0x3000
DEBUG:mtp.responder:Response: OK None None None None None
DEBUG:mtp.responder:Operation: GET_OBJECT_PROP_VALUE 0x107 0xdc04 0x0 0x0 0x0
DEBUG:mtp.responder:Response: OK None None None None None
DEBUG:mtp.responder:Operation: GET_OBJECT_PROPS_SUPPORTED 0x3000 0x0 0x0 0x0 0x0
WARNING:mtp.responder:format 0x3000
DEBUG:mtp.responder:Response: OK None None None None None
DEBUG:mtp.responder:Operation: GET_OBJECT_PROP_VALUE 0x107 0xdc04 0x0 0x0 0x0
DEBUG:mtp.responder:Response: OK None None None None None
So gvfs just asks for the object size repeatedly and does not ever
attempt to transfer the saved file.
What is going on here?
--
Alistair Buxton
a.j...@gm...
|
|
From: Philip L. <ph...@ov...> - 2017-12-09 22:59:41
|
On 2017-12-09 19:31, Alistair Buxton wrote: > I have implemented the following operations and properties and it > still doesn't work: > > Supported operations: > 1001: Get device info > 1002: Open session > 1003: Close session > 1004: Get storage IDs > 1005: Get storage info > 1006: Get number of objects > 1007: Get object handles > 1008: Get object info > 1009: Get object > 100b: Delete object > 100c: Send object info > 100d: Send object > 1014: Get device property description > 1015: Get device property value > 1016: Set device property value > 1017: Reset device property value > 101b: Get partial object > 95c1: Get Partial Object (64bit Offset) > 95c2: Send Partial Object > 95c3: Truncate Object > 95c4: Begin Edit Object > 95c5: End Edit Object > 9801: Get object properties supported > 9802: Get object property description > 9803: Get object property value > 9804: Set object property value > 9810: Get object references > 9811: Set object references > Events supported: > 0x4002 ((null)) > 0x4003 ((null)) > 0x4004 ((null)) > 0x4005 ((null)) > 0x4007 ((null)) > 0x4008 ((null)) > 0x400a ((null)) > 0x400b ((null)) > 0x400c ((null)) > 0x400e ((null)) > Device Properties Supported: > 0xd401: Synchronization Partner > 0xd402: Friendly Device Name > Playable File (Object) Types and Object Properties Supported: > 3000: Undefined Type > dc01: Storage ID UINT32 data type ANY 32BIT VALUE form GET/SET > dc02: Object Format UINT16 data type ANY 16BIT VALUE form GET/SET > dc03: Protection Status UINT16 data type ANY 16BIT VALUE form > GET/SET > dc04: Object Size UINT64 data type GET/SET > dc07: Object File Name STRING data type GET/SET > dc09: Date Modified STRING data type GET/SET > dc0b: Parent Object UINT32 data type ANY 32BIT VALUE form GET/SET > dc44: Name STRING data type GET/SET > 3001: Association/Directory > dc01: Storage ID UINT32 data type ANY 32BIT VALUE form GET/SET > dc02: Object Format UINT16 data type ANY 16BIT VALUE form GET/SET > dc03: Protection Status UINT16 data type ANY 16BIT VALUE form > GET/SET > dc04: Object Size UINT64 data type GET/SET > dc07: Object File Name STRING data type GET/SET > dc09: Date Modified STRING data type GET/SET > dc0b: Parent Object UINT32 data type ANY 32BIT VALUE form GET/SET > dc44: Name STRING data type GET/SET > > This is the tail of gvfs debug output: > > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (I) do_query_info > (filename = /Files/pi-tftp/tftpboot-old/config.txt) > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (III) > get_cache_entry: /Files/pi-tftp/tftpboot-old/config.txt > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (III) > get_cache_entry done: 0x7f46ac017ac0 > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (II) > get_file_info: 107 > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (II) get_file_info > done. > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: > send_reply(0x7f46c4002a00), failed=0 () > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: (I) do_query_info > done. > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: > backend_dbus_handler org.gtk.vfs.Mount:OpenForWriteFlags > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: Queued new job > 0x7f46ac00b040 (GVfsJobOpenForWrite) > Dec 09 19:28:10 al-desktop org.gtk.vfs.Daemon[2782]: > send_reply(0x7f46ac00b040), failed=1 (Operation unsupported) I don't know about how reasonable your device side call trace is but: https://git.gnome.org/browse/gvfs/tree/daemon/gvfsbackendmtp.c?h=gnome-3-26#n2527 You need to declare the android extension string for gvfsd-mtp to try and use the direct I/O extensions. > And this is the tail of debug log from my side: > > DEBUG:mtp.responder:Operation: GET_OBJECT_PROPS_SUPPORTED 0x3001 0x0 > 0x0 0x0 0x0 > WARNING:mtp.responder:format 0x3001 > DEBUG:mtp.responder:Response: OK None None None None None > DEBUG:mtp.responder:Operation: GET_OBJECT_PROP_VALUE 0x10c 0xdc04 0x0 > 0x0 0x0 > DEBUG:mtp.responder:Response: OK None None None None None > DEBUG:mtp.responder:Operation: GET_OBJECT_PROPS_SUPPORTED 0x3001 0x0 > 0x0 0x0 0x0 > WARNING:mtp.responder:format 0x3001 > DEBUG:mtp.responder:Response: OK None None None None None > DEBUG:mtp.responder:Operation: GET_OBJECT_PROP_VALUE 0x10b 0xdc04 0x0 > 0x0 0x0 > DEBUG:mtp.responder:Response: OK None None None None None > DEBUG:mtp.responder:Operation: GET_OBJECT_PROPS_SUPPORTED 0x3000 0x0 > 0x0 0x0 0x0 > WARNING:mtp.responder:format 0x3000 > DEBUG:mtp.responder:Response: OK None None None None None > DEBUG:mtp.responder:Operation: GET_OBJECT_PROP_VALUE 0x107 0xdc04 0x0 > 0x0 0x0 > DEBUG:mtp.responder:Response: OK None None None None None > DEBUG:mtp.responder:Operation: GET_OBJECT_PROPS_SUPPORTED 0x3000 0x0 > 0x0 0x0 0x0 > WARNING:mtp.responder:format 0x3000 > DEBUG:mtp.responder:Response: OK None None None None None > DEBUG:mtp.responder:Operation: GET_OBJECT_PROP_VALUE 0x107 0xdc04 0x0 > 0x0 0x0 > DEBUG:mtp.responder:Response: OK None None None None None > > So gvfs just asks for the object size repeatedly and does not ever > attempt to transfer the saved file. > > What is going on here? --phil |
|
From: Alistair B. <a.j...@gm...> - 2017-12-10 02:11:51
|
On 9 December 2017 at 22:59, Philip Langdale <ph...@ov...> wrote: > I don't know about how reasonable your device side call trace is but: > > https://git.gnome.org/browse/gvfs/tree/daemon/gvfsbackendmtp.c?h=gnome-3-26#n2527 > > You need to declare the android extension string for gvfsd-mtp to try and > use the > direct I/O extensions. > > --phil That's the problem then. I didn't declare the extension strings, just implemented the functions. But interestingly, gvfs still uses some of the android extensions - I have seen at least GET_PARTIAL_FILE_64 in my logs after I added it. I will implement those strings tomorrow and report back if it works. Thanks. -- Alistair Buxton a.j...@gm... |
|
From: Alistair B. <a.j...@gm...> - 2017-12-10 10:41:33
|
On 10 December 2017 at 02:11, Alistair Buxton <a.j...@gm...> wrote: > On 9 December 2017 at 22:59, Philip Langdale <ph...@ov...> wrote: > >> I don't know about how reasonable your device side call trace is but: >> >> https://git.gnome.org/browse/gvfs/tree/daemon/gvfsbackendmtp.c?h=gnome-3-26#n2527 >> >> You need to declare the android extension string for gvfsd-mtp to try and >> use the >> direct I/O extensions. >> >> --phil > > That's the problem then. I didn't declare the extension strings, just > implemented the functions. But interestingly, gvfs still uses some of > the android extensions - I have seen at least GET_PARTIAL_FILE_64 in > my logs after I added it. > > I will implement those strings tomorrow and report back if it works. Okay, this worked - I added the extension strings and now gvfs is calling my stubs. So I need to finish implementing those. Would I be right in saying the microsoft extensions are the operations beginning with 0x98.. and the google ones are the ones beginning with 0x95..? If I don't implement the 0x98.. operations (object properties), is it okay to not send the microsoft extension string? Finally, where are the google extensions documented? They don't seem to be in the MTP spec. -- Alistair Buxton a.j...@gm... |
|
From: Philip L. <ph...@ov...> - 2017-12-11 02:26:17
|
On Sun, 10 Dec 2017 10:41:25 +0000 Alistair Buxton <a.j...@gm...> wrote: > On 10 December 2017 at 02:11, Alistair Buxton <a.j...@gm...> > wrote: > > On 9 December 2017 at 22:59, Philip Langdale <ph...@ov...> > > wrote: > >> I don't know about how reasonable your device side call trace is > >> but: > >> > >> https://git.gnome.org/browse/gvfs/tree/daemon/gvfsbackendmtp.c?h=gnome-3-26#n2527 > >> > >> You need to declare the android extension string for gvfsd-mtp to > >> try and use the > >> direct I/O extensions. > >> > >> --phil > > > > That's the problem then. I didn't declare the extension strings, > > just implemented the functions. But interestingly, gvfs still uses > > some of the android extensions - I have seen at least > > GET_PARTIAL_FILE_64 in my logs after I added it. > > > > I will implement those strings tomorrow and report back if it > > works. > > Okay, this worked - I added the extension strings and now gvfs is > calling my stubs. So I need to finish implementing those. Glad to hear. > Would I be right in saying the microsoft extensions are the operations > beginning with 0x98.. and the google ones are the ones beginning with > 0x95..? > > If I don't implement the 0x98.. operations (object properties), is it > okay to not send the microsoft extension string? I don't know. I didn't consider if there's a specific namespace there, but I guess it makes sense. > Finally, where are the google extensions documented? They don't seem > to be in the MTP spec. > They are not part of the core spec, so would not be documented there. I never found any documentation for them - I used: https://github.com/hanwen/go-mtpfs as my reference as this was written by a Googler who understood how the extensions worked. --phil |
|
From: Alistair B. <a.j...@gm...> - 2017-12-11 12:55:00
|
On 11 December 2017 at 02:26, Philip Langdale <ph...@ov...> wrote: > They are not part of the core spec, so would not be documented there. I > never found any documentation for them - I used: > > https://github.com/hanwen/go-mtpfs > > as my reference as this was written by a Googler who understood how the > extensions worked. > > --phil Okay, thanks. I've implemented everything now and it all seems to work, but I'm hitting timestamp problems. Basically when I save a text file from my editor it checks the timestamp after writing, but gvfs does not update the timestamp until the file is closed. This causes the editor to produce spurious "file externally modified" warnings. Is this expected behaviour? Should the editor deal with it? This is more of a gvfs question, is there a more appropriate mailing list for that? -- Alistair Buxton a.j...@gm... |
|
From: Philip L. <ph...@ov...> - 2017-12-20 04:27:14
|
On Mon, 11 Dec 2017 12:54:52 +0000 Alistair Buxton <a.j...@gm...> wrote: > On 11 December 2017 at 02:26, Philip Langdale <ph...@ov...> > wrote: > > > They are not part of the core spec, so would not be documented > > there. I never found any documentation for them - I used: > > > > https://github.com/hanwen/go-mtpfs > > > > as my reference as this was written by a Googler who understood how > > the extensions worked. > > > > --phil > > Okay, thanks. > > I've implemented everything now and it all seems to work, but I'm > hitting timestamp problems. > > Basically when I save a text file from my editor it checks the > timestamp after writing, but gvfs does not update the timestamp until > the file is closed. This causes the editor to produce spurious "file > externally modified" warnings. > > Is this expected behaviour? Should the editor deal with it? > > This is more of a gvfs question, is there a more appropriate mailing > list for that? > The modified time of the file is set on the device side (in this case, your code). gvfs does not directly modify any file attributes like the modification time - that's the device's responsibility. --phil |