From 134aea8dd229daf938b109af7176be667e4201fb Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 25 Apr 2015 18:19:04 +0200 Subject: add telephony-and-music example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- doc/examples/telephony-and-music/.gitignore | 6 ++ doc/examples/telephony-and-music/Makefile | 13 +++ doc/examples/telephony-and-music/README | 30 +++++++ doc/examples/telephony-and-music/cleanup.c | 8 ++ doc/examples/telephony-and-music/end-call.c | 29 +++++++ doc/examples/telephony-and-music/init.c | 8 ++ doc/examples/telephony-and-music/monitor.c | 95 ++++++++++++++++++++++ .../telephony-and-music/receive-or-make-call.c | 29 +++++++ 8 files changed, 218 insertions(+) create mode 100644 doc/examples/telephony-and-music/.gitignore create mode 100644 doc/examples/telephony-and-music/Makefile create mode 100644 doc/examples/telephony-and-music/README create mode 100644 doc/examples/telephony-and-music/cleanup.c create mode 100644 doc/examples/telephony-and-music/end-call.c create mode 100644 doc/examples/telephony-and-music/init.c create mode 100644 doc/examples/telephony-and-music/monitor.c create mode 100644 doc/examples/telephony-and-music/receive-or-make-call.c (limited to 'doc') diff --git a/doc/examples/telephony-and-music/.gitignore b/doc/examples/telephony-and-music/.gitignore new file mode 100644 index 0000000..25615d2 --- /dev/null +++ b/doc/examples/telephony-and-music/.gitignore @@ -0,0 +1,6 @@ +cleanup +init +monitor +end-call +receive-or-make-call + diff --git a/doc/examples/telephony-and-music/Makefile b/doc/examples/telephony-and-music/Makefile new file mode 100644 index 0000000..10560cb --- /dev/null +++ b/doc/examples/telephony-and-music/Makefile @@ -0,0 +1,13 @@ +COMMANDS = init cleanup monitor end-call receive-or-make-call + +all: ${COMMANDS} + +%: %.c + ${CC} -Wall -Wextra -pedantic -std=c99 -lbus -o $@ $< + +clean: + -rm ${COMMANDS} + + +.PHONY: all clean + diff --git a/doc/examples/telephony-and-music/README b/doc/examples/telephony-and-music/README new file mode 100644 index 0000000..7c97878 --- /dev/null +++ b/doc/examples/telephony-and-music/README @@ -0,0 +1,30 @@ +Use-case example. + +Assume you have a music player and a telephony program. +You might like it if the music player pauses whenever +you make or receive a call. You may also like it, if +the music resumed when the call ended. + +In this example we will assume you the have moc/mocp +running. And we will use the shell to simulate a +telephony program. + + + +First of, run make to build this example. +Before starting run ./init. +And when you are done run ./cleanup. + +In one terminal run ./monitor. This program will +pause mocp when you make or receive a call, it will +also resume mocp when all calls have ended if it +did pause mocp. + +Then start any positive number of terminals. +We will pretend that each of them are telephony +programs. To make or receive a call, run +./receive-or-make-call, when you want to end +the pretend call, run ./end-call from the +terminal (or more accurately, from the same +process). + diff --git a/doc/examples/telephony-and-music/cleanup.c b/doc/examples/telephony-and-music/cleanup.c new file mode 100644 index 0000000..00f07bc --- /dev/null +++ b/doc/examples/telephony-and-music/cleanup.c @@ -0,0 +1,8 @@ +#include +#include + +int main() +{ + return bus_unlink("/tmp/example-bus") && (perror("cleanup"), 1); +} + diff --git a/doc/examples/telephony-and-music/end-call.c b/doc/examples/telephony-and-music/end-call.c new file mode 100644 index 0000000..edd9754 --- /dev/null +++ b/doc/examples/telephony-and-music/end-call.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#define t(stmt) if (stmt) goto fail + + + +static char message[BUS_MEMORY_SIZE]; + + + +int main() +{ + bus_t bus; + sprintf(message, "%ji unforce-pause", (intmax_t)getppid()); + /* Yes, PPID; in this example we pretend the shell is the telephony process. */ + t(bus_open(&bus, "/tmp/example-bus", BUS_WRONLY)); + t(bus_write(&bus, message)); + bus_close(&bus); + return 0; + +fail: + perror("end-call"); + bus_close(&bus); + return 1; +} + diff --git a/doc/examples/telephony-and-music/init.c b/doc/examples/telephony-and-music/init.c new file mode 100644 index 0000000..870e10d --- /dev/null +++ b/doc/examples/telephony-and-music/init.c @@ -0,0 +1,8 @@ +#include +#include + +int main() +{ + return bus_create("/tmp/example-bus", 0, NULL) && (perror("init"), 1); +} + diff --git a/doc/examples/telephony-and-music/monitor.c b/doc/examples/telephony-and-music/monitor.c new file mode 100644 index 0000000..8f8e244 --- /dev/null +++ b/doc/examples/telephony-and-music/monitor.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +#define t(stmt) if (stmt) goto fail + + + +static size_t pauser_count = 0; +static size_t pausers_size = 0; +static char* pausers = NULL; + + + +static int is_moc_playing(void) +{ + return !WEXITSTATUS(system("env LANG=C mocp -i 2>/dev/null | grep 'State: PLAY' >/dev/null")); +} + + + +/* In a proper implementation, message whould be copyied, and then + * a new thread would be created that parsed the copy. But that is + * too much for an example, especially since it would also require + * a mutex to make sure two threads do not modify data at the same + * time, causing chaos. */ +static int callback(const char *message, void *user_data) +{ + char *msg; + size_t len = 0; + while ((len < 2047) && message[len]) + len++; + msg = malloc((len + 1) * sizeof(char)); + t(msg == NULL); + memcpy(msg, message, len * sizeof(char)); + msg[len] = 0; + /* BEGIN run as in a separate thread */ + if (pauser_count || is_moc_playing()) { + char *begin = strchr(msg, ' '); + ssize_t pid; + int requests_pause; + if (begin == NULL) + return 1; + *begin++ = 0; + pid = (ssize_t)atoll(msg); + if (pid < 1) /* We need a real PID, too bad there is + no convient way to detect if it dies. */ + return 1; + if ((strstr(begin, "force-pause ") == begin) || !strcmp(begin, "force-pause")) + requests_pause = 1; + else if ((strstr(begin, "unforce-pause ") == begin) || !strcmp(begin, "unforce-pause")) + requests_pause = 0; + else + return 1; + if ((size_t)pid >= pausers_size) { + pausers = realloc(pausers, (size_t)(pid + 1) * sizeof(char)); + t(pausers == NULL); /* Let's ignore the memory leak. */ + memset(pausers + pausers_size, 0, ((size_t)(pid + 1) - pausers_size) * sizeof(char)); + pausers_size = (size_t)(pid + 1); + } + if (pausers[pid] ^ requests_pause) { + pauser_count += requests_pause ? 1 : -1; + pausers[pid] = requests_pause; + if (pauser_count == (size_t)requests_pause) + system(requests_pause ? "mocp -P" : "mocp -U"); + } + } + /* END run as in a separate thread */ + return 1; + (void) user_data; + +fail: + perror("monitor"); + return -1; +} + + + +int main() +{ + bus_t bus; + t(bus_open(&bus, "/tmp/example-bus", BUS_RDONLY)); + t(bus_read(&bus, callback, NULL)); + bus_close(&bus); + free(pausers); + return 0; + +fail: + perror("monitor"); + bus_close(&bus); + free(pausers); + return 1; +} + diff --git a/doc/examples/telephony-and-music/receive-or-make-call.c b/doc/examples/telephony-and-music/receive-or-make-call.c new file mode 100644 index 0000000..cdd7390 --- /dev/null +++ b/doc/examples/telephony-and-music/receive-or-make-call.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#define t(stmt) if (stmt) goto fail + + + +static char message[BUS_MEMORY_SIZE]; + + + +int main() +{ + bus_t bus; + sprintf(message, "%ji force-pause", (intmax_t)getppid()); + /* Yes, PPID; in this example we pretend the shell is the telephony process. */ + t(bus_open(&bus, "/tmp/example-bus", BUS_WRONLY)); + t(bus_write(&bus, message)); + bus_close(&bus); + return 0; + +fail: + perror("receive-or-make-call"); + bus_close(&bus); + return 1; +} + -- cgit v1.2.3-70-g09d2