viveris / uMTP-Responder

Lightweight USB Media Transfer Protocol (MTP) responder daemon for GNU/Linux
GNU General Public License v3.0
192 stars 52 forks source link

inotify of new file uploaded? #46

Open EricPHassey opened 3 years ago

EricPHassey commented 3 years ago

I see that inotify is being used. I'm looking to get notified anytime a new file has been added to the MTP. Is this functionality currently added, or is this something I'll need to add separately.

jfdelnero commented 3 years ago

The inotify and mtp events are already supported. This doesn't work for you ?

studiofuga commented 3 years ago

I have issues too with inotify. At least, it doesn't seem to be an issue with inotify but with the interrupt transfer. After a long debug, I found that when configured with FunctionFS, the Interrupt EP write blocks and fails with ret=-1. It seems an undocumented but apparently known issue that Interrupt Transfert are NOT supported with FunctionFS. This is what my experience, I Haven't tried with GadgetFS.

The issue also seems to hang the Linux host (KIO) when copying a file on the gadget. Disabling the inotify function from the config files definitely fix it.

Hope that helps.

jfdelnero commented 3 years ago

As far i know, the Interrupt EP is working properly, at least with the targets i am using. Which target have you ? (CPU, Kernel version...)

studiofuga commented 3 years ago

I found a few bugs (missing pthread_mutex_unlock) in some op, but they seem unrelated.

This is a small capture I got.

[uMTPrd - 11:04:46 - Debug] 16 58 4D 48 0C E1 9E C7 BA 7A 42 69 F4 FE 35 A9  .XMH.....zBi..5. 
[uMTPrd - 11:04:46 - Debug] 9D 8F 53 0E                                      ..S.             
[uMTPrd - 11:04:46 - Debug] mtp_get_storage_flags : FFFF0003
[uMTPrd - 11:04:46 - Debug] mtp_get_storage_flags : FFFF0003 -> 0x00000000
[uMTPrd - 11:04:46 - Debug] mtp_get_storage_root : FFFF0003
[uMTPrd - 11:04:46 - Debug] mtp_get_storage_root : FFFF0003 -> /var/lib/updates
[uMTPrd - 11:04:46 - Debug] build_full_path : msqlitecpp1_1.99.6_amd64.deb -> /var/lib/updates/msqlitecpp1_1.99.6_amd64.deb
[uMTPrd - 11:04:46 - Debug] Status response (12 Bytes):
[uMTPrd - 11:04:46 - Debug] Entry 0 - /
[uMTPrd - 11:04:46 - Debug] 0C 00 00 00 03 00 01 20 27 00 00 00              ............     
[uMTPrd - 11:04:46 - Debug] mtp_get_storage_root : FFFF0003
[uMTPrd - 11:04:46 - Debug] mtp_get_storage_root : FFFF0003 -> /var/lib/updates
[uMTPrd - 11:04:46 - Debug] build_full_path : / -> /var/lib/updates//
[uMTPrd - 11:04:46 - Debug] mtp_push_event : Event packet buffer - 16 Bytes :
[uMTPrd - 11:04:46 - Debug] 10 00 00 00 04 00 07 40 01 00 00 00 02 00 00 00  .......@........ 
[uMTPrd - 11:04:46 - Debug] --------------------------------------------------
[uMTPrd - 11:04:46 - Debug] Incoming_packet : 0x3d950 - rawsize : 16
[uMTPrd - 11:04:46 - Debug] MTP Packet size : 16 bytes
[uMTPrd - 11:04:46 - Debug] MTP Operation   : 0x0001 (OPERATION)
[uMTPrd - 11:04:46 - Debug] MTP code        : 0x1008 (MTP_OPERATION_GET_OBJECT_INFO)
[uMTPrd - 11:04:46 - Debug] MTP Tx ID       : 0x00000028
[uMTPrd - 11:04:46 - Debug] Header : 
[uMTPrd - 11:04:46 - Debug] 10 00 00 00 01 00 08 10 28 00 00 00              ........(...     
[uMTPrd - 11:04:46 - Debug] Payload : 
[uMTPrd - 11:04:46 - Debug] 02 00 00 00                                      ....             
[uMTPrd - 11:10:26 - Debug] 1 event(s)
[uMTPrd - 11:10:26 - Debug] EP0 FFS DISABLE
[uMTPrd - 11:10:26 - Debug] write_usb return: -1
[uMTPrd - 11:10:26 - Debug] inotify_thread (IN_MODIFY): Entry msqlitecpp1_1.99.6_amd64.deb modified (Handle 0x00000002)
[uMTPrd - 11:10:26 - Debug] inotify_thread (IN_MODIFY): Watch point descriptor not found in the db ! (Descriptor 0x00000001)

This happens after the last block of data of the SendObject function. the mtp_push_event is generated by the IN_CREATE event; at 11.04 the subsequent GetObjectInfo is blocked by the mutex that is busy trying to write to the USB interrupt endpoint. After a while (6 minutes) the usb write fails, probably due to the incoming FFS Disable event, so the mutex is unlocked and the write of the GetObjectInfo continues. Unfurtunately this happens too late and the client in the host side just timed out.

Anyway, I have not understood why the write to the Interrupt EP fails. I found somewhere in the net that FunctionFS doens't support this kind of setup, though I'm a bit surprised, that would explain the issue I'm experiencing.

My board is a AllWinner A33 cpu board similar to the Olimex A33 board. USB connector is a USB-C so it has some difference.

Kernel is 4.19, usb driver is sun4i-usb-phy. The mtp responder is setup using FunctionFS, not GadgetFS. At the moment, due to some limitation, I can't test it with GadgetFS and anyway we couldn't use it because of our USB setup (we need to provide multiple interface).

It is possible that the problem is in our kernel, I can't exclude. Anyway, disabling inotify just fix the issue on our side and the responder works perfectly on both linux and MacOS.

studiofuga commented 3 years ago

More precisely: we're configuring the gadget using ConfigFS.

jfdelnero commented 3 years ago

for sure the interrupt endpoints are supported by FunctionFS. What might not be supported is the MTP file transfer cancellation/interruption, which is a specific low level usb message, but you don't appear to use it in the present case. Have you tried to reduce the usb buffer size to 0x200 bytes ? (usb_max_packet_size in the config file)