diff options
Diffstat (limited to 'pjsip-apps/src/symbian_ua/ua.cpp')
-rw-r--r-- | pjsip-apps/src/symbian_ua/ua.cpp | 1186 |
1 files changed, 0 insertions, 1186 deletions
diff --git a/pjsip-apps/src/symbian_ua/ua.cpp b/pjsip-apps/src/symbian_ua/ua.cpp deleted file mode 100644 index 51e0c050..00000000 --- a/pjsip-apps/src/symbian_ua/ua.cpp +++ /dev/null @@ -1,1186 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) - * Copyright (C) 2003-2008 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_internal.h> -//#include <pjmedia/symbian_sound_aps.h> -#include "ua.h" - -#define THIS_FILE "symbian_ua.cpp" -#define CON_LOG_LEVEL 3 // console log level -#define FILE_LOG_LEVEL 4 // logfile log level - -// -// Basic config. -// -#define SIP_PORT 5060 - - -// -// Destination URI (to make call, or to subscribe presence) -// -#define SIP_DST_URI "<sip:100@pjsip.lab>" - -// -// Account -// -#define HAS_SIP_ACCOUNT 0 // 1 to enable registration -#define SIP_DOMAIN "pjsip.lab" -#define SIP_USER "400" -#define SIP_PASSWD "400" - -// -// Outbound proxy for all accounts -// -#define SIP_PROXY NULL -//#define SIP_PROXY "<sip:192.168.0.8;lr>" - -// -// SIP transports -// -#define ENABLE_SIP_UDP 1 -#define ENABLE_SIP_TCP 0 // experimental -#define ENABLE_SIP_TLS 0 // experimental - -// -// Configure nameserver if DNS SRV is to be used with both SIP -// or STUN (for STUN see other settings below) -// -#define NAMESERVER NULL -//#define NAMESERVER "192.168.0.2" - -// -// STUN server -#if 0 - // Use this to have the STUN server resolved normally -# define STUN_DOMAIN NULL -# define STUN_SERVER "stun.pjsip.org" -#elif 0 - // Use this to have the STUN server resolved with DNS SRV -# define STUN_DOMAIN "pjsip.org" -# define STUN_SERVER NULL -#else - // Use this to disable STUN -# define STUN_DOMAIN NULL -# define STUN_SERVER NULL -#endif - -// -// Use ICE? -// -#define USE_ICE 1 - -// -// Use SRTP? -// -#define USE_SRTP PJSUA_DEFAULT_USE_SRTP - -// -// Set QoS on transports? Yes! -// As an example, we set SIP transports DSCP value to CS3 (DSCP -// value 24 or 0x18), for no reason, and tag RTP/RTCP packets -// with VOICE type. -// -#define SIP_QOS_DSCP 0x18 -#define RTP_QOS_TYPE PJ_QOS_TYPE_VOICE - - -// -// Globals -// -static pjsua_acc_id g_acc_id = PJSUA_INVALID_ID; -static pjsua_call_id g_call_id = PJSUA_INVALID_ID; -static pjsua_buddy_id g_buddy_id = PJSUA_INVALID_ID; - - -/* Callback called by the library upon receiving incoming call */ -static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, - pjsip_rx_data *rdata) -{ - pjsua_call_info ci; - - PJ_UNUSED_ARG(acc_id); - PJ_UNUSED_ARG(rdata); - - if (g_call_id != PJSUA_INVALID_ID) { - pjsua_call_answer(call_id, PJSIP_SC_BUSY_HERE, NULL, NULL); - return; - } - - pjsua_call_get_info(call_id, &ci); - - PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!", - (int)ci.remote_info.slen, - ci.remote_info.ptr)); - - g_call_id = call_id; - - /* Automatically answer incoming calls with 180/Ringing */ - pjsua_call_answer(call_id, 180, NULL, NULL); -} - -/* Callback called by the library when call's state has changed */ -static void on_call_state(pjsua_call_id call_id, pjsip_event *e) -{ - pjsua_call_info ci; - - PJ_UNUSED_ARG(e); - - pjsua_call_get_info(call_id, &ci); - - if (ci.state == PJSIP_INV_STATE_DISCONNECTED) { - if (call_id == g_call_id) - g_call_id = PJSUA_INVALID_ID; - } else if (ci.state != PJSIP_INV_STATE_INCOMING) { - if (g_call_id == PJSUA_INVALID_ID) - g_call_id = call_id; - } - - PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id, - (int)ci.state_text.slen, - ci.state_text.ptr)); -} - -/* Callback called by the library when call's media state has changed */ -static void on_call_media_state(pjsua_call_id call_id) -{ - pjsua_call_info ci; - - pjsua_call_get_info(call_id, &ci); - - if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) { - // When media is active, connect call to sound device. - pjsua_conf_connect(ci.conf_slot, 0); - pjsua_conf_connect(0, ci.conf_slot); - } -} - - -/* Handler on buddy state changed. */ -static void on_buddy_state(pjsua_buddy_id buddy_id) -{ - pjsua_buddy_info info; - pjsua_buddy_get_info(buddy_id, &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 on_pager(pjsua_call_id call_id, const pj_str_t *from, - const pj_str_t *to, const pj_str_t *contact, - const pj_str_t *mime_type, const pj_str_t *text) -{ - /* Note: call index may be -1 */ - PJ_UNUSED_ARG(call_id); - PJ_UNUSED_ARG(to); - PJ_UNUSED_ARG(contact); - PJ_UNUSED_ARG(mime_type); - - PJ_LOG(3,(THIS_FILE,"MESSAGE from %.*s: %.*s", - (int)from->slen, from->ptr, - (int)text->slen, text->ptr)); -} - - -/* Received typing indication */ -static void on_typing(pjsua_call_id call_id, const pj_str_t *from, - const pj_str_t *to, const pj_str_t *contact, - pj_bool_t is_typing) -{ - PJ_UNUSED_ARG(call_id); - PJ_UNUSED_ARG(to); - PJ_UNUSED_ARG(contact); - - PJ_LOG(3,(THIS_FILE, "IM indication: %.*s %s", - (int)from->slen, from->ptr, - (is_typing?"is typing..":"has stopped typing"))); -} - - -/* Call transfer request status. */ -static void on_call_transfer_status(pjsua_call_id call_id, - int status_code, - const pj_str_t *status_text, - pj_bool_t final, - pj_bool_t *p_cont) -{ - PJ_LOG(3,(THIS_FILE, "Call %d: transfer status=%d (%.*s) %s", - call_id, status_code, - (int)status_text->slen, status_text->ptr, - (final ? "[final]" : ""))); - - if (status_code/100 == 2) { - PJ_LOG(3,(THIS_FILE, - "Call %d: call transfered successfully, disconnecting call", - call_id)); - pjsua_call_hangup(call_id, PJSIP_SC_GONE, NULL, NULL); - *p_cont = PJ_FALSE; - } -} - - -/* NAT detection result */ -static void on_nat_detect(const pj_stun_nat_detect_result *res) -{ - if (res->status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "NAT detection failed", res->status); - } else { - PJ_LOG(3, (THIS_FILE, "NAT detected as %s", res->nat_type_name)); - } -} - -/* Notification that call is being replaced. */ -static void on_call_replaced(pjsua_call_id old_call_id, - pjsua_call_id new_call_id) -{ - pjsua_call_info old_ci, new_ci; - - pjsua_call_get_info(old_call_id, &old_ci); - pjsua_call_get_info(new_call_id, &new_ci); - - PJ_LOG(3,(THIS_FILE, "Call %d with %.*s is being replaced by " - "call %d with %.*s", - old_call_id, - (int)old_ci.remote_info.slen, old_ci.remote_info.ptr, - new_call_id, - (int)new_ci.remote_info.slen, new_ci.remote_info.ptr)); -} - -/* - * Transport status notification - */ -static void on_transport_state(pjsip_transport *tp, - pjsip_transport_state state, - const pjsip_transport_state_info *info) -{ - char host_port[128]; - - pj_ansi_snprintf(host_port, sizeof(host_port), "[%.*s:%d]", - (int)tp->remote_name.host.slen, - tp->remote_name.host.ptr, - tp->remote_name.port); - - switch (state) { - case PJSIP_TP_STATE_CONNECTED: - { - PJ_LOG(3,(THIS_FILE, "SIP transport %s is connected to %s", - tp->type_name, host_port)); - } - break; - - case PJSIP_TP_STATE_DISCONNECTED: - { - char buf[100]; - - snprintf(buf, sizeof(buf), "SIP transport %s is disconnected from %s", - tp->type_name, host_port); - pjsua_perror(THIS_FILE, buf, info->status); - } - break; - - default: - break; - } - -#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0 - - if (!pj_ansi_stricmp(tp->type_name, "tls") && info->ext_info && - state == PJSIP_TP_STATE_CONNECTED) - { - pjsip_tls_state_info *tls_info = (pjsip_tls_state_info*)info->ext_info; - pj_ssl_sock_info *ssl_sock_info = (pj_ssl_sock_info*) - tls_info->ssl_sock_info; - char buf[2048]; - - /* Dump server TLS certificate */ - pj_ssl_cert_info_dump(ssl_sock_info->remote_cert_info, " ", - buf, sizeof(buf)); - PJ_LOG(4,(THIS_FILE, "TLS cert info of %s:\n%s", host_port, buf)); - } - -#endif -} - - -//#include<e32debug.h> - -/* Logging callback */ -static void log_writer(int level, const char *buf, int len) -{ - static wchar_t buf16[PJ_LOG_MAX_SIZE]; - - PJ_UNUSED_ARG(level); - - pj_ansi_to_unicode(buf, len, buf16, PJ_ARRAY_SIZE(buf16)); - - TPtrC16 aBuf((const TUint16*)buf16, (TInt)len); - //RDebug::Print(aBuf); - console->Write(aBuf); - -} - -/* - * app_startup() - * - * url may contain URL to call. - */ -static pj_status_t app_startup() -{ - pj_status_t status; - - /* Redirect log before pjsua_init() */ - pj_log_set_log_func(&log_writer); - - /* Set log level */ - pj_log_set_level(CON_LOG_LEVEL); - - /* Create pjsua first! */ - status = pjsua_create(); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "pjsua_create() error", status); - return status; - } - - /* Init pjsua */ - pjsua_config cfg; - pjsua_logging_config log_cfg; - pjsua_media_config med_cfg; - - pjsua_config_default(&cfg); - cfg.max_calls = 2; - cfg.thread_cnt = 0; // Disable threading on Symbian - cfg.use_srtp = USE_SRTP; - cfg.srtp_secure_signaling = 0; - - cfg.cb.on_incoming_call = &on_incoming_call; - cfg.cb.on_call_media_state = &on_call_media_state; - cfg.cb.on_call_state = &on_call_state; - cfg.cb.on_buddy_state = &on_buddy_state; - cfg.cb.on_pager = &on_pager; - cfg.cb.on_typing = &on_typing; - cfg.cb.on_call_transfer_status = &on_call_transfer_status; - cfg.cb.on_call_replaced = &on_call_replaced; - cfg.cb.on_nat_detect = &on_nat_detect; - cfg.cb.on_transport_state = &on_transport_state; - - if (SIP_PROXY) { - cfg.outbound_proxy_cnt = 1; - cfg.outbound_proxy[0] = pj_str(SIP_PROXY); - } - - if (NAMESERVER) { - cfg.nameserver_count = 1; - cfg.nameserver[0] = pj_str(NAMESERVER); - } - - if (NAMESERVER && STUN_DOMAIN) { - cfg.stun_domain = pj_str(STUN_DOMAIN); - } else if (STUN_SERVER) { - cfg.stun_host = pj_str(STUN_SERVER); - } - - - pjsua_logging_config_default(&log_cfg); - log_cfg.level = FILE_LOG_LEVEL; - log_cfg.console_level = CON_LOG_LEVEL; - log_cfg.cb = &log_writer; - log_cfg.log_filename = pj_str("C:\\data\\symbian_ua.log"); - - pjsua_media_config_default(&med_cfg); - med_cfg.thread_cnt = 0; // Disable threading on Symbian - med_cfg.has_ioqueue = PJ_FALSE; - med_cfg.clock_rate = 8000; - med_cfg.audio_frame_ptime = 40; - med_cfg.ec_tail_len = 0; - med_cfg.enable_ice = USE_ICE; - med_cfg.snd_auto_close_time = 0; // wait for 0 seconds idle before sound dev get auto-closed - //med_cfg.no_vad = PJ_TRUE; - - status = pjsua_init(&cfg, &log_cfg, &med_cfg); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "pjsua_init() error", status); - pjsua_destroy(); - return status; - } - - /* Adjust Speex priority and enable only the narrowband */ - { - pj_str_t codec_id = pj_str("speex/8000"); - pjmedia_codec_mgr_set_codec_priority( - pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt), - &codec_id, PJMEDIA_CODEC_PRIO_NORMAL+1); - - codec_id = pj_str("speex/16000"); - pjmedia_codec_mgr_set_codec_priority( - pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt), - &codec_id, PJMEDIA_CODEC_PRIO_DISABLED); - - codec_id = pj_str("speex/32000"); - pjmedia_codec_mgr_set_codec_priority( - pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt), - &codec_id, PJMEDIA_CODEC_PRIO_DISABLED); - } - - - pjsua_transport_config tcfg; - pjsua_transport_id tid; - -#if ENABLE_SIP_UDP - /* Add UDP transport. */ - pjsua_transport_config_default(&tcfg); - tcfg.port = SIP_PORT; - if (SIP_QOS_DSCP) { - tcfg.qos_params.flags |= PJ_QOS_PARAM_HAS_DSCP; - tcfg.qos_params.dscp_val = SIP_QOS_DSCP; - } - status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &tcfg, &tid); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Error creating UDP transport", status); - pjsua_destroy(); - return status; - } -#endif - -#if ENABLE_SIP_TCP - /* Add TCP transport */ - pjsua_transport_config_default(&tcfg); - tcfg.port = SIP_PORT; - if (SIP_QOS_DSCP) { - tcfg.qos_params.flags |= PJ_QOS_PARAM_HAS_DSCP; - tcfg.qos_params.dscp_val = SIP_QOS_DSCP; - } - status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, &tcfg, &tid); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Error creating TCP transport", status); - pjsua_destroy(); - return status; - } -#endif - -#if ENABLE_SIP_TLS - /* Add TLS transport */ - pjsua_transport_config_default(&tcfg); - tcfg.port = SIP_PORT + 1; - if (SIP_QOS_DSCP) { - tcfg.qos_params.flags |= PJ_QOS_PARAM_HAS_DSCP; - tcfg.qos_params.dscp_val = SIP_QOS_DSCP; - tcfg.tls_setting.qos_params = tcfg.qos_params; - } - status = pjsua_transport_create(PJSIP_TRANSPORT_TLS, &tcfg, &tid); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Error creating TLS transport", status); - pjsua_destroy(); - return status; - } -#endif - - /* Add account for the transport */ - pjsua_acc_add_local(tid, PJ_TRUE, &g_acc_id); - -#if DISABLED_FOR_TICKET_1185 - /* Create media transports */ - pjsua_transport_config mtcfg; - pjsua_transport_config_default(&mtcfg); - mtcfg.port = 4000; - mtcfg.qos_type = RTP_QOS_TYPE; - status = pjsua_media_transports_create(&mtcfg); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Error creating media transports", status); - pjsua_destroy(); - return status; - } -#endif - - /* Initialization is done, now start pjsua */ - status = pjsua_start(); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Error starting pjsua", status); - pjsua_destroy(); - return status; - } - - /* Register to SIP server by creating SIP account. */ - if (HAS_SIP_ACCOUNT) { - pjsua_acc_config cfg; - - pjsua_acc_config_default(&cfg); - cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN); - cfg.reg_uri = pj_str("sip:" SIP_DOMAIN); - cfg.cred_count = 1; - cfg.cred_info[0].realm = pj_str("*"); - cfg.cred_info[0].scheme = pj_str("digest"); - cfg.cred_info[0].username = pj_str(SIP_USER); - cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; - cfg.cred_info[0].data = pj_str(SIP_PASSWD); - - status = pjsua_acc_add(&cfg, PJ_TRUE, &g_acc_id); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Error adding account", status); - pjsua_destroy(); - return status; - } - } - - if (SIP_DST_URI) { - pjsua_buddy_config bcfg; - - pjsua_buddy_config_default(&bcfg); - bcfg.uri = pj_str(SIP_DST_URI); - bcfg.subscribe = PJ_FALSE; - - pjsua_buddy_add(&bcfg, &g_buddy_id); - } - return PJ_SUCCESS; -} - - -//////////////////////////////////////////////////////////////////////////// -/* - * The interractive console UI - */ -#include <e32base.h> - -class ConsoleUI : public CActive -{ -public: - ConsoleUI(CConsoleBase *con); - ~ConsoleUI(); - - // Run console UI - void Run(); - - // Stop - void Stop(); - -protected: - // Cancel asynchronous read. - void DoCancel(); - - // Implementation: called when read has completed. - void RunL(); - -private: - CConsoleBase *con_; -}; - - -ConsoleUI::ConsoleUI(CConsoleBase *con) -: CActive(EPriorityStandard), con_(con) -{ - CActiveScheduler::Add(this); -} - -ConsoleUI::~ConsoleUI() -{ - Stop(); -} - -// Run console UI -void ConsoleUI::Run() -{ - con_->Read(iStatus); - SetActive(); -} - -// Stop console UI -void ConsoleUI::Stop() -{ - Cancel(); -} - -// Cancel asynchronous read. -void ConsoleUI::DoCancel() -{ - con_->ReadCancel(); -} - -static void PrintMainMenu() -{ - const char *menu = - "\n\n" - "Main Menu:\n" - " d Enable/disable codecs\n" - " m Call " SIP_DST_URI "\n" - " a Answer call\n" - " g Hangup all calls\n" - " t Toggle audio route\n" -#if !defined(PJMEDIA_CONF_USE_SWITCH_BOARD) || PJMEDIA_CONF_USE_SWITCH_BOARD==0 - " j Toggle loopback audio\n" -#endif - "up/dn Increase/decrease output volume\n" - " s Subscribe " SIP_DST_URI "\n" - " S Unsubscribe presence\n" - " o Set account online\n" - " O Set account offline\n" - " w Quit\n"; - - PJ_LOG(3, (THIS_FILE, menu)); -} - -static void PrintCodecMenu() -{ - const char *menu = - "\n\n" - "Codec Menu:\n" - " a Enable all codecs\n" -#if PJMEDIA_HAS_PASSTHROUGH_CODECS && PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR - " d Enable only AMR\n" -#endif -#if PJMEDIA_HAS_PASSTHROUGH_CODECS && PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 - " g Enable only G.729\n" -#endif -#if PJMEDIA_HAS_PASSTHROUGH_CODECS && PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC - " j Enable only iLBC\n" -#endif - " m Enable only Speex\n" - " p Enable only GSM\n" - " t Enable only PCMU\n" - " w Enable only PCMA\n"; - - PJ_LOG(3, (THIS_FILE, menu)); -} - -static void HandleMainMenu(TKeyCode kc) { - switch (kc) { - - case EKeyUpArrow: - case EKeyDownArrow: - { - unsigned vol; - pj_status_t status; - - status = pjsua_snd_get_setting( - PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, &vol); - if (status == PJ_SUCCESS) { - if (kc == EKeyUpArrow) - vol = PJ_MIN(100, vol+10); - else - vol = (vol>=10 ? vol-10 : 0); - status = pjsua_snd_set_setting( - PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, - &vol, PJ_TRUE); - } - - if (status == PJ_SUCCESS) { - PJ_LOG(3,(THIS_FILE, "Output volume set to %d", vol)); - } else { - pjsua_perror(THIS_FILE, "Error setting volume", status); - } - } - break; - - case 't': - { - pjmedia_aud_dev_route route; - pj_status_t status; - - status = pjsua_snd_get_setting(PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE, - &route); - - if (status == PJ_SUCCESS) { - if (route == PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER) - route = PJMEDIA_AUD_DEV_ROUTE_EARPIECE; - else - route = PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER; - - status = pjsua_snd_set_setting( - PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE, - &route, PJ_TRUE); - } - - if (status != PJ_SUCCESS) - pjsua_perror(THIS_FILE, "Error switch audio route", status); - } - break; - - case 'j': - { - static pj_bool_t loopback_active = PJ_FALSE; - if (!loopback_active) - pjsua_conf_connect(0, 0); - else - pjsua_conf_disconnect(0, 0); - loopback_active = !loopback_active; - } - break; - - case 'm': - if (g_call_id != PJSUA_INVALID_ID) { - PJ_LOG(3,(THIS_FILE, "Another call is active")); - break; - } - - if (pjsua_verify_url(SIP_DST_URI) == PJ_SUCCESS) { - pj_str_t dst = pj_str(SIP_DST_URI); - pjsua_call_make_call(g_acc_id, &dst, 0, NULL, - NULL, &g_call_id); - } else { - PJ_LOG(3,(THIS_FILE, "Invalid SIP URI")); - } - break; - case 'a': - if (g_call_id != PJSUA_INVALID_ID) - pjsua_call_answer(g_call_id, 200, NULL, NULL); - break; - case 'g': - pjsua_call_hangup_all(); - break; - case 's': - case 'S': - if (g_buddy_id != PJSUA_INVALID_ID) - pjsua_buddy_subscribe_pres(g_buddy_id, kc=='s'); - break; - case 'o': - case 'O': - pjsua_acc_set_online_status(g_acc_id, kc=='o'); - break; - - default: - PJ_LOG(3,(THIS_FILE, "Keycode '%c' (%d) is pressed", kc, kc)); - break; - } - - PrintMainMenu(); -} - -static void HandleCodecMenu(TKeyCode kc) { - const pj_str_t ID_ALL = {"*", 1}; - pj_str_t codec = {NULL, 0}; - - if (kc == 'a') { - pjsua_codec_set_priority(&ID_ALL, PJMEDIA_CODEC_PRIO_NORMAL); - PJ_LOG(3,(THIS_FILE, "All codecs activated")); - } else { - switch (kc) { - case 'd': - codec = pj_str("AMR"); - break; - case 'g': - codec = pj_str("G729"); - break; - case 'j': - codec = pj_str("ILBC"); - break; - case 'm': - codec = pj_str("SPEEX/8000"); - break; - case 'p': - codec = pj_str("GSM"); - break; - case 't': - codec = pj_str("PCMU"); - break; - case 'w': - codec = pj_str("PCMA"); - break; - default: - PJ_LOG(3,(THIS_FILE, "Keycode '%c' (%d) is pressed", kc, kc)); - break; - } - - if (codec.slen) { - pj_status_t status; - - pjsua_codec_set_priority(&ID_ALL, PJMEDIA_CODEC_PRIO_DISABLED); - - status = pjsua_codec_set_priority(&codec, - PJMEDIA_CODEC_PRIO_NORMAL); - if (status == PJ_SUCCESS) - PJ_LOG(3,(THIS_FILE, "%s activated", codec.ptr)); - else - PJ_LOG(3,(THIS_FILE, "Failed activating %s, err=%d", - codec.ptr, status)); - } - } -} - -// Implementation: called when read has completed. -void ConsoleUI::RunL() -{ - enum { - MENU_TYPE_MAIN = 0, - MENU_TYPE_CODEC = 1 - }; - static int menu_type = MENU_TYPE_MAIN; - TKeyCode kc = con_->KeyCode(); - pj_bool_t reschedule = PJ_TRUE; - - if (menu_type == MENU_TYPE_MAIN) { - if (kc == 'w') { - CActiveScheduler::Stop(); - reschedule = PJ_FALSE; - } else if (kc == 'd') { - menu_type = MENU_TYPE_CODEC; - PrintCodecMenu(); - } else { - HandleMainMenu(kc); - } - } else { - HandleCodecMenu(kc); - - menu_type = MENU_TYPE_MAIN; - PrintMainMenu(); - } - - if (reschedule) - Run(); -} - -#if 0 -// IP networking related testing -static pj_status_t test_addr(void) -{ - int af; - unsigned i, count; - pj_addrinfo ai[8]; - pj_sockaddr ifs[8]; - const pj_str_t *hostname; - pj_hostent he; - pj_status_t status; - - pj_log_set_log_func(&log_writer); - - status = pj_init(); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "pj_init() error", status); - return status; - } - - af = pj_AF_INET(); - -#if 0 - pj_in_addr in_addr; - pj_str_t aa = pj_str("1.1.1.1"); - in_addr = pj_inet_addr(&aa); - char *the_addr = pj_inet_ntoa(in_addr); - PJ_LOG(3,(THIS_FILE, "IP addr=%s", the_addr)); - - aa = pj_str("192.168.0.15"); - in_addr = pj_inet_addr(&aa); - the_addr = pj_inet_ntoa(in_addr); - PJ_LOG(3,(THIS_FILE, "IP addr=%s", the_addr)); - - aa = pj_str("2.2.2.2"); - in_addr = pj_inet_addr(&aa); - the_addr = pj_inet_ntoa(in_addr); - PJ_LOG(3,(THIS_FILE, "IP addr=%s", the_addr)); - - return -1; -#endif - - // Hostname - hostname = pj_gethostname(); - if (hostname == NULL) { - status = PJ_ERESOLVE; - pjsua_perror(THIS_FILE, "pj_gethostname() error", status); - goto on_return; - } - - PJ_LOG(3,(THIS_FILE, "Hostname: %.*s", hostname->slen, hostname->ptr)); - - // Gethostbyname - status = pj_gethostbyname(hostname, &he); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "pj_gethostbyname() error", status); - } else { - PJ_LOG(3,(THIS_FILE, "gethostbyname: %s", - pj_inet_ntoa(*(pj_in_addr*)he.h_addr))); - } - - // Getaddrinfo - count = PJ_ARRAY_SIZE(ai); - status = pj_getaddrinfo(af, hostname, &count, ai); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "pj_getaddrinfo() error", status); - } else { - for (i=0; i<count; ++i) { - char ipaddr[PJ_INET6_ADDRSTRLEN+2]; - PJ_LOG(3,(THIS_FILE, "Addrinfo: %s", - pj_sockaddr_print(&ai[i].ai_addr, ipaddr, sizeof(ipaddr), 2))); - } - } - - // Enum interface - count = PJ_ARRAY_SIZE(ifs); - status = pj_enum_ip_interface(af, &count, ifs); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "pj_enum_ip_interface() error", status); - } else { - for (i=0; i<count; ++i) { - char ipaddr[PJ_INET6_ADDRSTRLEN+2]; - PJ_LOG(3,(THIS_FILE, "Interface: %s", - pj_sockaddr_print(&ifs[i], ipaddr, sizeof(ipaddr), 2))); - } - } - - // Get default iinterface - status = pj_getdefaultipinterface(af, &ifs[0]); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "pj_getdefaultipinterface() error", status); - } else { - char ipaddr[PJ_INET6_ADDRSTRLEN+2]; - PJ_LOG(3,(THIS_FILE, "Default IP: %s", - pj_sockaddr_print(&ifs[0], ipaddr, sizeof(ipaddr), 2))); - } - - // Get default IP address - status = pj_gethostip(af, &ifs[0]); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "pj_gethostip() error", status); - } else { - char ipaddr[PJ_INET6_ADDRSTRLEN+2]; - PJ_LOG(3,(THIS_FILE, "Host IP: %s", - pj_sockaddr_print(&ifs[0], ipaddr, sizeof(ipaddr), 2))); - } - - status = -1; - -on_return: - pj_shutdown(); - return status; -} -#endif - - -#include <es_sock.h> - -#if 0 -// Force network connection to use the first IAP, -// this is useful for debugging on emulator without GUI. -// Include commdb.lib & apengine.lib in symbian_ua.mmp file -// if this is enabled. - -#include <apdatahandler.h> - -inline void ForceUseFirstIAP() -{ - TUint32 rank = 1; - TUint32 bearers; - TUint32 prompt; - TUint32 iap; - - CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP); - CleanupStack::PushL(commDb); - - CApDataHandler* apDataHandler = CApDataHandler::NewLC(*commDb); - - TCommDbConnectionDirection direction = ECommDbConnectionDirectionOutgoing; - apDataHandler->GetPreferredIfDbIapTypeL(rank, direction, bearers, prompt, iap); - prompt = ECommDbDialogPrefDoNotPrompt; - apDataHandler->SetPreferredIfDbIapTypeL(rank, direction, bearers, (TCommDbDialogPref)prompt, iap, ETrue); - CleanupStack::PopAndDestroy(2); // apDataHandler, commDb -} - -static void SelectIAP() -{ - ForceUseFirstIAP(); -} - -#else - -static void SelectIAP() -{ -} - -#endif - - -// Class CConnMon to monitor network connection (RConnection). Whenever -// the connection is down, it will notify PJLIB and restart PJSUA-LIB. -class CConnMon : public CActive { -public: - static CConnMon* NewL(RConnection &conn, RSocketServ &sserver) { - CConnMon *self = new (ELeave) CConnMon(conn, sserver); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - - void Start() { - conn_.ProgressNotification(nif_progress_, iStatus); - SetActive(); - } - - void Stop() { - Cancel(); - } - - ~CConnMon() { Stop(); } - -private: - CConnMon(RConnection &conn, RSocketServ &sserver) : - CActive(EPriorityHigh), - conn_(conn), - sserver_(sserver) - { - CActiveScheduler::Add(this); - } - - void ConstructL() {} - - void DoCancel() { - conn_.CancelProgressNotification(); - } - - void RunL() { - int stage = nif_progress_().iStage; - - if (stage == KLinkLayerClosed) { - pj_status_t status; - TInt err; - - // Tell pjlib that connection is down. - pj_symbianos_set_connection_status(PJ_FALSE); - - PJ_LOG(3, (THIS_FILE, "RConnection closed, restarting PJSUA..")); - - // Destroy pjsua - pjsua_destroy(); - PJ_LOG(3, (THIS_FILE, "PJSUA destroyed.")); - - // Reopen the connection - err = conn_.Open(sserver_); - if (err == KErrNone) - err = conn_.Start(); - if (err != KErrNone) { - CActiveScheduler::Stop(); - return; - } - - // Reinit Symbian OS param before pj_init() - pj_symbianos_params sym_params; - pj_bzero(&sym_params, sizeof(sym_params)); - sym_params.rsocketserv = &sserver_; - sym_params.rconnection = &conn_; - pj_symbianos_set_params(&sym_params); - - // Reinit pjsua - status = app_startup(); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "app_startup() error", status); - CActiveScheduler::Stop(); - return; - } - - PJ_LOG(3, (THIS_FILE, "PJSUA restarted.")); - PrintMainMenu(); - } - - Start(); - } - - RConnection& conn_; - RSocketServ& sserver_; - TNifProgressBuf nif_progress_; -}; - -//////////////////////////////////////////////////////////////////////////// -int ua_main() -{ - RSocketServ aSocketServer; - RConnection aConn; - TInt err; - pj_symbianos_params sym_params; - pj_status_t status; - - SelectIAP(); - - // Initialize RSocketServ - if ((err=aSocketServer.Connect(32)) != KErrNone) - return PJ_STATUS_FROM_OS(err); - - // Open up a connection - if ((err=aConn.Open(aSocketServer)) != KErrNone) { - aSocketServer.Close(); - return PJ_STATUS_FROM_OS(err); - } - - if ((err=aConn.Start()) != KErrNone) { - aSocketServer.Close(); - return PJ_STATUS_FROM_OS(err); - } - - // Set Symbian OS parameters in pjlib. - // This must be done before pj_init() is called. - pj_bzero(&sym_params, sizeof(sym_params)); - sym_params.rsocketserv = &aSocketServer; - sym_params.rconnection = &aConn; - pj_symbianos_set_params(&sym_params); - - // Initialize pjsua - status = app_startup(); - //status = test_addr(); - if (status != PJ_SUCCESS) { - aConn.Close(); - aSocketServer.Close(); - return status; - } - - - // Run the UI - ConsoleUI *con = new ConsoleUI(console); - - con->Run(); - PrintMainMenu(); - - // Init & start connection monitor - CConnMon *connmon = CConnMon::NewL(aConn, aSocketServer); - connmon->Start(); - - CActiveScheduler::Start(); - - delete connmon; - delete con; - - // Dump memory statistics - PJ_LOG(3,(THIS_FILE, "Max heap usage: %u.%03uMB", - pjsua_var.cp.peak_used_size / 1000000, - (pjsua_var.cp.peak_used_size % 1000000)/1000)); - - // check max stack usage -#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0 - pj_thread_t* this_thread = pj_thread_this(); - if (!this_thread) - return status; - - const char* max_stack_file; - int max_stack_line; - status = pj_thread_get_stack_info(this_thread, &max_stack_file, &max_stack_line); - - PJ_LOG(3,(THIS_FILE, "Max stack usage: %u at %s:%d", - pj_thread_get_stack_max_usage(this_thread), - max_stack_file, max_stack_line)); -#endif - - // Shutdown pjsua - pjsua_destroy(); - - // Close connection and socket server - aConn.Close(); - aSocketServer.Close(); - - return status; -} - |