Preflight Check (Required)
Bug Description
HuaweiAhCh100Handler sends a user record with weight 0 to the scale, and the
scale answers by re-requesting it in a tight loop: 127 USER_CHANGED (op 0x20)
round trips in 33 seconds, each answered with a byte-identical encrypted
USER_INFO frame. The loop only stops once an actual measurement completes.
Cause is in sendUserInfo:
val w = (weightTenthKg ?: (user.initialWeight * 10f).toInt()).coerceAtLeast(0)
weightTenthKg comes from lastMeasuredWeightTenthKg, which is -1 until the
first measurement of the session, so on connect it falls back to
user.initialWeight — and that is 0f for a freshly created profile.
Decrypting the USER_INFO we send (XOR with the scale MAC, then AES-CTR with the
session magic key) confirms it:
11 22 33 44 55 10 01 | 29 | B9 | 00 | 00 00 | FF FF | 1C E2
auth token 41y 185cm pad weight resist const
= 0 kg
HuaweiCH100SHandler.sendUserInfo has the identical line and the same defect.
The measured values themselves are correct — this is not #1206 / #1280 resurfacing.
Weight, body fat, timestamp and weekday all decode exactly as the scale's own
display showed them.
Steps to Reproduce
- Fresh install, create a user profile without entering an initial weight.
- Add a Huawei AH100 / CH100 (mine advertises as
CH100, Chipsea CST34M97).
- Connect and watch the log before stepping on the scale.
op=0x20 / CMD* 0x09 repeat roughly every 250 ms until a measurement lands.
Debug Log (Required)
openScale 3.1.2 built from master 7a170e40, Pixel 10 Pro, Android 17 (API 37).
10:01:03.750 D/HuaweiAhCh100Handler: ← op=0x20 len=1 7D
10:01:03.752 D/HuaweiAhCh100Handler: → CMD* 0x09 len=16 (encrypted)
10:01:03.838 D/GattScaleAdapter: → write to chr=…faa1 len=19 payload=[DC 10 09 BB 27 B1 6E 64 C1 A2 43 4F 99 D0 FD B5 F9 95 96]
10:01:04.136 D/GattScaleAdapter: ← received data chr=…faa2 len=4 payload=[BD 01 20 21]
10:01:04.138 D/HuaweiAhCh100Handler: ← op=0x20 len=1 7D
10:01:04.141 D/HuaweiAhCh100Handler: → CMD* 0x09 len=16 (encrypted)
… 125 more identical cycles …
10:01:40.294 I/HuaweiAhCh100Handler: Measurement: 126.6 kg, fat=33.8%, impedance=306 Ω, userId=1
Note the payload= bytes are identical in every cycle.
With a fallback chain (last stored measurement → profile initial weight →
BMI-22 estimate from body height, never 0) the same hardware drops to 5 cycles.
Verified on the device, not only in unit tests. Happy to open a PR.
Preflight Check (Required)
Bug Description
HuaweiAhCh100Handlersends a user record with weight 0 to the scale, and thescale answers by re-requesting it in a tight loop: 127
USER_CHANGED(op 0x20)round trips in 33 seconds, each answered with a byte-identical encrypted
USER_INFOframe. The loop only stops once an actual measurement completes.Cause is in
sendUserInfo:weightTenthKgcomes fromlastMeasuredWeightTenthKg, which is-1until thefirst measurement of the session, so on connect it falls back to
user.initialWeight— and that is0ffor a freshly created profile.Decrypting the
USER_INFOwe send (XOR with the scale MAC, then AES-CTR with thesession magic key) confirms it:
HuaweiCH100SHandler.sendUserInfohas the identical line and the same defect.The measured values themselves are correct — this is not #1206 / #1280 resurfacing.
Weight, body fat, timestamp and weekday all decode exactly as the scale's own
display showed them.
Steps to Reproduce
CH100, Chipsea CST34M97).op=0x20/CMD* 0x09repeat roughly every 250 ms until a measurement lands.Debug Log (Required)
openScale 3.1.2 built from master
7a170e40, Pixel 10 Pro, Android 17 (API 37).Note the
payload=bytes are identical in every cycle.With a fallback chain (last stored measurement → profile initial weight →
BMI-22 estimate from body height, never 0) the same hardware drops to 5 cycles.
Verified on the device, not only in unit tests. Happy to open a PR.