summaryrefslogtreecommitdiff
path: root/pjsip-apps/src/symbian_ua/ua.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip-apps/src/symbian_ua/ua.cpp')
-rw-r--r--pjsip-apps/src/symbian_ua/ua.cpp1186
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;
-}
-