USB-Meter / Documentation / Research Resources / Payload Notes / TC66C Transport and Payload Working Note.md
1 contributor
284 lines | 8.954kb

TC66C Transport and Payload Working Note

This note translates the reviewed TC66 manuals and the current app code into an implementation-oriented working reference.

Scope

This note is about TC66C, not TC66.

Reason:

  • the manuals say TC66 is USB-only
  • the iOS and Android apps are TC66C-only
  • the current app code has a separate TC66C BLE path

Evidence Sources

Primary sources used for this note:

  • Documentation/Research Resources/Specifications/TC66 Manuals Working Summary.md
  • Documentation/Research Resources/Specifications/PW0316 BLE Module Working Summary.md
  • USB Meter/Model/Meter.swift
  • USB Meter/Model/BluetoothRadio.swift
  • USB Meter/Model/BluetoothSerial.swift

Current App Assumptions

The current app already treats TC66C as a different protocol family than UM25C / UM34C.

Confirmed from code:

  • model enum contains a dedicated TC66C case
  • TC66C is mapped to radio type PW0316
  • peripheral names TC66C and PW0316 are both recognized as TC66C
  • the scan path includes services FFE0 and FFE5 for this radio family

BLE Transport Assumptions In Code

The current code assumes the following BLE transport for TC66C:

  • notify characteristic: service FFE0, characteristic FFE4
  • write characteristic: service FFE5, characteristic FFE9

This differs from the UM family path already documented elsewhere:

  • UM25C / UM34C use FFE0 / FFE1
  • TC66C uses a separate PW0316-style path in the current app

The newly imported PW0316 vendor manual explicitly validates this mapping:

  • FFE5 / FFE9 is the BLE-to-UART write channel
  • FFE0 / FFE4 is the UART-to-BLE notification channel
  • FFC0 / FFC1 / FFC2 exists as an optional anti-hijack password channel

Request / Response Shape

The current app polls TC66C using ASCII commands.

Confirmed command surface already used by the app:

  • measurement snapshot request: bgetva\r\n
  • next page: bnextp\r\n
  • previous page: blastp\r\n
  • rotate screen: brotat\r\n

Expected snapshot response size in current code:

  • 192 bytes

Important implication:

  • the app assumes fixed-length snapshot framing for TC66C
  • this is not derived from the manuals directly; it comes from the existing reverse-engineered implementation

What the PW0316 module manual adds here:

  • the BLE layer itself is designed around 20-byte BLE payloads
  • UART transparent frames can be up to 200 bytes and are automatically split by the module

Working interpretation:

  • the app's reassembly of a 192-byte encrypted snapshot is application-layer behavior above the module transport
  • the module manual supports the fragmentation assumption, but not the 192-byte frame itself

Encrypted Snapshot Structure

The current parser decrypts the 192-byte response with AES ECB.

Observed implementation details:

  • the app uses a hard-coded 32-byte AES key
  • the decrypted payload is treated as three 64-byte packets
  • those packets are referred to as pac1, pac2, and pac3

Each packet is validated as:

  • first four bytes are ASCII header pac1, pac2, or pac3
  • bytes 0...59 are CRC-covered
  • CRC seed is 0xFFFF
  • stored CRC is little-endian at offset 60

If any of the three packets fail validation, the app rejects the snapshot as invalid.

Field Map Currently Parsed By The App

The offsets below are offsets inside the decrypted packet blocks, not offsets into the encrypted 192-byte BLE frame.

pac1

  • offset 4, size 4: candidate model name as ASCII
  • offset 8, size 4: candidate firmware version as ASCII
  • offset 12, size 4: candidate serial number, little-endian UInt32
  • offset 44, size 4: candidate boot count, little-endian UInt32
  • offset 48, size 4: voltage, raw / 10000
  • offset 52, size 4: current, raw / 100000
  • offset 56, size 4: power, raw / 10000

Confidence:

  • voltage / current / power are high-confidence because the app actively uses them
  • model / firmware / serial / boot count are medium-confidence because they exist as commented decoding hints in code, not active UI fields

