pjproject/pjsip-apps/src/pjsua/symbian/src/pjsuaAppUi.cpp

371 lines
8.8 KiB
C++

/*
========================================================================
Name : pjsuaAppUi.cpp
Author : nanang
Copyright : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
Description :
========================================================================
*/
// [[[ begin generated region: do not modify [Generated System Includes]
#include <eikmenub.h>
#include <akncontext.h>
#include <akntitle.h>
#include <pjsua.rsg>
// ]]] end generated region [Generated System Includes]
// [[[ begin generated region: do not modify [Generated User Includes]
#include "pjsuaAppUi.h"
#include "pjsua.hrh"
#include "pjsuaContainerView.h"
// ]]] end generated region [Generated User Includes]
// [[[ begin generated region: do not modify [Generated Constants]
// ]]] end generated region [Generated Constants]
#include "../../pjsua_app.h"
#include "../../pjsua_app_config.h"
/* Global vars */
static CpjsuaAppUi *appui = NULL;
static pj_ioqueue_t *app_ioqueue = NULL;
static int start_argc = 0;
static char **start_argv = NULL;
static pj_status_t InitSymbSocket();
static void DestroySymbSocket();
/* Helper funtions to init/restart/destroy the pjsua */
static void PjsuaInitL();
static void PjsuaDestroyL();
/* pjsua app callbacks */
static void PjsuaOnStarted(pj_status_t status, const char* title);
static void PjsuaOnStopped(pj_bool_t restart, int argc, char** argv);
static void PjsuaOnConfig(pjsua_app_config *cfg);
/* Helper class to schedule function execution */
class MyTimer : public CActive
{
public:
typedef void (*timer_func)();
public:
static MyTimer* NewL(int ms, timer_func f) {
MyTimer *self = new MyTimer(f);
CleanupStack::PushL(self);
self->ConstructL(ms);
CleanupStack::Pop(self);
return self;
}
MyTimer(timer_func f) : CActive(EPriorityStandard), func(f) {}
~MyTimer() {
Cancel();
rtimer.Close();
}
virtual void RunL() { (*func)(); delete this; }
virtual void DoCancel() { rtimer.Cancel(); }
private:
RTimer rtimer;
timer_func func;
void ConstructL(int ms) {
rtimer.CreateLocal();
CActiveScheduler::Add(this);
rtimer.After(iStatus, ms * 1000);
SetActive();
}
};
/**
* Construct the CpjsuaAppUi instance
*/
CpjsuaAppUi::CpjsuaAppUi()
{
// [[[ begin generated region: do not modify [Generated Contents]
// ]]] end generated region [Generated Contents]
}
/**
* The appui's destructor removes the container from the control
* stack and destroys it.
*/
CpjsuaAppUi::~CpjsuaAppUi()
{
// [[[ begin generated region: do not modify [Generated Contents]
// ]]] end generated region [Generated Contents]
}
// [[[ begin generated function: do not modify
void CpjsuaAppUi::InitializeContainersL()
{
iPjsuaContainerView = CpjsuaContainerView::NewL();
AddViewL( iPjsuaContainerView );
SetDefaultViewL( *iPjsuaContainerView );
}
// ]]] end generated function
/**
* Handle a command for this appui (override)
* @param aCommand command id to be handled
*/
void CpjsuaAppUi::HandleCommandL( TInt aCommand )
{
// [[[ begin generated region: do not modify [Generated Code]
TBool commandHandled = EFalse;
switch ( aCommand )
{ // code to dispatch to the AppUi's menu and CBA commands is generated here
default:
break;
}
if ( !commandHandled )
{
if ( aCommand == EAknSoftkeyExit || aCommand == EEikCmdExit )
{
Exit();
}
}
// ]]] end generated region [Generated Code]
}
/**
* Override of the HandleResourceChangeL virtual function
*/
void CpjsuaAppUi::HandleResourceChangeL( TInt aType )
{
CAknViewAppUi::HandleResourceChangeL( aType );
// [[[ begin generated region: do not modify [Generated Code]
// ]]] end generated region [Generated Code]
}
/**
* Override of the HandleKeyEventL virtual function
* @return EKeyWasConsumed if event was handled, EKeyWasNotConsumed if not
* @param aKeyEvent
* @param aType
*/
TKeyResponse CpjsuaAppUi::HandleKeyEventL(
const TKeyEvent& aKeyEvent,
TEventCode aType )
{
// The inherited HandleKeyEventL is private and cannot be called
// [[[ begin generated region: do not modify [Generated Contents]
// ]]] end generated region [Generated Contents]
// Left or right softkey pressed
if (aType==EEventKeyDown &&
(aKeyEvent.iScanCode == EStdKeyDevice0 ||
aKeyEvent.iScanCode == EStdKeyDevice1))
{
Cba()->MakeVisible(ETrue);
} else {
Cba()->MakeVisible(EFalse);
}
return EKeyWasNotConsumed;
}
/**
* Override of the HandleViewDeactivation virtual function
*
* @param aViewIdToBeDeactivated
* @param aNewlyActivatedViewId
*/
void CpjsuaAppUi::HandleViewDeactivation(
const TVwsViewId& aViewIdToBeDeactivated,
const TVwsViewId& aNewlyActivatedViewId )
{
CAknViewAppUi::HandleViewDeactivation(
aViewIdToBeDeactivated,
aNewlyActivatedViewId );
// [[[ begin generated region: do not modify [Generated Contents]
// ]]] end generated region [Generated Contents]
}
/**
* @brief Completes the second phase of Symbian object construction.
* Put initialization code that could leave here.
*/
void CpjsuaAppUi::ConstructL()
{
// [[[ begin generated region: do not modify [Generated Contents]
BaseConstructL( EAknEnableSkin |
EAknEnableMSK );
InitializeContainersL();
// ]]] end generated region [Generated Contents]
// Save pointer to this AppUi
appui = this;
// Full screen
StatusPane()->MakeVisible(EFalse);
Cba()->MakeVisible(EFalse);
if (InitSymbSocket() != PJ_SUCCESS) {
PutMsg("Failed to initialize Symbian network param.");
} else {
start_argc = pjsua_app_def_argc;
start_argv = (char**)pjsua_app_def_argv;
// Schedule Lib Init
MyTimer::NewL(100, &PjsuaInitL);
}
}
/* Called by Symbian GUI framework when app is about to exit */
void CpjsuaAppUi::PrepareToExit()
{
TRAPD(result, PjsuaDestroyL());
DestroySymbSocket();
CloseSTDLIB();
CAknViewAppUi::PrepareToExit();
}
/* Print message on screen */
void CpjsuaAppUi::PutMsg(const char *msg)
{
iPjsuaContainerView->PutMessage(msg);
}
#include <es_sock.h>
static RSocketServ aSocketServer;
static RConnection aConn;
/* Called when pjsua is started */
void PjsuaOnStarted(pj_status_t status, const char* title)
{
char err_msg[128];
if (status != PJ_SUCCESS || title == NULL) {
char err_str[PJ_ERR_MSG_SIZE];
pj_strerror(status, err_str, sizeof(err_str));
pj_ansi_snprintf(err_msg, sizeof(err_msg), "%s: %s",
(title?title:"App start error"), err_str);
title = err_msg;
}
appui->PutMsg(title);
}
/* Called when pjsua is stopped */
void PjsuaOnStopped(pj_bool_t restart, int argc, char** argv)
{
if (restart) {
start_argc = argc;
start_argv = argv;
// Schedule Lib Init
MyTimer::NewL(100, &PjsuaInitL);
} else {
/* Destroy & quit GUI, e.g: clean up window, resources */
appui->Exit();
}
}
/* Called before pjsua initializing config.
* We need to override some settings here.
*/
void PjsuaOnConfig(pjsua_app_config *cfg)
{
/* Disable threading */
cfg->cfg.thread_cnt = 0;
cfg->cfg.thread_cnt = 0;
cfg->media_cfg.thread_cnt = 0;
cfg->media_cfg.has_ioqueue = PJ_FALSE;
/* Create ioqueue for telnet CLI */
if (app_ioqueue == NULL) {
pj_ioqueue_create(cfg->pool, 0, &app_ioqueue);
}
cfg->cli_cfg.telnet_cfg.ioqueue = app_ioqueue;
}
// Set Symbian OS parameters in pjlib.
// This must be done before pj_init() is called.
pj_status_t InitSymbSocket()
{
pj_symbianos_params sym_params;
TInt err;
// 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) {
aConn.Close();
aSocketServer.Close();
return PJ_STATUS_FROM_OS(err);
}
pj_bzero(&sym_params, sizeof(sym_params));
sym_params.rsocketserv = &aSocketServer;
sym_params.rconnection = &aConn;
pj_symbianos_set_params(&sym_params);
return PJ_SUCCESS;
}
void DestroySymbSocket()
{
aConn.Close();
aSocketServer.Close();
}
void PjsuaInitL()
{
pjsua_app_cfg_t app_cfg;
pj_status_t status;
PjsuaDestroyL();
pj_bzero(&app_cfg, sizeof(app_cfg));
app_cfg.argc = start_argc;
app_cfg.argv = start_argv;
app_cfg.on_started = &PjsuaOnStarted;
app_cfg.on_stopped = &PjsuaOnStopped;
app_cfg.on_config_init = &PjsuaOnConfig;
appui->PutMsg("Initializing..");
status = pjsua_app_init(&app_cfg);
if (status != PJ_SUCCESS)
goto on_return;
appui->PutMsg("Starting..");
status = pjsua_app_run(PJ_FALSE);
if (status != PJ_SUCCESS)
goto on_return;
on_return:
if (status != PJ_SUCCESS)
appui->PutMsg("Initialization failed");
}
void PjsuaDestroyL()
{
if (app_ioqueue) {
pj_ioqueue_destroy(app_ioqueue);
app_ioqueue = NULL;
}
pjsua_app_destroy();
}