- account API implementation (incomplete, callback is still not called)
 - using callback class design pattern (observer?)
 - after this, it might be changed to use inheritance pattern instead


git-svn-id: https://svn.pjsip.org/repos/pjproject/branches/projects/pjsua2@4631 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2013-10-23 05:34:48 +00:00
parent 83757ced84
commit fe3e558601
10 changed files with 421 additions and 28 deletions

View File

@ -122,7 +122,16 @@ export APP_LDFLAGS := -L$(PJDIR)/pjlib/lib\
-L$(PJDIR)/third_party/lib\
$(PJ_VIDEO_LDFLAGS) \
@LDFLAGS@
export APP_LDLIBS := -lpjsua-$(TARGET_NAME)\
# x x x x x x x x x x x x x x x x x x x x x x x x
#
# FIX THIS
#
# pjsua2 is c++ library hence maybe needs to be put in separate
# variables. it will also require -lstdc++
# x x x x x x x x x x x x x x x x x x x x x x x x
export APP_LDLIBS := \
-lpjsua2-$(TARGET_NAME)\
-lpjsua-$(TARGET_NAME)\
-lpjsip-ua-$(TARGET_NAME)\
-lpjsip-simple-$(TARGET_NAME)\
-lpjsip-$(TARGET_NAME)\
@ -136,7 +145,16 @@ export APP_LDLIBS := -lpjsua-$(TARGET_NAME)\
$(APP_THIRD_PARTY_EXT)\
-lpj-$(TARGET_NAME)\
@LIBS@
export APP_LIB_FILES = $(PJ_DIR)/pjsip/lib/libpjsua-$(LIB_SUFFIX) \
# x x x x x x x x x x x x x x x x x x x x x x x x
#
# FIX THIS
#
# pjsua2 is c++ library hence maybe needs to be put in separate
# variables. it will also require -lstdc++
# x x x x x x x x x x x x x x x x x x x x x x x x
export APP_LIB_FILES = \
$(PJ_DIR)/pjsip/lib/libpjsua2-$(LIB_SUFFIX) \
$(PJ_DIR)/pjsip/lib/libpjsua-$(LIB_SUFFIX) \
$(PJ_DIR)/pjsip/lib/libpjsip-ua-$(LIB_SUFFIX) \
$(PJ_DIR)/pjsip/lib/libpjsip-simple-$(LIB_SUFFIX) \
$(PJ_DIR)/pjsip/lib/libpjsip-$(LIB_SUFFIX) \

View File

@ -56,8 +56,14 @@ export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
# Main entry
#
#
# x x x x x x x x x x x x x x x x x x x x x x x x
#
# FIX THIS
#
# x x x x x x x x x x x x x x x x x x x x x x x x
#TARGETS := swig pjsua pjsystest samples
TARGETS := swig
TARGETS := swig samples
.PHONY: $(TARGETS)

View File

