mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-08-27 21:19:56 +00:00
feat(lxst): Codec2-700C (ULBW) default profile + T:CALL_ANSWER hook
Adds two profile constants beyond the existing LXST_PROFILE_LBW (0x30, Codec2-3200): LXST_PROFILE_VLBW (0x20, Codec2-1600) and LXST_PROFILE_ULBW (0x10, Codec2-700C). Default is now ULBW — a 700C frame fits comfortably inside an SF7-9 LoRa packet, which is the target medium for pyxis voice. The previous 3200bps default was 4.5x larger and unsuitable for the radio path. Profile is selectable at runtime via T:CALL_PROFILE [hex]. Replaces five hardcoded LXST_PROFILE_LBW sites: three audio-init paths in call_process_signal and two profile-negotiation send_signal calls. Adds T:CALL_ANSWER for harness pyxis-as-callee testing — sets the same _call_answer_pending flag the UI button does so call_answer() runs on the main loop in its proper context. Validates against real LXST.Telephony.Telephone callers. Validated: pyxis dialed real LXST upstream Telephone bot, negotiated ULBW end-to-end, reached STATUS_ESTABLISHED, decoded frames cleanly both directions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
6dbbe1bee7
commit
612f44e274
@@ -1830,6 +1830,17 @@ static void handle_test_hook_command(const String& line) {
|
||||
ui_manager->test_call_hangup();
|
||||
Serial.println("T:OK hung_up");
|
||||
}
|
||||
else if (cmd == "T:CALL_ANSWER") {
|
||||
// T:CALL_ANSWER — accept an incoming ring. Only valid when state
|
||||
// is INCOMING_RINGING. Used by the harness for pyxis-as-callee
|
||||
// interop tests against real LXST.Telephony.Telephone clients.
|
||||
if (!ui_manager) { Serial.println("T:ERR no ui_manager"); return; }
|
||||
if (!ui_manager->test_call_answer()) {
|
||||
Serial.println("T:ERR not_ringing");
|
||||
return;
|
||||
}
|
||||
Serial.println("T:OK answered");
|
||||
}
|
||||
else if (cmd == "T:CALL_STATS") {
|
||||
// T:CALL_STATS — return audio frame counters for the most recent
|
||||
// call. tx = frames sent over the wire (encoded by capture path),
|
||||
@@ -1863,6 +1874,27 @@ static void handle_test_hook_command(const String& line) {
|
||||
Serial.print(" state=");
|
||||
Serial.println(ui_manager->test_call_state_name());
|
||||
}
|
||||
else if (cmd == "T:CALL_PROFILE") {
|
||||
// T:CALL_PROFILE [hex] — get/set pyxis's preferred Codec2 profile.
|
||||
// No arg: print current. With arg: set.
|
||||
// Valid: 0x10 (ULBW/700C), 0x20 (VLBW/1600), 0x30 (LBW/3200).
|
||||
if (!ui_manager) { Serial.println("T:ERR no ui_manager"); return; }
|
||||
if (args.length() == 0) {
|
||||
int p = ui_manager->test_call_get_profile();
|
||||
Serial.print("T:OK profile=0x");
|
||||
if (p < 16) Serial.print("0");
|
||||
Serial.println(String(p, HEX));
|
||||
return;
|
||||
}
|
||||
int profile = (int)strtol(args.c_str(), nullptr, 0);
|
||||
if (!ui_manager->test_call_set_profile(profile)) {
|
||||
Serial.println("T:ERR unknown profile");
|
||||
return;
|
||||
}
|
||||
Serial.print("T:OK profile=0x");
|
||||
if (profile < 16) Serial.print("0");
|
||||
Serial.println(String(profile, HEX));
|
||||
}
|
||||
else if (cmd == "T:CALL_INJECT") {
|
||||
// T:CALL_INJECT <on|off> [freq_hz] [amp_pct]
|
||||
// Replace mic capture with a synthesized sine wave for the
|
||||
|
||||
Reference in New Issue
Block a user