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:

Table 2.2. Sequence numbers observed in serial streams

<mtype><dir><fffb>Operation
011214 f7 8a 00Identify camera request
012214 f7 8a 00Identify camera response
01116a 08 79 04Download image request
0111aa 06 79 04Download thumbnail request (see below)
01216a 08 79 04Image data
0121aa 06 79 04Thumbnail data
0311 Upload file
031278 f3 64 01Get Date
041208 d3 9d 00Set date
0512fc d2 9d 00Change Owner name
0911d8 f7 8a 00Disk info request
0921d8 f7 8a 00Disk info response
0a11dc f7 8a 00Get disk(s) request
0a21dc f7 8a 00Get disk(s) response
0a1270 f6 8a 00Power Supply Status
0a2270 f6 8a 00Power Supply Status response
0b1194 f6 8a 00List without date request
0b2194 f6 8a 00List without date response
0b11a8 f6 8a 00List with date request
0b21a8 f6 8a 00List with date response
0d118c f4 7b 00Delete image request
0d218c f4 7b 00Delete image response
0e11 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 unknown. 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 power type: 0x10=ac-adapter, 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, 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/without 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:

Table 2.3. File attributes

bit0 (0x01)Set if this file is protected from deletion
bit4 (0x10)Set if this directory contains an item but was not recursively entered (NOT used with the set attributes command)
bit5 (0x20)Set if the file has not yet been downloaded (must be manually switched)
bit7 (0x80)Set if this directory was entered recursively (NOT used with the set attributes 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 first 10813 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 packets 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