123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- *****************************
- * Direct Cable(tm) protocol *
- * by roms 2006 *
- *****************************
- Based on preliminary work made by "Drake Wilson" <drake@libcom.com>. Thanks !
- The initialization sequence for the direct USB cable seems to always
- be setting the alternate interface to 0 and the configuration to 1.
- The endpoints used are 0x02 (for computer to calculator messages) and
- 0x81 (for calculator to computer messages). All messages are sent via
- bulk transfer.
- Data are sent on a per-block basis (URB = Usb Request Block).
- Block length is 256 bytes for TI84+ and Titanium.
- Please note this is different of packets below because URBs are managed by driver
- or lower layers (at least for Titanium).
- Packet length (chunck) is:
- - 255 bytes on TI84+,
- - 1023 bytes on Titanium.
- Clearly:
- - on TI84+, a packet is always contained in an URBs (255 < 256),
- - on Titanium, a packet may be contained in one or more URBs (1023 > 256).
- If this is not clear for you, take a look at screenshot.log (SniffUsb) and screenshot.pkt.
- 0°) Introduction
- ----------------
- The generic format for packets is below:
- | packet header | data (250/1018 bytes max) |
- | | or |
- | size | ty | size | code | data (246/1012 bytes) |
- | | | | | |
- | 00 00 00 10 | 04 | 00 00 00 0A | 00 01 | 00 03 00 01 00 00 00 00 07 D0 |
- The following notation will be used in this doc:
- aabbccdd (type) xxyyzztt {code} [pure data]
- Note: on Titanium, the data part usually follows the packet header but it may be sent in
- another URB (fragmented) when the data part is huge (> 1012). In this case, the packet
- header is sent alone in URB and is next followed by a 1023-bytes chunk of data in a second URB.
- TI seems not to like easy things :-(
- 1°) Packet Header (5 bytes)
- ---------------------------
- Each packet starts with the following header (packet header):
- HH HL LH LL = four-byte big-endian length of non-header part
- of packet (after opcode)
- OO = one-byte packet type
- ...
- Packets will be represented as "(opcode) data" in the following text.
- Types of packets include:
- 01 = handshake (HSK)
- 02 = handshake response (ANS)
- 03 = data packet (DATA)
- 04 = last data packet (LAST)
- 05 = acknowledgement (ACK)
- The handshake consists of:
- -> 00000004 (01) [00 00 04 00]
- <- 00000004 (02) [00 00 00 fa] TI84+
- <- 00000004 (02) [00 00 03 ff] Titanium
-
- The acknowledgment (ACK) packet is packet type 05. The data of the
- ACK packet is always E0 00 (if successful):
- -> 00000002 (05) [E0 00]
- Types 01,02 have 4 bytes of data, type 05 has 2 bytes only.
- 2°) Data header (6 bytes)
- -------------------------
- When sending any piece of data, the following header (data header) is
- prepended on the _first_ data packet:
- HH HL LH LL = four-byte big-endian length of non-header part
- of data (after opcode)
- OO OO = two-byte opcode
- ...
- On TI84+, the data is sent in 245-bytes chunks for the first packet or in 250-bytes
- chunks for the others. If data is greater than 245 bytes, then data is sent in several
- packets (several data/ack steps).
- On Titanium, the data is sent in 1012-bytes chunks for the first packet or in 1018-bytes
- chunks for the others. If data is greater than 1012 bytes, then data is sent in several
- packets (several data/ack steps).
- Packet type 03 is used for each of the packet except the last, and packet
- type 04 is used for the last packet. Each data packet is acknowledged
- with packet type 05. Thus, you have, for short data:
- -> (04) header, data...
- <- ACK
- And for longer data, you might have:
- -> (03) header, data...
- <- ACK
- -> (03) data...
- <- ACK
- -> (04) last part of data...
- <- ACK
- Note: usually, the data header size is 7 bytes greater than the size of real data because
- 7 bytes are prepended to data (4 bytes of request and 3 bytes of data size).
- 3°) Type IDs (tid)
- ------------------
- - 0022: screen
- - 0024: related to clock (???)
- - 0025: clock value
- - 0027: date format
- - 0028: time format (am/pm or 24h)
- 4°) Op-codes (opc)
- ------------------
- Data opcodes include:
- 0001 = unknown request (data = 00 03 00 01 00 00 00 00 07 D0)
- Reply with opcode 0012 and data = 00 00 07 D0
- Same for all calcs. Is an echo ?
- 0012 = ???
- Answer of 0001
-
- 0007 = request (REQ)
- The format seems to be the following:
- 00 NN tid1 tid2 ... tidN where NN is the number of requests and tidI the request on 2 bytes)
- Replied with opcode 0008 below.
- - screenshot with data = 00 01 00 22
- - clock with data = 00 04 00 25 00 27 00 28 00 24
- 0008 = request answer (VAR)
- The format seems to be the following:
- 00 NN [tid1 size1 data1] [tid2 size2 data2] ... [tidN sizeN dataN]
- where:
- - NN is the number of request
- - tidI is the previous request tidI (2 bytes)
- - sizeI is the size of data following (3 bytes)
- - dataI is the data request by tidI (sizeI bytes)
- and so on...
- 000e = request to send (RTS)
-
- The format is the following: tid size data
- where tid is the type id, size is the size of data
- aa00 = clear to send (CTS)
- 01
- bb00 = clear to receive (CTR)
- 00 01 d4 c0
- dd00 = end of transmission (EOT)
- no data
- ee00 = error
- data = CC CC where CCCC is a two-byte error code
- Error codes include:
- 00 08 = transmission error or invalid code?
- 00 0c = out of memory?
- 00 0e = invalid name?
- ////
- 0009 = Request directory from calculator
- 00 00 00 06 00 02 00 03 00 05 00 01 00 41 00 42
- 00 01 00 01 00 01 01
- 000a = Directory entry
- LL LL name... = big-endian length of name, followed by name
- 00 00 06 00 02 00
- 00 04 f0 07 00
- TT = type of variable
- 00 03 00 00 01
- FF = some kind of flags?
- bit 0 (0x01) = archived
- 00 05
- GG = more flags?
- bit 0 (0x01) = auxiliary data present
- If auxiliary data present:
- LL LL data... = big-endian length of data, followed by data
- 00 01 00 00 04
- SS SS SS SS = big-endian size of variable in bytes
- 00 04 01 00 42 01
- 000b = Send variable to calculator
- LL LL name... = big-endian length of name, followed by name
- 00
- SS SS SS SS = big-endian size of variable in bytes
- 01 00
- FF = not sure what this is...
- FF = 0x03 for lists and programs
- 0x02 for flash applications
- 00 02 00 04 f0 07
- 00
- TT = type of variable
- 00 03 00 01 00
- 00 08 00 04 00 = don't know what this means?
- 00 00 00
- ( The last 8 bytes did not appear during flash application
- transfer, but they did during list and program transfer. )
- 000c = Request variable from calculator
- LL LL name... = big-endian length of name, followed by name
- 00 01 ff ff ff ff
- 00 02 00 03 00 08
- 00 01 00 11 00 04
- f0 07 00
- TT = type of variable
- 00 00
- 000d = Variable data being transferred
- (Format depends on type of variable; seems to be related to the
- .8x? file types)
- Programs:
- SS SS = little-endian size of data in bytes
- ... = tokenized data
- Lists:
- LL LL = little-endian length of list in elements
- ... = packed real numbers in TI-83+ BCD format
-
- 0010 = Delete variable from calculator
- LL LL name... = big-endian length of name, followed by name
- 00 00 02 00 01 00
- f0 07 00
- TT = type of variable?
- 00 13 00 01 00 01
- 00 00 00 00
-
- 0011 = ?
-
- 0012 = ?
- 00 00 07 D0
- Answer of opcode 0001 (data contains the last 4 bytes of opcode 0001 ?!)
-
- dd00 = End of transmission (EOT)
- (no data)
- 4°) Communication Flow
- ----------------------
- Communication flow for requesting directory from calculator:
- -> Request directory
- <- ACK
- (
- <- Directory entry | EOT
- -> ACK
- )*
- Communication flow for sending variable to calculator:
- -> Send variable
- <- ACK
- <- CTS | Error
- -> ACK
- -> Variable data
- <- ACK
- <- CTS
- -> ACK
- ( Maybe jump back to earlier stage here if sending more
- than one variable simultaneously? )
- -> EOT
- <- ACK
- Communication flow for requesting variable from calculator:
- -> Request variable
- <- ACK
- <- Directory entry
- -> ACK
- <- Variable data
- -> ACK
- ( The USB endpoints were always reset after this transction, so
- it's hard to tell whether there was supposed to be anything else
- after this. )
- Communication flow for deleting variable from calculator:
- -> Delete variable
- <- ACK
- <- CTS
- -> ACK
- ( USB endpoints reset after this... ? )
- 10°) Unknown (all calcs)
- -----------------------
- This step is systematically done at startup after the HSK/RES.
- Moreover, it's needed for TI84+ else any other commands is rejected with error code 0008.
- PC: Data {0001} 00 03 00 01 00 00 00 00 07 D0
- TI: Ack
-
- TI: Data {0012} 00 00 07 D0
- PC: Ack
- 5°) Screenshot (on Titanium)
- ----------------------------
- Communication flow for requesting a screenshot (TI <-/-> PC):
- PC: Handshake
- TI: Response
-
- PC: Data {0007} 00 01 00 22
- TI: Ack
- ---- 84+ ----
- TI: Data {bb00} 00 01 D4 C0
- PC: Ack
- ---- 84+ ----
- TI: Data {0008} 00 01 00 22 00 0F 00 [3840 bytes of screen] (*)
- PC: Ack
- TI: Data [3840 bytes of screen]
- PC: Ack
- TI: Data [3840 bytes of screen]
- PC: Ack
- TI: Last [3840 bytes of screen]
- PC: Ack
- (*) 00 0F = 3840 bytes -> size of screen
- 6°) Getting clock (on TI84+)
- ----------------------------
- Communication flow for requesting a screenshot (TI <-/-> PC):
- PC: Handshake
- TI: Response
-
- PC: Data {0007} 00 04 00 25 00 27 00 28 00 24
- TI: Ack
- ---- 84+ ----
- TI: Data {bb00} 00 01 D4 C0
- PC: Ack
- ---- 84+ ----
- TI: Last {0008} 00 04 00 25 00 00 04 10 15 16 74 00 27 00 00 01 01 00 28 00 00 01 00 00 24 00 00 01 01 (*)
- PC: Ack
- (*)
- 24 is followed by ???
- 25 is followed by the the clock value
- 27 is followed by the date formatting (1: MDY, 2: DMY, 0:YMD)
- 28 is followed by the clock mode (0: am/pm or 1: 24h)
- 7°) Setting clock (on TI84+)
- ----------------------------
- PC: Handshake
- TI: Response
-
- PC: Data {000e} 00 25 00 04 10 15 17 01
- TI: Ack
- ---- 84+ ----
- TI: Data {aa00} 01
- PC: Ack
- ---- 84+ ----
- PC: Data {000e} 00 27 00 01 01
- TI: Ack
- ---- 84+ ----
- TI: Data {aa00} 01
- PC: Ack
- ---- 84+ ----
- PC: Data {000e} 00 28 00 01 00
- TI: Ack
- ---- 84+ ----
- TI: Data {aa00} 01
- PC: Ack
- ---- 84+ ----
- PC: Data {000e} 00 24 00 01 01
- TI: Ack
- ---- 84+ ----
- TI: Data {aa00} 01
- PC: Ack
- ---- 84+ ----
|