Skip to content

Huawei AH100/CH100: user record is sent with weight 0, scale re-requests it 127x per session #1449

Description

@martinriedel

Preflight Check (Required)

  • I tested the latest dev version
  • The issue still occurs in the dev version
  • I searched the existing open and closed issues
  • This issue has not already been reported or fixed

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

  1. Fresh install, create a user profile without entering an initial weight.
  2. Add a Huawei AH100 / CH100 (mine advertises as CH100, Chipsea CST34M97).
  3. Connect and watch the log before stepping on the scale.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions