User Tools

Site Tools


cvend

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
cvend [2026-04-26 17:19 UTC (5 weeks ago)] – not flags doofcvend [2026-05-24 10:59 UTC (6 days ago)] (current) – 0xd0 EMV doof
Line 5: Line 5:
 {{ :cvend_plug.pdf |}} {{ :cvend_plug.pdf |}}
  
-The associated serial device appears to be at ''%%/dev/ttymxc3%%'' in Linux.+The associated serial device appears to be at ''%%/dev/ttymxc3%%'' @ 115200 8n1 in Linux.
  
 ===== cVEND protocol notes ===== ===== cVEND protocol notes =====
Line 23: Line 23:
 | 6 | 1 | ''hdrCRC'' | CRC-8-Dallas/Maxim over previous 6 bytes | | 6 | 1 | ''hdrCRC'' | CRC-8-Dallas/Maxim over previous 6 bytes |
 | 7 | ''msgLen'' | ''msgData'' | message payload, structure depends on ''msgType'' | | 7 | ''msgLen'' | ''msgData'' | message payload, structure depends on ''msgType'' |
-| 7+''msgLen'' | 4 | ''msgCRC'' | little endian inverted IEEE CRC-32 over ''msgData'', iff ''msgType 0x80'' |+| 7+''msgLen'' | 4 | ''msgCRC'' | little endian bit inverted IEEE CRC-32/JAMCRC over ''msgData'', only present when ''msgType >= 0x80'' |
  
 ==== IPP message types ==== ==== IPP message types ====
Line 34: Line 34:
 | 0x07 | <- | Heartbeat| sent periodically by reader | | 0x07 | <- | Heartbeat| sent periodically by reader |
 | 0x0f | <- | Startup | sent by reader after startup, approx 1 minute after power on, e.g. "\x00" | | 0x0f | <- | Startup | sent by reader after startup, approx 1 minute after power on, e.g. "\x00" |
