diff options
Diffstat (limited to 'pjsip/src/pjsua/main.c')
-rw-r--r-- | pjsip/src/pjsua/main.c | 251 |
1 files changed, 163 insertions, 88 deletions
diff --git a/pjsip/src/pjsua/main.c b/pjsip/src/pjsua/main.c index 7070c761..25ce6dcf 100644 --- a/pjsip/src/pjsua/main.c +++ b/pjsip/src/pjsua/main.c @@ -23,29 +23,86 @@ #define THIS_FILE "main.c" /* Current dialog */ -static struct pjsua_inv_data *inv_session; +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<current_call; ++i) { + if (pjsua.calls[i].inv != NULL) { + 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; + + for (i=current_call-1; 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_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) +void pjsua_ui_inv_on_state_changed(int call_index, pjsip_event *e) { + pjsua_call *call = &pjsua.calls[call_index]; + PJ_UNUSED_ARG(e); - PJ_LOG(3,(THIS_FILE, "INVITE session state changed to %s", - pjsua_inv_state_names[inv->state])); + PJ_LOG(3,(THIS_FILE, "Call %d state changed to %s", + call_index, + pjsua_inv_state_names[call->inv->state])); - if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { - if (inv == inv_session->inv) { - inv_session = inv_session->next; - if (inv_session == &pjsua.inv_list) - inv_session = pjsua.inv_list.next; + if (call->inv->state == PJSIP_INV_STATE_DISCONNECTED) { + call->inv = NULL; + if ((int)call->index == current_call) { + find_next_call(); } } else { - if (inv_session == &pjsua.inv_list || inv_session == NULL) - inv_session = inv->mod_data[pjsua.mod.id]; + if (call && current_call==-1) + current_call = call->index; } } @@ -66,10 +123,10 @@ void pjsua_ui_regc_on_state_changed(int code) */ static void print_buddy_list(void) { - unsigned i; + int i; puts("Buddy list:"); - //puts("-------------------------------------------------------------------------------"); + if (pjsua.buddy_cnt == 0) puts(" -none-"); else { @@ -93,37 +150,56 @@ static void print_buddy_list(void) puts(""); } + /* - * Show a bit of help. + * Print account status. */ -static void keystroke_help(void) +static void print_acc_status(int acc_index) { char reg_status[128]; - if (pjsua.regc == NULL) { + if (pjsua.acc[acc_index].regc == NULL) { pj_ansi_strcpy(reg_status, " -not registered to server-"); - } else if (pjsua.regc_last_err != PJ_SUCCESS) { - pj_strerror(pjsua.regc_last_err, reg_status, sizeof(reg_status)); - } else if (pjsua.regc_last_code>=200 && pjsua.regc_last_code<=699) { + + } 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; - pjsip_regc_get_info(pjsua.regc, &info); + pjsip_regc_get_info(pjsua.acc[acc_index].regc, &info); pj_snprintf(reg_status, sizeof(reg_status), "%s (%.*s;expires=%d)", - pjsip_get_status_text(pjsua.regc_last_code)->ptr, + pjsip_get_status_text(pjsua.acc[acc_index].reg_last_code)->ptr, (int)info.client_uri.slen, info.client_uri.ptr, info.next_reg); } else { - pj_sprintf(reg_status, "in progress (%d)", pjsua.regc_last_code); + pj_sprintf(reg_status, "in progress (%d)", + pjsua.acc[acc_index].reg_last_code); } - printf(">>>>\nRegistration status: %s\n", reg_status); - printf("Online status: %s\n", - (pjsua.online_status ? "Online" : "Invisible")); + 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; i<pjsua.acc_cnt; ++i) + print_acc_status(i); + print_buddy_list(); //puts("Commands:"); @@ -134,7 +210,7 @@ static void keystroke_help(void) puts("| a Answer call | s Subscribe presence | rr (Re-)register |"); puts("| h Hangup call | u Unsubscribe presence | ru Unregister |"); puts("| ] Select next dialog | t ToGgle Online status | d Dump status |"); - puts("| [ Select previous dialog | | |"); + puts("| [ Select previous dialog | | dc Dump config |"); puts("| +--------------------------+-------------------+"); puts("| H Hold call | Conference Command | |"); puts("| v re-inVite (release hold) | cl List ports | |"); @@ -262,19 +338,19 @@ static void ui_input_url(const char *title, char *buf, int len, static void conf_list(void) { unsigned i, count; - pjmedia_conf_port_info info[16]; + 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; i<count; ++i) { - char txlist[80]; - unsigned j; + char txlist[PJSUA_MAX_CALLS*4+10]; + int j; pjmedia_conf_port_info *port_info = &info[i]; txlist[0] = '\0'; - for (j=0; j<pjsua.max_ports; ++j) { + for (j=0; j<pjsua.max_calls+PJSUA_CONF_MORE_PORTS; ++j) { char s[10]; if (port_info->listener[j]) { pj_sprintf(s, "#%d ", j); @@ -309,26 +385,27 @@ static void ui_console_main(void) case 'm': /* Make call! : */ - if (pj_list_size(&pjsua.inv_list)) - printf("(You have %d calls)\n", pj_list_size(&pjsua.inv_list)); + printf("(You currently have %d calls)\n", pjsua.call_cnt); ui_input_url("Make call", buf, sizeof(buf), &result); if (result.nb_result != NO_NB) { if (result.nb_result == -1) puts("You can't do that with make call!"); else - pjsua_invite(pjsua.buddies[result.nb_result].uri.ptr, NULL); + pjsua_make_call( current_acc, + pjsua.buddies[result.nb_result].uri.ptr, + NULL); } else if (result.uri_result) - pjsua_invite(result.uri_result, NULL); + pjsua_make_call( current_acc, result.uri_result, NULL); break; case 'a': - if (inv_session == &pjsua.inv_list || - inv_session->inv->role != PJSIP_ROLE_UAS || - inv_session->inv->state >= PJSIP_INV_STATE_CONNECTING) + if (current_call == -1 || + pjsua.calls[current_call].inv->role != PJSIP_ROLE_UAS || + pjsua.calls[current_call].inv->state >= PJSIP_INV_STATE_CONNECTING) { puts("No pending incoming call"); fflush(stdout); @@ -349,16 +426,18 @@ static void ui_console_main(void) * Call may have been disconnected while we're waiting for * keyboard input. */ - if (inv_session == &pjsua.inv_list) { + if (current_call == -1) { puts("Call has been disconnected"); fflush(stdout); continue; } - status = pjsip_inv_answer(inv_session->inv, atoi(buf), + status = pjsip_inv_answer(pjsua.calls[current_call].inv, + atoi(buf), NULL, NULL, &tdata); if (status == PJ_SUCCESS) - status = pjsip_inv_send_msg(inv_session->inv, tdata, NULL); + status = pjsip_inv_send_msg(pjsua.calls[current_call].inv, + tdata, NULL); if (status != PJ_SUCCESS) pjsua_perror(THIS_FILE, "Unable to create/send response", @@ -370,13 +449,13 @@ static void ui_console_main(void) case 'h': - if (inv_session == &pjsua.inv_list) { + if (current_call == -1) { puts("No current call"); fflush(stdout); continue; } else { - pjsua_inv_hangup(inv_session, PJSIP_SC_DECLINE); + pjsua_call_hangup(current_call, PJSIP_SC_DECLINE); } break; @@ -386,22 +465,19 @@ static void ui_console_main(void) * Cycle next/prev dialog. */ if (menuin[0] == ']') { - inv_session = inv_session->next; - if (inv_session == &pjsua.inv_list) - inv_session = pjsua.inv_list.next; + find_next_call(); } else { - inv_session = inv_session->prev; - if (inv_session == &pjsua.inv_list) - inv_session = pjsua.inv_list.prev; + find_prev_call(); } - if (inv_session != &pjsua.inv_list) { + if (current_call != -1) { char url[PJSIP_MAX_URL_SIZE]; int len; + const pjsip_uri *u; - len = pjsip_uri_print(0, inv_session->inv->dlg->remote.info->uri, - url, sizeof(url)-1); + 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, "<uri is too long>"); } else { @@ -419,9 +495,9 @@ static void ui_console_main(void) /* * Hold call. */ - if (inv_session != &pjsua.inv_list) { + if (current_call != -1) { - pjsua_inv_set_hold(inv_session); + pjsua_call_set_hold(current_call); } else { PJ_LOG(3,(THIS_FILE, "No current call")); @@ -432,9 +508,9 @@ static void ui_console_main(void) /* * Send re-INVITE (to release hold, etc). */ - if (inv_session != &pjsua.inv_list) { + if (current_call != -1) { - pjsua_inv_reinvite(inv_session); + pjsua_call_reinvite(current_call); } else { PJ_LOG(3,(THIS_FILE, "No current call")); @@ -445,18 +521,18 @@ static void ui_console_main(void) /* * Transfer call. */ - if (inv_session == &pjsua.inv_list) { + if (current_call == -1) { PJ_LOG(3,(THIS_FILE, "No current call")); } else { - struct pjsua_inv_data *cur = inv_session; + int call = current_call; ui_input_url("Transfer to URL", buf, sizeof(buf), &result); /* Check if call is still there. */ - if (cur != inv_session) { + if (call != current_call) { puts("Call has been disconnected"); continue; } @@ -465,11 +541,11 @@ static void ui_console_main(void) if (result.nb_result == -1) puts("You can't do that with transfer call!"); else - pjsua_inv_xfer_call( inv_session, - pjsua.buddies[result.nb_result].uri.ptr); + pjsua_call_xfer( current_call, + pjsua.buddies[result.nb_result].uri.ptr); } else if (result.uri_result) { - pjsua_inv_xfer_call( inv_session, result.uri_result); + pjsua_call_xfer( current_call, result.uri_result); } } break; @@ -478,17 +554,17 @@ static void ui_console_main(void) /* * Send DTMF strings. */ - if (inv_session == &pjsua.inv_list) { + if (current_call == -1) { PJ_LOG(3,(THIS_FILE, "No current call")); - } else if (inv_session->session == NULL) { + } else if (pjsua.calls[current_call].session == NULL) { PJ_LOG(3,(THIS_FILE, "Media is not established yet!")); } else { pj_str_t digits; - struct pjsua_inv_data *cur = inv_session; + int call = current_call; pj_status_t status; if (!simple_input("DTMF strings to send (0-9*#A-B)", buf, @@ -497,13 +573,13 @@ static void ui_console_main(void) break; } - if (cur != inv_session) { + if (call != current_call) { puts("Call has been disconnected"); continue; } digits = pj_str(buf); - status = pjmedia_session_dial_dtmf(inv_session->session, 0, + 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); @@ -521,14 +597,14 @@ static void ui_console_main(void) ui_input_url("(un)Subscribe presence of", buf, sizeof(buf), &result); if (result.nb_result != NO_NB) { if (result.nb_result == -1) { - unsigned i; + int i; for (i=0; i<pjsua.buddy_cnt; ++i) pjsua.buddies[i].monitor = (menuin[0]=='s'); } else { pjsua.buddies[result.nb_result].monitor = (menuin[0]=='s'); } - pjsua_pres_refresh(); + pjsua_pres_refresh(current_acc); } else if (result.uri_result) { puts("Sorry, can only subscribe to buddy's presence, " @@ -543,20 +619,21 @@ static void ui_console_main(void) /* * Re-Register. */ - pjsua_regc_update(PJ_TRUE); + pjsua_regc_update(current_acc, PJ_TRUE); break; case 'u': /* * Unregister */ - pjsua_regc_update(PJ_FALSE); + pjsua_regc_update(current_acc, PJ_FALSE); break; } break; case 't': - pjsua.online_status = !pjsua.online_status; - pjsua_pres_refresh(); + pjsua.acc[current_acc].online_status = + !pjsua.acc[current_acc].online_status; + pjsua_pres_refresh(current_acc); break; case 'c': @@ -606,7 +683,20 @@ static void ui_console_main(void) break; case 'd': - pjsua_dump(); + if (menuin[1] == 'c') { + char settings[2000]; + int len; + + len = pjsua_dump_settings(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(); + } break; case 'q': @@ -765,37 +855,31 @@ int main(int argc, char *argv[]) { /* Init default settings. */ - pjsua_default(); /* Initialize pjsua (to create pool etc). */ - if (pjsua_init() != PJ_SUCCESS) return 1; /* Parse command line arguments: */ - if (pjsua_parse_args(argc, argv) != PJ_SUCCESS) return 1; /* Init logging: */ - app_logging_init(); /* Register message logger to print incoming and outgoing * messages. */ - pjsip_endpt_register_module(pjsua.endpt, &console_msg_logger); /* Start pjsua! */ - if (pjsua_start() != PJ_SUCCESS) { pjsua_destroy(); @@ -804,27 +888,18 @@ int main(int argc, char *argv[]) /* Sleep for a while, let any messages get printed to console: */ - pj_thread_sleep(500); - /* No current call initially: */ - - inv_session = &pjsua.inv_list; - - /* Start UI console main loop: */ - ui_console_main(); /* Destroy pjsua: */ - pjsua_destroy(); /* Close logging: */ - app_logging_shutdown(); |