From c01fdece34cb0eac0c1fdbafb5c1cc242ec01933 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Fri, 26 May 2006 12:17:46 +0000 Subject: First stage in pjsua library re-arrangements towards creating an easy to use high level API git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@476 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip-apps/src/pjsua/main.c | 1023 +------------------------------------------ 1 file changed, 17 insertions(+), 1006 deletions(-) (limited to 'pjsip-apps/src/pjsua') diff --git a/pjsip-apps/src/pjsua/main.c b/pjsip-apps/src/pjsua/main.c index 97da6f34..1e060f4e 100644 --- a/pjsip-apps/src/pjsua/main.c +++ b/pjsip-apps/src/pjsua/main.c @@ -17,1004 +17,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include /* atoi */ -#include - -#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; - - for (i=current_call+1; i<(int)pjsua.max_calls; ++i) { - if (pjsua.calls[i].inv != NULL) { - current_call = i; - return PJ_TRUE; - } - } - - for (i=0; i=0; --i) { - if (pjsua.calls[i].inv != NULL) { - current_call = i; - return PJ_TRUE; - } - } - - for (i=pjsua.max_calls-1; i>current_call; --i) { - if (pjsua.calls[i].inv != NULL) { - current_call = i; - return PJ_TRUE; - } - } - - current_call = -1; - return PJ_FALSE; -} - - - -/* - * Notify UI when invite state has changed. - */ -void pjsua_ui_on_call_state(int call_index, pjsip_event *e) -{ - pjsua_call *call = &pjsua.calls[call_index]; - - PJ_UNUSED_ARG(e); - - if (call->inv->state == PJSIP_INV_STATE_DISCONNECTED) { - - PJ_LOG(3,(THIS_FILE, "Call %d is DISCONNECTED [reason=%d (%s)]", - call_index, - call->inv->cause, - pjsip_get_status_text(call->inv->cause)->ptr)); - - call->inv = NULL; - if ((int)call->index == current_call) { - find_next_call(); - } - - } else { - - PJ_LOG(3,(THIS_FILE, "Call %d state changed to %s", - call_index, - pjsua_inv_state_names[call->inv->state])); - - if (call && current_call==-1) - current_call = call->index; - - } -} - -/** - * Notify UI when registration status has changed. - */ -void pjsua_ui_on_reg_state(int acc_index) -{ - PJ_UNUSED_ARG(acc_index); - - // Log already written. -} - - -/** - * Incoming IM message (i.e. MESSAGE request)! - */ -void pjsua_ui_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 - */ -void pjsua_ui_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; - - puts("Buddy list:"); - - if (pjsua.buddy_cnt == 0) - puts(" -none-"); - else { - for (i=0; i %s\n", - i+1, status, pjsua.buddies[i].uri.ptr); - } - } - puts(""); -} - - -/* - * Print account status. - */ -static void print_acc_status(int acc_index) -{ - char reg_status[128]; - - if (pjsua.acc[acc_index].regc == NULL) { - pj_ansi_strcpy(reg_status, " -not registered to server-"); - - } else if (pjsua.acc[acc_index].reg_last_err != PJ_SUCCESS) { - pj_strerror(pjsua.acc[acc_index].reg_last_err, reg_status, sizeof(reg_status)); - - } else if (pjsua.acc[acc_index].reg_last_code>=200 && - pjsua.acc[acc_index].reg_last_code<=699) { - - pjsip_regc_info info; - const pj_str_t *status_str; - - pjsip_regc_get_info(pjsua.acc[acc_index].regc, &info); - - status_str = pjsip_get_status_text(pjsua.acc[acc_index].reg_last_code); - pj_ansi_snprintf(reg_status, sizeof(reg_status), - "%s (%.*s;expires=%d)", - status_str->ptr, - (int)info.client_uri.slen, - info.client_uri.ptr, - info.next_reg); - - } else { - pj_ansi_sprintf(reg_status, "in progress (%d)", - pjsua.acc[acc_index].reg_last_code); - } - - printf("[%2d] Registration status: %s\n", acc_index, reg_status); - printf(" Online status: %s\n", - (pjsua.acc[acc_index].online_status ? "Online" : "Invisible")); -} - -/* - * Show a bit of help. - */ -static void keystroke_help(void) -{ - int i; - - printf(">>>>\n"); - - for (i=0; inb_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" - " Empty input (or 'q') to cancel\n" - , pjsua.buddy_cnt, pjsua.buddy_cnt); - 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 (; inb_result = atoi(buf); - - if (result->nb_result >= 0 && result->nb_result <= (int)pjsua.buddy_cnt) { - 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; - pjmedia_conf_port_info info[PJSUA_MAX_CALLS]; - - printf("Conference ports:\n"); - - count = PJ_ARRAY_SIZE(info); - pjmedia_conf_get_ports_info(pjsua.mconf, &count, info); - for (i=0; ilistener[j]) { - pj_ansi_sprintf(s, "#%d ", j); - pj_ansi_strcat(txlist, s); - } - } - printf("Port #%02d[%2dKHz/%dms] %20.*s transmitting to: %s\n", - port_info->slot, - port_info->clock_rate/1000, - port_info->samples_per_frame * 1000 / port_info->clock_rate, - (int)port_info->name.slen, - port_info->name.ptr, - txlist); - - } - puts(""); -} - - -static void ui_console_main(void) -{ - char menuin[10]; - char buf[128]; - char text[128]; - int i, count; - char *uri; - struct input_result result; - - - /* If user specifies URI to call, then call the URI */ - if (pjsua.uri_to_call.slen) { - pjsua_make_call( current_acc, pjsua.uri_to_call.ptr, 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_cnt); - - 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 { - uri = pjsua.buddies[result.nb_result-1].uri.ptr; - } - - } else if (result.uri_result) { - uri = result.uri_result; - } - - pjsua_make_call( current_acc, uri, NULL); - break; - - case 'M': - /* Make multiple calls! : */ - printf("(You currently have %d calls)\n", pjsua.call_cnt); - - 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) { - if (result.nb_result == -1 || result.nb_result == 0) { - puts("You can't do that with make call!"); - continue; - } - uri = pjsua.buddies[result.nb_result-1].uri.ptr; - } else { - uri = result.uri_result; - } - - for (i=0; irole != PJSIP_ROLE_UAS || - pjsua.calls[current_call].inv->state >= PJSIP_INV_STATE_CONNECTING) - { - puts("No pending incoming call"); - fflush(stdout); - continue; - - } else { - pj_status_t status; - pjsip_tx_data *tdata; - - 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; - } - - status = pjsip_inv_answer(pjsua.calls[current_call].inv, - atoi(buf), - NULL, NULL, &tdata); - if (status == PJ_SUCCESS) - status = pjsip_inv_send_msg(pjsua.calls[current_call].inv, - tdata); - - if (status != PJ_SUCCESS) - pjsua_perror(THIS_FILE, "Unable to create/send response", - status); - } - - 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) { - char url[PJSIP_MAX_URL_SIZE]; - int len; - const pjsip_uri *u; - - u = pjsua.calls[current_call].inv->dlg->remote.info->uri; - len = pjsip_uri_print(0, u, url, sizeof(url)-1); - if (len < 1) { - pj_ansi_strcpy(url, ""); - } else { - url[len] = '\0'; - } - - PJ_LOG(3,(THIS_FILE,"Current dialog: %s", url)); - - } 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_call_xfer( current_call, - pjsua.buddies[result.nb_result-1].uri.ptr); - - } else if (result.uri_result) { - pjsua_call_xfer( current_call, result.uri_result); - } - } - break; - - case '#': - /* - * Send DTMF strings. - */ - if (current_call == -1) { - - PJ_LOG(3,(THIS_FILE, "No current call")); - - } else if (pjsua.calls[current_call].session == NULL) { - - 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 = pjmedia_session_dial_dtmf(pjsua.calls[current_call].session, 0, - &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; - for (i=0; imsg_info.len, - pjsip_rx_data_get_info(rdata), - rdata->pkt_info.src_name, - rdata->pkt_info.src_port, - rdata->msg_info.msg_buf)); - - /* Always return false, otherwise messages will not get processed! */ - return PJ_FALSE; -} - -/* Notification on outgoing messages */ -static pj_status_t console_on_tx_msg(pjsip_tx_data *tdata) -{ - - /* Important note: - * tp_info field is only valid after outgoing messages has passed - * transport layer. So don't try to access tp_info when the module - * has lower priority than transport layer. - */ - - PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n" - "%s\n" - "--end msg--", - (tdata->buf.cur - tdata->buf.start), - pjsip_tx_data_get_info(tdata), - tdata->tp_info.dst_name, - tdata->tp_info.dst_port, - tdata->buf.start)); - - /* Always return success, otherwise message will not get sent! */ - return PJ_SUCCESS; -} - -/* The module instance. */ -static pjsip_module console_msg_logger = -{ - NULL, NULL, /* prev, next. */ - { "mod-pjsua-log", 13 }, /* Name. */ - -1, /* Id */ - PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority */ - NULL, /* load() */ - NULL, /* start() */ - NULL, /* stop() */ - NULL, /* unload() */ - &console_on_rx_msg, /* on_rx_request() */ - &console_on_rx_msg, /* on_rx_response() */ - &console_on_tx_msg, /* on_tx_request. */ - &console_on_tx_msg, /* on_tx_response() */ - NULL, /* on_tsx_state() */ - -}; - - - -/***************************************************************************** - * Console application custom logging: - */ - - -static FILE *log_file; - - -static void app_log_writer(int level, const char *buffer, int len) -{ - /* Write to both stdout and file. */ - - if (level <= pjsua.app_log_level) - pj_log_write(level, buffer, len); - - if (log_file) { - fwrite(buffer, len, 1, log_file); - fflush(log_file); - } -} - - -pj_status_t app_logging_init(void) -{ - /* Redirect log function to ours */ - - pj_log_set_log_func( &app_log_writer ); - - /* If output log file is desired, create the file: */ - - if (pjsua.log_filename) { - log_file = fopen(pjsua.log_filename, "wt"); - if (log_file == NULL) { - PJ_LOG(1,(THIS_FILE, "Unable to open log file %s", - pjsua.log_filename)); - return -1; - } - } - - return PJ_SUCCESS; -} - - -void app_logging_shutdown(void) -{ - /* Close logging file, if any: */ - - if (log_file) { - fclose(log_file); - log_file = NULL; - } -} - -/***************************************************************************** - * 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)); -} - +#include +#define THIS_FILE "main.c" /***************************************************************************** * main(): @@ -1022,30 +28,35 @@ void pjsua_perror(const char *sender, const char *title, int main(int argc, char *argv[]) { + pjsua_config cfg; + /* Init default settings. */ - pjsua_default(); + pjsua_default_config(&cfg); - /* Initialize pjsua (to create pool etc). - */ - if (pjsua_init() != PJ_SUCCESS) - return 1; + /* Create PJLIB and memory pool */ + pjsua_create(); /* Parse command line arguments: */ - if (pjsua_parse_args(argc, argv) != PJ_SUCCESS) + if (pjsua_parse_args(argc, argv, &cfg) != PJ_SUCCESS) return 1; /* Init logging: */ - if (app_logging_init() != PJ_SUCCESS) + if (pjsua_console_app_logging_init(&cfg) != PJ_SUCCESS) return 1; + /* Init pjsua */ + if (pjsua_init(&cfg, &console_callback) != PJ_SUCCESS) + return 1; + /* Register message logger to print incoming and outgoing * messages. */ - pjsip_endpt_register_module(pjsua.endpt, &console_msg_logger); + pjsip_endpt_register_module(pjsua.endpt, + &pjsua_console_app_msg_logger); /* Start pjsua! */ @@ -1061,7 +72,7 @@ int main(int argc, char *argv[]) /* Start UI console main loop: */ - ui_console_main(); + pjsua_console_app_main(); /* Destroy pjsua: */ @@ -1069,7 +80,7 @@ int main(int argc, char *argv[]) /* Close logging: */ - app_logging_shutdown(); + pjsua_console_app_logging_shutdown(); /* Exit... */ -- cgit v1.2.3