USB-Meter / Documentation / Research Resources / Payload Notes / TC66C Transport and Payload Working Note.md
Newer Older
284 lines | 8.954kb
Bogdan Timofte authored 2 weeks ago
1
# TC66C Transport and Payload Working Note
2

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

            
5
## Scope
6

            
7
This note is about `TC66C`, not `TC66`.
8

            
9
Reason:
10

            
11
- the manuals say `TC66` is USB-only
12
- the iOS and Android apps are `TC66C`-only
13
- the current app code has a separate `TC66C` BLE path
14

            
15
## Evidence Sources
16

            
17
Primary sources used for this note:
18

            
19
- `Documentation/Research Resources/Specifications/TC66 Manuals Working Summary.md`
Bogdan Timofte authored 2 weeks ago
20
- `Documentation/Research Resources/Specifications/PW0316 BLE Module Working Summary.md`
Bogdan Timofte authored 2 weeks ago
21
- `USB Meter/Model/Meter.swift`
22
- `USB Meter/Model/BluetoothRadio.swift`
23
- `USB Meter/Model/BluetoothSerial.swift`
24

            
25
## Current App Assumptions
26

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

            
29
Confirmed from code:
30

            
31
- model enum contains a dedicated `TC66C` case
32
- `TC66C` is mapped to radio type `PW0316`
33
- peripheral names `TC66C` and `PW0316` are both recognized as `TC66C`
34
- the scan path includes services `FFE0` and `FFE5` for this radio family
35

            
36
## BLE Transport Assumptions In Code
37

            
38
The current code assumes the following BLE transport for `TC66C`:
39

            
40
- notify characteristic: service `FFE0`, characteristic `FFE4`
41
- write characteristic: service `FFE5`, characteristic `FFE9`
42

            
43
This differs from the `UM` family path already documented elsewhere:
44

            
45
- `UM25C` / `UM34C` use `FFE0` / `FFE1`
46
- `TC66C` uses a separate `PW0316`-style path in the current app
47

            
Bogdan Timofte authored 2 weeks ago
48
The newly imported `PW0316` vendor manual explicitly validates this mapping:
49

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

            
Bogdan Timofte authored 2 weeks ago
54
## Request / Response Shape
55

            
56
The current app polls `TC66C` using ASCII commands.
57

            
58
Confirmed command surface already used by the app:
59

            
60
- measurement snapshot request: `bgetva\r\n`
61
- next page: `bnextp\r\n`
62
- previous page: `blastp\r\n`
63
- rotate screen: `brotat\r\n`
64

            
65
Expected snapshot response size in current code:
66

            
67
- `192` bytes
68

            
69
Important implication:
70

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

            
Bogdan Timofte authored 2 weeks ago
74
What the `PW0316` module manual adds here:
75

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

            
79
Working interpretation:
80

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

            
Bogdan Timofte authored 2 weeks ago
84
## Encrypted Snapshot Structure
85

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

            
88
Observed implementation details:
89

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

            
94
Each packet is validated as:
95

            
96
- first four bytes are ASCII header `pac1`, `pac2`, or `pac3`
97
- bytes `0...59` are CRC-covered
98
- CRC seed is `0xFFFF`
99
- stored CRC is little-endian at offset `60`
100

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

            
103
## Field Map Currently Parsed By The App
104

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

            
107
### `pac1`
108

            
109
- offset `4`, size `4`: candidate model name as ASCII
110
- offset `8`, size `4`: candidate firmware version as ASCII
111
- offset `12`, size `4`: candidate serial number, little-endian `UInt32`
112
- offset `44`, size `4`: candidate boot count, little-endian `UInt32`
113
- offset `48`, size `4`: voltage, raw / `10000`
114
- offset `52`, size `4`: current, raw / `100000`
115
- offset `56`, size `4`: power, raw / `10000`
116

            
117
Confidence:
118

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

            
122
### `pac2`
123

            
124
- offset `4`, size `4`: load resistance, raw / `10`
125
- offset `8`, size `4`: data group `0` accumulated charge, raw / `1000`
126
- offset `16`, size `4`: data group `1` accumulated charge, raw / `1000`
127
- offset `48`, size `4`: data group `0` accumulated energy, raw / `1000`
128
- offset `56`, size `4`: data group `1` accumulated energy, raw / `1000`
129
- offset `24`, size `4`: temperature sign flag, `1` means negative in current parser
130
- offset `28`, size `4`: temperature magnitude
131
- offset `32`, size `4`: `D+` voltage, raw / `100`
132
- offset `36`, size `4`: `D-` voltage, raw / `100`
133

            
134
Confidence:
135

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

            
139
### `pac3`
140

            
141
- no fields are currently decoded from `pac3`
142

            
143
This is a major open area for further reverse engineering.
144

            
145
## Mismatch Between Manuals And Current App
146

            
147
### 1. Device pages vs exposed controls
148

            
149
The manuals describe many on-device capabilities:
150

            
151
- offline recording
152
- protocol detection
153
- trigger / decoy
154
- system settings
155
- information page
156
- simple mode
157

            
158
The current app only implements these direct `TC66C` controls:
159

            
160
- request live snapshot
161
- previous page
162
- next page
163
- rotate screen
164

            
165
Not implemented in the current app for `TC66C`:
166

            
167
- clear data group
168
- select data group
169
- brightness change
170
- screen timeout change
171
- recording-threshold change
172

            
173
The code explicitly guards these setters off for `TC66C`.
174

            
175
### 2. Data-group coverage
176

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

            
179
Working interpretation:
180

            
181
- either `TC66C` exposes only two remotely readable groups in the current snapshot layout
182
- or the current parser only decodes the first two groups and leaves the rest unknown
183

            
184
This needs verification from captures or app analysis.
185

            
186
### 3. Bluetooth scope
187

            
188
The manuals are clear that:
189

            
190
- `TC66` is not a Bluetooth target
191
- `TC66C` uses BLE for mobile apps
192

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

            
195
## Working State Model For `TC66C`
196

            
197
The current implementation implicitly models at least these state domains:
198

            
199
- connection state
200
- active device page
201
- instantaneous electrical measurements:
202
  - voltage