pac2

  • offset 4, size 4: load resistance, raw / 10
  • offset 8, size 4: data group 0 accumulated charge, raw / 1000
  • offset 16, size 4: data group 1 accumulated charge, raw / 1000
  • offset 48, size 4: data group 0 accumulated energy, raw / 1000
  • offset 56, size 4: data group 1 accumulated energy, raw / 1000
  • offset 24, size 4: temperature sign flag, 1 means negative in current parser
  • offset 28, size 4: temperature magnitude
  • offset 32, size 4: D+ voltage, raw / 100
  • offset 36, size 4: D- voltage, raw / 100

Confidence:

  • load resistance, temperature, D+, and D- are high-confidence in the sense that the app displays them
  • exact data-group interpretation is medium-confidence because the parser only fills groups 0 and 1

pac3

  • no fields are currently decoded from pac3

This is a major open area for further reverse engineering.

Mismatch Between Manuals And Current App

1. Device pages vs exposed controls

The manuals describe many on-device capabilities:

  • offline recording
  • protocol detection
  • trigger / decoy
  • system settings
  • information page
  • simple mode

The current app only implements these direct TC66C controls:

  • request live snapshot
  • previous page
  • next page
  • rotate screen

Not implemented in the current app for TC66C:

  • clear data group
  • select data group
  • brightness change
  • screen timeout change
  • recording-threshold change

The code explicitly guards these setters off for TC66C.

2. Data-group coverage

The manuals discuss data groups, but the current parser only populates two groups for TC66C.

Working interpretation:

  • either TC66C exposes only two remotely readable groups in the current snapshot layout
  • or the current parser only decodes the first two groups and leaves the rest unknown

This needs verification from captures or app analysis.

3. Bluetooth scope

The manuals are clear that:

  • TC66 is not a Bluetooth target
  • TC66C uses BLE for mobile apps

This matches the current app architecture and strengthens confidence that TC66C should remain a separate transport family in the codebase.

Working State Model For TC66C

The current implementation implicitly models at least these state domains:

  • connection state
  • active device page
  • instantaneous electrical measurements:
    • voltage
    • current
    • power
    • current direction is documented in manuals but not currently decoded into a separate published field
  • accumulated data:
    • charge
    • energy
    • at least two data groups
  • cable and charger context:
    • load resistance
    • D+
    • D-
    • quick-charge related behavior
  • environment:
    • temperature
  • device metadata:
    • firmware version candidate
    • serial number candidate
    • boot count candidate

Practical Implications For Implementation

Keep TC66C separate from UM-family decoding

  • transport is different
  • request commands are different
  • payload framing is different
  • encryption is different

The code already reflects this split and the manuals support it.

Treat pac3 as the highest-value unknown

We already have enough for a basic live meter UI from pac1 and pac2.

What is still likely hidden:

  • additional device settings
  • active page information
  • recording configuration
  • protocol-detection or trigger state
  • more complete data-group information

Do not over-trust current group mapping

The app's TC66C parser only maps two groups, while the manuals talk more generally about groups and offline storage.

Until verified, avoid hard-coding a stronger assumption than:

  • TC66C snapshots currently expose at least two group-like accumulators in our parser

Separate manual truth from protocol truth

The manuals are strong for:

  • feature list
  • UX flow
  • transport family split
  • required PD / CC pull-down behavior

The manuals are not enough for:

  • exact BLE field map
  • command framing completeness
  • full payload offsets

Suggested Verification Priorities

  1. confirm FFE0/FFE4 notify and FFE5/FFE9 write behavior against real TC66C hardware
  2. capture and archive one or more raw 192-byte encrypted snapshots
  3. decrypt and annotate unknown bytes in pac3
  4. verify whether more than two data groups exist in BLE snapshots
  5. determine whether current device page is present in payload
  6. verify whether recording state and interval are exposed remotely
  7. promote candidate metadata fields in pac1 from code comments to confirmed fields

Recommended Next Notes

The next helpful artifacts for the repository would be:

  • a raw TC66C sample-capture note in Payload Notes
  • a byte-offset map for pac1, pac2, and pac3
  • an implementation checklist for exposing currently undocumented TC66C features in the UI