libmtp: chdk_ptp.h Source File

libmtp 1.1.23

chdk_ptp.h
1#ifndef __CHDK_PTP_H
2#define __CHDK_PTP_H
3
4// CHDK PTP protocol interface (can also be used in client PTP programs)
5
6// Note: used in modules and platform independent code.
7// Do not add platform dependent stuff in here (#ifdef/#endif compile options or camera dependent values)
8
9#define PTP_CHDK_VERSION_MAJOR 2 // increase only with backwards incompatible changes (and reset minor)
10#define PTP_CHDK_VERSION_MINOR 6 // increase with extensions of functionality
11 // minor > 1000 for development versions
12
13/*
14protocol version history
150.1 - initial proposal from mweerden, + luar
160.2 - Added ScriptStatus and ScriptSupport, based on work by ultimA
171.0 - removed old script result code (luar), replace with message system
182.0 - return PTP_CHDK_TYPE_TABLE for tables instead of TYPE_STRING, allow return of empty strings
192.1 - experimental live view, not formally released
202.2 - live view (work in progress)
212.3 - live view - released in 1.1
222.4 - live view protocol 2.1
232.5 - remote capture
242.6 - script execution flags
25*/
26
27#define PTP_OC_CHDK 0x9999
28
29// N.B.: unused parameters should be set to 0
30//enum ptp_chdk_command {
31enum PTP_CHDK_Command {
32 PTP_CHDK_Version = 0, // return param1 is major version number
33 // return param2 is minor version number
34 PTP_CHDK_GetMemory, // param2 is base address (not NULL; circumvent by taking 0xFFFFFFFF and size+1)
35 // param3 is size (in bytes)
36 // return data is memory block
37 PTP_CHDK_SetMemory, // param2 is address
38 // param3 is size (in bytes)
39 // data is new memory block
40 PTP_CHDK_CallFunction, // data is array of function pointer and 32 bit int arguments (max: 10 args prior to protocol 2.5)
41 // return param1 is return value
42 PTP_CHDK_TempData, // data is data to be stored for later
43 // param2 is for the TD flags below
44 PTP_CHDK_UploadFile, // data is 4-byte length of filename, followed by filename and contents
45 PTP_CHDK_DownloadFile, // preceded by PTP_CHDK_TempData with filename
46 // return data are file contents
47 PTP_CHDK_ExecuteScript, // data is script to be executed
48 // param2 is language of script
49 // in proto 2.6 and later, language is the lower byte, rest is used for PTP_CHDK_SCRIPT_FL* flags
50 // return param1 is script id, like a process id
51 // return param2 is status from ptp_chdk_script_error_type
52 PTP_CHDK_ScriptStatus, // Script execution status
53 // return param1 bits
54 // PTP_CHDK_SCRIPT_STATUS_RUN is set if a script running, cleared if not
55 // PTP_CHDK_SCRIPT_STATUS_MSG is set if script messages from script waiting to be read
56 // all other bits and params are reserved for future use
57 PTP_CHDK_ScriptSupport, // Which scripting interfaces are supported in this build
58 // param1 CHDK_PTP_SUPPORT_LUA is set if lua is supported, cleared if not
59 // all other bits and params are reserved for future use
60 PTP_CHDK_ReadScriptMsg, // read next message from camera script system
61 // return param1 is chdk_ptp_s_msg_type
62 // return param2 is message subtype:
63 // for script return and users this is ptp_chdk_script_data_type
64 // for error ptp_chdk_script_error_type
65 // return param3 is script id of script that generated the message
66 // return param4 is length of the message data.
67 // return data is message.
68 // A minimum of 1 bytes of zeros is returned if the message has no data (empty string or type NONE)
69 PTP_CHDK_WriteScriptMsg, // write a message for scripts running on camera
70 // input param2 is target script id, 0=don't care. Messages for a non-running script will be discarded
71 // data length is handled by ptp data phase
72 // input messages do not have type or subtype, they are always a string destined for the script (similar to USER/string)
73 // output param1 is ptp_chdk_script_msg_status
74 PTP_CHDK_GetDisplayData, // Return camera display data
75 // This is defined as separate sub protocol in live_view.h
76 // Changes to the sub-protocol will always be considered a minor change to the main protocol
77 // param2 bitmask of data
78 // output param1 = total size of data
79 // return data is protocol information, frame buffer descriptions and selected display data
80 // Currently a data phase is always returned. Future versions may define other behavior
81 // for values in currently unused parameters.
82 // Direct image capture over USB.
83 // Use lua get_usb_capture_support for available data types, lua init_usb_capture for setup
84 PTP_CHDK_RemoteCaptureIsReady, // Check if data is available
85 // return param1 is status
86 // 0 = not ready
87 // 0x10000000 = remote capture not initialized
88 // otherwise bitmask of PTP_CHDK_CAPTURE_* datatypes
89 // return param2 is image number
90 PTP_CHDK_RemoteCaptureGetData // retrieve data
91 // param2 is bit indicating data type to get
92 // return param1 is length
93 // return param2 more chunks available?
94 // 0 = no more chunks of selected format
95 // return param3 seek required to pos (-1 = no seek)
96};
97
98// data types as used by ReadScriptMessage
99enum ptp_chdk_script_data_type {
100 PTP_CHDK_TYPE_UNSUPPORTED = 0, // type name will be returned in data
101 PTP_CHDK_TYPE_NIL,
102 PTP_CHDK_TYPE_BOOLEAN,
103 PTP_CHDK_TYPE_INTEGER,
104 PTP_CHDK_TYPE_STRING, // Empty strings are returned with length=0
105 PTP_CHDK_TYPE_TABLE, // tables are converted to a string by usb_msg_table_to_string,
106 // this function can be overridden in lua to change the format
107 // the string may be empty for an empty table
108};
109
110// TempData flags
111#define PTP_CHDK_TD_DOWNLOAD 0x1 // download data instead of upload
112#define PTP_CHDK_TD_CLEAR 0x2 // clear the stored data; with DOWNLOAD this
113 // means first download, then clear and
114 // without DOWNLOAD this means no uploading,
115 // just clear
116
117// Script Languages - for execution only lua is supported for now
118#define PTP_CHDK_SL_LUA 0
119#define PTP_CHDK_SL_UBASIC 1
120#define PTP_CHDK_SL_MASK 0xFF
121
122/* standard message chdkptp sends */
123#define PTP_CHDK_LUA_SERIALIZE "\n\
124serialize_r = function(v,opts,r,seen,depth)\n\
125 local vt = type(v)\n\
126 if vt == 'nil' or vt == 'boolean' or vt == 'number' then\n\
127 table.insert(r,tostring(v))\n\
128 return\n\
129 end\n\
130 if vt == 'string' then\n\
131 table.insert(r,string.format('%%q',v))\n\
132 return\n\
133 end\n\
134 if vt == 'table' then\n\
135 if not depth then\n\
136 depth = 1\n\
137 end\n\
138 if depth >= opts.maxdepth then\n\
139 error('serialize: max depth')\n\
140 end\n\
141 if not seen then\n\
142 seen={}\n\
143 elseif seen[v] then\n\
144 if opts.err_cycle then\n\
145 error('serialize: cycle')\n\
146 else\n\
147 table.insert(r,'\"cycle:'..tostring(v)..'\"')\n\
148 return\n\
149 end\n\
150 end\n\
151 seen[v] = true;\n\
152 table.insert(r,'{')\n\
153 for k,v1 in pairs(v) do\n\
154 if opts.pretty then\n\
155 table.insert(r,'\\n'..string.rep(' ',depth))\n\
156 end\n\
157 if type(k) == 'string' and string.match(k,'^[_%%a][%%a%%d_]*$') then\n\
158 table.insert(r,k)\n\
159 else\n\
160 table.insert(r,'[')\n\
161 serialize_r(k,opts,r,seen,depth+1)\n\
162 table.insert(r,']')\n\
163 end\n\
164 table.insert(r,'=')\n\
165 serialize_r(v1,opts,r,seen,depth+1)\n\
166 table.insert(r,',')\n\
167 end\n\
168 if opts.pretty then\n\
169 table.insert(r,'\\n'..string.rep(' ',depth-1))\n\
170 end\n\
171 table.insert(r,'}')\n\
172 return\n\
173 end\n\
174 if opts.err_type then\n\
175 error('serialize: unsupported type ' .. vt, 2)\n\
176 else\n\
177 table.insert(r,'\"'..tostring(v)..'\"')\n\
178 end\n\
179end\n\
180serialize_defaults = {\n\
181 maxdepth=10,\n\
182 err_type=true,\n\
183 err_cycle=true,\n\
184 pretty=false,\n\
185}\n\
186function serialize(v,opts)\n\
187 if opts then\n\
188 for k,v in pairs(serialize_defaults) do\n\
189 if not opts[k] then\n\
190 opts[k]=v\n\
191 end\n\
192 end\n\
193 else\n\
194 opts=serialize_defaults\n\
195 end\n\
196 local r={}\n\
197 serialize_r(v,opts,r)\n\
198 return table.concat(r)\n\
199end\n"
200
201#define PTP_CHDK_LUA_SERIALIZE_SIMPLEQUOTE "\n\
202serialize_r = function(v,opts,r,seen,depth)\n\
203 local vt = type(v)\n\
204 if vt == 'nil' or vt == 'boolean' or vt == 'number' then\n\
205 table.insert(r,tostring(v))\n\
206 return\n\
207 end\n\
208 if vt == 'string' then\n\
209 table.insert(r,string.format('%q',v))\n\
210 return\n\
211 end\n\
212 if vt == 'table' then\n\
213 if not depth then\n\
214 depth = 1\n\
215 end\n\
216 if depth >= opts.maxdepth then\n\
217 error('serialize: max depth')\n\
218 end\n\
219 if not seen then\n\
220 seen={}\n\
221 elseif seen[v] then\n\
222 if opts.err_cycle then\n\
223 error('serialize: cycle')\n\
224 else\n\
225 table.insert(r,'\"cycle:'..tostring(v)..'\"')\n\
226 return\n\
227 end\n\
228 end\n\
229 seen[v] = true;\n\
230 table.insert(r,'{')\n\
231 for k,v1 in pairs(v) do\n\
232 if opts.pretty then\n\
233 table.insert(r,'\\n'..string.rep(' ',depth))\n\
234 end\n\
235 if type(k) == 'string' and string.match(k,'^[_%a][%a%d_]*$') then\n\
236 table.insert(r,k)\n\
237 else\n\
238 table.insert(r,'[')\n\
239 serialize_r(k,opts,r,seen,depth+1)\n\
240 table.insert(r,']')\n\
241 end\n\
242 table.insert(r,'=')\n\
243 serialize_r(v1,opts,r,seen,depth+1)\n\
244 table.insert(r,',')\n\
245 end\n\
246 if opts.pretty then\n\
247 table.insert(r,'\\n'..string.rep(' ',depth-1))\n\
248 end\n\
249 table.insert(r,'}')\n\
250 return\n\
251 end\n\
252 if opts.err_type then\n\
253 error('serialize: unsupported type ' .. vt, 2)\n\
254 else\n\
255 table.insert(r,'\"'..tostring(v)..'\"')\n\
256 end\n\
257end\n\
258serialize_defaults = {\n\
259 maxdepth=10,\n\
260 err_type=true,\n\
261 err_cycle=true,\n\
262 pretty=false,\n\
263}\n\
264function serialize(v,opts)\n\
265 if opts then\n\
266 for k,v in pairs(serialize_defaults) do\n\
267 if not opts[k] then\n\
268 opts[k]=v\n\
269 end\n\
270 end\n\
271 else\n\
272 opts=serialize_defaults\n\
273 end\n\
274 local r={}\n\
275 serialize_r(v,opts,r)\n\
276 return table.concat(r)\n\
277end\n"
278
279#define PTP_CHDK_LUA_SERIALIZE_MSGS \
280PTP_CHDK_LUA_SERIALIZE\
281"usb_msg_table_to_string=serialize\n"
282
283#define PTP_CHDK_LUA_SERIALIZE_MSGS_SIMPLEQUOTE \
284PTP_CHDK_LUA_SERIALIZE_SIMPLEQUOTE\
285"usb_msg_table_to_string=serialize\n"
286
287#define PTP_CHDK_LUA_EXTEND_TABLE \
288"function extend_table(target,source,deep)\n\
289 if type(target) ~= 'table' then\n\
290 error('extend_table: target not table')\n\
291 end\n\
292 if source == nil then\n\
293 return target\n\
294 end\n\
295 if type(source) ~= 'table' then \n\
296 error('extend_table: source not table')\n\
297 end\n\
298 if source == target then\n\
299 error('extend_table: source == target')\n\
300 end\n\
301 if deep then\n\
302 return extend_table_r(target, source)\n\
303 else \n\
304 for k,v in pairs(source) do\n\
305 target[k]=v\n\
306 end\n\
307 return target\n\
308 end\n\
309end\n"
310
311#define PTP_CHDK_LUA_MSG_BATCHER \
312PTP_CHDK_LUA_SERIALIZE_MSGS \
313PTP_CHDK_LUA_EXTEND_TABLE \
314"function msg_batcher(opts)\n\
315 local t = extend_table({\n\
316 batchsize=50,\n\
317 batchgc='step',\n\
318 timeout=100000,\n\
319 },opts)\n\
320 t.data={}\n\
321 t.n=0\n\
322 if t.dbgmem then\n\
323 t.init_free = get_meminfo().free_block_max_size\n\
324 t.init_count = collectgarbage('count')\n\
325 end\n\
326 t.write=function(self,val)\n\
327 self.n = self.n+1\n\
328 self.data[self.n]=val\n\
329 if self.n >= self.batchsize then\n\
330 return self:flush()\n\
331 end\n\
332 return true\n\
333 end\n\
334 t.flush = function(self)\n\
335 if self.n > 0 then\n\
336 if self.dbgmem then\n\
337 local count=collectgarbage('count')\n\
338 local free=get_meminfo().free_block_max_size\n\
339 self.data._dbg=string.format(\"count %%d (%%d) free %%d (%%d)\",\n\
340 count, count - self.init_count, free, self.init_free-free)\n\
341 end\n\
342 if not write_usb_msg(self.data,self.timeout) then\n\
343 return false\n\
344 end\n\
345 self.data={}\n\
346 self.n=0\n\
347 if self.batchgc then\n\
348 collectgarbage(self.batchgc)\n\
349 end\n\
350 if self.batchpause then\n\
351 sleep(self.batchpause)\n\
352 end\n\
353 end\n\
354 return true\n\
355 end\n\
356 return t\n\
357end\n"
358
359#define PTP_CHDK_LUA_LS_SIMPLE \
360PTP_CHDK_LUA_MSG_BATCHER \
361"function ls_simple(path)\n\
362 local b=msg_batcher()\n\
363 local t,err=os.listdir(path)\n\
364 if not t then\n\
365 return false,err\n\
366 end\n\
367 for i,v in ipairs(t) do\n\
368 if not b:write(v) then\n\
369 return false\n\
370 end\n\
371 end\n\
372 return b:flush()\n\
373end\n"
374
375#define PTP_CHDK_LUA_JOINPATH \
376"function joinpath(...)\n\
377 local parts={...}\n\
378 if #parts < 2 then\n\
379 error('joinpath requires at least 2 parts',2)\n\
380 end\n\
381 local r=parts[1]\n\
382 for i = 2, #parts do\n\
383 local v = string.gsub(parts[i],'^/','')\n\
384 if not string.match(r,'/$') then\n\
385 r=r..'/'\n\
386 end\n\
387 r=r..v\n\
388 end\n\
389 return r\n\
390end\n"
391
392#define PTP_CHDK_LUA_LS \
393PTP_CHDK_LUA_MSG_BATCHER \
394PTP_CHDK_LUA_JOINPATH \
395"function ls_single(opts,b,path,v)\n\
396 if not opts.match or string.match(v,opts.match) then\n\
397 if opts.stat then\n\
398 local st,msg=os.stat(joinpath(path,v))\n\
399 if not st then\n\
400 return false,msg\n\
401 end\n\
402 if opts.stat == '/' then\n\
403 if st.is_dir then\n\
404 b:write(v .. '/')\n\
405 else\n\
406 b:write(v)\n\
407 end\n\
408 elseif opts.stat == '*' then\n\
409 st.name=v\n\
410 b:write(st)\n\
411 end\n\
412 else\n\
413 b:write(v)\n\
414 end\n\
415 end\n\
416 return true\n\
417end\n\
418\n\
419function ls(path,opts_in)\n\
420 local opts={\n\
421 msglimit=50,\n\
422 msgtimeout=100000,\n\
423 dirsonly=true\n\
424 }\n\
425 if opts_in then\n\
426 for k,v in pairs(opts_in) do\n\
427 opts[k]=v\n\
428 end\n\
429 end\n\
430 local st, err = os.stat(path)\n\
431 if not st then\n\
432 return false, err\n\
433 end\n\
434 \n\
435 local b=msg_batcher{\n\
436 batchsize=opts.msglimit,\n\
437 timeout=opts.msgtimeout\n\
438 }\n\
439 \n\
440 if not st.is_dir then\n\
441 if opts.dirsonly then\n\
442 return false, 'not a directory'\n\
443 end\n\
444 if opts.stat == '*' then\n\
445 st.name=path\n\
446 b:write(st)\n\
447 else\n\
448 b:write(path)\n\
449 end\n\
450 b:flush()\n\
451 return true\n\
452 end\n\
453 \n\
454 if os.idir then\n\
455 for v in os.idir(path,opts.listall) do\n\
456 local status,err=ls_single(opts,b,path,v)\n\
457 if not status then\n\
458 return false, err\n\
459 end\n\
460 end\n\
461 else\n\
462 local t,msg=os.listdir(path,opts.listall)\n\
463 if not t then\n\
464 return false,msg\n\
465 end\n\
466 for i,v in ipairs(t) do\n\
467 local status,err=ls_single(opts,b,path,v)\n\
468 if not status then\n\
469 return false, err\n\
470 end\n\
471 end\n\
472 end\n\
473 b:flush()\n\
474 return true\n\
475end\n"
476
477#define PTP_CHDK_LUA_RLIB_SHOOT_COMMON \
478"function rlib_shoot_init_exp(opts) \n\
479 if opts.tv then\n\
480 set_tv96_direct(opts.tv)\n\
481 end\n\
482 if opts.sv then\n\
483 set_sv96(opts.sv)\n\
484 end\n\
485 if opts.svm then\n\
486 if type(sv96_market_to_real) ~= 'function' then\n\
487 error('svm not supported')\n\
488 end\n\
489 set_sv96(sv96_market_to_real(opts.svm))\n\
490 end\n\
491 if opts.isomode then\n\
492 set_iso_mode(opts.isomode)\n\
493 end\n\
494 if opts.av then\n\
495 set_av96_direct(opts.av)\n\
496 end\n\
497 if opts.nd then\n\
498 set_nd_filter(opts.nd)\n\
499 end\n\
500 if opts.sd then\n\
501 set_focus(opts.sd)\n\
502 end\n\
503end\n"
504
505#define PTP_CHDK_LUA_RLIB_SHOOT \
506PTP_CHDK_LUA_RLIB_SHOOT_COMMON \
507"function rlib_shoot(opts)\n\
508 local rec,vid = get_mode()\n\
509 if not rec then\n\
510 return false,'not in rec mode'\n\
511 end\n\
512\n\
513 rlib_shoot_init_exp(opts)\n\
514\n\
515 local save_raw\n\
516 if opts.raw then\n\
517 save_raw=get_raw()\n\
518 set_raw(opts.raw)\n\
519 end\n\
520 local save_dng\n\
521 if opts.dng then\n\
522 save_dng=get_config_value(226)\n\
523 set_config_value(226,opts.dng)\n\
524 end\n\
525 shoot()\n\
526 local r\n\
527 if opts.info then\n\
528 r = {\n\
529 dir=get_image_dir(),\n\
530 exp=get_exp_count(),\n\
531 raw=(get_raw() == 1),\n\
532 }\n\
533 if r.raw then\n\
534 r.raw_in_dir = (get_config_value(35) == 1)\n\
535 r.raw_pfx = get_config_value(36)\n\
536 r.raw_ext = get_config_value(37)\n\
537 r.dng = (get_config_value(226) == 1)\n\
538 if r.dng then\n\
539 r.use_dng_ext = (get_config_value(234) == 1)\n\
540 end\n\
541 end\n\
542 else\n\
543 r=true\n\
544 end\n\
545 if save_raw then\n\
546 set_raw(save_raw)\n\
547 end\n\
548 if save_dng then\n\
549 set_config_value(226,save_dng)\n\
550 end\n\
551 return r\n\
552end\n"
553
554
555
556// bit flags for script start
557#define PTP_CHDK_SCRIPT_FL_NOKILL 0x100 // if script is running return error instead of killing
558#define PTP_CHDK_SCRIPT_FL_FLUSH_CAM_MSGS 0x200 // discard existing cam->host messages before starting
559#define PTP_CHDK_SCRIPT_FL_FLUSH_HOST_MSGS 0x400 // discard existing host->cam messages before starting
560
561// bit flags for script status
562#define PTP_CHDK_SCRIPT_STATUS_RUN 0x1 // script running
563#define PTP_CHDK_SCRIPT_STATUS_MSG 0x2 // messages waiting
564// bit flags for scripting support
565#define PTP_CHDK_SCRIPT_SUPPORT_LUA 0x1
566
567
568// bit flags for remote capture
569// used to select and also to indicate available data in PTP_CHDK_RemoteCaptureIsReady
570/*
571Full jpeg file. Note supported on all cameras, use Lua get_usb_capture_support to check
572*/
573#define PTP_CHDK_CAPTURE_JPG 0x1
574
575/*
576Raw framebuffer data, in camera native format.
577A subset of rows may be requested in init_usb_capture.
578*/
579#define PTP_CHDK_CAPTURE_RAW 0x2
580
581/*
582DNG header.
583The header will be DNG version 1.3
584Does not include image data, clients wanting to create a DNG file should also request RAW
585Raw data for all known cameras will be packed, little endian. Client is responsible for
586reversing the byte order if creating a DNG.
587Can requested without RAW to get sensor dimensions, exif values etc.
588
589ifd 0 specifies a 128x96 RGB thumbnail, 4 byte aligned following the header
590client is responsible for generating thumbnail data.
591
592ifd 0 subifd 0 specifies the main image
593The image dimensions always contain the full sensor dimensions, if a sub-image was requested
594with init_usb_capture, the client is responsible for padding the data to the full image or
595adjusting dimensions.
596
597Bad pixels will not be patched, but DNG opcodes will specify how to patch them
598*/
599#define PTP_CHDK_CAPTURE_DNGHDR 0x4
600
601// status from PTP_CHDK_RemoteCaptureIsReady if capture not enabled
602#define PTP_CHDK_CAPTURE_NOTSET 0x10000000
603
604// message types
605enum ptp_chdk_script_msg_type {
606 PTP_CHDK_S_MSGTYPE_NONE = 0, // no messages waiting
607 PTP_CHDK_S_MSGTYPE_ERR, // error message
608 PTP_CHDK_S_MSGTYPE_RET, // script return value
609 PTP_CHDK_S_MSGTYPE_USER, // message queued by script
610// TODO chdk console data ?
611};
612
613// error subtypes for PTP_CHDK_S_MSGTYPE_ERR and script startup status
614enum ptp_chdk_script_error_type {
615 PTP_CHDK_S_ERRTYPE_NONE = 0,
616 PTP_CHDK_S_ERRTYPE_COMPILE,
617 PTP_CHDK_S_ERRTYPE_RUN,
618 // the following are for ExecuteScript status only, not message types
619 PTP_CHDK_S_ERR_SCRIPTRUNNING = 0x1000, // script already running with NOKILL
620};
621
622// message status
623enum ptp_chdk_script_msg_status {
624 PTP_CHDK_S_MSGSTATUS_OK = 0, // queued ok
625 PTP_CHDK_S_MSGSTATUS_NOTRUN, // no script is running
626 PTP_CHDK_S_MSGSTATUS_QFULL, // queue is full
627 PTP_CHDK_S_MSGSTATUS_BADID, // specified ID is not running
628};
629
630#endif // __CHDK_PTP_H