203
  - current
204
  - power
205
  - current direction is documented in manuals but not currently decoded into a separate published field
206
- accumulated data:
207
  - charge
208
  - energy
209
  - at least two data groups
210
- cable and charger context:
211
  - load resistance
212
  - `D+`
213
  - `D-`
214
  - quick-charge related behavior
215
- environment:
216
  - temperature
217
- device metadata:
218
  - firmware version candidate
219
  - serial number candidate
220
  - boot count candidate
221

            
222
## Practical Implications For Implementation
223

            
224
### Keep `TC66C` separate from UM-family decoding
225

            
226
- transport is different
227
- request commands are different
228
- payload framing is different
229
- encryption is different
230

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

            
233
### Treat `pac3` as the highest-value unknown
234

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

            
237
What is still likely hidden:
238

            
239
- additional device settings
240
- active page information
241
- recording configuration
242
- protocol-detection or trigger state
243
- more complete data-group information
244

            
245
### Do not over-trust current group mapping
246

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

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

            
251
- `TC66C` snapshots currently expose at least two group-like accumulators in our parser
252

            
253
### Separate manual truth from protocol truth
254

            
255
The manuals are strong for:
256

            
257
- feature list
258
- UX flow
259
- transport family split
260
- required `PD / CC pull-down` behavior
261

            
262
The manuals are not enough for:
263

            
264
- exact BLE field map
265
- command framing completeness
266
- full payload offsets
267

            
268
## Suggested Verification Priorities
269

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

            
278
## Recommended Next Notes
279

            
280
The next helpful artifacts for the repository would be:
281

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