libmtp  1.1.18
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 /*
14 protocol version history
15 0.1 - initial proposal from mweerden, + luar
16 0.2 - Added ScriptStatus and ScriptSupport, based on work by ultimA
17 1.0 - removed old script result code (luar), replace with message system
18 2.0 - return PTP_CHDK_TYPE_TABLE for tables instead of TYPE_STRING, allow return of empty strings
19 2.1 - experimental live view, not formally released
20 2.2 - live view (work in progress)
21 2.3 - live view - released in 1.1
22 2.4 - live view protocol 2.1
23 2.5 - remote capture
24 2.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 {
31 enum 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
99 enum 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\
124 serialize_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\
179 end\n\
180 serialize_defaults = {\n\
181  maxdepth=10,\n\
182  err_type=true,\n\
183  err_cycle=true,\n\
184  pretty=false,\n\
185 }\n\
186 function 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\
199 end\n"
200 
201 #define PTP_CHDK_LUA_SERIALIZE_SIMPLEQUOTE "\n\
202 serialize_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\
257 end\n\
258 serialize_defaults = {\n\
259  maxdepth=10,\n\
260  err_type=true,\n\
261  err_cycle=true,\n\
262  pretty=false,\n\
263 }\n\
264 function 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\
277 end\n"
278 
279 #define PTP_CHDK_LUA_SERIALIZE_MSGS \
280 PTP_CHDK_LUA_SERIALIZE\
281 "usb_msg_table_to_string=serialize\n"
282 
283 #define PTP_CHDK_LUA_SERIALIZE_MSGS_SIMPLEQUOTE \
284 PTP_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\
309 end\n"
310 
311 #define PTP_CHDK_LUA_MSG_BATCHER \
312 PTP_CHDK_LUA_SERIALIZE_MSGS \
313 PTP_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\
357 end\n"
358 
359 #define PTP_CHDK_LUA_LS_SIMPLE \
360 PTP_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\
373 end\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\
390 end\n"
391 
392 #define PTP_CHDK_LUA_LS \
393 PTP_CHDK_LUA_MSG_BATCHER \
394 PTP_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\
417 end\n\
418 \n\
419 function 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\
475 end\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\
503 end\n"
504 
505 #define PTP_CHDK_LUA_RLIB_SHOOT \
506 PTP_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\
552 end\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 /*
571 Full 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 /*
576 Raw framebuffer data, in camera native format.
577 A subset of rows may be requested in init_usb_capture.
578 */
579 #define PTP_CHDK_CAPTURE_RAW 0x2
580 
581 /*
582 DNG header.
583 The header will be DNG version 1.3
584 Does not include image data, clients wanting to create a DNG file should also request RAW
585 Raw data for all known cameras will be packed, little endian. Client is responsible for
586 reversing the byte order if creating a DNG.
587 Can requested without RAW to get sensor dimensions, exif values etc.
588 
589 ifd 0 specifies a 128x96 RGB thumbnail, 4 byte aligned following the header
590 client is responsible for generating thumbnail data.
591 
592 ifd 0 subifd 0 specifies the main image
593 The image dimensions always contain the full sensor dimensions, if a sub-image was requested
594 with init_usb_capture, the client is responsible for padding the data to the full image or
595 adjusting dimensions.
596 
597 Bad 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
605 enum 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
614 enum 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
623 enum 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