Skip to content

Add SET_SATELLITE_INFO (opcode 77) request + reply body structs#27

Open
cameronzucker wants to merge 2 commits into
khusmann:mainfrom
cameronzucker:add-satellite-info-body
Open

Add SET_SATELLITE_INFO (opcode 77) request + reply body structs#27
cameronzucker wants to merge 2 commits into
khusmann:mainfrom
cameronzucker:add-satellite-info-body

Conversation

@cameronzucker

@cameronzucker cameronzucker commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Follows up #26 with the SET_SATELLITE_INFO (BasicCommand 77) payload structs.

SET_SATELLITE_INFO is sent phone → radio while the app is tracking an
amateur satellite. It pushes the current pass solution so the HT can show
az/el/range on its own screen during a pass. (Doppler shift is handled
separately via FREQ_MODE_SET_PAR, not here.)

Wire layout (fixed 30 bytes)

off size field notes
0 20 B name satellite name, GB2312, NUL-padded
20 9 b azimuth integer degrees 0–359
7 b reserved (0)
8 b elevation integer degrees (unsigned)
8 b reserved (0)
24 16 b range_km slant range, km
26 16 b altitude_km orbital altitude, km
28 16 b countdown_secs seconds to next event; 0xFFFF = unknown

Bitfields are MSB-first / big-endian, matching the rest of the protocol.

Provenance

The fields come from the BTECH UV Programmer app (com.benshikj.ht.btech.ham):
the serializer w4.d#a() and its caller com.dw.ht.satellite.b#W(), which
computes the look-angle vector via Orekit and rounds az/el/range/altitude into
the fields above. Meanings are cross-checked against the app's embedded
satellite.proto data model (RfInfo/GP/TLE).

Verification

Golden vector — name="ISS", az=180°, el=45°, range=800 km, alt=420 km, countdown=600 s:

49 53 53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
5A 00 2D 00 03 20 01 A4 02 58

SetSatelliteInfoBody(...).to_bytes() reproduces this byte-for-byte and
round-trips via from_bytes. The countdown_secs sentinel (0xFFFFNone)
round-trips, and SetSatelliteInfoReplyBody encodes a ReplyStatus.SUCCESS
ack to 0x00.

Notes

  • Name charset is GB2312 (bf_str(20, "gb2312")), not ASCII — identical for
    typical names (ISS, AO-91, SO-50), diverging only on non-ASCII.
  • Firmware clamps range_km/altitude_km > 65535 to 0 (not a sentinel).
  • The reply body is inferred, not captured. Every SET_* command in this
    protocol returns a bare ReplyStatus ack (modeled here on
    SetPhoneStatusReplyBody), and the decompile contains no dedicated reply
    parser. The request body is the verified contribution; the reply struct can
    be dropped from this PR if confirming it against an on-air BLE/RFCOMM capture
    first is preferable.

SetSatelliteInfoBody is the fixed 30-byte phone->radio payload pushed while
the app tracks an amateur satellite (name, az/el, range, altitude, countdown).
SetSatelliteInfoReplyBody is the bare ReplyStatus ack inferred from the SET_*
convention. Derived from the BTECH UV Programmer decompile; verified against a
golden vector.
Import the new bodies, add the BasicCommand.SET_SATELLITE_INFO case to
body_disc(), and export both classes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant