ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
main.h File Reference

ascii-chat Discovery Mode Entry Point Header More...

Go to the source code of this file.

Functions

int discovery_main (void)
 Discovery mode entry point for unified binary.
 

Detailed Description

ascii-chat Discovery Mode Entry Point Header

This header exposes the discovery mode entry point for the unified binary architecture. The unified binary dispatches to discovery_main() when invoked as ascii-chat discovery.

Discovery Mode Philosophy

"ascii-chat should be as simple as making a phone call."

Discovery mode enables zero-configuration video chat:

  • One command to start: ascii-chat swift-river-mountain
  • Automatic host negotiation: Best NAT quality participant becomes host
  • Dynamic role switching: Participants can become hosts mid-session
  • Seamless failover: If host disconnects, another participant takes over

Mode Entry Point Contract

Each mode entry point (server_main, client_main, discovery_main) must:

  • Accept no arguments: int mode_main(void)
  • Options are already parsed by main dispatcher (available via GET_OPTION())
  • Return 0 on success, non-zero error code on failure
  • Perform mode-specific initialization and main loop
  • Perform complete cleanup before returning

Implementation Notes

Discovery mode combines client and server capabilities:

  • Uses session library (lib/session/) for capture, display, hosting
  • Connects to ACDS for session discovery and NAT quality assessment
  • Can transition between participant and host roles dynamically
Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
January 2026
Version
1.0

Definition in file discovery/main.h.

Function Documentation

◆ discovery_main()

int discovery_main ( void  )

Discovery mode entry point for unified binary.

This function implements the complete discovery mode lifecycle:

  • Session discovery via ACDS or LAN mDNS
  • NAT quality assessment for host selection
  • Dynamic role switching (participant <-> host)
  • Media streaming (video/audio capture and display)
  • Graceful shutdown and cleanup

Options are already parsed by the main dispatcher before this function is called, so they are available via GET_OPTION().

Returns
0 on success, non-zero error code on failure
Example
# Join a session (session string as positional argument):
ascii-chat discovery swift-river-mountain
# Or more concisely (session strings are auto-detected):
ascii-chat swift-river-mountain

Discovery mode entry point for unified binary.

Handles session discovery, host negotiation, and media flow.

Returns
0 on success, non-zero error code on failure

Definition at line 661 of file discovery/main.c.