@ -28,6 +28,7 @@ SAMPLES := auddemo \
mix \
pjsip-perf \
pcaputil \
pjsua2_demo \
playfile \
playsine \
recfile \
@ -45,20 +46,34 @@ SAMPLES := auddemo \
tonegen \
vid_streamutil
# x x x x x x x x x x x x x x x x x x x x x x x x
#
# FIX THIS
#
# Only pjsua2_demo is built, and also -lstdc++ is added for all
# samples
# x x x x x x x x x x x x x x x x x x x x x x x x
SAMPLES := pjsua2_demo
EXES := $(foreach file, $(SAMPLES), $(BINDIR)/$(file)$(HOST_EXE))
all: $(BINDIR) $(OBJDIR) $(EXES)
$(BINDIR)/%$(HOST_EXE): $(OBJDIR)/%$(OBJEXT) $(PJ_LIB_FILES)
$(BINDIR)/%$(HOST_EXE): $(OBJDIR)/%$(OBJEXT) $(PJ_LIB_FILES)
$(LD) $(LDOUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<) \
$(_LDFLAGS)
$(_LDFLAGS) -lstdc++
$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c
$(CC) $(_CFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp
$(CC) $(_CFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
$(OBJDIR):
$(subst @@,$(subst /,$(HOST_PSEP),$@),$(HOST_MKDIR))

View File

@ -0,0 +1,91 @@
/* $Id$ */
/*
* Copyright (C) 2008-2013 Teluu Inc. (http://www.teluu.com)
*
* 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 <pjsua2.hpp>
#include <iostream>
#include <memory>
using namespace pj;
class MyAccountCallback : public AccountCallback
{
public:
MyAccountCallback()
: AccountCallback()
{}
virtual void onRegState(OnRegStateParam &prm)
{
AccountInfo ai = account()->getInfo();
std::cout << (ai.regIsActive? "*** Register: code=" : "*** Unregister: code=")
<< prm.code << std::endl;
}
};
static void mainProg() throw(Error)
{
Endpoint & ep = Endpoint::instance();
// Create library
ep.libCreate();
// Init library
ep.libInit( EpConfig() );
// Transport
TransportConfig tcfg;
tcfg.port = 5060;
ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg);
// Start library
ep.libStart();
std::cout << "*** PJSUA2 STARTED ***" << std::endl;
// Add account
AccountConfig acc_cfg;
acc_cfg.idUri = "sip:test1@pjsip.org";
acc_cfg.regConfig.registrarUri = "sip:pjsip.org";
acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*",
"test1", 0, "test1") );
std::auto_ptr<Account> acc(new Account(new MyAccountCallback, NULL));
acc->create(acc_cfg);
pj_thread_sleep(2000);
// Destroy library
std::cout << "*** PJSUA2 SHUTTING DOWN ***" << std::endl;
ep.libDestroy();
}
int main()
{
int ret = 0;
try {
mainProg();
} catch (Error & err) {
std::cout << "Exception: " << err.info() << std::endl;
ret = 1;
}
Endpoint::instance().libDestroy();
return ret;
}

25
pjsip/include/pjsua2.hpp Normal file
View File

@ -0,0 +1,25 @@
/* $Id$ */
/*
* Copyright (C) 2008-2013 Teluu Inc. (http://www.teluu.com)
*
* 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
*/
#ifndef __PJSUA2_HPP__
#define __PJSUA2_HPP__
#include <pjsua2/endpoint.hpp>
#include <pjsua2/account.hpp>
#endif

View File

@ -798,6 +798,7 @@ public:
AccountPresenceStatus();
};
/**
* Account information. Application can query the account information
* by calling Account::getInfo().
@ -823,30 +824,30 @@ struct AccountInfo
* Flag to tell whether this account has registration setting
* (reg_uri is not empty).
*/
bool hasRegistration;
bool regIsConfigured;
/**
* Flag to tell whether this account is currently registered
* (has active registration session).
*/
bool isRegistered;
bool regIsActive;
/**
* An up to date expiration interval for account registration session.
*/
int expiresSec;
int regExpiresSec;
/**
* Last registration status code. If status code is zero, the account
* is currently not registered. Any other value indicates the SIP
* status code of the registration.
*/
pjsip_status_code status;
pjsip_status_code regStatus;
/**
* String describing the registration status.
*/
string statusText;
string regStatusText;
/**
* Last registration error code. When the status field contains a SIP
@ -866,6 +867,8 @@ struct AccountInfo
*/
string onlineStatusText;
public:
void fromPj(const pjsua_acc_info &pai);
};
/**
@ -908,7 +911,7 @@ struct OnRegStateParam
/**
* SIP status code received.
*/
int code;
pjsip_status_code code;
/**
* SIP reason phrase received.
@ -1090,6 +1093,12 @@ public:
/** Virtual destructor */
virtual ~AccountCallback() {}
/**
* Get the account associated with this callback.
*/
Account *account()
{ return acc; }
/**
* Notify application on incoming call.
*
@ -1190,6 +1199,20 @@ public:
*/
virtual void onMwiInfo(OnMwiInfoParam &prm)
{}
protected:
AccountCallback()
: acc(NULL)
{}
private:
Account *acc;
/** Set the account. Must only be called by Account class */
void setAccount(Account *the_acc)
{ acc = the_acc; }
friend class Account;
};
@ -1209,6 +1232,34 @@ public:
class Account
{
public:
/**
* Constructor.
*/
Account(AccountCallback *cb, Token user_data);
/**
* Destructor.
*/
~Account();
/**
* Create the account.
*
* @param cfg The account config.
* @param make_default Make this the default account.
*/
void create(const AccountConfig &cfg,
bool make_default=false) throw(Error);
/**
* Modify the account to use the specified account configuration.
* Depending on the changes, this may cause unregistration or
* reregistration on the account.
*
* @param cfg New account config to be applied to the account.
*/
void modify(const AccountConfig &acc) throw(Error);
/**
* Check if this account is still valid.
*
@ -1259,16 +1310,7 @@ public:
*
* @return Account info.
*/
AccountInfo getInfo() const;
/**
* Modify the account to use the specified account configuration.
* Depending on the changes, this may cause unregistration or
* reregistration on the account.
*
* @param cfg New account config to be applied to the account.
*/
void modify(const AccountConfig &acc) throw(Error);
AccountInfo getInfo() const throw(Error);
/**
* Update registration or perform unregistration. Application normally
@ -1310,7 +1352,10 @@ public:
protected:
friend class Endpoint;
Account();
private:
pjsua_acc_id id;
AccountCallback *cb;
Token userData;
};
} // namespace pj

View File

@ -69,6 +69,14 @@ typedef int TransportId;
*/
typedef void *TransportHandle;
/*
* Forward declaration of Account, AccountCallback, AccountConfig, to be used
* by Endpoint.
*/
class Account;
class AccountCallback;
class AccountConfig;
/**
* Constants
@ -105,6 +113,9 @@ struct Error
/** The line number of PJSUA source file that throws the error */
int srcLine;
/** Build error string. */
string info(bool multi_line=false) const;
/** Default constructor */
Error();
@ -155,6 +166,11 @@ struct Error
#define PJSUA2_CHECK_RAISE_ERROR(status) \
PJSUA2_CHECK_RAISE_ERROR2(status, "")
#define PJSUA2_CHECK_EXPR(expr) \
do { \
pj_status_t the_status = expr; \
PJSUA2_CHECK_RAISE_ERROR2(the_status, #expr); \
} while (0)
//////////////////////////////////////////////////////////////////////////////
@ -164,17 +180,17 @@ struct Error
*/
struct AuthCredInfo
{
/**
* The authentication scheme (e.g. "digest").
*/
string scheme;
/**
* Realm on which this credential is to be used. Use "*" to make
* a credential that can be used to authenticate against any challenges.
*/
string realm;
/**
* The authentication scheme (e.g. "digest").
*/
string scheme;
/**
* Authentication user name.
*/
@ -207,6 +223,15 @@ struct AuthCredInfo
/** Authentication Management Field */
string akaAmf;
/** Default constructor */
AuthCredInfo();
/** Construct a credential with the specified parameters */
AuthCredInfo(const string &scheme,
const string &realm,
const string &user_name,
const int data_type,
const string data);
};
/** Array of SIP credentials */

View File

@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pjsua2/account.hpp>
#include <pjsua2/endpoint.hpp>
#include <pj/ctype.h>
#include "util.hpp"
@ -329,4 +330,114 @@ void AccountConfig::fromPj(const pjsua_acc_config &prm,
videoConfig.rateControlBandwidth = prm.vid_stream_rc_cfg.bandwidth;
}
///////////////////////////////////////////////////////////////////////////////
void AccountInfo::fromPj(const pjsua_acc_info &pai)
{
id = pai.id;
isDefault = pai.is_default != 0;
uri = pj2Str(pai.acc_uri);
regIsConfigured = pai.has_registration != 0;
regIsActive = pai.has_registration && pai.expires > 0 &&
(pai.status / 100 == 2);
regExpiresSec = pai.expires;
regStatus = pai.status;
regStatusText = pj2Str(pai.status_text);
regLastErr = pai.reg_last_err;
onlineStatus = pai.online_status != 0;
onlineStatusText = pj2Str(pai.online_status_text);
}
///////////////////////////////////////////////////////////////////////////////
Account::Account(AccountCallback *param_cb, Token user_data)
: id(PJSUA_INVALID_ID), cb(param_cb), userData(user_data)
{
cb->setAccount(this);
}
Account::~Account()
{
delete cb;
}
void Account::create(const AccountConfig &acc_cfg,
bool make_default) throw(Error)
{
pjsua_acc_config pj_acc_cfg = acc_cfg.toPj();
PJSUA2_CHECK_EXPR( pjsua_acc_add(&pj_acc_cfg, make_default, &id) );
}
void Account::modify(const AccountConfig &acc_cfg) throw(Error)
{
pjsua_acc_config pj_acc_cfg = acc_cfg.toPj();
PJSUA2_CHECK_EXPR( pjsua_acc_modify(id, &pj_acc_cfg) );
}
bool Account::isValid() const
{
return pjsua_acc_is_valid(id) != 0;
}
void Account::setDefault() throw(Error)
{
PJSUA2_CHECK_EXPR( pjsua_acc_set_default(id) );
}
bool Account::isDefault() const
{
return pjsua_acc_get_default() == id;
}
int Account::getIndex() const
{
return id;
}
void Account::setUserData(Token user_data)
{
userData = user_data;
}
Token Account::getUserData() const
{
return userData;
}
AccountInfo Account::getInfo() const throw(Error)
{
pjsua_acc_info pj_ai;
AccountInfo ai;
PJSUA2_CHECK_EXPR( pjsua_acc_get_info(id, &pj_ai) );
ai.fromPj(pj_ai);
return ai;
}
void Account::setRegistration(bool renew) throw(Error)
{
PJSUA2_CHECK_EXPR( pjsua_acc_set_registration(id, renew) );
}
void
Account::setOnlineStatus(const AccountPresenceStatus &pres_st) throw(Error)
{
pjrpid_element pj_rpid;
pj_bzero(&pj_rpid, sizeof(pj_rpid));
pj_rpid.type = PJRPID_ELEMENT_TYPE_PERSON;
pj_rpid.activity = pres_st.activity;
pj_rpid.id = str2Pj(pres_st.rpidId);
pj_rpid.note = str2Pj(pres_st.note);
PJSUA2_CHECK_EXPR( pjsua_acc_set_online_status2(id, pres_st.isOnline,
&pj_rpid) );
}
void Account::setTransport(TransportId tp_id) throw(Error)
{
PJSUA2_CHECK_EXPR( pjsua_acc_set_transport(id, tp_id) );
}

View File

@ -383,7 +383,6 @@ void Endpoint::libDestroy(unsigned flags) throw(Error)
PJSUA2_CHECK_RAISE_ERROR(status);
}
///////////////////////////////////////////////////////////////////////////////
/*
* Endpoint Utilities
@ -588,3 +587,5 @@ void Endpoint::transportClose(TransportId id) throw(Error)
PJSUA2_CHECK_RAISE_ERROR(status);
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -44,6 +44,62 @@ Error::Error( pj_status_t prm_status,
}
}
string Error::info(bool multi_line) const
{
string output;
if (status==PJ_SUCCESS) {
output = "No error";
} else if (!multi_line) {
char temp[80];
if (!title.empty()) {
output += title + " error: ";
}
snprintf(temp, sizeof(temp), " (status=%d)", status);
output += reason + temp;
if (!srcFile.empty()) {
output += " [";
output += srcFile;
snprintf(temp, sizeof(temp), ":%d]", srcLine);
output += temp;
}
} else {
char temp[80];
if (!title.empty()) {
output += string("Title: ") + title + "\n";
}
snprintf(temp, sizeof(temp), "%d\n", status);
output += string("Code: ") + temp;
output += string("Description: ") + reason + "\n";
if (!srcFile.empty()) {
snprintf(temp, sizeof(temp), ":%d\n", srcLine);
output += string("Location: ") + srcFile + temp;
}
}
return output;
}
///////////////////////////////////////////////////////////////////////////////
AuthCredInfo::AuthCredInfo()
: dataType(0)
{
}
AuthCredInfo::AuthCredInfo(const string &param_scheme,
const string &param_realm,
const string &param_user_name,
const int param_data_type,
const string param_data)
: scheme(param_scheme), realm(param_realm), username(param_user_name),
dataType(param_data_type), data(param_data)
{
}
///////////////////////////////////////////////////////////////////////////////