/
Protocol
1016 lines (762 loc) · 38.8 KB
/
Protocol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(read/print this document with a non-proportional font such as courier)
============================================
====== Canon PowerShot Series ======
==== Transfer Protocol Specifications =====
============================================
* About this document
The following document is an overview of the Canon PowerShot serial
and USB transfer protocols. It should be a valid reference for models
ranging from PowerShot A5 to S20.
No information present in this document was obtained from Canon.
Everything is the result of observations and logical analysis. It is
by no means guaranteed to be accurate, nor even right. Nevertheless, a
lot of people have managed to communicate with their PowerShot cameras
using these commands, so they cannot be completely wrong either !
An implementation of this communication protocol was made for the
GPhoto digital camera software, available at www.gphoto.org.
* Contributors:
This document was written thanks to the efforts of:
Wolfgang G. Reissnegger, Werner Almesberger, Philippe Marzouk, Mikael
Nyström, Edouard Lafargue.
* Copyright :
The Canon Protocol information. Copyright © 2000 by its respective
authors (see the Contributors section).
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the:
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
USA.
* To Do :
(send updates to Edouard.Lafargue@bigfoot.com or to the
gphoto-devel mailing-list)
- Serial:
Update get_directory description to match what was discovered in USB.
Describe the structure of the initial ID packet.
Find out what the real meaning of the "fffb" command is.
Describe error recovery protocol.
Describe format of low batt condition.
Find out the rest of the commands that were discovered in USB:
- Make dir
- Delete dir
- Change attribute
- etc.
Describe File upload.
Describe each command in detail.
- USB:
Describe the generic get_directory reply packet with the location of
the error code offset.
- General:
Rewrite this document in XML (LinuxDoc).
* Changelog:
09 May 2000: first version with both USB and serial protocols
described in the same document.
=========================================================================
============================================
== Serial Protocol ==
=== Specifications ===
============================================
Introduction
============
We have chosen to describe the Canon Serial Protocol as successive
layers. I used OSI-like names but the protocol is not really a network
protocol.
a. Data link layer:
Responsible for framing, escaping and checksuming messages
b. Transport (packet) layer:
Responsible for dividing messages into packets of known length.
This layer also handles handshaking, retries, etc.
c. Session (message) layer:
Last layer, carrying whole messages, such as download requests,
image data, and such information.
Currently, all these layers are documented, but we still lack
information on how to handle protocol retries, and errors in general.
Data link layer
=====================
The following figure illustrates the lower layers of the protocol
used by some Canon PowerShot cameras:
[ Upper layers ] Example: payload "00 C0 01"
| ^
| | 00 C0 01
<CRC>
| | 00 C0 01 12 34 (fictious CRC)
<Escaping>
| | 00 7E E0 01 12 34
<Framing>
| | C0 00 7E E0 01 12 34 C1
v |
[ Wire format ]
The upper layers are described later in this file.
0) Serial timing
----------------
Initialization: PC sends sequences of "U" bytes at 9600 bps until the
camera responds by sending its ID. Each sequence has a length of 2-8
bytes. The interval to wait between sequences is 0.9-1.04 sec
(measured for 8 bytes).
When the camera sends its ID, the computer can ask it to change to a
higher speed. The speed can go up to 115200 bps.
Afterwards, a one/two seconds command timeout should be set.
E.g. retrieving a directory with 1200 files takes several
seconds. Opening a large capacity flash card takes time as well.
1) Framing
----------
Each message begins with the byte C0 and ends with the byte C1. The
length of a message including the framing bytes and any escape bytes
(see below) never exceeds 1024 bytes.
2) Escaping
-----------
The value 7E is used to XOR the following byte with the value 0x20. This
is used for the following three combinations:
7E 5E -> 7E
7E E0 -> C0
7E E1 -> C1
3) CRC
------
The last two bytes of a message (without framing and escaping) contain
a 16-bit "CCITT" CRC in little-endian order. The CRC is calculated
over the entire message, without framing and escaping, and without
including the CRC bytes. The CRC generator [1] is initialized to a
length-dependent value. The algorithim for the initial value is not
known. However, a table of values emitted by the camera has been
compiled and is in crc.c:crc_init. It is indexed by the length,
i.e. the number of bytes over which the CRC is taken.
[1] Assuming the use of
http://www.cse.fau.edu/~sam/course/dc_htm/src_dir/crc_att.c,
generator polynom 0102010 (octal), the initial value of "crc" is
the CRC generator's initial value (in the original code always
zero).
Transport layer
=====================
Communication is done through messages, which may be split into
several fragments, which are then sent as individual packets. Packets
are framed as described earlier in this file.
Packet level
------------
Each packet consists of the following two-byte header:
<sequence> <ptype>
There are two sequence numbers: the message sequence number <mseq> and
the fragment sequence number <fseq>. They are counted independently
and start at zero. <mseq> is reset at the beginning of a session,
while <fseq> is reset at the beginning of each message.
The following packet types are known:
00 Message fragment
03 Speed message from computer
04 EOT
05 ACK
06 Compatibility?
A packet with type 03 is sent once, early in the initialization for
the computer to ask the camera to switch to a higher speed.
Each message ends with an EOT packet, which is then confirmed by an
ACK packet.
EOT has the following format:
xx 04 xx 00 00 00
| |
| indication of the message length. Known values:
<mseq> 00 empty message (no fragments)
01 short message (one fragment)
03 used when uploading
ff maximum length data packet, more to follow
else data packet, at end (observed values: 0f, 7f)
ACK has the following format:
xx 05 xx 00 00 00
| |
| error code
<mseq> 00 No error, acknowledged
01 Not acknowledged
FF retransmit last sequence
else other values not known
A packet with type 06 is sent once, as the first packet coming from
the camera. It contains a length, just like a normal message fragment,
but the message structure is different.
An empty message can be used to test if the camera is still responding.
If yes, it will respond with an ACK. Example:
PC->CAM xx 04 00 00 00 00
CAM->PC xx 05 00 00 00 00
Message fragment level
----------------------
Message fragments have the following structure:
xx 00 xx xx ...
| | | |
| | | fragment data
| | data length, MSB
| data length, LSB
<fseq>
The data length is the length (in bytes) of the fragment data that
follows the length. Fragment data is simply concatenated to form the
complete message.
Session (message) Layer
=======================
All messages (except the one with type 03) have the following structure:
00 02 00 00 xx 00 00 xx xx xx 00 00 ...
| | | | |
| | | | message payload
| | | message length, MSB
| | message length, LSB
| direction code <dir>
message type <mtype>
The message length is the length of the entire message, including the
header shown above.
The first four bytes of the message payload <fffb> seem to depend on
the message type. The following combinations have been sighted:
<mtype> <dir> <fffb> Operation
01 12 14 f7 8a 00 Identify camera request
01 22 14 f7 8a 00 Identify camera response
01 11 6a 08 79 04 Download image request
01 11 aa 06 79 04 Download "thumbnail" request (see below)
01 21 6a 08 79 04 Image data
01 21 aa 06 79 04 "Thumbnail" data
03 11 Upload file
03 12 78 f3 64 01 Get Date
04 12 08 d3 9d 00 Set date
05 12 fc d2 9d 00 Change Owner name
09 11 d8 f7 8a 00 Disk info request
09 21 d8 f7 8a 00 Disk info response
0a 11 dc f7 8a 00 Get disk(s) request
0a 21 dc f7 8a 00 Get disk(s) response
0a 12 70 f6 8a 00 Power Supply Status
0a 22 70 f6 8a 00 Power Supply Status response
0b 11 94 f6 8a 00 List without date request
0b 21 94 f6 8a 00 List without date response
0b 11 a8 f6 8a 00 List with date request
0b 21 a8 f6 8a 00 List with date response
0d 11 8c f4 7b 00 Delete image request
0d 21 8c f4 7b 00 Delete image response
0e 11 -- -- -- -- Set file attributes.
Important note : it seems that the "fffb" part can be set to 0 in
every case, and the commands will still work. The exact meaning of
this part of the packet is unknwown. It is probably used as a unique
ID for each transaction and can be chosen at random each time.
Identify camera
---------------
The identify camera request has no data.
The identify camera response has the following structure:
00 00 00 00 00 02 00 00 00 00 00 01 <camera_name> 00 (more 00s)
On the S10, the response has the following structure:
00 00 00 00 00 04 00 00 00 00 00 01 and then:
<firmware rev> (32 bit word) (offset: 0x08)
<model name> (C string) (offset: 12 / 0x0c)
<owner name> (C string) (offset: 44 / 0x2c)
Firmware version: 04 03 02 01 is version 1.2.3.4
01 00 00 01 is version 1.0.0.1
Example (full packet): for a PowerShot S10 with firmware 1.0.0.0
RECV: (98 bytes)
00000000: 00 00 5C 00 02 00 00 00 01 00 00 22 5C 00 00 00 - ..\........"\...
00000010: 14 F7 8A 00 00 00 00 00 00 04 00 00 00 00 00 01 - ................
00000020: 43 61 6E 6F 6E 20 50 6F 77 65 72 53 68 6F 74 20 - Canon PowerShot
00000030: 53 31 30 00 00 00 00 00 00 00 00 00 00 00 00 00 - S10.............
00000040: 45 64 6F 75 61 72 64 20 4C 61 66 61 72 67 75 65 - Edouard Lafargue
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................
00000060: 9C EA - ..
Get Power Status
----------------
Offsets in the payload:
0x04 contains a byte with power status: 0x6=good, 0x4=bad
0x07 contains a byte with powertype: 0x10=ac-adaptor, 0x30=battery
Example (full packet):
RECV: (30 bytes)
00000000: 00 00 18 00 02 00 00 00 0A 00 00 22 18 00 00 00 - ..........."....
00000010: 70 F6 8A 00 00 00 00 00 06 00 00 30 B5 5A - p..........0.Z
Change Owner Name
----------------
The name (payload) can be 30 characters max.
Set Date
--------
The payload of this message is 4 bytes, it must be the same unix
format as in the directory with date request, for example the
01/01/2000 is 80 43 6D 38.
Get disk(s)
-----------
The get disk(s) request has no data.
The get disk response has the following structure:
00 00 00 00 <disk_name> 00
Disk name example: "C:"
Disk info
---------
Disk info requests have the following structure:
<root_name> 00
Disk info responses have the following structure:
00 00 00 00 xx xx xx xx xx xx xx xx
| |
| Free space (in bytes)
Total capacity (in bytes)
Root name example: "C:\" (The trailing slash is required.)
List (show directory contents)
------------------------------
Note: It seems that directory listing as described in the USB part is
more accurate, when it comes to the meaning of the first byte (
"date/withtout date").
List requests have the following structure:
xx <directory_name> 00 00 00
|
00 if with date, 02 if without date
Directory name example: "C:\PWRSHOT", "D:", or "D:\.", but not
"D:\" (trailing slash), or "D:\.\FOO" (dot not allowed in path ?)
List responses have the following structure:
Failure:
00 00 00 00 01 00 00 00 00 00 00 00
Success:
00 00 00 00 xx 80 00 00 00 00 00 00 00 00 00 00
|
01 if last message, 00 if more
<directory_name> 00
<type> 00 <size> <date> <entry_name> 00
...
<type> 00 <size> <date> <entry_name> 00 (many 00s)
<type> is one byte containing the file attributes:
File attributes:
bit0 (0x01) (1=delete protected, 0=NOT delete protected)
bit4 (0x10) (1=directory contains item but not recursived entered)
(NOT used with the attrib command)
bit5 (0x20) (1=NOT downloaded, 0=downloaded)
(must be manually switched)
bit7 (0x80) (1=recurively entered directory)
(NOT used with the attrib command)
<size> is the size in bytes. Directory size is always 0.
Entry name example: "AUT_1201.JPG" or "MISC"
The date is a four bytes Unix-style date. The list without date responses
also contains the four data bytes, but sets them to zero.
Note: it's unclear if the list with/without date commands differ in any
other way than the inclusion of the date.
If the directory is so large that additional messages are needed, they
have the following structure:
00 00 00 00 xx <entry>
|
1 if last message, 00 if more
The boundary between messages is always chosen such that the terminating
00 of an entry is the last byte in the earlier message.
Download and Data
-----------------
Download requests have the following structure:
00 00 00 00 00 xx 00 00 <name> 00
|
Length of name (including terminating \0)
Data messages have the following structure:
00 00 00 00 xx xx xx xx xx xx xx xx xx xx xx xx xx 00 00 00 ...
| | | | |
| | | | data
| | | 00 if more, 01 at end
| | data size in this message
| current offset
total length
All lengths are measured in bytes.
The camera only sends the 10813 first bytes from the image for the thumbnail
download request. However it is not a valid thumbnail image, the first part
is the Exif header, the second part is the thumbnail itself between a FF D8
and a FF D9, the remaining is the beginning of the picture.
The camera always sends 8 messages then waits for an ACK from the computer,
if the computer has not received everything, it sends an ACK with an error
value asking to retransmit one of the eight packet sent. These error values
are not yet known.
Upload file
-----------
The serial upload protocol description is not done yet. These are just
ideas on what it could be. Maybe it's right, maybe it's wrong.
* This command sends a file to the camera.
* Request structure:
xx 00 00 00 00 xx 00 00 <name>
Each data block has the following format:
00 00 00 02 XX XX XX XX - YY YY YY YY filename - datablock
XX XX XX XX : offset within the file for this block
YY YY YY YY : len2: length of this block
filename : 0-terminated string
datablock: the data itself.
Switch Camera off
-----------------
In order to switch the camera off, you need to send the following
characters (directly, without extra framing) :
C0 00 02 55 2C C1
C0 00 04 01 00 00 00 24 C6 C1
Low Battery warning
-------------------
If the camera batteries run too low during a transfer and the camera
needs to switch itself off, it will send a special packet just before
going down. You can see how it is handled in psa50.c
===============================================
=
= USB Interface
=
===============================================
Nota:
When mentioning word, 32bit word little_endian is implied.
References to usb11.pdf (Chaper 9.3 page 199):
http://www.usb.org/developers/data/usbspec.zip (1.8Mb)
bmRequestType is 0xC0 during read and 0x40 during write.
bRequest is 0x4 if length of data is >1, 0x0c otherwise (length > 1 ? 0x04 : 0x0C)
wValue differs between operations.
wIndex is always 0x00
wLength is simply the length of data
In linux sending/reciving commands is using usb_control_msg (in usb.c).
usb11.pdf name | usb.c name)
--------------------------------
bmRequestType | requesttype
bRequest | request
wValue | value
wIndex | index
wLength | length
================================================================================
Init of camera:
================================================================================
1. Control_transfer_read requesttype=0xC0 value=0x55 length=1
Camera responds with following data (single char):
"A" = Camera was already active
"C" = Camera was woken up
"I" = Unknown (some kind of error)
"E" = Unknown (some kind of error)
2. Control_transfer_read requesttype=0xC0 value=0x1 length=0x58
The first 0x48 bytes can be trashed, save the last 0x10 byte and us it as
data in next step.
Example:
00000000 18 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 01 00 02 00 43 30 A9 04-00 08 00 00 FF FF FF FF ....C0..........
00000050 00 FD 00 00 00 FD 00 00 ........
3 'A' If the response to step 1 was 'A',
Control_transfer_read requesttype=0x4 value=0x4 length=0x50
Throw away the data and we are finished with the initialization [1].
3 'C' If the response to step 1 was 'C', take the packet from step 2, change
the byte at offset 0 to 0x10, move the last 0x10 bytes to position 0x40 and
Control_transfer_write requesttype=0x40 value=0x11 length=0x50
4. PC sign should now appear on the LCD. Not all cameras have PC signs though.
5. We should now read a total of 0x44 bytes from bulk_in, but some cameras are
picky at this stage and we must first read 0x40 bytes and then 0x4 bytes
(the symptoms if not doing this right is that camera initialization only works
every second time).
Newer Canon USB cameras return 0x54 0x78 0x00 0x00 ('Tx\0\0') under some
cicumstances [2] as the last four bytes in either of these two reads.
If we get that from the first read we should not try to read the next 0x4 bytes.
Example:
00000000 04 00 00 00 02 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 00 00 00 00 ....
[1] Many cameras fail the first camera command after this (the command response
is returned without the first 0x40 bytes). It seems Canon got the same
problem and worked around it in the Windows driver instead of fixing the
firmware. The workaround is to retry the first camera command (Identify
camera is a suitable command) up to four times.
[2] It seems this was due to an error in the init sequence described in earlier
versions of this document. When done like the Windows driver does it, we
always get 00 00 00 00 back as the last four bytes of step 5.
================================================================================
USB Commands
================================================================================
1. Structure of a command block
Example:
* Command block sent in general: (Example:Disk info request)
0000000: 14 00 00 00 01 02 00 00-00 00 00 00 00 00 00 00 ................
0000010: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000020: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000030: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000040: 02 00 00 00 09 00 00 11-14 00 00 00 78 56 34 12 ............xV4.
0000050: 44 3A 5C 00 D:\.
USB arguments:
- value is always 0x10
- length is TOTAL length (0x54 in example above)
* Generic format of block sent:
0000000: xx xx xx xx yy yy yy yy - 00 00 00 00 00 00 00 00
0000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0000040: 02 00 00 00 UU 00 00 VV - xx xx xx xx SS SS SS SS
0000050: ... (payload/arguments)
xx xx xx xx : Length (word)
yy yy yy yy : cmd3 (word)
UU : cmd1 (byte)
VV : cmd2 (byte)
xx xx xx xx : Length (again)
SS SS SS SS : sequence number (word)
- 'length' is the length of the block, excluding the first 0x40 bytes
in block, and is never less than 0x10.
- cmd1 and cmd2 are a single byte
- cmd3 is a word
- Sequence number is a word, sent back in command reply.
2. Summary of available (known) commands:
cmd1 | cmd2 | cmd3 | Argument(eg.) Response Length | Operation
-----------------------------------------------------------------------------------------------
0x01 0x11 0x202 | 0x00000000 0x00001400 "D:\DCIM\100CANON\IMG_0100.JPG" 0x00 L | Get picture
0x01 0x11 0x202 | 0x00000001 0x00001400 "D:\DCIM\100CANON\IMG_0100.JPG" 0x00 L | Get thumbnail
0x01 0x12 0x201 | none 0x9c | Identify camera request
0x03 0x12 0x201 | none 0x60 | Get time
0x04 0x12 0x201 | 0x390873f0 0x00000000 0x00000000 0x54 | Set time (0x390873f0) (UNIX-type)
0x05 0x11 0x201 | "D:\DCIM" 0x00 0x54 | Make directory
0x05 0x12 0x201 | "Donald Duck" 0x00 0x54 | Change owner
0x06 0x11 0x201 | "D:\DCIM" 0x00 0x54 | Remove directory
0x09 0x11 0x201 | "D:\" 0x00 0x5c | Disk info request
0x0A 0x11 0x202 | none L | Flash device identification
0x0A 0x12 0x201 | none 0x58 | Power supply status
0x0B 0x11 0x202 | 0x01 "D:\DCIM" 0x00 0x00 0x00 L | Get directory (0x1 = max depth of recursion)
0x0D 0x11 0x201 | "D:\DCIM\100CANON" 0x00 "IMG_0002.JPG" 0x00 0x54 | Delete file
0x0E 0x11 0x201 | 0x00000021 "D:\DCIM\100CANON" 0x00 "IMG_0002.JPG" 0x00 0x54 | Set file attribute
0x1B 0x12 0x201 | 0x06 0x00 0x00 0x00 0x54 | EOS (D30) lock keys
0x1C 0x12 0x201 | none 0x54 | EOS (D30) unlock keys
0x1F 0x12 0x201 | none 0x380 | Get camera photo abilities?
0x20 0x12 0x201 | none 0x54 | Lock keys, turn off LCD
L means that the program reads 0x40 from bulk in, checks for a word at
position 0x6 for the length (0xd1fcf in this case), and then reads the
rest in 0x1400 buffers. (long bulk in read)
00000000 00 00 00 00 02 03 CF 1F-0D 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
****
** Disk Info Request:
****
* Argument structure:
Null-terminated string containing the name of the disk.
* Camera response block:
Data received via bulk in after a command block: (Disk info request)
0000000: 00 00 00 00 01 03 00 00 00 00 00 00 00 00 00 00 ................
0000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0000040: 02 00 00 00 09 00 00 21 1C 00 00 00 78 56 34 12 .......!....xV4.
0000050: 00 00 00 00 00 80 E8 03 00 A0 AF 03 ............
First 0x40 bytes is throwable.
0x54 contains a word with totalbytes on flash.
0x58 contains a word with bytes free.
****
** Delete directory
****
Data received via bulk in after a command block: (Delete directory)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 06 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
00000050 00 00 00 00 ....
****
** Make directory
****
Data received via bulk in after a command block: (Make directory)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 05 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
00000050 00 00 00 00 ....
****
** Get time
****
Data received via bulk_in after a command block: (Get time)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 03 00 00 22-20 00 00 00 78 56 34 12 ......." ...xV4.
00000050 00 00 00 00 8D 1D 12 39-00 00 00 00 00 00 00 00 .......9........
First 0x40 bytes is throwable.
0x54 contains a UNIX time
****
** Power supply status
****
Data received via bulk_in after a command block: (Power supply status)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 0A 00 00 22-18 00 00 00 78 56 34 12 ......."....xV4.
00000050 00 00 00 00 06 00 00 10- ........
First 0x40 bytes is throwable.
0x54 contains a byte with power status: 0x6=good, 0x4=bad
0x57 contains a byte with powertype in bit 4:
((value & 0x20) == 0) running from ac-adaptor
((value & 0x20) != 0) running from battery
Note that the original document claimed for 0x57 that it contained
"a byte with powertype: 0x10=ac-adaptor, 0x30=battery", whereas a
PowerShot G2 just toggles one bit.
****
** Identify Camera request
****
Data received via bulk_in after a command block: (Identify camera request)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 01 00 00 22-5C 00 00 00 78 56 34 12 ......."\...xV4.
00000050 00 00 00 00 00 04 00 00-01 00 00 01 43 61 6E 6F ............Cano
00000060 6E 20 50 6F 77 65 72 53-68 6F 74 20 53 32 30 00 n PowerShot S20.
00000070 00 00 00 00 00 00 00 00-00 00 00 00 44 6F 6E 61 ............Dona
00000080 6C 64 20 44 75 63 6B 00-00 00 00 00 00 00 00 00 ld Duck.........
00000090 00 00 00 00 00 00 00 00-00 00 00 00 ............
First 0x40 bytes is throwable (as usual)
At 0x5c a string with camera type exist
At 0x7c a string with owner name exist.
0x58-0x5b is firmware version (04 03 02 01 is version 1.2.3.4; 01 00 00 01 is version 1.0.0.1)
Data at 0x54-0x57 has unknown purpose.
****
** Flash device identification
****
Data received via a long_bulk_in_read: (Flash device identification)
00000000 44 3A 00 00 D:..
****
** Set File Attribute
****
Data received via bulk_in after a command block: (Set file attribute)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 0E 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
00000050 00 00 00 00 ....
Data received via bulk_in after a command block: (Set file attribute) (file did not exist).
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 0E 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
00000050 22 00 00 02 "...
File attributes:
bit0 (0x01) (1=delete protected, 0=NOT delete protected)
bit4 (0x10) (1=directory contains item but not recursived entered)
(NOT used with the attrib command)
bit5 (0x20) (1=NOT downloaded, 0=downloaded)
(must be manually switched)
bit7 (0x80) (1=recurively entered directory)
(NOT used with the attrib command)
Example: 0x21 file is NOT downloaded but delete protected
****
** Delete file
****
Data received via bulk_in after a command block: (Delete file) (file did not exist).
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 0D 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
00000050 22 00 00 02 "...
Data received via bulk_in after a command block: (Delete file) (file was protected)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 0D 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
00000050 29 00 00 02 )...
Data received via bulk_in after a command block: (Delete file) (successful)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 0D 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
00000050 00 00 00 00 ....
****
** Change Owner
****
Data received via bulk_in after a command block: (Change owner) (no errorcodes)
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000040 02 00 00 00 05 00 00 22-14 00 00 00 78 56 34 12 ......."....xV4.
00000050 00 00 00 00 ....
****
** Directory Listing
****
Errorcodes:
0x02000022 File not found
0x00000000 No errors
0x02000086 Path not found
0x02000029 File was protected
File attributes:
bit0 (0x01) (1=delete protected, 0=NOT delete protected)
bit4 (0x10) (1=directory contains item but not recursived entered)
(NOT used with the attrib command)
bit5 (0x20) (1=NOT downloaded, 0=downloaded)
(must be manually switched)
bit7 (0x80) (1=recurively entered directory)
(NOT used with the attrib command)
Example: 0x21 file is NOT downloaded but delete protected
Directory handling:
Thu May 4 00:11:40 2000 D:\DCIM\100CANON\IMG_0001.JPG 778435
Thu May 4 00:28:32 2000 D:\DCIM\100CANON\IMG_0002.JPG 44409
Thu May 4 00:28:32 2000 D:\DCIM\CANONMSC\100.CTG 2634
Thu May 4 00:28:32 2000 D:\DCIM\CANONMSC\D.CTG 383
Directory contents: "D:" (recurse = 0x0)
00000000 80 00 00 00 00 00 00 00-00 00 44 3A 00 10 00 00 ..........D:....
00000010 00 00 00 C6 B5 10 39 44-43 49 4D 00 00 00 00 00 ......9DCIM.....
00000020 00 00 00 00 00 00 00 .......
Directory contents: "D:" (recurse = 0x1)
00000000 80 00 00 00 00 00 00 00-00 00 44 3A 00 80 00 00 ..........D:....
00000010 00 00 00 36 C0 10 39 2E-5C 44 43 49 4D 00 10 00 ...6..9.\DCIM...
00000020 00 00 00 00 36 C0 10 39-31 30 30 43 41 4E 4F 4E ....6..9100CANON
00000030 00 10 00 00 00 00 00 CC-B5 10 39 43 41 4E 4F 4E ..........9CANON
00000040 4D 53 43 00 80 00 00 00-00 00 00 00 00 00 2E 2E MSC.............
00000050 00 00 00 00 00 00 00 00-00 00 00 00 ............
Directory contents: "D:" (recurse = 0x2)
00000000 80 00 00 00 00 00 00 00-00 00 44 3A 00 80 00 00 ..........D:....
00000010 00 00 00 36 C0 10 39 2E-5C 44 43 49 4D 00 80 00 ...6..9.\DCIM...
00000020 00 00 00 00 3C C0 10 39-2E 5C 31 30 30 43 41 4E ....<..9.\100CAN
00000030 4F 4E 00 20 00 C3 E0 0B-00 3C C0 10 39 49 4D 47 ON. .....<..9IMG
00000040 5F 30 30 30 31 2E 4A 50-47 00 20 00 79 AD 00 00 _0001.JPG. .y...
00000050 30 C4 10 39 49 4D 47 5F-30 30 30 32 2E 4A 50 47 0..9IMG_0002.JPG
00000060 00 80 00 00 00 00 00 00-00 00 00 2E 2E 00 80 00 ................
00000070 00 00 00 00 30 C4 10 39-2E 5C 43 41 4E 4F 4E 4D ....0..9.\CANONM
00000080 53 43 00 20 00 4A 0A 00-00 30 C4 10 39 31 30 30 SC. .J...0..9100
00000090 2E 43 54 47 00 20 00 7F-01 00 00 30 C4 10 39 44 .CTG. ....0..9D
000000A0 2E 43 54 47 00 80 00 00-00 00 00 00 00 00 00 2E .CTG............
000000B0 2E 00 80 00 00 00 00 00-00 00 00 00 2E 2E 00 00 ................
000000C0 00 00 00 00 00 00 00 00-00 00 ..........
Directory contents:
attribute 0x00 size date "name" 0x00
attribute is a byte describe little earlier in this document
(0 in attribute, date, length and name means end of direntry, ".." in name means "leave directory".
size is a word (filesize in byte)
time is a word (UNIX time)
****
** Upload (a little bit special):
****
Control_transfer_write
requesttype=0x40
requestvalue=0x04
value=0x10
length=0x40
data=0x00000000 0x0203 0x40+len1[explained later] [0x00 repeated 0x38]
Example:
00000000 00 00 00 00 03 02 7A 14-00 00 00 00 00 00 00 00 ......z.........
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
bulk_in_read [0x40 bytes]
Example:
00000000 00 00 00 00 03 03 00 00-00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
bulk_write [data below]
len1[explained later] 0x00 0x00 0x00000403 0x00000000 0x00000000
[0x00 repeated 0x30 times]
0x00000002 0x03 0x00 0x00 0x11 len1 0x00 0x00 serial (this line looks very similar to "ordinary" commands)
0x00000002 offs len2 filename 0x00 datablock
bulk_in_read [0x5c bytes]
The whole procedure (i.e. Control_transfer_write(0x40 bytes) -> bulkread(0x40 bytes) ->
bulkwrite(len1+0x40 bytes) -> bulkread(0x5c bytes))
is repeated until the whole file is transmitted:
- offs is a word that starts at 0 and increments with blocksize each time.
- len1 is the length of the "bulk_write_data" block above, minus 0x40 (the
first length and padded zeros is not counted as in all other commands).
len1 is typically 0x143A using a standard 0x1400 (ms-windows) block
using the filename below (29 chars), last block is shorter.
- len2 is length of datablock (0x1400 is used in ms-windows), last
block is shorter serial is a random word that is returned as a reply.