Hi chdk'ers, this is my first post!!! I'm working on implementing the PTP protocol in kotlin for some things I'm playing around with and the descriptions in ptp.h are helpful, but I have some points of confusion on the description I could use help with if anyone knows the answers off-hand.
Welcome. There isn't really a description beyond what's in ptp.h and live_view.h. If you want working (I hope
) examples, you can refer to the ptp_chdk_* functions in the chdkptp
client source http://subversion.assembla.com/svn/chdkptp/trunk/ptp.c
I've noticed that Live view only returns a data message and not a response message. Is it standard for the PTP flow to not return a seperate response when data is returned (Can I expect the same behavior from GetMemory/etc...)?
It varies. CHDK ptp.h should describe the behavior of each operation, if something is wrong or unclear, feel free to post here.
PTP_CHDK_GetDisplayData actually returns total size param 1, though the client should also be able to determine this in the data phase.
PTP_CHDK_GetMemory returns everything in the data phase.
PTP_CHDK_ReadScriptMsg returns various attributes of the message in return params, and only the message body as data.
The relationship between TempData and DownloadFile is confusing even with the description.
As I read it, the flow looks like:
Send TempData command with Download (and possibly clear flag)
It should set PTP_CHDK_TD_DOWNLOAD, and the data phase should be the filenname.
For download, the clear flag is not actually used. The filename will be cleared and free'd automatically in the PTP_CHDK_DownloadFile despite what the comments say. (hmm, I should fix that)
And in fact, there is currently no *other* use of TempData. This was a very early part of the protocol and it was assumed other operations would need something similar, but so far they haven't.
Get response from TempDataCommand
It doesn't return parameters, but you should check for RC_OK
Send DownloadFile Command
Receive download file data (and at this point tempdata will be cleared if clear flag was included)
As above, it will be cleared no matter what.
Send a data packet with the encoded filename
The file name was sent in the TempData command, before Download. That's whole reason it is needed, because PTP only allows bulk data in one direction.
RemoteCaptureGetData, I haven't gone too deep into this yet because deciphering the interplay between lua and ptp will take some work, it would be nice to see the typical flow for what is expected to be sent/recieved for a single retrieval.
You can see some of this if you use the remoteshoot command in chdkptp with cli_verbose=2
However, be warned that different camera models behave differently.
Based on the comment in ptp.h, so far I'm wondering what does "return param3 seek required to pos (-1 = no seek)" mean? Is that param3 supposed to be used somewhere on the client side or is it just informational
Unfortunately, it's inherently complicated (for jpeg) because of how it's hooked into the Canon firmware. See platform/generic/filewrite.c and core/remotecap.c in the CHDK source.
jpeg remote shoot is implemented by hooking the Canon filewrite firmware task (process/thread) that would normally write the file to the SD card. We modify it to replace calls to open(), write(), seek(), close() with our own functions. At certain points, we block the calling task (which thinks it's writing to the SD card) until the PTP client asks* for a chunk. Then we send the data that would been written in the write() call over PTP instead. When PTP transaction is done, we allow the filewrite task to continue.
The behavior of the Canon filewrite task has varied over the years. Some models just sequentially write chunks. Others open, close and seek between writes. Because client is essentially just pretending it's the filesystem, it needs to replicate the seek calls on the received data
So the seek described in return param3 must cause the data to be written the specified offset in the file. See chdku.rc_handler_file in chdkptp/lua/chdku.lua
Note that CHDK raw/DNG is much simpler. In that case, we control the writing and have the entire raw image in memory, so it's just the header (for DNG) and data in single chunks.
* We don't have PTP events / interrupts on the camera side, so everything is done by polling
PTP_CHDK_S_ERR_SCRIPTRUNNING = 0x1000, // script already running with NOKILL... Does this mean the previous call was run with the nokill flag and that makes it durable, or that the current call is run with the nokill flag and therefore errors out instead of killing the script that is running?
No, the NOKILL determines how any existing, running script is handled when you try to run a new one:
#define PTP_CHDK_SCRIPT_FL_NOKILL 0x100 // if script is running return error instead of killing
If a script is already running and you call PTP_CHDK_ExecuteScript, the default behavior is to silently kill the running script. If you specify NOKILL, then it returns an error instead.
Silently clobbering was the original behavior, but in practice it's often not what you want, and calling PTP_CHDK_ScriptStatus before every script execution added a lot of overhead.