661 {
662 log_debug("discovery_main() starting");
663
664 // Discovery-specific setup: initialize ACDS connection and session negotiation
665 // Note: Shared setup (keepawake, splash, terminal, capture, display, audio)
666 // is handled by session_client_like_run()
667
668 // Get session string from options (command-line argument)
669 const char *session_string = GET_OPTION(session_string);
670 bool is_initiator = (session_string == NULL || session_string[0] == '\0');
671
672 int port_int = GET_OPTION(port);
673
674 log_debug("Discovery: is_initiator=%d, port=%d", is_initiator, port_int);
675
676 // Validate mutually exclusive options: discovery_service_url vs discovery_port
677 const char *service_url = GET_OPTION(discovery_service_url);
678 if (service_url && service_url[0] != '\0') {
679 int discovery_port = GET_OPTION(discovery_port);
680 if (discovery_port != ACIP_DISCOVERY_DEFAULT_PORT) {
681 log_fatal("--discovery-service-url and --discovery-service-port are mutually exclusive");
682 return ERROR_USAGE;
683 }
684 }
685
686 // Create discovery session configuration
687 discovery_config_t discovery_config = {
688 .acds_address = GET_OPTION(discovery_server),
689 .acds_port = (uint16_t)GET_OPTION(discovery_port),
690 .acds_url = service_url,
691 .session_string = is_initiator ? NULL : session_string,
692 .password = GET_OPTION(password),
693 .local_port = (uint16_t)port_int,
694 .on_state_change = on_discovery_state_change,
695 .on_session_ready = on_session_ready,
696 .on_error = on_discovery_error,
697 .callback_user_data = NULL,
698 .should_exit_callback = discovery_capture_should_exit_adapter,
699 .exit_callback_data = NULL,
700 };
701
702 // Create discovery session (stored in global for discovery_run() to access)
703 g_discovery = discovery_session_create(&discovery_config);
704 if (!g_discovery) {
705 log_fatal("Failed to create discovery session");
706 return ERROR_MEMORY;
707 }
708
709 // Start discovery session (connects to ACDS, creates/joins, initiates NAT negotiation)
710 log_debug("Discovery: starting discovery session");
711 asciichat_error_t result = discovery_session_start(g_discovery);
712 if (result != ASCIICHAT_OK) {
713 log_fatal("Failed to start discovery session: %d", result);
714 discovery_session_destroy(g_discovery);
715 g_discovery = NULL;
716 return result;
717 }
718
719 // No network interrupt callback needed - discovery session handles its own shutdown
721
722 /* ========================================================================
723 * Configure and Run Shared Client-Like Session Framework
724 * ========================================================================
725 * session_client_like_run() handles all shared initialization:
726 * - Terminal output management
727 * - Keepawake system
728 * - Splash screen lifecycle
729 * - Media source selection
730 * - FPS probing
731 * - Audio initialization
732 * - Display context creation
733 * - Proper cleanup ordering
734 *
735 * Discovery mode provides:
736 * - discovery_run() callback: NAT negotiation, role determination, media handling
737 * - discovery_keyboard_handler: interactive controls for participant role
738 */
739
741 .run_fn = discovery_run,
742 .run_user_data = NULL,
744 .discovery = (void *)g_discovery, // Opaque pointer to discovery session
745 .custom_should_exit = NULL,
746 .exit_user_data = NULL,
747 .keyboard_handler = discovery_keyboard_handler,
748 .max_reconnect_attempts = 0, // Discovery doesn't retry - role is determined once
749 .should_reconnect_callback = NULL,
750 .reconnect_user_data = NULL,
751 .reconnect_delay_ms = 0,
752 .print_newline_on_tty_exit = false, // Server/participant manages cursor
753 };
754
755 log_debug("Discovery: calling session_client_like_run()");
756 asciichat_error_t session_result = session_client_like_run(&config);
757 log_debug("Discovery: session_client_like_run() returned %d", session_result);
758
759 // Cleanup discovery session
760 log_debug("Discovery: cleaning up");
761
762 if (g_discovery) {
763 discovery_session_stop(g_discovery);
764 discovery_session_destroy(g_discovery);
765 g_discovery = NULL;
766 }
767
768 return (session_result == ASCIICHAT_OK) ? 0 : (int)session_result;
769}
asciichat_error_t session_client_like_run(const session_client_like_config_t *config)
@ SESSION_CLIENT_LIKE_KIND_DISCOVERY
Definition client_like.h:66
#define ACIP_DISCOVERY_DEFAULT_PORT
Discovery server default port (use OPT_ACDS_PORT_INT_DEFAULT from options.h)
Definition acds.h:1094
unsigned short uint16_t
Definition common.h:57
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:49
@ ERROR_MEMORY
Definition error_codes.h:56
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_USAGE
Definition error_codes.h:53
#define log_fatal(...)
Log a FATAL message.
Definition log/log.h:599
#define log_debug(...)
Log a DEBUG message.
Definition log/log.h:548
#define GET_OPTION(field)
Safely get a specific option field (lock-free read)
void set_interrupt_callback(void(*callback)(void))
Definition misc.c:125
void discovery_session_stop(discovery_session_t *session)
Stop the discovery session.
discovery_session_t * discovery_session_create(const discovery_config_t *config)
Create a new discovery session.
asciichat_error_t discovery_session_start(discovery_session_t *session)
Start the discovery session.
void discovery_session_destroy(discovery_session_t *session)
Destroy discovery session and free resources.
Configuration for discovery session.
const char * acds_address
ACDS address (default: "127.0.0.1")
session_client_like_run_fn run_fn

References discovery_config_t::acds_address, ACIP_DISCOVERY_DEFAULT_PORT, ASCIICHAT_OK, discovery_session_create(), discovery_session_destroy(), discovery_session_start(), discovery_session_stop(), ERROR_MEMORY, ERROR_USAGE, GET_OPTION, log_debug, log_fatal, SESSION_CLIENT_LIKE_KIND_DISCOVERY, session_client_like_run(), and set_interrupt_callback().