diff options
-rw-r--r-- | include/baresip.h | 28 | ||||
-rw-r--r-- | modules/cons/cons.c | 104 | ||||
-rw-r--r-- | modules/evdev/evdev.c | 63 | ||||
-rw-r--r-- | modules/gst/gst.c | 2 | ||||
-rw-r--r-- | modules/stdio/stdio.c | 62 | ||||
-rw-r--r-- | modules/wincons/wincons.c | 67 | ||||
-rw-r--r-- | src/audio.c | 2 | ||||
-rw-r--r-- | src/config.c | 25 | ||||
-rw-r--r-- | src/ua.c | 2 | ||||
-rw-r--r-- | src/ui.c | 106 |
10 files changed, 235 insertions, 226 deletions
diff --git a/include/baresip.h b/include/baresip.h index 8a83ad3..966c618 100644 --- a/include/baresip.h +++ b/include/baresip.h @@ -130,11 +130,6 @@ enum audio_mode { /** Core configuration */ struct config { - /** Input */ - struct config_input { - char device[64]; /**< Input device name */ - uint32_t port; /**< Input port number */ - } input; /** SIP User-Agent */ struct config_sip { @@ -536,27 +531,24 @@ struct sipevent_sock *uag_sipevent_sock(void); * User Interface */ -struct ui; -struct ui_st; +typedef int (ui_output_h)(const char *str); -/** User Interface parameters */ -struct ui_prm { - char *device; /**< Device name */ - uint16_t port; /**< Port number */ +/** Defines a User-Interface module */ +struct ui { + struct le le; /**< Linked-list element */ + const char *name; /**< Name of the UI-module */ + ui_output_h *outputh; /**< Handler for output strings (optional) */ }; -typedef void (ui_input_h)(char key, struct re_printf *pf, void *arg); -typedef int (ui_alloc_h)(struct ui_st **stp, struct ui_prm *prm, - ui_input_h *ih, void *arg); -typedef int (ui_output_h)(struct ui_st *st, const char *str); +void ui_register(struct ui *ui); +void ui_unregister(struct ui *ui); -void ui_init(const struct config_input *cfg); +void ui_reset(void); void ui_input(char key); +void ui_input_key(char key, struct re_printf *pf); void ui_input_str(const char *str); int ui_input_pl(struct re_printf *pf, const struct pl *pl); void ui_output(const char *str); -int ui_register(struct ui **uip, const char *name, - ui_alloc_h *alloch, ui_output_h *outh); /* diff --git a/modules/cons/cons.c b/modules/cons/cons.c index 8cf5b10..91c86c6 100644 --- a/modules/cons/cons.c +++ b/modules/cons/cons.c @@ -7,20 +7,40 @@ #include <baresip.h> +/** + * @defgroup cons cons + * + * Console User-Interface (UI) using UDP/TCP sockets + * + * + * This module implements a simple console for connecting to Baresip via + * UDP or TCP-based sockets. You can use programs like telnet or netcat to + * connect to the command-line interface. + * + * Example, with the cons-module listening on default port 5555: + * + \verbatim + $ netcat -u 127.0.0.1 5555 + \endverbatim + * + * The following options can be configured: + * + \verbatim + cons_listen 0.0.0.0:5555 # IP-address and port to listen on + \endverbatim + */ + + enum {CONS_PORT = 5555}; struct ui_st { - struct ui *ui; /* base class */ struct udp_sock *us; struct tcp_sock *ts; struct tcp_conn *tc; - ui_input_h *h; - void *arg; }; -static struct ui *cons; -static struct ui_st *cons_cur = NULL; /* allow only one instance */ +static struct ui_st *cons = NULL; /* allow only one instance */ static int print_handler(const char *p, size_t size, void *arg) @@ -38,8 +58,14 @@ static void udp_recv(const struct sa *src, struct mbuf *mb, void *arg) pf.vph = print_handler; pf.arg = mbr; - while (mbuf_get_left(mb)) - st->h(mbuf_read_u8(mb), &pf, st->arg); + while (mbuf_get_left(mb)) { + char ch = mbuf_read_u8(mb); + + if (ch == '\r') + ch = '\n'; + + ui_input_key(ch, &pf); + } mbr->pos = 0; (void)udp_send(st->us, src, mbr); @@ -55,10 +81,6 @@ static void cons_destructor(void *arg) mem_deref(st->us); mem_deref(st->tc); mem_deref(st->ts); - - mem_deref(st->ui); - - cons_cur = NULL; } @@ -84,9 +106,12 @@ static void tcp_recv_handler(struct mbuf *mb, void *arg) while (mbuf_get_left(mb) > 0) { - const char key = mbuf_read_u8(mb); + char ch = mbuf_read_u8(mb); + + if (ch == '\r') + ch = '\n'; - st->h(key, &pf, st->arg); + ui_input_key(ch, &pf); } } @@ -114,64 +139,71 @@ static void tcp_conn_handler(const struct sa *peer, void *arg) } -static int cons_alloc(struct ui_st **stp, struct ui_prm *prm, - ui_input_h *h, void *arg) +static int cons_alloc(struct ui_st **stp, const struct sa *laddr) { - struct sa local; struct ui_st *st; int err; if (!stp) return EINVAL; - if (cons_cur) { - *stp = mem_ref(cons_cur); - return 0; - } - st = mem_zalloc(sizeof(*st), cons_destructor); if (!st) return ENOMEM; - st->ui = mem_ref(cons); - st->h = h; - st->arg = arg; - - err = sa_set_str(&local, "0.0.0.0", prm->port ? prm->port : CONS_PORT); - if (err) - goto out; - err = udp_listen(&st->us, &local, udp_recv, st); + err = udp_listen(&st->us, laddr, udp_recv, st); if (err) { - warning("cons: failed to listen on UDP port %d (%m)\n", - sa_port(&local), err); + warning("cons: failed to listen on UDP %J (%m)\n", + laddr, err); goto out; } - err = tcp_listen(&st->ts, &local, tcp_conn_handler, st); + err = tcp_listen(&st->ts, laddr, tcp_conn_handler, st); if (err) { - warning("cons: failed to listen on TCP port %d (%m)\n", - sa_port(&local), err); + warning("cons: failed to listen on TCP %J (%m)\n", + laddr, err); goto out; } + debug("cons: UI console listening on %J\n", laddr); + out: if (err) mem_deref(st); else - *stp = cons_cur = st; + *stp = st; return err; } +static struct ui ui_cons = { + .name = "cons", +}; + + static int cons_init(void) { - return ui_register(&cons, "cons", cons_alloc, NULL); + struct sa laddr; + int err; + + if (conf_get_sa(conf_cur(), "cons_listen", &laddr)) { + sa_set_str(&laddr, "0.0.0.0", CONS_PORT); + } + + err = cons_alloc(&cons, &laddr); + if (err) + return err; + + ui_register(&ui_cons); + + return 0; } static int cons_close(void) { + ui_unregister(&ui_cons); cons = mem_deref(cons); return 0; } diff --git a/modules/evdev/evdev.c b/modules/evdev/evdev.c index ba924f4..962cdc9 100644 --- a/modules/evdev/evdev.c +++ b/modules/evdev/evdev.c @@ -14,22 +14,26 @@ #include "print.h" -/* Note: +/** + * @defgroup evdev evdev + * + * User-Interface (UI) module using the Linux input subsystem. * - * KEY_NUMERIC_xyz added in linux kernel 2.6.28 + * The following options can be configured: + * + \verbatim + evdev_device /dev/input/event0 # Name of the input device to use + \endverbatim */ struct ui_st { - struct ui *ui; /* base class */ int fd; - ui_input_h *h; - void *arg; }; -static struct ui *evdev; -static char evdev_device[64] = "/dev/event0"; +static struct ui_st *evdev; +static char evdev_device[64] = "/dev/input/event0"; static void evdev_close(struct ui_st *st) @@ -48,7 +52,6 @@ static void evdev_destructor(void *arg) struct ui_st *st = arg; evdev_close(st); - mem_deref(st->ui); } @@ -160,14 +163,10 @@ static int stderr_handler(const char *p, size_t sz, void *arg) static void reportkey(struct ui_st *st, int ascii) { - struct re_printf pf; - - pf.vph = stderr_handler; + static struct re_printf pf_stderr = {stderr_handler, NULL}; + (void)st; - if (!st->h) - return; - - st->h(ascii, &pf, st->arg); + ui_input_key(ascii, &pf_stderr); } @@ -221,10 +220,8 @@ static void evdev_fd_handler(int flags, void *arg) } -static int evdev_alloc(struct ui_st **stp, struct ui_prm *prm, - ui_input_h *uih, void *arg) +static int evdev_alloc(struct ui_st **stp, const char *dev) { - const char *dev = str_isset(prm->device) ? prm->device : evdev_device; struct ui_st *st; int err = 0; @@ -235,10 +232,10 @@ static int evdev_alloc(struct ui_st **stp, struct ui_prm *prm, if (!st) return ENOMEM; - st->ui = mem_ref(evdev); st->fd = open(dev, O_RDWR); if (st->fd < 0) { err = errno; + warning("evdev: failed to open device '%s' (%m)\n", dev, err); goto out; } @@ -259,9 +256,6 @@ static int evdev_alloc(struct ui_st **stp, struct ui_prm *prm, if (err) goto out; - st->h = uih; - st->arg = arg; - out: if (err) mem_deref(st); @@ -290,11 +284,12 @@ static int buzz(const struct ui_st *st, int value) } -static int evdev_output(struct ui_st *st, const char *str) +static int evdev_output(const char *str) { + struct ui_st *st = evdev; int err = 0; - if (!str) + if (!st || !str) return EINVAL; while (*str) { @@ -314,14 +309,32 @@ static int evdev_output(struct ui_st *st, const char *str) } +static struct ui ui_evdev = { + .name = "evdev", + .outputh = evdev_output +}; + + static int module_init(void) { - return ui_register(&evdev, "evdev", evdev_alloc, evdev_output); + int err; + + conf_get_str(conf_cur(), "evdev_device", + evdev_device, sizeof(evdev_device)); + + err = evdev_alloc(&evdev, evdev_device); + if (err) + return err; + + ui_unregister(&ui_evdev); + + return 0; } static int module_close(void) { + ui_unregister(&ui_evdev); evdev = mem_deref(evdev); return 0; } diff --git a/modules/gst/gst.c b/modules/gst/gst.c index 301fe93..46973a4 100644 --- a/modules/gst/gst.c +++ b/modules/gst/gst.c @@ -37,7 +37,7 @@ struct ausrc_st { void *arg; /**< Handler argument */ struct ausrc_prm prm; /**< Read parameters */ struct aubuf *aubuf; /**< Packet buffer */ - uint32_t psize; /**< Packet size in bytes */ + size_t psize; /**< Packet size in bytes */ size_t sampc; /* Gstreamer */ diff --git a/modules/stdio/stdio.c b/modules/stdio/stdio.c index bfdc9e7..244dc01 100644 --- a/modules/stdio/stdio.c +++ b/modules/stdio/stdio.c @@ -11,24 +11,30 @@ #include <baresip.h> +/** + * @defgroup stdio stdio + * + * User-Interface (UI) module for standard input/output + * + * This module sets up the terminal in raw mode, and reads characters from the + * input to the UI subsystem. The module is indented for Unix-based systems. + */ + + /** Local constants */ enum { RELEASE_VAL = 250 /**< Key release value in [ms] */ }; struct ui_st { - struct ui *ui; /* base class */ struct tmr tmr; struct termios term; bool term_set; - ui_input_h *h; - void *arg; }; /* We only allow one instance */ -static struct ui_st *_ui; -static struct ui *stdio; +static struct ui_st *ui_state; static void ui_destructor(void *arg) @@ -41,9 +47,6 @@ static void ui_destructor(void *arg) tcsetattr(STDIN_FILENO, TCSANOW, &st->term); tmr_cancel(&st->tmr); - mem_deref(st->ui); - - _ui = NULL; } @@ -57,12 +60,10 @@ static int print_handler(const char *p, size_t size, void *arg) static void report_key(struct ui_st *ui, char key) { - struct re_printf pf; - - pf.vph = print_handler; + static struct re_printf pf_stderr = {print_handler, NULL}; + (void)ui; - if (ui->h) - ui->h(key, &pf, ui->arg); + ui_input_key(key, &pf_stderr); } @@ -115,27 +116,18 @@ static int term_setup(struct ui_st *st) } -static int ui_alloc(struct ui_st **stp, struct ui_prm *prm, - ui_input_h *ih, void *arg) +static int ui_alloc(struct ui_st **stp) { struct ui_st *st; int err; - (void)prm; - if (!stp) return EINVAL; - if (_ui) { - *stp = mem_ref(_ui); - return 0; - } - st = mem_zalloc(sizeof(*st), ui_destructor); if (!st) return ENOMEM; - st->ui = mem_ref(stdio); tmr_init(&st->tmr); err = fd_listen(STDIN_FILENO, FD_READ, ui_fd_handler, st); @@ -148,28 +140,40 @@ static int ui_alloc(struct ui_st **stp, struct ui_prm *prm, err = 0; } - st->h = ih; - st->arg = arg; - out: if (err) mem_deref(st); else - *stp = _ui = st; + *stp = st; return err; } +static struct ui ui_stdio = { + .name = "stdio" +}; + + static int module_init(void) { - return ui_register(&stdio, "stdio", ui_alloc, NULL); + int err; + + err = ui_alloc(&ui_state); + if (err) + return err; + + ui_register(&ui_stdio); + + return 0; } static int module_close(void) { - stdio = mem_deref(stdio); + ui_unregister(&ui_stdio); + ui_state = mem_deref(ui_state); + return 0; } diff --git a/modules/wincons/wincons.c b/modules/wincons/wincons.c index 6724fc7..0ab7153 100644 --- a/modules/wincons/wincons.c +++ b/modules/wincons/wincons.c @@ -9,35 +9,44 @@ #include <baresip.h> +/** + * @defgroup wincons wincons + * + * User-Interface (UI) module for Windows Console + */ + + /** Local constants */ enum { RELEASE_VAL = 250 /**< Key release value in [ms] */ }; struct ui_st { - struct ui *ui; /* base class */ struct tmr tmr; struct mqueue *mq; HANDLE hThread; bool run; - ui_input_h *h; - void *arg; + HANDLE hstdin; + DWORD mode; }; -static struct ui *wincons; +static struct ui_st *wincons; static void destructor(void *arg) { struct ui_st *st = arg; + /* Restore the console to its previous state */ + if (st->mode) + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), st->mode); + st->run = false; CloseHandle(st->hThread); tmr_cancel(&st->tmr); mem_deref(st->mq); - mem_deref(st->ui); } @@ -51,12 +60,10 @@ static int print_handler(const char *p, size_t size, void *arg) static void report_key(struct ui_st *ui, char key) { - struct re_printf pf; - - pf.vph = print_handler; + static struct re_printf pf_stderr = {print_handler, NULL}; + (void)ui; - if (ui->h) - ui->h(key, &pf, ui->arg); + ui_input_key(key, &pf_stderr); } @@ -73,19 +80,15 @@ static DWORD WINAPI input_thread(LPVOID arg) { struct ui_st *st = arg; - HANDLE hstdin = GetStdHandle( STD_INPUT_HANDLE ); - DWORD mode; - /* Switch to raw mode */ - GetConsoleMode(hstdin, &mode); - SetConsoleMode(hstdin, 0); + SetConsoleMode(st->hstdin, 0); while (st->run) { char buf[4]; DWORD i, count = 0; - ReadConsole(hstdin, buf, sizeof(buf), &count, NULL); + ReadConsole(st->hstdin, buf, sizeof(buf), &count, NULL); for (i=0; i<count; i++) { int ch = buf[i]; @@ -102,9 +105,6 @@ static DWORD WINAPI input_thread(LPVOID arg) } } - /* Restore the console to its previous state */ - SetConsoleMode(hstdin, mode); - return 0; } @@ -119,13 +119,11 @@ static void mqueue_handler(int id, void *data, void *arg) } -static int ui_alloc(struct ui_st **stp, struct ui_prm *prm, - ui_input_h *ih, void *arg) +static int ui_alloc(struct ui_st **stp) { struct ui_st *st; DWORD threadID; int err = 0; - (void)prm; if (!stp) return EINVAL; @@ -134,16 +132,17 @@ static int ui_alloc(struct ui_st **stp, struct ui_prm *prm, if (!st) return ENOMEM; - st->ui = mem_ref(wincons); - st->h = ih; - st->arg = arg; - tmr_init(&st->tmr); err = mqueue_alloc(&st->mq, mqueue_handler, st); if (err) goto out; + st->hstdin = GetStdHandle(STD_INPUT_HANDLE); + + /* save the current console mode */ + GetConsoleMode(st->hstdin, &st->mode); + st->run = true; st->hThread = CreateThread(NULL, 0, input_thread, st, 0, &threadID); if (!st->hThread) { @@ -162,14 +161,28 @@ static int ui_alloc(struct ui_st **stp, struct ui_prm *prm, } +static struct ui ui_wincons = { + .name = "wincons" +}; + + static int module_init(void) { - return ui_register(&wincons, "wincons", ui_alloc, NULL); + int err; + + err = ui_alloc(&wincons); + if (err) + return err; + + ui_register(&ui_wincons); + + return 0; } static int module_close(void) { + ui_unregister(&ui_wincons); wincons = mem_deref(wincons); return 0; } diff --git a/src/audio.c b/src/audio.c index 1d7c71f..954dd72 100644 --- a/src/audio.c +++ b/src/audio.c @@ -334,7 +334,7 @@ static void encode_rtp_send(struct audio *a, struct autx *tx, */ frame_size = (tx->is_g722 ? sampc/2 : sampc) / tx->ac->ch; - tx->ts += frame_size; + tx->ts += (uint32_t)frame_size; out: tx->marker = false; diff --git a/src/config.c b/src/config.c index a63d3c5..f882e39 100644 --- a/src/config.c +++ b/src/config.c @@ -18,11 +18,6 @@ /** Core Run-time Configuration - populated from config file */ /** @todo: move config parsing/decoding to a module */ static struct config core_config = { - /* Input */ - { - "/dev/event0", - 5555 - }, /** SIP User-Agent */ { @@ -139,11 +134,6 @@ int config_parse_conf(struct config *cfg, const struct conf *conf) } } - /* Input */ - (void)conf_get_str(conf, "input_device", cfg->input.device, - sizeof(cfg->input.device)); - (void)conf_get_u32(conf, "input_port", &cfg->input.port); - /* SIP */ (void)conf_get_u32(conf, "sip_trans_bsize", &cfg->sip.trans_bsize); (void)conf_get_str(conf, "sip_listen", cfg->sip.local, @@ -240,10 +230,6 @@ int config_print(struct re_printf *pf, const struct config *cfg) err = re_hprintf(pf, "\n" - "# Input\n" - "input_device\t\t%s\n" - "input_port\t\t%u\n" - "\n" "# SIP\n" "sip_trans_bsize\t\t%u\n" "sip_listen\t\t%s\n" @@ -288,8 +274,6 @@ int config_print(struct re_printf *pf, const struct config *cfg) #endif , - cfg->input.device, cfg->input.port, - cfg->sip.trans_bsize, cfg->sip.local, cfg->sip.cert, cfg->audio.play_mod, cfg->audio.play_dev, @@ -397,9 +381,6 @@ static int core_config_template(struct re_printf *pf, const struct config *cfg) #ifdef HAVE_EPOLL ", epoll ..\n" #endif - "\n# Input\n" - "input_device\t\t/dev/event0\n" - "input_port\t\t5555\n" "\n# SIP\n" "sip_trans_bsize\t\t128\n" "#sip_listen\t\t0.0.0.0:5060\n" @@ -694,6 +675,12 @@ int config_write_template(const char *file, const struct config *cfg) (void)re_fprintf(f, "# Module parameters\n"); (void)re_fprintf(f, "\n"); + (void)re_fprintf(f, "\n"); + (void)re_fprintf(f, "cons_listen\t\t0.0.0.0:5555\n"); + + (void)re_fprintf(f, "\n"); + (void)re_fprintf(f, "evdev_device\t\t/dev/input/event0\n"); + (void)re_fprintf(f, "\n# Speex codec parameters\n"); (void)re_fprintf(f, "speex_quality\t\t7 # 0-10\n"); (void)re_fprintf(f, "speex_complexity\t7 # 0-10\n"); @@ -1099,7 +1099,6 @@ int ua_init(const char *software, bool udp, bool tcp, bool tls, uag.cfg = &cfg->sip; bsize = cfg->sip.trans_bsize; - ui_init(&cfg->input); play_init(); @@ -1164,6 +1163,7 @@ void ua_close(void) cmd_unregister(cmdv); net_close(); play_close(); + ui_reset(); uag.evsock = mem_deref(uag.evsock); uag.sock = mem_deref(uag.sock); @@ -8,34 +8,13 @@ #include "core.h" -/** User Interface */ -struct ui { - struct le le; - const char *name; - struct ui_st *st; /* only one instance */ - ui_output_h *outputh; - struct cmd_ctx *ctx; -}; - static struct list uil; /**< List of UIs (struct ui) */ -static struct config_input input_cfg; +static struct cmd_ctx *uictx; -static void ui_handler(char key, struct re_printf *pf, void *arg) +static void ui_handler(char key, struct re_printf *pf) { - struct ui *ui = arg; - - (void)cmd_process(ui ? &ui->ctx : NULL, key, pf); -} - - -static void destructor(void *arg) -{ - struct ui *ui = arg; - - list_unlink(&ui->le); - mem_deref(ui->st); - mem_deref(ui->ctx); + (void)cmd_process(&uictx, key, pf); } @@ -53,50 +32,30 @@ static int stdout_handler(const char *p, size_t size, void *arg) /** * Register a new User-Interface (UI) module * - * @param uip Pointer to allocated UI module - * @param name Name of the UI module - * @param alloch UI allocation handler - * @param outh UI output handler - * - * @return 0 if success, otherwise errorcode + * @param ui The User-Interface (UI) module to register */ -int ui_register(struct ui **uip, const char *name, - ui_alloc_h *alloch, ui_output_h *outh) +void ui_register(struct ui *ui) { - struct ui *ui; - int err = 0; - - if (!uip) - return EINVAL; - - ui = mem_zalloc(sizeof(*ui), destructor); if (!ui) - return ENOMEM; + return; list_append(&uil, &ui->le, ui); - ui->name = name; - ui->outputh = outh; - - if (alloch) { - struct ui_prm prm; - - prm.device = input_cfg.device; - prm.port = input_cfg.port; + debug("ui: %s\n", ui->name); +} - err = alloch(&ui->st, &prm, ui_handler, ui); - if (err) { - warning("ui: register: module '%s' failed (%m)\n", - ui->name, err); - } - } - if (err) - mem_deref(ui); - else - *uip = ui; +/** + * Un-register a User-Interface (UI) module + * + * @param ui The User-Interface (UI) module to un-register + */ +void ui_unregister(struct ui *ui) +{ + if (!ui) + return; - return err; + list_unlink(&ui->le); } @@ -107,12 +66,21 @@ int ui_register(struct ui **uip, const char *name, */ void ui_input(char key) { - struct re_printf pf; + static struct re_printf pf_stdout = {stdout_handler, NULL}; - pf.vph = stdout_handler; - pf.arg = NULL; + ui_handler(key, &pf_stdout); +} - ui_handler(key, &pf, list_ledata(uil.head)); + +/** + * Send an input key to the UI subsystem, with a print function for response + * + * @param key Input character + * @param pf Print function for the response + */ +void ui_input_key(char key, struct re_printf *pf) +{ + ui_handler(key, pf); } @@ -171,15 +139,15 @@ void ui_output(const char *str) const struct ui *ui = le->data; if (ui->outputh) - ui->outputh(ui->st, str); + ui->outputh(str); } } -void ui_init(const struct config_input *cfg) +/** + * Reset the state of the UI subsystem, free resources + */ +void ui_reset(void) { - if (!cfg) - return; - - input_cfg = *cfg; + uictx = mem_deref(uictx); } |