Lifecycle
Module lifecycle
Siprix module lifecycle shown on image below.
Create
Lifecycle starts from invoking method Module_Create(), which allocates internal singletone structures.
In this state library can only return its version and all other methods will return error ENotInitialized.
Application can’t create one more instance, method always returns the same existing one.
Application can’t destroy created instance, it automatically deallocated when application ends.
Initialize
Method Module_Initialize() initializes module.
It creates log file, starts worker and background threads, does other required actions.
In this state module is ready to process all available actions: add/remove accounts, making calls, etc.
When this method finished application can restore previous state (list of accounts,
selected devices) by deserialize saved data and invoking Account_Add().
One more important operation after initialize it’s set event handler, which will receive events (callbacks) raised by library. Library provides two ways to do that:
Create own class inherited from
ISiprixEventHandlerand set its instance as argument of methodCallback_SetEventHandler().Set each callback function separately using methods like
Callback_SetAccountRegState().
UnInitialize
Method Module_UnInitialize() un-initializes module. It unregisters accounts, ends calls, stops threads, does other required actions.
class SiprixCliApp : public Siprix::ISiprixEventHandler
{
...
bool initializeSiprixModule()
{
sprxModule_ = Siprix::Module_Create();
Siprix::IniData* ini = Siprix::Ini_GetDefault();
Ini_SetLicense(ini, "...license-credentials...");
Ini_SetLogLevelFile(ini, Siprix::LogLevel::Debug);
Ini_SetLogLevelIde(ini, Siprix::LogLevel::NoLog);
Ini_SetTlsVerifyServer(ini, true);
const Siprix::ErrorCode err = Siprix::Module_Initialize(sprxModule_, ini);
if (err != Siprix::ErrorCode::EOK)
{
std::cout << "Can't initialize siprix module.\n"
<< " Err: " << err << " " << Siprix::GetErrorText(err) << std::endl;
return false;
}
else
{
std::cout << "Siprix module successfully initialized.\n"
<< "Version: "<<Siprix::Module_Version(sprxModule_) << std::endl;
Callback_SetEventHandler(sprxModule_, this);
return true;
}
}
void SiprixCliApp::handleCmds()
{
while (true)
{
std::cout << "\n>>> Enter command: ";
...
bool menuExit = false;
menuExit = handleCmdMain(curMenu, cmd); break;
...
break;
}
Module_UnInitialize(sprxModule_);
}
...
protected:
Siprix::ISiprixModule* sprxModule_ = nullptr;
};
Account lifecycle
Add account
Siprix account lifecycle starts from invoking method Account_Add(),
which adds account to list of accounts, opens new port (if required), sends registration request (if required).
Each account has its own settings and doesn’t depend on other accounts.
Application can add as many accounts as required.
For each added account library assigns its own unique id starting from 1. Returned account id is using as argument of other methods. This id is valid only during current session. When application will add account after new library initialization it may got different id.
If application tries to add account with same AOR (user@domain) as alredy exist
lib will return error ErrorCode::EDuplicateAccount and existing account id.
List of all available account attributes see in Account attributes functions.
Siprix::AccData* acc = Siprix::Acc_GetDefault();
Siprix::Acc_SetSipServer(acc, "sip.someserver.com");
Siprix::Acc_SetSipExtension(acc, "113355");
Siprix::Acc_SetSipPassword(acc, "abcdefg");
Siprix::Acc_SetExpireTime(acc, 300);
Siprix::Acc_SetTranspProtocol(acc, Siprix::SipTransport::TCP);
...
Siprix::AccountId accId=0;
const Siprix::ErrorCode err = Siprix::Account_Add(sprxModule_, acc, &accId);
if (err != Siprix::ErrorCode::EOK)
{
std::cout << "Can't add account.\n"
<< " Err: " << err << " " << Siprix::GetErrorText(err) << std::endl;
}
else
{
std::cout << "Accound added. Assigned id: "<< accId << std::endl;
}
Edit (update) account
App can edit account’s attributes and apply changes by invoking Account_Update().
Library has the following limitations related editing:
It’s not allowed to modify sipExtension, sipServer, transport attributes. App can only add new account with required attributes and remove existing if it’s not required;
It’s not allowed to edit account when there are call(s) on it. In this case lib will return error
ErrorCode::EAccountHasCalls.
Account’s registration state
Possible states of accounts registration shown on image below.
When application set non zero expire time via method Acc_SetExpireTime()
library will send REGISTER request just after adding account.
When application set zero expire time account will not able to receive incoming calls
(its registration state set as RegState::REMOVED), but it’s valid and can be used for starting outgoing calls.
When received response from remote side or expired timeout library raises
ISiprixEventHandler::OnAccountRegState() which application should use for updating actual account state and UI.
Call lifecycle
Siprix call lifecycle shown on image below.
It has three entry points:
Outgoing call, initiated by the app via invoking
Call_Invite()Incoming call, reported by the library via invoking
ISiprixEventHandler::OnCallIncoming()Redirected call, reported by the library via invoking
ISiprixEventHandler::OnCallRedirected()
For each new call library assigns its own unique id starting from 200, when account’s ids started from 1. It allows easily distinct CallId and AccountId values during debugging.
Siprix::DestData* dest = Siprix::Dest_GetDefault();
Dest_SetExtension(dest, destExtension);
Dest_SetAccountId(dest, accId);
Dest_SetVideoCall(dest, withVideo);
...
Siprix::CallId callId = 0;
const Siprix::ErrorCode err = Siprix::Call_Invite(sprxModule_, dest, &callId);
if (err != Siprix::ErrorCode::EOK)
{
std::cout << "Can't initiate call.\n"
<< " Err: " << err << " " << Siprix::GetErrorText(err) << std::endl;
}
else
{
std::cout << "Call initiated. Assigned id: "<< callId << std::endl;
}
Subscriptions lifecycle
Siprix provides ability to create subscriptions via sending SUBSCRIBE request and receive updates with NOTIFY response. App can use it for tracking presence, BLF and other states of remote extensions. Subscription lifecycle shown on image below.
Lifecycle starts from invoking method Subscription_Create(),
which adds new subscription and sends SUBSCRIBE request using credentials and transport of the specified account.
Remote side may accept this subscription and notify its current state or reject it (depends on the SIP server settings and client implementation).
See more ISiprixEventHandler::OnSubscriptionState().
App maintains list of subscriptions by creating them, displaying updated status when received NOTIFY (signalled by library’s callback) and removing if not required.