Report preparation
What happened?
Antenna Genius Port B section is hidden when connecting via manual IP
What happened
When the Antenna Genius (AG) applet connects to a 2-radio-input AG device (e.g. AG 8x2) using a manual IP address in Radio Setup → Peripherals, only Port A is rendered in the applet. The Port B section is hidden, even though the AG hardware has a second radio input that is wired and active. Switching the FLEX between ANT1 and ANT2 does not cause Port B to appear, because the section was never created visible in the first place.
The same AG, connected via auto-discovery (UDP beacon, same LAN), correctly shows both Port A and Port B.
Environment
Note: the bug also reproduces on a single LAN if the user enters the IP manually instead of waiting for auto-discovery. Off-subnet was just the original trigger for noticing it.
Suggested fix
Root cause
AntennaGeniusModel.cpp:316 contains a ShackSwitch-specific fallback that fires for every device when no UDP beacon has arrived:
// Uno Q sends V2.0, R4 sends V1.0.
m_device.radioPorts = (m_device.version == "2.0") ? 2 : 1;
For a real AG (firmware version like 4.1.16), neither branch matches and radioPorts defaults to 1. Manual-IP connections never receive a UDP beacon, so this fallback is the sole source of radioPorts for them. The applet then hides Port B at AntennaGeniusApplet.cpp:308:
m_portBSection->setVisible(m_model->connectedDevice().radioPorts >= 2);
Verification via pcap
A packet capture of 4O3A's Antenna Genius Utility connecting to the same AG shows it issues an info get command immediately after authentication. The AG responds on a single line:
R2|0|info v=4.1.16 date=2024-10-18 btl=1.6 hw=4.0 serial=18-3A-D0 name=Antenna_Genius ports=2 antennas=8 mode=master uptime=22159
Fields of interest: ports=2 antennas=8. The format is the same key=value syntax that the existing UDP beacon parser already handles via parseKeyValues(). The command is documented at https://github.com/4o3a/genius-api-docs/wiki/Antenna-Genius-API.
AetherSDR currently does not send info get anywhere. The 4O3A Utility's full connect cascade is: auth code (if required) → info get → band list → antenna list → conf get → sub port all → sub relay → sub output → keepalive enable → periodic ping. AetherSDR's runInitSequence() skips the info get step entirely.
Proposed fix
- Send
C<seq>|info get immediately after the prologue is accepted (or, when present, after a successful auth code exchange).
- Parse the response body with the existing
parseKeyValues() helper. The leading literal info token has no = and is ignored by the regex automatically.
- Update
m_device.radioPorts, m_device.antennaPorts, and optionally m_device.serial, m_device.name, m_device.version, m_device.mode from the parsed values.
- Emit a new
deviceInfoChanged() signal so the applet re-evaluates Port B visibility (which today is only set inside the connected() handler, before info get would have responded).
- Call
runInitSequence() from the info get response handler, in both success and failure paths, so the connection never stalls if a device does not respond to info get (e.g. ShackSwitch).
- Keep the existing ShackSwitch fallback heuristic on line 316 intact so ShackSwitch continues to work as a baseline that
info get overrides when available.
Parser detail worth flagging
info get returns its data on a single non-empty body line with no terminating empty-body line, unlike antenna list and band list which accumulate multiple lines and end with an empty body. A naive port of the m_seqAuth dispatch pattern (which lives inside if (body.isEmpty())) will never fire for info get because the body is non-empty on the only line that arrives. The handler needs to dispatch from the non-empty-body path. A local patch verifying this works is in hand and can be submitted as a PR.
Independence from #2313
This bug is independent of #2313 (Auth Code support). It triggers for any manual-IP connection to a real AG, with or without auth required. The fix should land regardless of #2313's status; the only coordination point is that the post-prologue command order changes from <auth?> → runInitSequence to <auth?> → info get → runInitSequence.
What did you expect?
What I expected
Both Port A and Port B should be visible in the AntennaGeniusApplet whenever the connected AG hardware has two radio inputs, regardless of how the connection was established (auto-discovery vs manual IP). This matches the behavior of 4O3A's Antenna Genius Utility on Windows, which always shows the correct number of radio ports for the connected device.
Steps to reproduce
Steps to reproduce
- Have an AG with two radio inputs (e.g. AG 8x2), firmware 4.1.16, reachable on the network.
- In AetherSDR, open Radio Setup → Peripherals.
- Enter the AG's IP address manually in the AG row, leave port at 9007, click Connect.
- Open the Antenna Genius applet.
- Observe: only Port A is visible. Port B section is absent.
- For comparison: disconnect, restart AetherSDR on the same LAN as the AG so UDP discovery works, connect via auto-discovery. Now both Port A and Port B are visible.
AetherSDR version
v26.5.3
Radio model & firmware
AU-520
Operating system
Linux
OS version and hardware
CachyOS
Report preparation
What happened?
Antenna Genius Port B section is hidden when connecting via manual IP
What happened
When the Antenna Genius (AG) applet connects to a 2-radio-input AG device (e.g. AG 8x2) using a manual IP address in Radio Setup → Peripherals, only Port A is rendered in the applet. The Port B section is hidden, even though the AG hardware has a second radio input that is wired and active. Switching the FLEX between ANT1 and ANT2 does not cause Port B to appear, because the section was never created visible in the first place.
The same AG, connected via auto-discovery (UDP beacon, same LAN), correctly shows both Port A and Port B.
Environment
Note: the bug also reproduces on a single LAN if the user enters the IP manually instead of waiting for auto-discovery. Off-subnet was just the original trigger for noticing it.
Suggested fix
Root cause
AntennaGeniusModel.cpp:316contains a ShackSwitch-specific fallback that fires for every device when no UDP beacon has arrived:For a real AG (firmware version like 4.1.16), neither branch matches and
radioPortsdefaults to 1. Manual-IP connections never receive a UDP beacon, so this fallback is the sole source ofradioPortsfor them. The applet then hides Port B atAntennaGeniusApplet.cpp:308:Verification via pcap
A packet capture of 4O3A's Antenna Genius Utility connecting to the same AG shows it issues an
info getcommand immediately after authentication. The AG responds on a single line:Fields of interest:
ports=2 antennas=8. The format is the samekey=valuesyntax that the existing UDP beacon parser already handles viaparseKeyValues(). The command is documented at https://github.com/4o3a/genius-api-docs/wiki/Antenna-Genius-API.AetherSDR currently does not send
info getanywhere. The 4O3A Utility's full connect cascade is:auth code(if required) →info get→band list→antenna list→conf get→sub port all→sub relay→sub output→keepalive enable→ periodicping. AetherSDR'srunInitSequence()skips theinfo getstep entirely.Proposed fix
C<seq>|info getimmediately after the prologue is accepted (or, when present, after a successfulauth codeexchange).parseKeyValues()helper. The leading literalinfotoken has no=and is ignored by the regex automatically.m_device.radioPorts,m_device.antennaPorts, and optionallym_device.serial,m_device.name,m_device.version,m_device.modefrom the parsed values.deviceInfoChanged()signal so the applet re-evaluates Port B visibility (which today is only set inside theconnected()handler, beforeinfo getwould have responded).runInitSequence()from theinfo getresponse handler, in both success and failure paths, so the connection never stalls if a device does not respond toinfo get(e.g. ShackSwitch).info getoverrides when available.Parser detail worth flagging
info getreturns its data on a single non-empty body line with no terminating empty-body line, unlikeantenna listandband listwhich accumulate multiple lines and end with an empty body. A naive port of them_seqAuthdispatch pattern (which lives insideif (body.isEmpty())) will never fire forinfo getbecause the body is non-empty on the only line that arrives. The handler needs to dispatch from the non-empty-body path. A local patch verifying this works is in hand and can be submitted as a PR.Independence from #2313
This bug is independent of #2313 (Auth Code support). It triggers for any manual-IP connection to a real AG, with or without auth required. The fix should land regardless of #2313's status; the only coordination point is that the post-prologue command order changes from
<auth?> → runInitSequenceto<auth?> → info get → runInitSequence.What did you expect?
What I expected
Both Port A and Port B should be visible in the AntennaGeniusApplet whenever the connected AG hardware has two radio inputs, regardless of how the connection was established (auto-discovery vs manual IP). This matches the behavior of 4O3A's Antenna Genius Utility on Windows, which always shows the correct number of radio ports for the connected device.
Steps to reproduce
Steps to reproduce
AetherSDR version
v26.5.3
Radio model & firmware
AU-520
Operating system
Linux
OS version and hardware
CachyOS