~singpolyma/ccd

ea19096f0bcdaace643513bd12ddf7f92a03df10 — Stephen Paul Weber 4 months ago 09f3e41
Support sending DTMF from stdin
1 files changed, 45 insertions(+), 13 deletions(-)

M main.c
M main.c => main.c +45 -13
@@ 1,3 1,4 @@
#define _POSIX_C_SOURCE 1
#include <pulse/simple.h>
#include <signal.h>
#include <snikket.h>


@@ 5,15 6,17 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>

// NOTE: callbacks all happen on other threads, so be careful

// Globals, ew
static volatile sig_atomic_t hangup = 0; // Gross control flow flag
static void *chat = NULL;
static void *dtmf = NULL;
static pa_simple *pulse = NULL;
static pa_sample_spec ss_rec;
static pa_simple *pulse_rec = NULL;
static bool exiting = false;

struct online_ctx {
	void *client;


@@ 31,14 34,14 @@ void on_call_retract(const char *chat_id, void *dummy) {
	snikket_release(chat_id);
	puts("Hung up...");
	chat = NULL; // So we don't call hangup again
	hangup = 1;
	if (!exiting) exit(0);
}

// User asked to stop
void sigint_handler(int sig) {
	(void)sig;
	puts("Hang up...");
	hangup = 1;
	exit(0);
}

// Audio track got some from the other side, so let's play it


@@ 112,6 115,9 @@ void on_call_media(void* session, bool audio, bool video, void* dummy) {
	streams[cstreams++] = snikket_jingle_media_stream_make_audio();
	size_t ctracks = snikket_jingle_media_stream_get_tracks(streams[cstreams-1], &tracks);
	for (size_t i = 0; i < ctracks; i++) {
		if (!dtmf) {
			dtmf = snikket_jingle_dtmf_sender_new(tracks[i]);
		}
		snikket_jingle_media_stream_track_add_pcm_listener(tracks[i], &on_pcm, NULL);
		snikket_jingle_media_stream_track_add_ready_for_pcm_listener(tracks[i], &on_ready_for_pcm, tracks[i]);
		snikket_release(tracks[i]);


@@ 170,6 176,21 @@ void on_password_needed(void *client, void *password) {
	snikket_release(client);
}

void at_exit(void) {
	exiting = true;

	// If it was us, send the hangup signal
	if (chat) {
		snikket_chat_hangup(chat);
		sleep(3); // Give time for hangup to send, etc
	}

	// We could release stuff here, but we're gonna exit anyway

	// Stop the SDK, no waiting
	snikket_stop(false);
}

int main(int argc, const char **argv) {
	const char *err;



@@ 187,6 208,9 @@ int main(int argc, const char **argv) {
		return 1;
	}

	// Set cleanup hook
	atexit(&at_exit);

	// And make a persistence layer
	void *persistence = snikket_persistence_dummy_new();



@@ 208,20 232,28 @@ int main(int argc, const char **argv) {
	puts("Connecting...");
	snikket_client_start(client);

	// Wait for one side to hang up
	while (!hangup) {
		sleep(1);
	struct termios term;
	int fd = fileno(stdin);

	// Get the current terminal attributes
	if (tcgetattr(fd, &term) == -1) {
		perror("tcgetattr");
		return 1;
	}

	// If it was us, send the hangup signal
	if (chat) {
		snikket_chat_hangup(chat);
		sleep(3); // Give time for hangup to send, etc
	// Set non-canonical mode, to get characters immediately
	term.c_lflag &= ~ICANON;

	// Apply the new attributes immediately
	if (tcsetattr(fd, TCSANOW, &term) == -1) {
		perror("tcsetattr");
		return 1;
	}

	// We could release stuff here, but we're gonna exit anyway
	char tone[2] = " ";
	while ((tone[0] = fgetc(stdin)) != EOF) {
		if (dtmf) snikket_jingle_dtmf_sender_insert_dtmf(dtmf, tone);
	}

	// Stop the SDK, no waiting
	snikket_stop(false);
	return 0;
}