-| 0x10 | -> | Reset | | +| 0x10 | -> | Reset | first byte selects subcommand (2 = restart application, 3 = reboot, 4 = poweroff, 33-36 = reset sam 1-4, others = ''Error: Reset Code not implemented yet. [IppBaseTelegram.cpp:157]''
-| 0x11 | <- | ResetReply | |+| 0x11 | <- | ResetReply | e.g. "\x00\x00" |
 | 0x20 | -> | LEDs | sets LED status, u32 bitmap; the only two externally visible LEDs on the PM3 are "\x00\x00\x00\x40" and "\x00\x00\x00\x80" | | 0x20 | -> | LEDs | sets LED status, u32 bitmap; the only two externally visible LEDs on the PM3 are "\x00\x00\x00\x40" and "\x00\x00\x00\x80" |
 | 0x22 | -> | Buzzer | makes the cvend beep; u16 frequency, u16 duration.  e.g. "\x06\x00\x01\x00" | | 0x22 | -> | Buzzer | makes the cvend beep; u16 frequency, u16 duration.  e.g. "\x06\x00\x01\x00" |
Line 48: Line 48:
 | 0x9c | -> | FileInfo | | | 0x9c | -> | FileInfo | |
 | 0x9d | <- | FileInfoReply | | | 0x9d | <- | FileInfoReply | |
-| 0xa4 | -> | FileList | | +| 0xa4 | -> | FileList | Seems to list files on the cVEND. First 2 bytes are the path length, remaining bytes are the path to list 
-| 0xa5 | <- | FileListReply | |+| 0xa5 | <- | FileListReply | First 4 bytes are reply length, remaining bytes seem to be null seperated modification timestamps and file/folder names |
 | 0xaa | -> | SetTime | | | 0xaa | -> | SetTime | |
 | 0xab | <- | SetTimeReply | | | 0xab | <- | SetTimeReply | |
Line 67: Line 67:
 | 0xbc | -> | DESFireCommand | sends desfire command, documented in {{ 0:m075031_desfire.pdf}} | | 0xbc | -> | DESFireCommand | sends desfire command, documented in {{ 0:m075031_desfire.pdf}} |
 | 0xbd | <- | DESFireCommandReply | response to command, documented above | | 0xbd | <- | DESFireCommandReply | response to command, documented above |
-| 0xbe | <- | UnhandledCard | sent by reader when a card is presented that is not supported by any enabled ProxCardFunction, containing UID, historical bytes, and other data |+| 0xbe | <- | UnhandledCard | sent by reader when a card is presented that is not supported by any enabled ProxCardFunction, containing UID, historical bytes, and other data. First two bytes seem to be card type |
 | 0xce | -> | | //unknown, registered in IppHandling::IppHandling()// | | 0xce | -> | | //unknown, registered in IppHandling::IppHandling()// |
-| 0xd0 | -> | EMV | first byte selects subcommand (0 = load config, 1 = preprocess, 2 = toggle polling) |+| 0xd0 | -> | EMV | first byte selects subcommand (0 = load config, 1 = preprocess, 2 = toggle polling)\\ * load config followed by null terminated filename, which is read and passed to fetfpd ''emvco_ep_configure''\\ * preprocess following bytes passed to fetfpd ''emvco_ep_preprocess''\\ * toggle polling following byte (0 = start polling, 1 = stop polling) |
 | 0xd1 | <- | EMVStatus | sent by reader after startup and certain nfc state changes, format and semantics not yet understood | | 0xd1 | <- | EMVStatus | sent by reader after startup and certain nfc state changes, format and semantics not yet understood |
-| 0xd4 | -> | | //unknown, registered in ProxCardUltralightC::ProxCardUltralightC(RFIDReader&)// |+| 0xd4 | -> | UltralightCommand Sends a subcommand to the UltralightC/NTAG card in the field. First byte is subcmd. See table below. | 
 +| 0xd5 | <- | UltralightReply | Unsolicited card event (''replyTo'' = 0), or reply to a 0xD4 command (''replyTo'' = seq of the 0xD4). See tables below. |
 | 0xe4 | -> | ProxCardFunction | first 2 bytes specify function (4=VdvKa, 5=MifareClassic, 6=Iso, 7=Desfire, 8=Girogo, 9=Itso, 10=UltralightC), next byte must be 1, next byte (0=disable, 1=enable)\\ ''00070101'' sent by PM3 to enable DESFire reading at startup | | 0xe4 | -> | ProxCardFunction | first 2 bytes specify function (4=VdvKa, 5=MifareClassic, 6=Iso, 7=Desfire, 8=Girogo, 9=Itso, 10=UltralightC), next byte must be 1, next byte (0=disable, 1=enable)\\ ''00070101'' sent by PM3 to enable DESFire reading at startup |
-| 0xe5 | <- | ProxCardFunctionReply | |+| 0xe5 | <- | ProxCardFunctionReply | Returns 4 byte payload: 0x00, the function number (as above), 0x00, 0x00 |
 | 0xe6 | -> | | //unknown, registered in GirogoIppHandler::GirogoIppHandler(RFIDReader&, ProxCardGirogo*)// | | 0xe6 | -> | | //unknown, registered in GirogoIppHandler::GirogoIppHandler(RFIDReader&, ProxCardGirogo*)// |
 | 0xe8 | -> | SecurityServices | first byte selects subcommand (0=GetVersionOfKey, 1=RemoveX509Cert, 2=RemoveKeyBlock, 3=ImportX509Cert, 4=ExportX509Cert, 5=ImportKeyBlock, 6=ExportKeyBlock, 7=GenerateKSKPair), remaining bytes unknown | | 0xe8 | -> | SecurityServices | first byte selects subcommand (0=GetVersionOfKey, 1=RemoveX509Cert, 2=RemoveKeyBlock, 3=ImportX509Cert, 4=ExportX509Cert, 5=ImportKeyBlock, 6=ExportKeyBlock, 7=GenerateKSKPair), remaining bytes unknown |
Line 82: Line 83:
 -> - Host to Reader\\ -> - Host to Reader\\
 <- - Reader to Host <- - Reader to Host
 +
 +==== 0xD5 UltralightReply — unsolicited card events ====
 +
 +''replyTo'' = 0 for both forms.
 +
 +^ byte 0 ^ meaning ^ payload ^
 +| 0x00 | Card entered field | byte 1 = 0x00 (purpose unknown); bytes 2–8 = 7-byte UID (cascade / double UID format, e.g. ''04 21 B9 01 10 04 03'' for NTAG 215) |
 +| 0x01 | Card left field    | byte 1 = 0x00 |
 +
 +==== 0xD4 UltralightCommand / 0xD5 UltralightReply — subcommands ====
 +
 +Host sends 0xD4 with ''msgData[0]'' = subcmd. Reader replies with 0xD5 where ''replyTo'' = seq of the 0xD4.
 +
 +Reply format: ''[subcmd_echo, status, payload...]''
 +
 +Status codes: ''0x00'' = success, ''0x01'' = operation error (e.g. no card in field), ''0x02'' = invalid parameters.
 +
 +^ subcmd ^ name ^ request payload (after subcmd byte) ^ reply payload (after subcmd + status) ^
 +| 0x02 | Read | ''[start_page: u8, num_pages: u8]'' — exactly 3 bytes total | page data, 4 bytes per page (e.g. 135 pages × 4 = 540 bytes for NTAG 215) |
 +| 0x03 | Write | ''[page_addr: u8, data: 4 bytes]'' — 5 bytes total | //empty// |
 +| 0x04 | Authenticate (raw key) | ''[key: 16 bytes]'' — 17 bytes total | //empty// |
 +| 0x05 | Authenticate (key index) | ''[key_idx: BE u16]'' — 3 bytes total | //empty// |
 +| 0x06 | Authenticate (index + key) | ''[key_idx: BE u16, key: 16 bytes]'' — 19 bytes total | //empty// |
 +| 0x07 | Abort | //none// — exactly 1 byte total | //empty// |
 +| 0x00–0x01, 0x08+ | (invalid) | — | no reply frame; device logs "Unknown subcommand" |
 +
 +Notes:
 +  * Subcmds 0x02–0x07 are registered in ''ProxCardUltralightC::ProxCardUltralightC(RFIDReader&)'' (confirmed by disassembly of ''feig'' ARM binary from V0200.C72 firmware).
 +  * If no card is in the field, the device echoes ''[subcmd, 0x01]'' immediately without attempting the operation.
 +  * To read all pages of an NTAG 215: send subcmd 0x02 with ''start_page=0x00'', ''num_pages=135''.
  
 ==== Sample reader flow ==== ==== Sample reader flow ====
Line 146: Line 177:
  
 * Host only sends two types of messages after initialization - both of type 0xBC. One is length 1 and the body is always 0x60 (+ negated CRC 2A714F60), the other is of length 4 and the body is always 5A2BC3F9 (+ negated-CRC 11A8A56A) * Host only sends two types of messages after initialization - both of type 0xBC. One is length 1 and the body is always 0x60 (+ negated CRC 2A714F60), the other is of length 4 and the body is always 5A2BC3F9 (+ negated-CRC 11A8A56A)
 +
cvend.1777223994.txt.gz · Last modified: by doof