Files
qortal-go-2.0/MOBILE_VOICE_HUB_DEV_NOTE.md

3.6 KiB
Raw Permalink Blame History

Native mobile voice calls are working with the Hub — one small Hub tweak away from complete

We've built a native Android Qortal client with Reticulum voice calling that interoperates with the desktop Hub, and we're genuinely at the finish line. This is the breakthrough: a phone and the Hub now hold a real RNS voice call. We just need one small adjustment on the Hub side to make it work in both call directions.

The breakthrough

Hub → mobile calls work fully today — clean twoway audio, low latency. No Hub changes were needed for this. The phone:

  • captures mic audio, encodes Opus, and QGAUwraps frames byteforbyte like the desktop peer;
  • performs the QGCCTL1 + signed GC_JOIN linkauth handshake over the RNS audio link, and the Hub verifies it and delivers GC_KEY over the link — exactly as designed;
  • carries audio both ways over the verified Reticulum link.

In other words, the entire wire protocol — audio framing, Ed25519 linkauth signatures, key delivery, RNS link transport — is already correct and the Hub already accepts it. That's the hard part, and it's done.

The one remaining gap

Mobileinitiated calls (phone → Hub) get stuck on the Hub showing "connecting…" and drop after a few seconds, even though the phone is already "in call", sending audio, and sending the same signed linkauth the Hub happily accepts in the other direction.

We traced it through electron/src/group-call.ts, and it is not a protocol or signature problem — the join verifies. It's a small ordering precondition:

  • The audiolink owner is chosen by address ordering (isLocalAddressReticulumAudioLinkOwner), not by who placed the call, so the Hub opens the link in both directions.
  • Inbound link audio is dropped unless the link is marked verified (audio-unverified-address).
  • A link is only marked verified in applyVerifiedReticulumLinkAuthJoin if the sender is already present in room.participants at that instant.

When the phone initiates, its verified linkauth GC_JOIN arrives before the Hub has registered the caller in room.participants, so the Hub closes the link with link-auth-no-participant / drops audio as audio-unverified-address, and never leaves "connecting". In the Hubinitiated direction the participant state is already in place, so the identical handshake verifies and the call connects. That single ordering difference is the whole gap.

The small Hub change we're asking for

In applyVerifiedReticulumLinkAuthJoin, when the signed GC_JOIN verifies and the sender is a valid Qortal member of the call, admit the participant from the verified join instead of bailing with link-auth-no-participant.

The verified join is itself authenticated proof of membership (Ed25519 over buildGcJoinSignedFields, already checked), so this removes the race without weakening security at all — it just lets a correctlysigned mobile caller be admitted regardless of which side's participant bookkeeping landed first.

That's it. One precondition relaxed for the alreadyverified path. With that in place, mobile→Hub (and mobile↔mobile) calls verify deterministically, exactly like the Hub→mobile calls that already work today.

What we are NOT asking for

  • No change to the wire format, audio framing, signing, key delivery, or the linkowner rule.
  • Nothing changes for Hubinitiated calls — they keep working asis.

Happy to jump on a call or share a build to demo the working direction live. We think this is a great step toward Qortal voice on phones, and we're one small Hub tweak from calls working every direction.