diff options
Diffstat (limited to 'pjsip/src/pjsua-lib/pjsua_console_app.c')
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_console_app.c | 926 |
1 files changed, 0 insertions, 926 deletions
diff --git a/pjsip/src/pjsua-lib/pjsua_console_app.c b/pjsip/src/pjsua-lib/pjsua_console_app.c deleted file mode 100644 index a54dd689..00000000 --- a/pjsip/src/pjsua-lib/pjsua_console_app.c +++ /dev/null @@ -1,926 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <pjsua-lib/pjsua.h> -#include <pjsua-lib/pjsua_console_app.h> -#include <stdlib.h> /* atoi */ -#include <stdio.h> - -#define THIS_FILE "main.c" - -/* Current dialog */ -static int current_acc; -static int current_call = -1; - - -/* - * Find next call. - */ -static pj_bool_t find_next_call(void) -{ - int i, max; - - max = pjsua_call_get_max_count(); - for (i=current_call+1; i<max; ++i) { - if (pjsua_call_is_active(i)) { - current_call = i; - return PJ_TRUE; - } - } - - for (i=0; i<current_call; ++i) { - if (pjsua_call_is_active(i)) { - current_call = i; - return PJ_TRUE; - } - } - - current_call = -1; - return PJ_FALSE; -} - - -/* - * Find previous call. - */ -static pj_bool_t find_prev_call(void) -{ - int i, max; - - max = pjsua_call_get_max_count(); - for (i=current_call-1; i>=0; --i) { - if (pjsua_call_is_active(i)) { - current_call = i; - return PJ_TRUE; - } - } - - for (i=max-1; i>current_call; --i) { - if (pjsua_call_is_active(i)) { - current_call = i; - return PJ_TRUE; - } - } - - current_call = -1; - return PJ_FALSE; -} - - - -/* - * Notify UI when invite state has changed. - */ -static void console_on_call_state(int call_index, pjsip_event *e) -{ - pjsua_call_info call_info; - - PJ_UNUSED_ARG(e); - - pjsua_call_get_info(call_index, &call_info); - - if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) { - - PJ_LOG(3,(THIS_FILE, "Call %d is DISCONNECTED [reason=%d (%s)]", - call_index, - call_info.last_status, - call_info.last_status_text.ptr)); - - if ((int)call_index == current_call) { - find_next_call(); - } - - } else { - - PJ_LOG(3,(THIS_FILE, "Call %d state changed to %s", - call_index, - call_info.state_text.ptr)); - - if (current_call==-1) - current_call = call_index; - - } -} - -/** - * Notify UI when registration status has changed. - */ -static void console_on_reg_state(int acc_index) -{ - PJ_UNUSED_ARG(acc_index); - - // Log already written. -} - - -/** - * Notify UI on buddy state changed. - */ -static void console_on_buddy_state(int buddy_index) -{ - pjsua_buddy_info info; - pjsua_buddy_get_info(buddy_index, &info); - - PJ_LOG(3,(THIS_FILE, "%.*s status is %.*s", - (int)info.uri.slen, - info.uri.ptr, - (int)info.status_text.slen, - info.status_text.ptr)); -} - - -/** - * Incoming IM message (i.e. MESSAGE request)! - */ -static void console_on_pager(int call_index, const pj_str_t *from, - const pj_str_t *to, const pj_str_t *text) -{ - /* Note: call index may be -1 */ - PJ_UNUSED_ARG(call_index); - PJ_UNUSED_ARG(to); - - PJ_LOG(3,(THIS_FILE,"MESSAGE from %.*s: %.*s", - (int)from->slen, from->ptr, - (int)text->slen, text->ptr)); -} - - -/** - * Typing indication - */ -static void console_on_typing(int call_index, const pj_str_t *from, - const pj_str_t *to, pj_bool_t is_typing) -{ - PJ_UNUSED_ARG(call_index); - PJ_UNUSED_ARG(to); - - PJ_LOG(3,(THIS_FILE, "IM indication: %.*s %s", - (int)from->slen, from->ptr, - (is_typing?"is typing..":"has stopped typing"))); -} - - -/* - * Print buddy list. - */ -static void print_buddy_list(void) -{ - int i, count; - - puts("Buddy list:"); - - count = pjsua_get_buddy_count(); - - if (count == 0) - puts(" -none-"); - else { - for (i=0; i<count; ++i) { - pjsua_buddy_info info; - - if (pjsua_buddy_get_info(i, &info) != PJ_SUCCESS) - continue; - - if (!info.is_valid) - continue; - - printf(" [%2d] <%7s> %.*s\n", - i+1, info.status_text.ptr, - (int)info.uri.slen, - info.uri.ptr); - } - } - puts(""); -} - - -/* - * Print account status. - */ -static void print_acc_status(int acc_index) -{ - char buf[80]; - pjsua_acc_info info; - - pjsua_acc_get_info(acc_index, &info); - - if (!info.has_registration) { - pj_ansi_strcpy(buf, " -not registered to server-"); - - } else { - pj_ansi_snprintf(buf, sizeof(buf), - "%.*s (%.*s;expires=%d)", - (int)info.status_text.slen, - info.status_text.ptr, - (int)info.acc_id.slen, - info.acc_id.ptr, - info.expires); - - } - - printf("[%2d] Registration status: %s\n", acc_index, buf); - printf(" Online status: %s\n", - (info.online_status ? "Online" : "Invisible")); -} - -/* - * Show a bit of help. - */ -static void keystroke_help(void) -{ - int i; - - printf(">>>>\n"); - - for (i=0; i<(int)pjsua_get_acc_count(); ++i) - print_acc_status(i); - - print_buddy_list(); - - //puts("Commands:"); - puts("+=============================================================================+"); - puts("| Call Commands: | IM & Presence: | Misc: |"); - puts("| | | |"); - puts("| m Make new call | i Send IM | o Send OPTIONS |"); - puts("| M Make multiple calls | s Subscribe presence | rr (Re-)register |"); - puts("| a Answer call | u Unsubscribe presence | ru Unregister |"); - puts("| h Hangup call (ha=all) | t ToGgle Online status | |"); - puts("| H Hold call | | |"); - puts("| v re-inVite (release hold) +--------------------------+-------------------+"); - puts("| ] Select next dialog | Conference Command | |"); - puts("| [ Select previous dialog | cl List ports | d Dump status |"); - puts("| x Xfer call | cc Connect port | dd Dump detailed |"); - puts("| # Send DTMF string | cd Disconnect port | dc Dump config |"); - puts("+------------------------------+--------------------------+-------------------+"); - puts("| q QUIT |"); - puts("+=============================================================================+"); -} - - -/* - * Input simple string - */ -static pj_bool_t simple_input(const char *title, char *buf, pj_size_t len) -{ - char *p; - - printf("%s (empty to cancel): ", title); fflush(stdout); - fgets(buf, len, stdin); - - /* Remove trailing newlines. */ - for (p=buf; ; ++p) { - if (*p=='\r' || *p=='\n') *p='\0'; - else if (!*p) break; - } - - if (!*buf) - return PJ_FALSE; - - return PJ_TRUE; -} - - -#define NO_NB -2 -struct input_result -{ - int nb_result; - char *uri_result; -}; - - -/* - * Input URL. - */ -static void ui_input_url(const char *title, char *buf, int len, - struct input_result *result) -{ - result->nb_result = NO_NB; - result->uri_result = NULL; - - print_buddy_list(); - - printf("Choices:\n" - " 0 For current dialog.\n" - " -1 All %d buddies in buddy list\n" - " [1 -%2d] Select from buddy list\n" - " URL An URL\n" - " <Enter> Empty input (or 'q') to cancel\n" - , pjsua_get_buddy_count(), pjsua_get_buddy_count()); - printf("%s: ", title); - - fflush(stdout); - fgets(buf, len, stdin); - len = strlen(buf); - - /* Left trim */ - while (pj_isspace(*buf)) { - ++buf; - --len; - } - - /* Remove trailing newlines */ - while (len && (buf[len-1] == '\r' || buf[len-1] == '\n')) - buf[--len] = '\0'; - - if (len == 0 || buf[0]=='q') - return; - - if (pj_isdigit(*buf) || *buf=='-') { - - int i; - - if (*buf=='-') - i = 1; - else - i = 0; - - for (; i<len; ++i) { - if (!pj_isdigit(buf[i])) { - puts("Invalid input"); - return; - } - } - - result->nb_result = atoi(buf); - - if (result->nb_result >= 0 && - result->nb_result <= (int)pjsua_get_buddy_count()) - { - return; - } - if (result->nb_result == -1) - return; - - puts("Invalid input"); - result->nb_result = NO_NB; - return; - - } else { - pj_status_t status; - - if ((status=pjsua_verify_sip_url(buf)) != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Invalid URL", status); - return; - } - - result->uri_result = buf; - } -} - -static void conf_list(void) -{ - unsigned i, count; - pjsua_conf_port_id id[PJSUA_MAX_CALLS]; - - printf("Conference ports:\n"); - - count = PJ_ARRAY_SIZE(id); - pjsua_conf_enum_port_ids(id, &count); - - for (i=0; i<count; ++i) { - char txlist[PJSUA_MAX_CALLS*4+10]; - unsigned j; - pjsua_conf_port_info info; - - pjsua_conf_get_port_info(id[i], &info); - - txlist[0] = '\0'; - for (j=0; j<info.listener_cnt; ++j) { - char s[10]; - pj_ansi_sprintf(s, "#%d ", info.listeners[j]); - pj_ansi_strcat(txlist, s); - } - printf("Port #%02d[%2dKHz/%dms] %20.*s transmitting to: %s\n", - info.slot_id, - info.clock_rate/1000, - info.samples_per_frame * 1000 / info.clock_rate, - (int)info.name.slen, - info.name.ptr, - txlist); - - } - puts(""); -} - - -void pjsua_console_app_main(const pj_str_t *uri_to_call) -{ - char menuin[10]; - char buf[128]; - char text[128]; - int i, count; - char *uri; - pj_str_t tmp; - struct input_result result; - pjsua_call_info call_info; - pjsua_acc_info acc_info; - - - /* If user specifies URI to call, then call the URI */ - if (uri_to_call->slen) { - pjsua_call_make_call( current_acc, uri_to_call, NULL); - } - - keystroke_help(); - - for (;;) { - - printf(">>> "); - fflush(stdout); - - fgets(menuin, sizeof(menuin), stdin); - - switch (menuin[0]) { - - case 'm': - /* Make call! : */ - printf("(You currently have %d calls)\n", - pjsua_call_get_count()); - - uri = NULL; - ui_input_url("Make call", buf, sizeof(buf), &result); - if (result.nb_result != NO_NB) { - - if (result.nb_result == -1 || result.nb_result == 0) { - puts("You can't do that with make call!"); - continue; - } else { - pjsua_buddy_info binfo; - pjsua_buddy_get_info(result.nb_result-1, &binfo); - uri = binfo.uri.ptr; - } - - } else if (result.uri_result) { - uri = result.uri_result; - } - - tmp = pj_str(uri); - pjsua_call_make_call( current_acc, &tmp, NULL); - break; - - case 'M': - /* Make multiple calls! : */ - printf("(You currently have %d calls)\n", - pjsua_call_get_count()); - - if (!simple_input("Number of calls", menuin, sizeof(menuin))) - continue; - - count = atoi(menuin); - if (count < 1) - continue; - - ui_input_url("Make call", buf, sizeof(buf), &result); - if (result.nb_result != NO_NB) { - pjsua_buddy_info binfo; - if (result.nb_result == -1 || result.nb_result == 0) { - puts("You can't do that with make call!"); - continue; - } - pjsua_buddy_get_info(result.nb_result-1, &binfo); - uri = binfo.uri.ptr; - } else { - uri = result.uri_result; - } - - for (i=0; i<atoi(menuin); ++i) { - pj_status_t status; - - tmp = pj_str(uri); - status = pjsua_call_make_call(current_acc, &tmp, NULL); - if (status != PJ_SUCCESS) - break; - } - break; - - case 'i': - /* Send instant messaeg */ - - /* i is for call index to send message, if any */ - i = -1; - - /* Make compiler happy. */ - uri = NULL; - - /* Input destination. */ - ui_input_url("Send IM to", buf, sizeof(buf), &result); - if (result.nb_result != NO_NB) { - - if (result.nb_result == -1) { - puts("You can't send broadcast IM like that!"); - continue; - - } else if (result.nb_result == 0) { - - i = current_call; - - } else { - pjsua_buddy_info binfo; - pjsua_buddy_get_info(result.nb_result-1, &binfo); - uri = binfo.uri.ptr; - } - - } else if (result.uri_result) { - uri = result.uri_result; - } - - - /* Send typing indication. */ - if (i != -1) - pjsua_call_send_typing_ind(i, PJ_TRUE); - else { - pj_str_t tmp_uri = pj_str(uri); - pjsua_im_typing(current_acc, &tmp_uri, PJ_TRUE); - } - - /* Input the IM . */ - if (!simple_input("Message", text, sizeof(text))) { - /* - * Cancelled. - * Send typing notification too, saying we're not typing. - */ - if (i != -1) - pjsua_call_send_typing_ind(i, PJ_FALSE); - else { - pj_str_t tmp_uri = pj_str(uri); - pjsua_im_typing(current_acc, &tmp_uri, PJ_FALSE); - } - continue; - } - - tmp = pj_str(text); - - /* Send the IM */ - if (i != -1) - pjsua_call_send_im(i, &tmp); - else { - pj_str_t tmp_uri = pj_str(uri); - pjsua_im_send(current_acc, &tmp_uri, &tmp); - } - - break; - - case 'a': - - if (current_call != -1) { - pjsua_call_get_info(current_call, &call_info); - } else { - /* Make compiler happy */ - call_info.active = 0; - call_info.role = PJSIP_ROLE_UAC; - call_info.state = PJSIP_INV_STATE_DISCONNECTED; - } - - if (current_call == -1 || - call_info.active==0 || - call_info.role != PJSIP_ROLE_UAS || - call_info.state >= PJSIP_INV_STATE_CONNECTING) - { - puts("No pending incoming call"); - fflush(stdout); - continue; - - } else { - if (!simple_input("Answer with code (100-699)", buf, sizeof(buf))) - continue; - - if (atoi(buf) < 100) - continue; - - /* - * Must check again! - * Call may have been disconnected while we're waiting for - * keyboard input. - */ - if (current_call == -1) { - puts("Call has been disconnected"); - fflush(stdout); - continue; - } - - pjsua_call_answer(current_call, atoi(buf)); - } - - break; - - - case 'h': - - if (current_call == -1) { - puts("No current call"); - fflush(stdout); - continue; - - } else if (menuin[1] == 'a') { - - /* Hangup all calls */ - pjsua_call_hangup_all(); - - } else { - - /* Hangup current calls */ - pjsua_call_hangup(current_call); - } - break; - - case ']': - case '[': - /* - * Cycle next/prev dialog. - */ - if (menuin[0] == ']') { - find_next_call(); - - } else { - find_prev_call(); - } - - if (current_call != -1) { - - pjsua_call_get_info(current_call, &call_info); - PJ_LOG(3,(THIS_FILE,"Current dialog: %.*s", - (int)call_info.remote_info.slen, - call_info.remote_info.ptr)); - - } else { - PJ_LOG(3,(THIS_FILE,"No current dialog")); - } - break; - - case 'H': - /* - * Hold call. - */ - if (current_call != -1) { - - pjsua_call_set_hold(current_call); - - } else { - PJ_LOG(3,(THIS_FILE, "No current call")); - } - break; - - case 'v': - /* - * Send re-INVITE (to release hold, etc). - */ - if (current_call != -1) { - - pjsua_call_reinvite(current_call); - - } else { - PJ_LOG(3,(THIS_FILE, "No current call")); - } - break; - - case 'x': - /* - * Transfer call. - */ - if (current_call == -1) { - - PJ_LOG(3,(THIS_FILE, "No current call")); - - } else { - int call = current_call; - - ui_input_url("Transfer to URL", buf, sizeof(buf), &result); - - /* Check if call is still there. */ - - if (call != current_call) { - puts("Call has been disconnected"); - continue; - } - - if (result.nb_result != NO_NB) { - if (result.nb_result == -1 || result.nb_result == 0) - puts("You can't do that with transfer call!"); - else { - pjsua_buddy_info binfo; - pjsua_buddy_get_info(result.nb_result-1, &binfo); - pjsua_call_xfer( current_call, - &binfo.uri); - } - - } else if (result.uri_result) { - pj_str_t tmp; - tmp = pj_str(result.uri_result); - pjsua_call_xfer( current_call, &tmp); - } - } - break; - - case '#': - /* - * Send DTMF strings. - */ - if (current_call == -1) { - - PJ_LOG(3,(THIS_FILE, "No current call")); - - } else if (!pjsua_call_has_media(current_call)) { - - PJ_LOG(3,(THIS_FILE, "Media is not established yet!")); - - } else { - pj_str_t digits; - int call = current_call; - pj_status_t status; - - if (!simple_input("DTMF strings to send (0-9*#A-B)", buf, - sizeof(buf))) - { - break; - } - - if (call != current_call) { - puts("Call has been disconnected"); - continue; - } - - digits = pj_str(buf); - status = pjsua_call_dial_dtmf(current_call, &digits); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Unable to send DTMF", status); - } else { - puts("DTMF digits enqueued for transmission"); - } - } - break; - - case 's': - case 'u': - /* - * Subscribe/unsubscribe presence. - */ - ui_input_url("(un)Subscribe presence of", buf, sizeof(buf), &result); - if (result.nb_result != NO_NB) { - if (result.nb_result == -1) { - int i, count; - count = pjsua_get_buddy_count(); - for (i=0; i<count; ++i) - pjsua_buddy_subscribe_pres(i, menuin[0]=='s'); - } else if (result.nb_result == 0) { - puts("Sorry, can only subscribe to buddy's presence, " - "not from existing call"); - } else { - pjsua_buddy_subscribe_pres(result.nb_result-1, (menuin[0]=='s')); - } - - } else if (result.uri_result) { - puts("Sorry, can only subscribe to buddy's presence, " - "not arbitrary URL (for now)"); - } - - break; - - case 'r': - switch (menuin[1]) { - case 'r': - /* - * Re-Register. - */ - pjsua_acc_set_registration(current_acc, PJ_TRUE); - break; - case 'u': - /* - * Unregister - */ - pjsua_acc_set_registration(current_acc, PJ_FALSE); - break; - } - break; - - case 't': - pjsua_acc_get_info(current_acc, &acc_info); - acc_info.online_status = !acc_info.online_status; - pjsua_acc_set_online_status(current_acc, acc_info.online_status); - printf("Setting %s online status to %s\n", - acc_info.acc_id.ptr, - (acc_info.online_status?"online":"offline")); - break; - - case 'c': - switch (menuin[1]) { - case 'l': - conf_list(); - break; - case 'c': - case 'd': - { - char src_port[10], dst_port[10]; - pj_status_t status; - const char *src_title, *dst_title; - - conf_list(); - - src_title = (menuin[1]=='c'? - "Connect src port #": - "Disconnect src port #"); - dst_title = (menuin[1]=='c'? - "To dst port #": - "From dst port #"); - - if (!simple_input(src_title, src_port, sizeof(src_port))) - break; - - if (!simple_input(dst_title, dst_port, sizeof(dst_port))) - break; - - if (menuin[1]=='c') { - status = pjsua_conf_connect(atoi(src_port), - atoi(dst_port)); - } else { - status = pjsua_conf_disconnect(atoi(src_port), - atoi(dst_port)); - } - if (status == PJ_SUCCESS) { - puts("Success"); - } else { - puts("ERROR!!"); - } - } - break; - } - break; - - case 'd': - if (menuin[1] == 'c') { - char settings[2000]; - int len; - - len = pjsua_dump_settings(NULL, settings, - sizeof(settings)); - if (len < 1) - PJ_LOG(3,(THIS_FILE, "Error: not enough buffer")); - else - PJ_LOG(3,(THIS_FILE, - "Dumping configuration (%d bytes):\n%s\n", - len, settings)); - } else { - pjsua_dump(menuin[1]=='d'); - } - break; - - case 'q': - goto on_exit; - - default: - if (menuin[0] != '\n' && menuin[0] != '\r') { - printf("Invalid input %s", menuin); - } - keystroke_help(); - break; - } - } - -on_exit: - ; -} - - -/***************************************************************************** - * Error display: - */ - -/* - * Display error message for the specified error code. - */ -void pjsua_perror(const char *sender, const char *title, - pj_status_t status) -{ - char errmsg[PJ_ERR_MSG_SIZE]; - - pj_strerror(status, errmsg, sizeof(errmsg)); - - PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status)); -} - - - -pjsua_callback console_callback = -{ - &console_on_call_state, - NULL, /* on_incoming_call */ - NULL, /* default accept transfer */ - &console_on_reg_state, - &console_on_buddy_state, - &console_on_pager, - &console_on_typing, -}; |