summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-06-06 18:40:40 +0000
committerBenny Prijono <bennylp@teluu.com>2006-06-06 18:40:40 +0000
commit8db4ef281d67eee2ebeac22a31bc1961e96d78b2 (patch)
treeb910ef526c864da15ab3d05840fc78ff8c6c7608
parent40d75a0cb404fc0bafa20934e992befd0eab673b (diff)
Another huge chunks of modifications in PJSUA API, too many things to mention!
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@492 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/build/pjmedia.dsp4
-rw-r--r--pjmedia/include/pjmedia/conference.h18
-rw-r--r--pjmedia/src/pjmedia/conference.c25
-rw-r--r--pjsip-apps/src/activex-pjsua/activex-pjsua.idl25
-rw-r--r--pjsip-apps/src/activex-pjsua/activex-pjsuaCP.h24
-rw-r--r--pjsip-apps/src/activex-pjsua/app.cpp285
-rw-r--r--pjsip-apps/src/activex-pjsua/app.h23
-rw-r--r--pjsip-apps/src/activex-pjsua/pjsua-structs.idl127
-rw-r--r--pjsip-apps/src/pjsua/main.c11
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h175
-rw-r--r--pjsip/include/pjsua-lib/pjsua_console_app.h2
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c98
-rw-r--r--pjsip/src/pjsua-lib/pjsua_console_app.c148
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c187
-rw-r--r--pjsip/src/pjsua-lib/pjsua_im.c34
-rw-r--r--pjsip/src/pjsua-lib/pjsua_imp.h25
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c67
-rw-r--r--pjsip/src/pjsua-lib/pjsua_reg.c61
-rw-r--r--pjsip/src/pjsua-lib/pjsua_settings.c151
19 files changed, 1108 insertions, 382 deletions
diff --git a/pjmedia/build/pjmedia.dsp b/pjmedia/build/pjmedia.dsp
index dce99cff..a6050c1b 100644
--- a/pjmedia/build/pjmedia.dsp
+++ b/pjmedia/build/pjmedia.dsp
@@ -303,6 +303,10 @@ SOURCE=..\include\pjmedia\sound_port.h
# End Source File
# Begin Source File
+SOURCE=..\include\pjmedia\splitcomb.h
+# End Source File
+# Begin Source File
+
SOURCE=..\include\pjmedia\stream.h
# End Source File
# Begin Source File
diff --git a/pjmedia/include/pjmedia/conference.h b/pjmedia/include/pjmedia/conference.h
index bde63f77..208a8743 100644
--- a/pjmedia/include/pjmedia/conference.h
+++ b/pjmedia/include/pjmedia/conference.h
@@ -46,7 +46,9 @@ typedef struct pjmedia_conf_port_info
pjmedia_port_op rx_setting; /**< Receive settings. */
pj_bool_t *listener; /**< Array of listeners. */
unsigned clock_rate; /**< Clock rate of the port. */
+ unsigned channel_count; /**< Number of channels. */
unsigned samples_per_frame; /**< Samples per frame */
+ unsigned bits_per_sample; /**< Bits per sample. */
int tx_adj_level; /**< Tx level adjustment. */
int rx_adj_level; /**< Rx level adjustment. */
} pjmedia_conf_port_info;
@@ -254,6 +256,22 @@ PJ_DECL(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
/**
+ * Enumerate occupied ports in the bridge.
+ *
+ * @param conf The conference bridge.
+ * @param ports Array of port numbers to be filled in.
+ * @param count On input, specifies the maximum number of ports
+ * in the array. On return, it will be filled with
+ * the actual number of ports.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,
+ unsigned ports[],
+ unsigned *count );
+
+
+/**
* Get port info.
*
* @param conf The conference bridge.
diff --git a/pjmedia/src/pjmedia/conference.c b/pjmedia/src/pjmedia/conference.c
index 6dd1b66e..d175213f 100644
--- a/pjmedia/src/pjmedia/conference.c
+++ b/pjmedia/src/pjmedia/conference.c
@@ -820,6 +820,29 @@ PJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
return PJ_SUCCESS;
}
+
+/*
+ * Enum ports.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,
+ unsigned ports[],
+ unsigned *p_count )
+{
+ unsigned i, count=0;
+
+ PJ_ASSERT_RETURN(conf && p_count && ports, PJ_EINVAL);
+
+ for (i=0; i<conf->max_ports && count<*p_count; ++i) {
+ if (!conf->ports[i])
+ continue;
+
+ ports[count++] = i;
+ }
+
+ *p_count = count;
+ return PJ_SUCCESS;
+}
+
/*
* Get port info
*/
@@ -843,7 +866,9 @@ PJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
info->rx_setting = conf_port->rx_setting;
info->listener = conf_port->listeners;
info->clock_rate = conf_port->clock_rate;
+ info->channel_count = conf->channel_count;
info->samples_per_frame = conf_port->samples_per_frame;
+ info->bits_per_sample = conf->bits_per_sample;
info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL;
info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL;
diff --git a/pjsip-apps/src/activex-pjsua/activex-pjsua.idl b/pjsip-apps/src/activex-pjsua/activex-pjsua.idl
index 6b980efa..6b85d2c6 100644
--- a/pjsip-apps/src/activex-pjsua/activex-pjsua.idl
+++ b/pjsip-apps/src/activex-pjsua/activex-pjsua.idl
@@ -29,7 +29,7 @@ import "../src/activex-pjsua/pjsua-structs.idl";
[id(9), helpstring("method call_is_active")] HRESULT call_is_active([in] int call_index, [out,retval] Pj_Bool *retVal);
[id(10), helpstring("method call_has_media")] HRESULT call_has_media([in] int call_index, [out,retval] Pj_Bool *pRet);
[id(11), helpstring("method call_get_info")] HRESULT call_get_info([in] int call_index, [out] Pjsua_Call_Info *pInfo, [out,retval] Pj_Status *pRet);
- [id(12), helpstring("method call_make_call")] HRESULT call_make_call([in] int acc_index, [in,string] Pj_String dst_uri, [out] int *call_index, [out,retval] Pj_Status *pRet);
+ [id(12), helpstring("method call_make_call")] HRESULT call_make_call([in] int acc_id, [in,string] Pj_String dst_uri, [out] int *call_index, [out,retval] Pj_Status *pRet);
[id(13), helpstring("method call_answer")] HRESULT call_answer([in] int call_index, [in] int status_code, [out,retval] Pj_Status *pRet);
[id(14), helpstring("method call_hangup")] HRESULT call_hangup([in] int call_index, [out,retval] Pj_Status *pRet);
[id(15), helpstring("method call_set_hold")] HRESULT call_set_hold([in] int call_index, [out,retval] Pj_Status *pRet);
@@ -40,16 +40,16 @@ import "../src/activex-pjsua/pjsua-structs.idl";
[id(20), helpstring("method call_typing")] HRESULT call_typing([in] int call_index, [in] int is_typing, [out,retval] Pj_Status *pRet);
[id(21), helpstring("method call_hangup_all")] HRESULT call_hangup_all();
[id(22), helpstring("method acc_get_count")] HRESULT acc_get_count([out,retval] int *pCount);
- [id(23), helpstring("method acc_get_info")] HRESULT acc_get_info([in] int acc_index, [out] Pjsua_Acc_Info *pInfo, [out,retval] Pj_Status *pRet);
+ [id(23), helpstring("method acc_get_info")] HRESULT acc_get_info([in] int acc_id, [out] Pjsua_Acc_Info *pInfo, [out,retval] Pj_Status *pRet);
[id(24), helpstring("method acc_add")] HRESULT acc_add([in] Pjsua_Acc_Config *pConfig, [out] int *pAcc_Index, [out,retval] Pj_Status *pRet);
- [id(25), helpstring("method acc_set_online_status")] HRESULT acc_set_online_status([in] int acc_index, [in] int is_online, [out,retval] Pj_Status *pRet);
- [id(26), helpstring("method acc_set_registration")] HRESULT acc_set_registration([in] int acc_index, [in] int reg_active, [out,retval] Pj_Status *pRet);
+ [id(25), helpstring("method acc_set_online_status")] HRESULT acc_set_online_status([in] int acc_id, [in] int is_online, [out,retval] Pj_Status *pRet);
+ [id(26), helpstring("method acc_set_registration")] HRESULT acc_set_registration([in] int acc_id, [in] int reg_active, [out,retval] Pj_Status *pRet);
[id(27), helpstring("method buddy_get_count")] HRESULT buddy_get_count([out,retval] int *pCount);
[id(28), helpstring("method buddy_get_info")] HRESULT buddy_get_info([in] int buddy_index, [out] Pjsua_Buddy_Info *pInfo, [out,retval] Pj_Status *pRet);
[id(29), helpstring("method buddy_add")] HRESULT buddy_add([in,string] Pj_String uri, [out] int *pBuddy_Index, [out,retval] Pj_Status *pRet);
[id(30), helpstring("method buddy_subscribe_pres")] HRESULT buddy_subscribe_pres([in] int buddy_index, [in] int subscribe, [out,retval] Pj_Status *pRet);
- [id(31), helpstring("method im_send_text")] HRESULT im_send_text([in] int acc_index, [in,string] Pj_String dst_uri, [in,string] Pj_String text, [out,retval] Pj_Status *pRet);
- [id(32), helpstring("method im_typing")] HRESULT im_typing([in] int acc_index, [in,string] Pj_URI dst_uri, [in] int is_typing, [out,retval] Pj_Status *pRet);
+ [id(31), helpstring("method im_send_text")] HRESULT im_send_text([in] int acc_id, [in,string] Pj_String dst_uri, [in,string] Pj_String text, [out,retval] Pj_Status *pRet);
+ [id(32), helpstring("method im_typing")] HRESULT im_typing([in] int acc_id, [in,string] Pj_URI dst_uri, [in] int is_typing, [out,retval] Pj_Status *pRet);
[id(33), helpstring("method conf_connect")] HRESULT conf_connect([in] int src_port, [in] int sink_port, [out,retval] Pj_Status *pRet);
[id(34), helpstring("method conf_disconnect")] HRESULT conf_disconnect([in] int src_port, [in] int sink_port, [out,retval] Pj_Status *pRet);
[id(35), helpstring("method player_create")] HRESULT player_create([in,string] Pj_String filename, [out] int *pPlayer_Id, [out,retval] Pj_Status *pRet);
@@ -66,6 +66,15 @@ import "../src/activex-pjsua/pjsua-structs.idl";
[id(46), helpstring("method app_verify_sip_url")] HRESULT app_verify_sip_url([in,string] Pj_String uri, [out,retval] Pj_Status *pRet);
[id(47), helpstring("method call_get_textstat")] HRESULT call_get_textstat([in] int call_index, [out,retval] BSTR *textstat);
[id(48), helpstring("method app_handle_events")] HRESULT app_handle_events([in] int msec_timeout, [out,retval] int *pEvCount);
+ [id(49), helpstring("method app_parse_uri")] HRESULT app_parse_uri([in] BSTR uriString, [out] Pjsip_Sip_Uri *pSipUri, [out,retval] Pj_Status *pStatus);
+ [id(50), helpstring("method app_print_uri")] HRESULT app_print_uri([in] Pjsip_Sip_Uri *pSipURI, [in] Pjsip_Uri_Context context, [out,retval] BSTR *uriText);
+ [id(51), helpstring("method app_compare_uri_string")] HRESULT app_compare_uri_string([in] Pjsip_Uri_Context context, [in] BSTR uri1, [in] BSTR uri2, [out,retval] Pj_Status *pStatus);
+ [id(52), helpstring("method buddy_del")] HRESULT buddy_del([in] int buddy_index, [out,retval] Pj_Status *pRet);
+ [id(53), helpstring("method acc_del")] HRESULT acc_del([in] int acc_id, [out,retval] Pj_Status *pRet);
+ [id(54), helpstring("method acc_find_for_outgoing")] HRESULT acc_find_for_outgoing([in] BSTR url, [out,retval] int *acc_id);
+ [id(55), helpstring("method acc_enum_id")] HRESULT acc_enum_id([out,retval] SAFEARRAY(int) *accIdArray);
+ [id(56), helpstring("method conf_enum_ports")] HRESULT conf_enum_ports([out,retval] SAFEARRAY(int) *pPortsArray);
+ [id(57), helpstring("method conf_get_port_info")] HRESULT conf_get_port_info([in] int port_id, [out] Pjsua_Conf_Port_Info *pInfo, [out,retval] Pj_Status *pRet);
};
[
@@ -84,6 +93,7 @@ library ACTIVEPJSUALib
struct Pjsua_Call_Info;
struct Pjsua_Buddy_Info;
struct Pjsua_Acc_Info;
+ struct Pjsua_Conf_Port_Info;
[
uuid(DC91CBCE-4B9E-4369-80B9-39341EEFD814),
@@ -94,10 +104,11 @@ library ACTIVEPJSUALib
properties:
methods:
[id(1), helpstring("method OnCallState")] void OnCallState([in] int call_index, [in] Pjsua_Call_Info *pInfo);
- [id(2), helpstring("method OnRegState")] void OnRegState([in] int acc_index);
+ [id(2), helpstring("method OnRegState")] void OnRegState([in] int acc_id);
[id(3), helpstring("method OnBuddyState")] void OnBuddyState([in] int buddy_index);
[id(4), helpstring("method OnIncomingPager")] void OnIncomingPager([in] int call_index, [in] BSTR fromUri, [in] BSTR toURI, [in] BSTR pagerText);
[id(5), helpstring("method OnTypingIndication")] void OnTypingIndication([in] int call_index, [in] BSTR fromUri, [in] BSTR toURI, [in] int isTyping);
+ [id(6), helpstring("method OnIncomingCall")] void OnIncomingCall([in] int call_index);
};
[
diff --git a/pjsip-apps/src/activex-pjsua/activex-pjsuaCP.h b/pjsip-apps/src/activex-pjsua/activex-pjsuaCP.h
index db150156..b9aaea41 100644
--- a/pjsip-apps/src/activex-pjsua/activex-pjsuaCP.h
+++ b/pjsip-apps/src/activex-pjsua/activex-pjsuaCP.h
@@ -2,6 +2,7 @@
#define _ACTIVEXPJSUACP_H_
//#import "C:\project\pjproject\pjsip-apps\src\activex-pjsua\activex-pjsua.tlb" raw_interfaces_only, raw_native_types, no_namespace, named_guids //"Import typelib"
+
template <class T>
class CProxy_IPjsuaEvents : public IConnectionPointImpl<T, &DIID__IPjsuaEvents, CComDynamicUnkArray>
{
@@ -147,5 +148,28 @@ public:
delete[] pvars;
}
+ VOID Fire_OnIncomingCall(INT call_index)
+ {
+ T* pT = static_cast<T*>(this);
+ int nConnectionIndex;
+ CComVariant* pvars = new CComVariant[1];
+ int nConnections = m_vec.GetSize();
+
+ for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
+ {
+ pT->Lock();
+ CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
+ pT->Unlock();
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
+ if (pDispatch != NULL)
+ {
+ pvars[0] = call_index;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ pDispatch->Invoke(0x6, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ }
+ delete[] pvars;
+
+ }
};
#endif \ No newline at end of file
diff --git a/pjsip-apps/src/activex-pjsua/app.cpp b/pjsip-apps/src/activex-pjsua/app.cpp
index bbcb9a38..6686279d 100644
--- a/pjsip-apps/src/activex-pjsua/app.cpp
+++ b/pjsip-apps/src/activex-pjsua/app.cpp
@@ -13,6 +13,10 @@
static const GUID IID_Pjsip_Cred_Info =
{ 0x9ce3052a, 0x7a32, 0x4229, { 0xb3, 0x1c, 0x5e, 0x2, 0xe0, 0x66, 0x7a, 0x77 } };
+// {7F6CFF0F-C5B3-41e8-B278-61CD584C1F34}
+static const GUID IID_Pjsip_Sip_Uri =
+{ 0x7f6cff0f, 0xc5b3, 0x41e8, { 0xb2, 0x78, 0x61, 0xcd, 0x58, 0x4c, 0x1f, 0x34 } };
+
// {3B12B04F-6E48-46a7-B9E0-6C4BF1594A96}
static const GUID IID_Pjsua_Acc_Config =
{ 0x3b12b04f, 0x6e48, 0x46a7, { 0xb9, 0xe0, 0x6c, 0x4b, 0xf1, 0x59, 0x4a, 0x96 } };
@@ -33,6 +37,11 @@ static const GUID IID_Pjsua_Buddy_Info =
static const GUID IID_Pjsua_Acc_Info =
{ 0x8d345956, 0x10b7, 0x4450, { 0x8a, 0x6, 0xa8, 0xd, 0x2f, 0x31, 0x9e, 0xfd } };
+// {0D05907A-3E1F-4c92-9FD0-26CB6E1CC56A}
+static const GUID IID_Pjsua_Conf_Port_Info =
+{ 0xd05907a, 0x3e1f, 0x4c92, { 0x9f, 0xd0, 0x26, 0xcb, 0x6e, 0x1c, 0xc5, 0x6a } };
+
+
#define SA_SIZE(lbound,ubound) (ubound-lbound)
@@ -117,7 +126,7 @@ static void SafeStringArray2pjstrarray(pj_pool_t *pool,
else {
*count = 0;
for (i=0; i<sa->cbElements; ++i) {
- BSTR str;
+ BSTR str = NULL;
long rg = lbound + i;
hr = SafeArrayGetElement(sa, &rg, &str);
if (FAILED(hr))
@@ -174,6 +183,7 @@ static void AccConfig2accconfig(pj_pool_t *pool,
for (i=0; i<c1->cred_info->cbElements; ++i) {
Pjsip_Cred_Info cred_info;
long rg = lbound + i;
+ pj_memset(&cred_info, 0, sizeof(cred_info));
hr = SafeArrayGetElement(c1->cred_info, &rg, &cred_info);
if (FAILED(hr))
break;
@@ -244,6 +254,7 @@ static HRESULT Config2config(pj_pool_t *pool, Pjsua_Config *c1, pjsua_config *c2
c2->sip_host = Pj_str(pool, c1->sip_host);
c2->sip_port = c1->sip_port;
c2->start_rtp_port = c1->rtp_port;
+ c2->msg_logging = c1->msg_logging;
c2->max_calls = c1->max_calls;
c2->conf_ports = c1->conf_ports;
c2->thread_cnt = c1->thread_cnt;
@@ -280,6 +291,7 @@ static HRESULT Config2config(pj_pool_t *pool, Pjsua_Config *c1, pjsua_config *c2
for (i=0; i<c1->acc_config->cbElements; ++i) {
Pjsua_Acc_Config acc_config;
long rg = lbound + i;
+ pj_memset(&acc_config, 0, sizeof(acc_config));
hr = SafeArrayGetElement(c1->acc_config, &rg, &acc_config);
if (FAILED(hr))
break;
@@ -311,6 +323,7 @@ static HRESULT config2Config(pjsua_config *c1, Pjsua_Config *c2)
Cp(c2->sip_host, &c1->sip_host);
c2->sip_port = c1->sip_port;
c2->rtp_port = c1->start_rtp_port;
+ c2->msg_logging = c1->msg_logging;
c2->max_calls = c1->max_calls;
c2->conf_ports = c1->conf_ports;
c2->thread_cnt = c1->thread_cnt;
@@ -386,8 +399,8 @@ static void callinfo2CallInfo(pjsua_call_info *c1, Pjsua_Call_Info *c2)
Cp(c2->state_text, &c1->state_text);
c2->connect_duration = c1->connect_duration.sec;
c2->total_duration = c1->total_duration.sec;
- c2->cause = c1->cause;
- Cp(c2->cause_text, &c1->cause_text);
+ c2->last_status = c1->last_status;
+ Cp(c2->last_status_text, &c1->last_status_text);
c2->has_media = c1->has_media;
c2->conf_slot = c1->conf_slot;
}
@@ -397,7 +410,7 @@ static void accinfo2AccInfo(pjsua_acc_info *info1, Pjsua_Acc_Info *info2)
pj_memset(info2, 0, sizeof(Pjsua_Acc_Info));
info2->index = info1->index;
- Cp(info2->acc_id, &info1->acc_id);
+ Cp(info2->acc_uri, &info1->acc_id);
info2->has_registration = info1->has_registration;
info2->expires = info1->expires;
info2->status_code = info1->status;
@@ -419,7 +432,6 @@ static void buddyinfo2BuddyInfo(pjsua_buddy_info *info1, Pjsua_Buddy_Info *info2
info2->status = (Pjsua_Buddy_State)info1->status;
Cp(info2->status_text, &info1->status_text);
info2->monitor = info1->monitor;
- info2->acc_index = info1->acc_index;
}
static CApp *CApp_Instance;
@@ -463,15 +475,21 @@ static void on_call_state(int call_index, pjsip_event *e)
pjsua_call_info call_info;
Pjsua_Call_Info *Call_Info = new Pjsua_Call_Info;
- pjsua_get_call_info(call_index, &call_info);
+ pjsua_call_get_info(call_index, &call_info);
callinfo2CallInfo(&call_info, Call_Info);
CApp_Instance->Fire_OnCallState(call_index, Call_Info);
}
-static void on_reg_state(int acc_index)
+static void on_incoming_call(int acc_id, int call_index,
+ pjsip_rx_data *rdata)
{
- CApp_Instance->Fire_OnRegState(acc_index);
+ CApp_Instance->Fire_OnIncomingCall(call_index);
+}
+
+static void on_reg_state(int acc_id)
+{
+ CApp_Instance->Fire_OnRegState(acc_id);
}
static void on_buddy_state(int buddy_index)
@@ -512,6 +530,7 @@ STDMETHODIMP CApp::app_init(Pjsua_Config *pConfig, Pj_Status *pStatus)
pj_memset(&cb, 0, sizeof(cb));
cb.on_call_state = &on_call_state;
+ cb.on_incoming_call = &on_incoming_call;
cb.on_reg_state = &on_reg_state;
cb.on_buddy_state = &on_buddy_state;
cb.on_pager = &on_pager;
@@ -539,13 +558,13 @@ STDMETHODIMP CApp::app_destroy(Pj_Status *retStatus)
STDMETHODIMP CApp::call_get_max_count(int *retCount)
{
- *retCount = pjsua_get_max_calls();
+ *retCount = pjsua_call_get_max_count();
return S_OK;
}
STDMETHODIMP CApp::call_get_count(int *retCount)
{
- *retCount = pjsua_get_call_count();
+ *retCount = pjsua_call_get_count();
return S_OK;
}
@@ -564,24 +583,23 @@ STDMETHODIMP CApp::call_has_media(int call_index, Pj_Bool *pRet)
STDMETHODIMP CApp::call_get_info(int call_index, Pjsua_Call_Info *pInfo, Pj_Status *pRet)
{
pjsua_call_info info;
- *pRet = pjsua_get_call_info(call_index, &info);
+ *pRet = pjsua_call_get_info(call_index, &info);
callinfo2CallInfo(&info, pInfo);
return S_OK;
}
-STDMETHODIMP CApp::call_make_call(int acc_index, Pj_String dst_uri, int *call_index, Pj_Status *pRet)
+STDMETHODIMP CApp::call_make_call(int acc_id, Pj_String dst_uri, int *call_index, Pj_Status *pRet)
{
Temp_Pool tp;
pj_str_t tmp = Pj_str(tp.get_pool(), dst_uri);
- *pRet = pjsua_make_call(acc_index, &tmp, call_index);
+ *pRet = pjsua_call_make_call(acc_id, &tmp, call_index);
return S_OK;
}
STDMETHODIMP CApp::call_answer(int call_index, int status_code, Pj_Status *pRet)
{
- pjsua_call_answer(call_index, status_code);
- *pRet = PJ_SUCCESS;
+ *pRet = pjsua_call_answer(call_index, status_code);
return S_OK;
}
@@ -601,8 +619,7 @@ STDMETHODIMP CApp::call_set_hold(int call_index, Pj_Status *pRet)
STDMETHODIMP CApp::call_release_hold(int call_index, Pj_Status *pRet)
{
- pjsua_call_reinvite(call_index);
- *pRet = PJ_SUCCESS;
+ *pRet = pjsua_call_reinvite(call_index);
return S_OK;
}
@@ -610,8 +627,7 @@ STDMETHODIMP CApp::call_xfer(int call_index, Pj_String dst_uri, Pj_Status *pRet)
{
Temp_Pool tp;
pj_str_t tmp = Pj_str(tp.get_pool(), dst_uri);
- pjsua_call_xfer(call_index, &tmp);
- *pRet = PJ_SUCCESS;
+ *pRet = pjsua_call_xfer(call_index, &tmp);
return S_OK;
}
@@ -627,15 +643,13 @@ STDMETHODIMP CApp::call_send_im(int call_index, Pj_String text, Pj_Status *pRet)
{
Temp_Pool tp;
pj_str_t tmp = Pj_str(tp.get_pool(), text);
- pjsua_call_send_im(call_index, &tmp);
- *pRet = PJ_SUCCESS;
+ *pRet = pjsua_call_send_im(call_index, &tmp);
return S_OK;
}
STDMETHODIMP CApp::call_typing(int call_index, int is_typing, Pj_Status *pRet)
{
- pjsua_call_typing(call_index, is_typing);
- *pRet = PJ_SUCCESS;
+ *pRet = pjsua_call_send_typing_ind(call_index, is_typing);
return S_OK;
}
@@ -648,7 +662,7 @@ STDMETHODIMP CApp::call_hangup_all()
STDMETHODIMP CApp::call_get_textstat(int call_index, BSTR *textstat)
{
char buf[1024];
- pjsua_dump_call(call_index, 1, buf, sizeof(buf), "");
+ pjsua_call_dump(call_index, 1, buf, sizeof(buf), "");
OLECHAR wbuf[1024];
pj_ansi_to_unicode(buf, strlen(buf), wbuf, PJ_ARRAY_SIZE(wbuf));
@@ -663,10 +677,10 @@ STDMETHODIMP CApp::acc_get_count(int *pCount)
return S_OK;
}
-STDMETHODIMP CApp::acc_get_info(int acc_index, Pjsua_Acc_Info *pInfo, Pj_Status *pRet)
+STDMETHODIMP CApp::acc_get_info(int acc_id, Pjsua_Acc_Info *pInfo, Pj_Status *pRet)
{
pjsua_acc_info info;
- *pRet = pjsua_acc_get_info(acc_index, &info);
+ *pRet = pjsua_acc_get_info(acc_id, &info);
accinfo2AccInfo(&info, pInfo);
return S_OK;
}
@@ -680,15 +694,15 @@ STDMETHODIMP CApp::acc_add(Pjsua_Acc_Config *pConfig, int *pAcc_Index, Pj_Status
return S_OK;
}
-STDMETHODIMP CApp::acc_set_online_status(int acc_index, int is_online, Pj_Status *pRet)
+STDMETHODIMP CApp::acc_set_online_status(int acc_id, int is_online, Pj_Status *pRet)
{
- *pRet = pjsua_acc_set_online_status(acc_index, is_online);
+ *pRet = pjsua_acc_set_online_status(acc_id, is_online);
return S_OK;
}
-STDMETHODIMP CApp::acc_set_registration(int acc_index, int reg_active, Pj_Status *pRet)
+STDMETHODIMP CApp::acc_set_registration(int acc_id, int reg_active, Pj_Status *pRet)
{
- *pRet = pjsua_acc_set_registration(acc_index, reg_active);
+ *pRet = pjsua_acc_set_registration(acc_id, reg_active);
return S_OK;
}
@@ -717,24 +731,23 @@ STDMETHODIMP CApp::buddy_add(Pj_String uri, int *pBuddy_Index, Pj_Status *pRet)
STDMETHODIMP CApp::buddy_subscribe_pres(int buddy_index, int subscribe, Pj_Status *pRet)
{
*pRet = pjsua_buddy_subscribe_pres(buddy_index, subscribe);
- pjsua_pres_refresh();
return S_OK;
}
-STDMETHODIMP CApp::im_send_text(int acc_index, Pj_String dst_uri, Pj_String text, Pj_Status *pRet)
+STDMETHODIMP CApp::im_send_text(int acc_id, Pj_String dst_uri, Pj_String text, Pj_Status *pRet)
{
Temp_Pool tp;
pj_str_t tmp_uri = Pj_str(tp.get_pool(), dst_uri);
pj_str_t tmp_text = Pj_str(tp.get_pool(), text);
- *pRet = pjsua_im_send(acc_index, &tmp_uri, &tmp_text);
+ *pRet = pjsua_im_send(acc_id, &tmp_uri, &tmp_text);
return S_OK;
}
-STDMETHODIMP CApp::im_typing(int acc_index, Pj_URI dst_uri, int is_typing, Pj_Status *pRet)
+STDMETHODIMP CApp::im_typing(int acc_id, Pj_URI dst_uri, int is_typing, Pj_Status *pRet)
{
Temp_Pool tp;
pj_str_t tmp_uri = Pj_str(tp.get_pool(), dst_uri);
- *pRet = pjsua_im_typing(acc_index, &tmp_uri, is_typing);
+ *pRet = pjsua_im_typing(acc_id, &tmp_uri, is_typing);
return S_OK;
}
@@ -802,7 +815,7 @@ STDMETHODIMP CApp::app_load_config(Pj_String filename, Pjsua_Config *pConfig, Pj
Temp_Pool tp;
pj_str_t tmp = Pj_str(tp.get_pool(), filename);
pjsua_default_config(&config);
- *pRet = pjsua_load_settings(tmp.ptr, &config);
+ *pRet = pjsua_load_settings(tmp.ptr, &config, NULL);
if (*pRet == PJ_SUCCESS)
*pRet = config2Config(&config, pConfig);
return S_OK;
@@ -825,9 +838,11 @@ STDMETHODIMP CApp::app_save_config(Pj_String filename, Pjsua_Config *pConfig, Pj
STDMETHODIMP CApp::app_get_current_config(Pjsua_Config *pConfig)
{
- pjsua_config *config;
- config = (pjsua_config*) pjsua_get_config();
- return config2Config(config, pConfig);
+ Temp_Pool tp;
+ pjsua_config config;
+
+ pjsua_get_config(tp.get_pool(), &config);
+ return config2Config(&config, pConfig);
}
STDMETHODIMP CApp::app_get_error_msg(Pj_Status status, BSTR * pRet)
@@ -856,3 +871,195 @@ STDMETHODIMP CApp::app_handle_events(int msec_timeout, int *pEvCount)
*pEvCount = pjsua_handle_events(msec_timeout);
return S_OK;
}
+
+STDMETHODIMP CApp::app_parse_uri(BSTR uriString, Pjsip_Sip_Uri *pSipUri, Pj_Status *pStatus)
+{
+ Temp_Pool tp;
+ pj_str_t tmp = Pj_str(tp.get_pool(), uriString);
+ pjsip_name_addr *addr;
+ char buf[1024];
+ pj_str_t s;
+
+ addr = (pjsip_name_addr*)
+ pjsip_parse_uri(tp.get_pool(), tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+ if (addr == NULL) {
+ *pStatus = PJSIP_EINVALIDURI;
+ return S_OK;
+ }
+
+ if (!PJSIP_URI_SCHEME_IS_SIP(addr) && !PJSIP_URI_SCHEME_IS_SIPS(addr)) {
+ *pStatus = PJSIP_EINVALIDSCHEME;
+ return S_OK;
+ }
+
+ pjsip_sip_uri *sip = (pjsip_sip_uri*)addr->uri;
+
+ Cp2(&pSipUri->display, &addr->display);
+ Cp2(&pSipUri->user, &sip->user);
+ Cp2(&pSipUri->passwd, &sip->passwd);
+ Cp2(&pSipUri->host, &sip->host);
+ pSipUri->port = sip->port;
+ Cp2(&pSipUri->param_user, &sip->user_param);
+ Cp2(&pSipUri->param_method, &sip->method_param);
+ Cp2(&pSipUri->param_transport, &sip->transport_param);
+ pSipUri->param_ttl = sip->ttl_param;
+ pSipUri->param_lr = sip->lr_param;
+ Cp2(&pSipUri->param_maddr, &sip->maddr_param);
+
+ s.ptr = buf;
+ s.slen = pjsip_param_print_on(&sip->other_param, buf, sizeof(buf),
+ &pjsip_PARAM_CHAR_SPEC, &pjsip_PARAM_CHAR_SPEC, ';');
+ Cp2(&pSipUri->param_other, &s);
+
+ s.slen = pjsip_param_print_on(&sip->header_param, buf, sizeof(buf),
+ &pjsip_HDR_CHAR_SPEC, &pjsip_HDR_CHAR_SPEC, '?');
+ Cp2(&pSipUri->param_header, &s);
+
+ *pStatus = PJ_SUCCESS;
+ return S_OK;
+}
+
+STDMETHODIMP CApp::app_print_uri(Pjsip_Sip_Uri *pSipURI, Pjsip_Uri_Context context, BSTR *uriText)
+{
+ Temp_Pool tp;
+ pjsip_name_addr *addr;
+ pj_str_t tmp;
+ char buf[1024];
+ pjsip_sip_uri *sip;
+
+ addr = pjsip_name_addr_create(tp.get_pool());
+ sip = pjsip_sip_uri_create(tp.get_pool(), PJ_FALSE);
+ addr->uri = (pjsip_uri*)sip;
+
+ addr->display = Pj_str(tp.get_pool(), pSipURI->display);
+ sip->user = Pj_str(tp.get_pool(), pSipURI->user);
+ sip->passwd = Pj_str(tp.get_pool(), pSipURI->passwd);
+ sip->host = Pj_str(tp.get_pool(), pSipURI->host);
+ sip->port = pSipURI->port;
+ sip->user_param = Pj_str(tp.get_pool(), pSipURI->param_user);
+ sip->method_param = Pj_str(tp.get_pool(), pSipURI->param_method);
+ sip->transport_param = Pj_str(tp.get_pool(), pSipURI->param_transport);
+ sip->ttl_param = pSipURI->param_ttl;
+ sip->lr_param = pSipURI->param_lr;
+ sip->maddr_param = Pj_str(tp.get_pool(), pSipURI->param_maddr);
+
+ /* Unfortunately can't transport params yet (no parsing function) */
+
+ tmp.ptr = buf;
+ tmp.slen = pjsip_uri_print((pjsip_uri_context_e)context, addr, buf, sizeof(buf));
+
+ Cp2(uriText, &tmp);
+ return S_OK;
+}
+
+STDMETHODIMP CApp::app_compare_uri_string(Pjsip_Uri_Context context, BSTR uri1, BSTR uri2, Pj_Status *pStatus)
+{
+ Temp_Pool tp;
+
+ pj_str_t tmp_uri1 = Pj_str(tp.get_pool(), uri1);
+ pj_str_t tmp_uri2 = Pj_str(tp.get_pool(), uri2);
+
+ pjsip_uri *u1, *u2;
+
+ u1 = pjsip_parse_uri(tp.get_pool(), tmp_uri1.ptr, tmp_uri1.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+ if (u1 == NULL) {
+ *pStatus = PJSIP_EINVALIDURI;
+ return S_OK;
+ }
+
+ u2 = pjsip_parse_uri(tp.get_pool(), tmp_uri2.ptr, tmp_uri2.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+ if (u2 == NULL) {
+ *pStatus = PJSIP_EINVALIDURI;
+ return S_OK;
+ }
+
+ *pStatus = pjsip_uri_cmp((pjsip_uri_context_e)context, u1, u2);
+ return S_OK;
+}
+
+STDMETHODIMP CApp::buddy_del(int buddy_index, Pj_Status *pRet)
+{
+ *pRet = pjsua_buddy_del(buddy_index);
+ return S_OK;
+}
+
+STDMETHODIMP CApp::acc_del(int acc_id, Pj_Status *pRet)
+{
+ *pRet = pjsua_acc_del(acc_id);
+ return S_OK;
+}
+
+STDMETHODIMP CApp::acc_find_for_outgoing(BSTR url, int *acc_id)
+{
+ Temp_Pool tp;
+
+ pj_str_t tmp_uri = Pj_str(tp.get_pool(), url);
+
+ *acc_id = pjsua_acc_find_for_outgoing(&tmp_uri);
+
+ return S_OK;
+}
+
+STDMETHODIMP CApp::acc_enum_id(SAFEARRAY **accIdArray)
+{
+ int id[32];
+ unsigned count = PJ_ARRAY_SIZE(id);
+ unsigned i;
+
+ pjsua_acc_enum_id(id, &count);
+
+ *accIdArray = SafeArrayCreateVector(VT_INT, 0, count);
+
+ for (i=0; i<count; ++i) {
+ long rg = i;
+ SafeArrayPutElement(*accIdArray, &rg, &id[i]);
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CApp::conf_enum_ports(SAFEARRAY **pPortsArray)
+{
+ int id[128];
+ unsigned count = PJ_ARRAY_SIZE(id);
+ unsigned i;
+
+ pjsua_conf_enum_port_ids(id, &count);
+
+ *pPortsArray = SafeArrayCreateVector(VT_INT, 0, count);
+
+ for (i=0; i<count; ++i) {
+ long rg = i;
+ SafeArrayPutElement(*pPortsArray, &rg, &id[i]);
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CApp::conf_get_port_info(int port_id, Pjsua_Conf_Port_Info *pInfo, Pj_Status *pRet)
+{
+ unsigned i;
+ pjsua_conf_port_info info;
+
+ *pRet = pjsua_conf_get_port_info(port_id, &info);
+ if (*pRet != PJ_SUCCESS)
+ return S_OK;
+
+ pInfo->slot_id = info.slot_id;
+ Cp2(&pInfo->name, &info.name);
+ pInfo->clock_rate = info.clock_rate;
+ pInfo->channel_count = info.channel_count;
+ pInfo->samples_per_frame = info.samples_per_frame;
+ pInfo->bits_per_sample = info.bits_per_sample;
+
+
+ pInfo->listeners = SafeArrayCreateVector(VT_INT, 0, info.listener_cnt);
+
+ for (i=0; i<info.listener_cnt; ++i) {
+ long rg = i;
+ SafeArrayPutElement(pInfo->listeners, &rg, &info.listeners[i]);
+ }
+
+ return S_OK;
+}
+
diff --git a/pjsip-apps/src/activex-pjsua/app.h b/pjsip-apps/src/activex-pjsua/app.h
index ba0f9971..1c8483a5 100644
--- a/pjsip-apps/src/activex-pjsua/app.h
+++ b/pjsip-apps/src/activex-pjsua/app.h
@@ -4,7 +4,7 @@
#define __APP_H_
#include "resource.h" // main symbols
-#include "..\activex-pjsua\activex-pjsuaCP.h"
+#include "activex-pjsuaCP.h"
/////////////////////////////////////////////////////////////////////////////
@@ -37,6 +37,15 @@ END_CONNECTION_POINT_MAP()
// IApp
public:
+ STDMETHOD(app_destroy)(/*[out,retval]*/ Pj_Status *retStatus);
+ STDMETHOD(app_start)(/*[out,retval]*/ Pj_Status *retStatus);
+ STDMETHOD(app_init)(/*[in]*/ Pjsua_Config *pConfig, /*[out,retval]*/ Pj_Status *pStatus);
+ STDMETHOD(app_test_config)(/*[in]*/ Pjsua_Config *pConfig, /*[out,retval,string]*/ BSTR *retmsg);
+ STDMETHOD(app_default_config)(/*[in,out]*/ Pjsua_Config *pConfig);
+ STDMETHOD(app_create)(/*[out,retval]*/ Pj_Status *ret);
+ STDMETHOD(app_compare_uri_string)(/*[in]*/ Pjsip_Uri_Context context, /*[in]*/ BSTR uri1, /*[in]*/ BSTR uri2, /*[out,retval]*/ Pj_Status *pStatus);
+ STDMETHOD(app_print_uri)(/*[in]*/ Pjsip_Sip_Uri *pSipURI, Pjsip_Uri_Context context, /*[out,retval]*/ BSTR *uriText);
+ STDMETHOD(app_parse_uri)(/*[in]*/ BSTR uriString, /*[out]*/ Pjsip_Sip_Uri *pSipUri, /*[out,retval]*/ Pj_Status *pStatus);
STDMETHOD(app_handle_events)(/*[in]*/ int msec_timeout, /*[out,retval]*/ int *pEvCount);
STDMETHOD(app_verify_sip_url)(/*[in,string]*/ Pj_String uri, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(app_get_error_msg)(/*[in]*/ Pj_Status status, /*[out,retval]*/ BSTR * errmsg);
@@ -52,17 +61,23 @@ public:
STDMETHOD(player_create)(/*[in,string]*/ Pj_String filename, /*[out]*/ int *pPlayer_Id, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(conf_disconnect)(/*[in]*/ int src_port, /*[in]*/ int sink_port, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(conf_connect)(/*[in]*/ int src_port, /*[in]*/ int sink_port, /*[out,retval]*/ Pj_Status *pRet);
+ STDMETHOD(conf_enum_ports)(SAFEARRAY **pPortsArray);
+ STDMETHOD(conf_get_port_info)(int port_id, Pjsua_Conf_Port_Info *pInfo, Pj_Status *pRet);
STDMETHOD(im_typing)(/*[in]*/ int acc_index, /*[in,string]*/ Pj_URI dst_uri, /*[in]*/ int is_typing, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(im_send_text)(/*[in]*/ int acc_index, /*[in,string]*/ Pj_String dst_uri, /*[in,string]*/ Pj_String text, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(buddy_subscribe_pres)(/*[in]*/ int buddy_index, /*[in]*/ int subscribe, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(buddy_add)(/*[in,string]*/ Pj_String uri, /*[out]*/ int *pBuddy_Index, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(buddy_get_info)(/*[in]*/ int buddy_index, /*[out]*/ Pjsua_Buddy_Info *pInfo, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(buddy_get_count)(/*[out,retval]*/ int *pCount);
+ STDMETHOD(buddy_del)(/*[in]*/ int buddy_index, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(acc_set_registration)(/*[in]*/ int acc_index, /*[in]*/ int reg_active, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(acc_set_online_status)(/*[in]*/ int acc_index, /*[in]*/ int is_online, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(acc_add)(/*[in]*/ Pjsua_Acc_Config *pConfig, /*[out]*/ int *pAcc_Index, /*[out,retval]*/ Pj_Status *pRet);
+ STDMETHOD(acc_del)(/*[out,retval]*/ int acc_index, Pj_Status *pRet);
STDMETHOD(acc_get_info)(/*[in]*/ int acc_index, /*[out]*/ Pjsua_Acc_Info *pInfo, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(acc_get_count)(/*[out,retval]*/ int *pCount);
+ STDMETHOD(acc_enum_id)(SAFEARRAY **accIdArray);
+ STDMETHOD(acc_find_for_outgoing)(/*[in]*/ BSTR url, /*[out,retval]*/ int *acc_index);
STDMETHOD(call_hangup_all)();
STDMETHOD(call_typing)(/*[in]*/ int call_index, /*[in]*/ int is_typing, /*[out,retval]*/ Pj_Status *pRet);
STDMETHOD(call_send_im)(/*[in]*/ int call_index, /*[in,string]*/ Pj_String text, /*[out,retval]*/ Pj_Status *pRet);
@@ -78,12 +93,6 @@ public:
STDMETHOD(call_is_active)(/*[in]*/ int call_index, /*[out,retval]*/ Pj_Bool *retVal);
STDMETHOD(call_get_count)(/*[out,retval]*/ int *retCount);
STDMETHOD(call_get_max_count)(/*[out,retval]*/ int *retCount);
- STDMETHOD(app_destroy)(/*[out,retval]*/ Pj_Status *retStatus);
- STDMETHOD(app_start)(/*[out,retval]*/ Pj_Status *retStatus);
- STDMETHOD(app_init)(/*[in]*/ Pjsua_Config *pConfig, /*[out,retval]*/ Pj_Status *pStatus);
- STDMETHOD(app_test_config)(/*[in]*/ Pjsua_Config *pConfig, /*[out,retval,string]*/ BSTR *retmsg);
- STDMETHOD(app_default_config)(/*[in,out]*/ Pjsua_Config *pConfig);
- STDMETHOD(app_create)(/*[out,retval]*/ Pj_Status *ret);
STDMETHOD(call_get_textstat)(/* [in] */ int call_index, /* [retval][out] */ BSTR *textstat);
};
diff --git a/pjsip-apps/src/activex-pjsua/pjsua-structs.idl b/pjsip-apps/src/activex-pjsua/pjsua-structs.idl
index 1c90742f..e41f6711 100644
--- a/pjsip-apps/src/activex-pjsua/pjsua-structs.idl
+++ b/pjsip-apps/src/activex-pjsua/pjsua-structs.idl
@@ -23,6 +23,39 @@ typedef struct Pjsip_Cred_Info
[
+ uuid(7F6CFF0F-C5B3-41e8-B278-61CD584C1F34),
+ version(1.0),
+ helpstring("PJSIP SIP URI"),
+]
+typedef struct Pjsip_Sip_Uri
+{
+ Pj_String display;
+ Pj_String user;
+ Pj_String passwd;
+ Pj_String host;
+ int port;
+ Pj_String param_user;
+ Pj_String param_method;
+ Pj_String param_transport;
+ int param_ttl;
+ int param_lr;
+ Pj_String param_maddr;
+ Pj_String param_other;
+ Pj_String param_header;
+} Pjsip_Sip_Uri;
+
+
+typedef enum Pjsip_Uri_Context
+{
+ PJSIPX_URI_IN_REQ_URI,
+ PJSIPX_URI_IN_FROMTO_HDR,
+ PJSIPX_URI_IN_CONTACT_HDR,
+ PJSIPX_URI_IN_ROUTING_HDR,
+ PJSIPX_URI_IN_OTHER
+} Pjsip_Uri_Context;
+
+
+[
uuid(3B12B04F-6E48-46a7-B9E0-6C4BF1594A96),
version(1.0),
helpstring("PJSUA Account configuration"),
@@ -44,33 +77,34 @@ typedef struct Pjsua_Acc_Config
]
typedef struct Pjsua_Config
{
- unsigned int udp_port;
- Pj_String sip_host;
- unsigned int sip_port;
- unsigned int rtp_port;
- unsigned int max_calls;
- unsigned int conf_ports;
- unsigned int thread_cnt;
- Pj_String stun_srv1;
- unsigned int stun_port1;
- Pj_String stun_srv2;
- unsigned int stun_port2;
- unsigned int snd_player_id;
- unsigned int snd_capture_id;
- unsigned int clock_rate;
- Pj_Bool null_audio;
- unsigned int quality;
- unsigned int complexity;
- SAFEARRAY(Pj_String) codec_arg;
- unsigned int auto_answer;
- unsigned int uas_refresh;
- Pj_String outbound_proxy;
+ int udp_port;
+ Pj_String sip_host;
+ int sip_port;
+ int rtp_port;
+ int msg_logging;
+ int max_calls;
+ int conf_ports;
+ int thread_cnt;
+ Pj_String stun_srv1;
+ int stun_port1;
+ Pj_String stun_srv2;
+ int stun_port2;
+ int snd_player_id;
+ int snd_capture_id;
+ int clock_rate;
+ Pj_Bool null_audio;
+ int quality;
+ int complexity;
+ SAFEARRAY(Pj_String) codec_arg;
+ int auto_answer;
+ int uas_refresh;
+ Pj_String outbound_proxy;
SAFEARRAY(Pjsua_Acc_Config) acc_config;
- unsigned int log_level;
- unsigned int app_log_level;
- unsigned long log_decor;
- Pj_String log_filename;
- SAFEARRAY(Pj_String) buddy_uri;
+ int log_level;
+ int app_log_level;
+ long log_decor;
+ Pj_String log_filename;
+ SAFEARRAY(Pj_String) buddy_uri;
} Pjsua_Config;
@@ -93,19 +127,19 @@ typedef enum Pjsua_Call_State
]
typedef struct Pjsua_Call_Info
{
- unsigned int index;
+ int index;
Pj_Bool active;
Pj_Bool is_uac;
Pj_String local_info;
Pj_String remote_info;
Pjsua_Call_State state;
Pj_String state_text;
- unsigned int connect_duration;
- unsigned int total_duration;
- unsigned int cause;
- Pj_String cause_text;
+ int connect_duration;
+ int total_duration;
+ int last_status;
+ Pj_String last_status_text;
Pj_Bool has_media;
- unsigned int conf_slot;
+ int conf_slot;
} Pjsua_Call_Info;
@@ -124,17 +158,16 @@ typedef enum Pjsua_Buddy_State
]
typedef struct Pjsua_Buddy_Info
{
- unsigned int index;
+ int index;
Pj_Bool is_valid;
Pj_String name;
Pj_String display;
Pj_String host;
- unsigned int port;
+ int port;
Pj_URI uri;
Pjsua_Buddy_State status;
Pj_String status_text;
Pj_Bool monitor;
- int acc_index;
} Pjsua_Buddy_Info;
@@ -145,12 +178,30 @@ typedef struct Pjsua_Buddy_Info
]
typedef struct Pjsua_Acc_Info
{
- unsigned int index;
- Pj_URI acc_id;
+ int index;
+ Pj_URI acc_uri;
Pj_Bool has_registration;
int expires;
- unsigned int status_code;
+ int status_code;
Pj_String status_text;
Pj_Bool online_status;
} Pjsua_Acc_Info;
+
+
+[
+ uuid(0D05907A-3E1F-4c92-9FD0-26CB6E1CC56A),
+ version(1.0),
+ helpstring("PJSUA Conference Port Information"),
+]
+typedef struct Pjsua_Conf_Port_Info
+{
+ int slot_id;
+ Pj_String name;
+ int clock_rate;
+ int channel_count;
+ int samples_per_frame;
+ int bits_per_sample;
+ SAFEARRAY(int) listeners;
+} Pjsua_Conf_Port_Info;
+
diff --git a/pjsip-apps/src/pjsua/main.c b/pjsip-apps/src/pjsua/main.c
index 03e5eb6c..b5774e73 100644
--- a/pjsip-apps/src/pjsua/main.c
+++ b/pjsip-apps/src/pjsua/main.c
@@ -28,6 +28,7 @@
int main(int argc, char *argv[])
{
pjsua_config cfg;
+ pj_str_t uri_to_call = { NULL, 0 };
/* Init default settings. */
pjsua_default_config(&cfg);
@@ -38,7 +39,7 @@ int main(int argc, char *argv[])
/* Parse command line arguments: */
- if (pjsua_parse_args(argc, argv, &cfg) != PJ_SUCCESS)
+ if (pjsua_parse_args(argc, argv, &cfg, &uri_to_call) != PJ_SUCCESS)
return 1;
@@ -46,12 +47,6 @@ int main(int argc, char *argv[])
if (pjsua_init(&cfg, &console_callback) != PJ_SUCCESS)
return 1;
- /* Register message logger to print incoming and outgoing
- * messages.
- */
- pjsip_endpt_register_module(pjsua_get_pjsip_endpt(),
- &pjsua_console_app_msg_logger);
-
/* Start pjsua! */
if (pjsua_start() != PJ_SUCCESS) {
@@ -65,7 +60,7 @@ int main(int argc, char *argv[])
/* Start UI console main loop: */
- pjsua_console_app_main();
+ pjsua_console_app_main(&uri_to_call);
/* Destroy pjsua: */
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 622991f6..dba8560c 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -68,6 +68,13 @@ PJ_BEGIN_DECL
#endif
+typedef int pjsua_acc_id;
+typedef int pjsua_buddy_id;
+typedef int pjsua_player_id;
+typedef int pjsua_recorder_id;
+typedef int pjsua_conf_port_id;
+
+
/**
* Account configuration.
*/
@@ -135,6 +142,11 @@ struct pjsua_config
*/
unsigned start_rtp_port;
+ /**
+ * Enable incoming and outgoing message logging (default: 1).
+ */
+ pj_bool_t msg_logging;
+
/** Maximum calls to support (default: 4) */
unsigned max_calls;
@@ -223,9 +235,6 @@ struct pjsua_config
/** Outbound proxy (default: none) */
pj_str_t outbound_proxy;
- /** URI to call. */
- pj_str_t uri_to_call;
-
/** Number of SIP accounts */
unsigned acc_cnt;
@@ -272,6 +281,12 @@ struct pjsua_callback
void (*on_call_state)(int call_index, pjsip_event *e);
/**
+ * Notify application on incoming call.
+ */
+ void (*on_incoming_call)(pjsua_acc_id acc_id, int call_index,
+ pjsip_rx_data *rdata);
+
+ /**
* Notify application on call being transfered.
* Application can decide to accept/reject transfer request
* by setting the code (default is 200). When this callback
@@ -287,13 +302,13 @@ struct pjsua_callback
* Application may then query the account info to get the
* registration details.
*/
- void (*on_reg_state)(int acc_index);
+ void (*on_reg_state)(pjsua_acc_id acc_id);
/**
* Notify application when the buddy state has changed.
* Application may then query the buddy into to get the details.
*/
- void (*on_buddy_state)(int buddy_index);
+ void (*on_buddy_state)(pjsua_buddy_id buddy_id);
/**
* Notify application on incoming pager (i.e. MESSAGE request).
@@ -329,12 +344,12 @@ struct pjsua_call_info
pj_str_t remote_info;
pjsip_inv_state state;
pj_str_t state_text;
+ pjsip_status_code last_status;
+ pj_str_t last_status_text;
pj_time_val connect_duration;
pj_time_val total_duration;
- pjsip_status_code cause;
- pj_str_t cause_text;
pj_bool_t has_media;
- unsigned conf_slot;
+ pjsua_conf_port_id conf_slot;
};
typedef struct pjsua_call_info pjsua_call_info;
@@ -355,7 +370,7 @@ typedef enum pjsua_buddy_status pjsua_buddy_status;
*/
struct pjsua_buddy_info
{
- unsigned index;
+ pjsua_buddy_id index;
pj_bool_t is_valid;
pj_str_t name;
pj_str_t display_name;
@@ -365,7 +380,6 @@ struct pjsua_buddy_info
pjsua_buddy_status status;
pj_str_t status_text;
pj_bool_t monitor;
- int acc_index;
};
typedef struct pjsua_buddy_info pjsua_buddy_info;
@@ -376,7 +390,7 @@ typedef struct pjsua_buddy_info pjsua_buddy_info;
*/
struct pjsua_acc_info
{
- unsigned index;
+ pjsua_acc_id index;
pj_str_t acc_id;
pj_bool_t has_registration;
int expires;
@@ -389,9 +403,23 @@ struct pjsua_acc_info
typedef struct pjsua_acc_info pjsua_acc_info;
-typedef int pjsua_player_id;
-typedef int pjsua_recorder_id;
+/**
+ * Conference port info.
+ */
+struct pjsua_conf_port_info
+{
+ pjsua_conf_port_id slot_id;
+ pj_str_t name;
+ unsigned clock_rate;
+ unsigned channel_count;
+ unsigned samples_per_frame;
+ unsigned bits_per_sample;
+ unsigned listener_cnt;
+ pjsua_conf_port_id listeners[256];
+};
+
+typedef struct pjsua_conf_port_info pjsua_conf_port_info;
/*****************************************************************************
@@ -478,12 +506,12 @@ PJ_DECL(pj_status_t) pjsua_set_call_media_transport(unsigned call_index,
/**
* Get maximum number of calls configured in pjsua.
*/
-PJ_DECL(unsigned) pjsua_get_max_calls(void);
+PJ_DECL(unsigned) pjsua_call_get_max_count(void);
/**
* Get current number of active calls.
*/
-PJ_DECL(unsigned) pjsua_get_call_count(void);
+PJ_DECL(unsigned) pjsua_call_get_count(void);
/**
* Check if the specified call has active INVITE session and the INVITE
@@ -501,14 +529,14 @@ PJ_DECL(pj_bool_t) pjsua_call_has_media(unsigned call_index);
/**
* Get call info.
*/
-PJ_DECL(pj_status_t) pjsua_get_call_info(unsigned call_index,
+PJ_DECL(pj_status_t) pjsua_call_get_info(unsigned call_index,
pjsua_call_info *info);
/**
* Duplicate call info.
*/
-PJ_DECL(void) pjsua_dup_call_info(pj_pool_t *pool,
+PJ_DECL(void) pjsua_call_info_dup(pj_pool_t *pool,
pjsua_call_info *dst_info,
const pjsua_call_info *src_info);
@@ -516,15 +544,15 @@ PJ_DECL(void) pjsua_dup_call_info(pj_pool_t *pool,
/**
* Make outgoing call.
*/
-PJ_DECL(pj_status_t) pjsua_make_call(unsigned acc_index,
- const pj_str_t *dst_uri,
- int *p_call_index);
+PJ_DECL(pj_status_t) pjsua_call_make_call(unsigned acc_id,
+ const pj_str_t *dst_uri,
+ int *p_call_index);
/**
* Answer call.
*/
-PJ_DECL(void) pjsua_call_answer(int call_index, int code);
+PJ_DECL(pj_status_t) pjsua_call_answer(int call_index, int code);
/**
* Hangup call.
@@ -535,19 +563,19 @@ PJ_DECL(void) pjsua_call_hangup(int call_index);
/**
* Put call on-hold.
*/
-PJ_DECL(void) pjsua_call_set_hold(int call_index);
+PJ_DECL(pj_status_t) pjsua_call_set_hold(int call_index);
/**
* Send re-INVITE (to release hold).
*/
-PJ_DECL(void) pjsua_call_reinvite(int call_index);
+PJ_DECL(pj_status_t) pjsua_call_reinvite(int call_index);
/**
* Transfer call.
*/
-PJ_DECL(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest);
+PJ_DECL(pj_status_t) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest);
/**
* Dial DTMF.
@@ -559,13 +587,14 @@ PJ_DECL(pj_status_t) pjsua_call_dial_dtmf(unsigned call_index,
/**
* Send instant messaging inside INVITE session.
*/
-PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *text);
+PJ_DECL(pj_status_t) pjsua_call_send_im(int call_index, const pj_str_t *text);
/**
* Send IM typing indication inside INVITE session.
*/
-PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing);
+PJ_DECL(pj_status_t) pjsua_call_send_typing_ind(int call_index,
+ pj_bool_t is_typing);
/**
* Terminate all calls.
@@ -576,7 +605,7 @@ PJ_DECL(void) pjsua_call_hangup_all(void);
/**
* Dump call and media statistics to string.
*/
-PJ_DECL(void) pjsua_dump_call(int call_index, int with_media,
+PJ_DECL(void) pjsua_call_dump(int call_index, int with_media,
char *buffer, unsigned maxlen,
const char *indent);
@@ -594,9 +623,34 @@ PJ_DECL(unsigned) pjsua_get_acc_count(void);
/**
* Get account info.
*/
-PJ_DECL(pj_status_t) pjsua_acc_get_info(unsigned acc_index,
+PJ_DECL(pj_status_t) pjsua_acc_get_info(pjsua_acc_id acc_id,
pjsua_acc_info *info);
+
+/**
+ * Enum accounts id.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_enum_id( pjsua_acc_id ids[],
+ unsigned *count );
+
+
+/**
+ * Enum accounts info.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_enum_info( pjsua_acc_info info[],
+ unsigned *count );
+
+
+/**
+ * Find account for outgoing request.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *url);
+
+/**
+ * Find account for incoming request.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata);
+
/**
* Add a new account.
* This function should be called after pjsua_init().
@@ -604,14 +658,18 @@ PJ_DECL(pj_status_t) pjsua_acc_get_info(unsigned acc_index,
* registration for this account.
*/
PJ_DECL(pj_status_t) pjsua_acc_add(const pjsua_acc_config *cfg,
- int *acc_index);
+ pjsua_acc_id *acc_id);
+
+/**
+ * Delete account.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id);
/**
* Set account's presence status.
- * Must call pjsua_pres_refresh() after this.
*/
-PJ_DECL(pj_status_t) pjsua_acc_set_online_status(unsigned acc_index,
+PJ_DECL(pj_status_t) pjsua_acc_set_online_status(pjsua_acc_id acc_id,
pj_bool_t is_online);
@@ -619,7 +677,8 @@ PJ_DECL(pj_status_t) pjsua_acc_set_online_status(unsigned acc_index,
* Update registration or perform unregistration. If renew argument is zero,
* this will start unregistration process.
*/
-PJ_DECL(pj_status_t) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew);
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(pjsua_acc_id acc_id,
+ pj_bool_t renew);
@@ -637,28 +696,28 @@ PJ_DECL(unsigned) pjsua_get_buddy_count(void);
/**
* Get buddy info.
*/
-PJ_DECL(pj_status_t) pjsua_buddy_get_info(unsigned buddy_index,
+PJ_DECL(pj_status_t) pjsua_buddy_get_info(pjsua_buddy_id buddy_index,
pjsua_buddy_info *info);
/**
* Add new buddy.
*/
PJ_DECL(pj_status_t) pjsua_buddy_add(const pj_str_t *uri,
- int *buddy_index);
+ pjsua_buddy_id *buddy_index);
/**
- * Enable/disable buddy's presence monitoring.
- * Must call pjsua_pres_refresh() after this.
+ * Delete buddy.
*/
-PJ_DECL(pj_status_t) pjsua_buddy_subscribe_pres(unsigned buddy_index,
- pj_bool_t monitor);
+PJ_DECL(pj_status_t) pjsua_buddy_del(pjsua_buddy_id buddy_index);
/**
- * Refresh both presence client and server subscriptions.
+ * Enable/disable buddy's presence monitoring.
*/
-PJ_DECL(void) pjsua_pres_refresh(void);
+PJ_DECL(pj_status_t) pjsua_buddy_subscribe_pres(pjsua_buddy_id buddy_index,
+ pj_bool_t monitor);
+
/**
* Dump presence subscriptions.
@@ -680,14 +739,14 @@ extern const pjsip_method pjsip_message_method;
/**
* Send IM outside dialog.
*/
-PJ_DECL(pj_status_t) pjsua_im_send(int acc_index, const pj_str_t *dst_uri,
+PJ_DECL(pj_status_t) pjsua_im_send(int acc_id, const pj_str_t *dst_uri,
const pj_str_t *text);
/**
* Send typing indication outside dialog.
*/
-PJ_DECL(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri,
+PJ_DECL(pj_status_t) pjsua_im_typing(int acc_id, const pj_str_t *dst_uri,
pj_bool_t is_typing);
@@ -705,22 +764,29 @@ PJ_DECL(unsigned) pjsua_conf_max_ports(void);
/**
* Enum all conference ports.
*/
-PJ_DECL(pj_status_t) pjsua_conf_enum_ports(unsigned *count,
- pjmedia_conf_port_info info[]);
+PJ_DECL(pj_status_t) pjsua_conf_enum_port_ids(pjsua_conf_port_id id[],
+ unsigned *count);
+
+
+/**
+ * Get information about the specified conference port
+ */
+PJ_DECL(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id id,
+ pjsua_conf_port_info *info);
/**
* Connect conference port.
*/
-PJ_DECL(pj_status_t) pjsua_conf_connect(unsigned src_port,
- unsigned dst_port);
+PJ_DECL(pj_status_t) pjsua_conf_connect(pjsua_conf_port_id src_port,
+ pjsua_conf_port_id dst_port);
/**
* Connect conference port connection.
*/
-PJ_DECL(pj_status_t) pjsua_conf_disconnect(unsigned src_port,
- unsigned dst_port);
+PJ_DECL(pj_status_t) pjsua_conf_disconnect(pjsua_conf_port_id src_port,
+ pjsua_conf_port_id dst_port);
/**
@@ -733,7 +799,7 @@ PJ_DECL(pj_status_t) pjsua_player_create(const pj_str_t *filename,
/**
* Get conference port associated with player.
*/
-PJ_DECL(int) pjsua_player_get_conf_port(pjsua_player_id id);
+PJ_DECL(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id);
/**
@@ -760,7 +826,7 @@ PJ_DECL(pj_status_t) pjsua_recorder_create(const pj_str_t *filename,
/**
* Get conference port associated with recorder.
*/
-PJ_DECL(int) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
+PJ_DECL(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
/**
@@ -797,18 +863,21 @@ extern const char *pjsua_inv_state_names[];
* Parse arguments (pjsua_opt.c).
*/
PJ_DECL(pj_status_t) pjsua_parse_args(int argc, char *argv[],
- pjsua_config *cfg);
+ pjsua_config *cfg,
+ pj_str_t *uri_to_call);
/**
* Load settings from a file.
*/
PJ_DECL(pj_status_t) pjsua_load_settings(const char *filename,
- pjsua_config *cfg);
+ pjsua_config *cfg,
+ pj_str_t *uri_to_call);
/**
* Get pjsua running config.
*/
-PJ_DECL(const pjsua_config*) pjsua_get_config(void);
+PJ_DECL(void) pjsua_get_config(pj_pool_t *pool,
+ pjsua_config *config);
/**
diff --git a/pjsip/include/pjsua-lib/pjsua_console_app.h b/pjsip/include/pjsua-lib/pjsua_console_app.h
index ee7213ed..8be93714 100644
--- a/pjsip/include/pjsua-lib/pjsua_console_app.h
+++ b/pjsip/include/pjsua-lib/pjsua_console_app.h
@@ -20,7 +20,7 @@
#define __PJSUA_CONSOLE_APP_H__
-void pjsua_console_app_main(void);
+void pjsua_console_app_main(const pj_str_t *uri_to_call);
extern pjsip_module pjsua_console_app_msg_logger;
extern pjsua_callback console_callback;
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 70d9a088..507e3c93 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -127,7 +127,7 @@ static pj_status_t call_destroy_media(int call_index)
/**
* Get maximum number of calls configured in pjsua.
*/
-PJ_DEF(unsigned) pjsua_get_max_calls(void)
+PJ_DEF(unsigned) pjsua_call_get_max_count(void)
{
return pjsua.config.max_calls;
}
@@ -136,7 +136,7 @@ PJ_DEF(unsigned) pjsua_get_max_calls(void)
/**
* Get current number of active calls.
*/
-PJ_DEF(unsigned) pjsua_get_call_count(void)
+PJ_DEF(unsigned) pjsua_call_get_count(void)
{
return pjsua.call_cnt;
}
@@ -166,7 +166,7 @@ PJ_DEF(pj_bool_t) pjsua_call_has_media(unsigned call_index)
/**
* Get call info.
*/
-PJ_DEF(pj_status_t) pjsua_get_call_info( unsigned call_index,
+PJ_DEF(pj_status_t) pjsua_call_get_info( unsigned call_index,
pjsua_call_info *info)
{
pjsua_call *call;
@@ -212,8 +212,8 @@ PJ_DEF(pj_status_t) pjsua_get_call_info( unsigned call_index,
PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
}
- info->cause = call->inv->cause;
- info->cause_text = *pjsip_get_status_text(info->cause);
+ info->last_status = call->last_code;
+ info->last_status_text = *pjsip_get_status_text(info->last_status);
info->has_media = (call->session != NULL);
info->conf_slot = call->conf_slot;
@@ -225,7 +225,7 @@ PJ_DEF(pj_status_t) pjsua_get_call_info( unsigned call_index,
/**
* Duplicate call info.
*/
-PJ_DEF(void) pjsua_dup_call_info( pj_pool_t *pool,
+PJ_DEF(void) pjsua_call_info_dup( pj_pool_t *pool,
pjsua_call_info *dst_info,
const pjsua_call_info *src_info)
{
@@ -245,9 +245,9 @@ PJ_DEF(void) pjsua_dup_call_info( pj_pool_t *pool,
/**
* Make outgoing call.
*/
-PJ_DEF(pj_status_t) pjsua_make_call(unsigned acc_index,
- const pj_str_t *dest_uri,
- int *p_call_index)
+PJ_DEF(pj_status_t) pjsua_call_make_call(unsigned acc_index,
+ const pj_str_t *dest_uri,
+ int *p_call_index)
{
pjsip_dialog *dlg = NULL;
pjmedia_sdp_session *offer;
@@ -384,18 +384,18 @@ on_error:
/**
* Answer call.
*/
-PJ_DEF(void) pjsua_call_answer(int call_index, int code)
+PJ_DEF(pj_status_t) pjsua_call_answer(int call_index, int code)
{
pjsip_tx_data *tdata;
pj_status_t status;
- PJ_ASSERT_ON_FAIL(call_index >= 0 &&
+ PJ_ASSERT_RETURN( call_index >= 0 &&
call_index < (int)pjsua.config.max_calls,
- return);
+ PJ_EINVAL);
if (pjsua.calls[call_index].inv == NULL) {
PJ_LOG(3,(THIS_FILE, "Call %d already disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
status = pjsip_inv_answer(pjsua.calls[call_index].inv,
@@ -408,6 +408,7 @@ PJ_DEF(void) pjsua_call_answer(int call_index, int code)
pjsua_perror(THIS_FILE, "Unable to create/send response",
status);
+ return status;
}
@@ -612,6 +613,11 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
pjsua.config.uas_duration);
}
+ /* Notify application */
+ if (pjsua.cb.on_incoming_call)
+ pjsua.cb.on_incoming_call(acc_index, call_index, rdata);
+
+
/* This INVITE request has been handled. */
return PJ_TRUE;
}
@@ -635,17 +641,19 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
case PJSIP_INV_STATE_CONNECTING:
if (call->res_time.sec == 0)
pj_gettimeofday(&call->res_time);
+ call->last_code = e->body.tsx_state.tsx->status_code;
break;
case PJSIP_INV_STATE_CONFIRMED:
pj_gettimeofday(&call->conn_time);
break;
case PJSIP_INV_STATE_DISCONNECTED:
pj_gettimeofday(&call->dis_time);
+ if (e->body.tsx_state.tsx->status_code > call->last_code) {
+ call->last_code = e->body.tsx_state.tsx->status_code;
+ }
break;
default:
- /* Nothing to do. Just to keep gcc from complaining about
- * unused enums.
- */
+ call->last_code = e->body.tsx_state.tsx->status_code;
break;
}
@@ -682,7 +690,7 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
ev_state = PJSIP_EVSUB_STATE_TERMINATED;
break;
- default:
+ case PJSIP_INV_STATE_INCOMING:
/* Nothing to do. Just to keep gcc from complaining about
* unused enums.
*/
@@ -853,7 +861,7 @@ static void on_call_transfered( pjsip_inv_session *inv,
/* Now make the outgoing call. */
tmp = pj_str(uri);
- status = pjsua_make_call(existing_call->acc_index, &tmp, &new_call);
+ status = pjsua_call_make_call(existing_call->acc_index, &tmp, &new_call);
if (status != PJ_SUCCESS) {
/* Notify xferer about the error */
@@ -1354,7 +1362,7 @@ PJ_DEF(void) pjsua_call_hangup(int call_index)
/*
* Put call on-Hold.
*/
-PJ_DEF(void) pjsua_call_set_hold(int call_index)
+PJ_DEF(pj_status_t) pjsua_call_set_hold(int call_index)
{
pjmedia_sdp_session *sdp;
pjsua_call *call;
@@ -1365,37 +1373,39 @@ PJ_DEF(void) pjsua_call_set_hold(int call_index)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed"));
- return;
+ return PJSIP_ESESSIONSTATE;
}
status = create_inactive_sdp(call, &sdp);
if (status != PJ_SUCCESS)
- return;
+ return status;
/* Send re-INVITE with new offer */
status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
- return;
+ return status;
}
status = pjsip_inv_send_msg( call->inv, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
- return;
+ return status;
}
+
+ return PJ_SUCCESS;
}
/*
* re-INVITE.
*/
-PJ_DEF(void) pjsua_call_reinvite(int call_index)
+PJ_DEF(pj_status_t) pjsua_call_reinvite(int call_index)
{
pjmedia_sdp_session *sdp;
pjsip_tx_data *tdata;
@@ -1406,13 +1416,13 @@ PJ_DEF(void) pjsua_call_reinvite(int call_index)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed"));
- return;
+ return PJSIP_ESESSIONSTATE;
}
/* Create SDP */
@@ -1421,28 +1431,30 @@ PJ_DEF(void) pjsua_call_reinvite(int call_index)
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",
status);
- return;
+ return status;
}
/* Send re-INVITE with new offer */
status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
- return;
+ return status;
}
status = pjsip_inv_send_msg( call->inv, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
- return;
+ return status;
}
+
+ return PJ_SUCCESS;
}
/*
* Transfer call.
*/
-PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
+PJ_DEF(pj_status_t) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
{
pjsip_evsub *sub;
pjsip_tx_data *tdata;
@@ -1454,7 +1466,7 @@ PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
/* Create xfer client subscription.
@@ -1464,7 +1476,7 @@ PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
status = pjsip_xfer_create_uac(call->inv->dlg, NULL, &sub);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create xfer", status);
- return;
+ return status;
}
/*
@@ -1473,20 +1485,22 @@ PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
status = pjsip_xfer_initiate(sub, dest, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create REFER request", status);
- return;
+ return status;
}
/* Send. */
status = pjsip_xfer_send_request(sub, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send REFER request", status);
- return;
+ return status;
}
/* For simplicity (that's what this program is intended to be!),
* leave the original invite session as it is. More advanced application
* may want to hold the INVITE, or terminate the invite, or whatever.
*/
+
+ return PJ_SUCCESS;
}
@@ -1512,7 +1526,7 @@ PJ_DEF(pj_status_t) pjsua_call_dial_dtmf( unsigned call_index,
/**
* Send instant messaging inside INVITE session.
*/
-PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *str)
+PJ_DEF(pj_status_t) pjsua_call_send_im(int call_index, const pj_str_t *str)
{
pjsua_call *call;
const pj_str_t mime_text = pj_str("text");
@@ -1524,7 +1538,7 @@ PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *str)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
/* Lock dialog. */
@@ -1560,13 +1574,15 @@ PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *str)
on_return:
pjsip_dlg_dec_lock(call->inv->dlg);
+ return status;
}
/**
* Send IM typing indication inside INVITE session.
*/
-PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing)
+PJ_DEF(pj_status_t) pjsua_call_send_typing_ind(int call_index,
+ pj_bool_t is_typing)
{
pjsua_call *call;
pjsip_tx_data *tdata;
@@ -1576,7 +1592,7 @@ PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
/* Lock dialog. */
@@ -1602,7 +1618,9 @@ PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing)
}
on_return:
- pjsip_dlg_dec_lock(call->inv->dlg);}
+ pjsip_dlg_dec_lock(call->inv->dlg);
+ return status;
+}
/*
diff --git a/pjsip/src/pjsua-lib/pjsua_console_app.c b/pjsip/src/pjsua-lib/pjsua_console_app.c
index 58f64c7f..a54dd689 100644
--- a/pjsip/src/pjsua-lib/pjsua_console_app.c
+++ b/pjsip/src/pjsua-lib/pjsua_console_app.c
@@ -36,7 +36,7 @@ static pj_bool_t find_next_call(void)
{
int i, max;
- max = pjsua_get_max_calls();
+ max = pjsua_call_get_max_count();
for (i=current_call+1; i<max; ++i) {
if (pjsua_call_is_active(i)) {
current_call = i;
@@ -63,7 +63,7 @@ static pj_bool_t find_prev_call(void)
{
int i, max;
- max = pjsua_get_max_calls();
+ max = pjsua_call_get_max_count();
for (i=current_call-1; i>=0; --i) {
if (pjsua_call_is_active(i)) {
current_call = i;
@@ -93,14 +93,14 @@ static void console_on_call_state(int call_index, pjsip_event *e)
PJ_UNUSED_ARG(e);
- pjsua_get_call_info(call_index, &call_info);
+ pjsua_call_get_info(call_index, &call_info);
if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) {
PJ_LOG(3,(THIS_FILE, "Call %d is DISCONNECTED [reason=%d (%s)]",
call_index,
- call_info.cause,
- call_info.cause_text.ptr));
+ call_info.last_status,
+ call_info.last_status_text.ptr));
if ((int)call_index == current_call) {
find_next_call();
@@ -385,31 +385,32 @@ static void ui_input_url(const char *title, char *buf, int len,
static void conf_list(void)
{
unsigned i, count;
- pjmedia_conf_port_info info[PJSUA_MAX_CALLS];
+ pjsua_conf_port_id id[PJSUA_MAX_CALLS];
printf("Conference ports:\n");
- count = PJ_ARRAY_SIZE(info);
- pjsua_conf_enum_ports(&count, info);
+ count = PJ_ARRAY_SIZE(id);
+ pjsua_conf_enum_port_ids(id, &count);
+
for (i=0; i<count; ++i) {
char txlist[PJSUA_MAX_CALLS*4+10];
- int j;
- pjmedia_conf_port_info *port_info = &info[i];
-
+ unsigned j;
+ pjsua_conf_port_info info;
+
+ pjsua_conf_get_port_info(id[i], &info);
+
txlist[0] = '\0';
- for (j=0; j<(int)count; ++j) {
+ for (j=0; j<info.listener_cnt; ++j) {
char s[10];
- if (port_info->listener[j]) {
- pj_ansi_sprintf(s, "#%d ", j);
- pj_ansi_strcat(txlist, s);
- }
+ pj_ansi_sprintf(s, "#%d ", info.listeners[j]);
+ pj_ansi_strcat(txlist, s);
}
printf("Port #%02d[%2dKHz/%dms] %20.*s transmitting to: %s\n",
- port_info->slot,
- port_info->clock_rate/1000,
- port_info->samples_per_frame * 1000 / port_info->clock_rate,
- (int)port_info->name.slen,
- port_info->name.ptr,
+ info.slot_id,
+ info.clock_rate/1000,
+ info.samples_per_frame * 1000 / info.clock_rate,
+ (int)info.name.slen,
+ info.name.ptr,
txlist);
}
@@ -417,7 +418,7 @@ static void conf_list(void)
}
-void pjsua_console_app_main(void)
+void pjsua_console_app_main(const pj_str_t *uri_to_call)
{
char menuin[10];
char buf[128];
@@ -431,9 +432,8 @@ void pjsua_console_app_main(void)
/* If user specifies URI to call, then call the URI */
- if (pjsua_get_config()->uri_to_call.slen) {
- pjsua_make_call( current_acc, &pjsua_get_config()->uri_to_call,
- NULL);
+ if (uri_to_call->slen) {
+ pjsua_call_make_call( current_acc, uri_to_call, NULL);
}
keystroke_help();
@@ -449,7 +449,8 @@ void pjsua_console_app_main(void)
case 'm':
/* Make call! : */
- printf("(You currently have %d calls)\n", pjsua_get_call_count());
+ printf("(You currently have %d calls)\n",
+ pjsua_call_get_count());
uri = NULL;
ui_input_url("Make call", buf, sizeof(buf), &result);
@@ -469,12 +470,13 @@ void pjsua_console_app_main(void)
}
tmp = pj_str(uri);
- pjsua_make_call( current_acc, &tmp, NULL);
+ pjsua_call_make_call( current_acc, &tmp, NULL);
break;
case 'M':
/* Make multiple calls! : */
- printf("(You currently have %d calls)\n", pjsua_get_call_count());
+ printf("(You currently have %d calls)\n",
+ pjsua_call_get_count());
if (!simple_input("Number of calls", menuin, sizeof(menuin)))
continue;
@@ -500,7 +502,7 @@ void pjsua_console_app_main(void)
pj_status_t status;
tmp = pj_str(uri);
- status = pjsua_make_call(current_acc, &tmp, NULL);
+ status = pjsua_call_make_call(current_acc, &tmp, NULL);
if (status != PJ_SUCCESS)
break;
}
@@ -540,7 +542,7 @@ void pjsua_console_app_main(void)
/* Send typing indication. */
if (i != -1)
- pjsua_call_typing(i, PJ_TRUE);
+ pjsua_call_send_typing_ind(i, PJ_TRUE);
else {
pj_str_t tmp_uri = pj_str(uri);
pjsua_im_typing(current_acc, &tmp_uri, PJ_TRUE);
@@ -553,7 +555,7 @@ void pjsua_console_app_main(void)
* Send typing notification too, saying we're not typing.
*/
if (i != -1)
- pjsua_call_typing(i, PJ_FALSE);
+ pjsua_call_send_typing_ind(i, PJ_FALSE);
else {
pj_str_t tmp_uri = pj_str(uri);
pjsua_im_typing(current_acc, &tmp_uri, PJ_FALSE);
@@ -576,7 +578,7 @@ void pjsua_console_app_main(void)
case 'a':
if (current_call != -1) {
- pjsua_get_call_info(current_call, &call_info);
+ pjsua_call_get_info(current_call, &call_info);
} else {
/* Make compiler happy */
call_info.active = 0;
@@ -650,7 +652,7 @@ void pjsua_console_app_main(void)
if (current_call != -1) {
- pjsua_get_call_info(current_call, &call_info);
+ pjsua_call_get_info(current_call, &call_info);
PJ_LOG(3,(THIS_FILE,"Current dialog: %.*s",
(int)call_info.remote_info.slen,
call_info.remote_info.ptr));
@@ -781,8 +783,6 @@ void pjsua_console_app_main(void)
pjsua_buddy_subscribe_pres(result.nb_result-1, (menuin[0]=='s'));
}
- pjsua_pres_refresh();
-
} else if (result.uri_result) {
puts("Sorry, can only subscribe to buddy's presence, "
"not arbitrary URL (for now)");
@@ -814,7 +814,6 @@ void pjsua_console_app_main(void)
printf("Setting %s online status to %s\n",
acc_info.acc_id.ptr,
(acc_info.online_status?"online":"offline"));
- pjsua_pres_refresh();
break;
case 'c':
@@ -897,80 +896,6 @@ on_exit:
/*****************************************************************************
- * This is a very simple PJSIP module, whose sole purpose is to display
- * incoming and outgoing messages to log. This module will have priority
- * higher than transport layer, which means:
- *
- * - incoming messages will come to this module first before reaching
- * transaction layer.
- *
- * - outgoing messages will come to this module last, after the message
- * has been 'printed' to contiguous buffer by transport layer and
- * appropriate transport instance has been decided for this message.
- *
- */
-
-/* Notification on incoming messages */
-static pj_bool_t console_on_rx_msg(pjsip_rx_data *rdata)
-{
- PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"
- "%s\n"
- "--end msg--",
- rdata->msg_info.len,
- pjsip_rx_data_get_info(rdata),
- rdata->pkt_info.src_name,
- rdata->pkt_info.src_port,
- rdata->msg_info.msg_buf));
-
- /* Always return false, otherwise messages will not get processed! */
- return PJ_FALSE;
-}
-
-/* Notification on outgoing messages */
-static pj_status_t console_on_tx_msg(pjsip_tx_data *tdata)
-{
-
- /* Important note:
- * tp_info field is only valid after outgoing messages has passed
- * transport layer. So don't try to access tp_info when the module
- * has lower priority than transport layer.
- */
-
- PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"
- "%s\n"
- "--end msg--",
- (tdata->buf.cur - tdata->buf.start),
- pjsip_tx_data_get_info(tdata),
- tdata->tp_info.dst_name,
- tdata->tp_info.dst_port,
- tdata->buf.start));
-
- /* Always return success, otherwise message will not get sent! */
- return PJ_SUCCESS;
-}
-
-/* The module instance. */
-pjsip_module pjsua_console_app_msg_logger =
-{
- NULL, NULL, /* prev, next. */
- { "mod-pjsua-log", 13 }, /* Name. */
- -1, /* Id */
- PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority */
- NULL, /* load() */
- NULL, /* start() */
- NULL, /* stop() */
- NULL, /* unload() */
- &console_on_rx_msg, /* on_rx_request() */
- &console_on_rx_msg, /* on_rx_response() */
- &console_on_tx_msg, /* on_tx_request. */
- &console_on_tx_msg, /* on_tx_response() */
- NULL, /* on_tsx_state() */
-
-};
-
-
-
-/*****************************************************************************
* Error display:
*/
@@ -992,7 +917,8 @@ void pjsua_perror(const char *sender, const char *title,
pjsua_callback console_callback =
{
&console_on_call_state,
- NULL, /* default accept transfer */
+ NULL, /* on_incoming_call */
+ NULL, /* default accept transfer */
&console_on_reg_state,
&console_on_buddy_state,
&console_on_pager,
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 3f63ce8f..01b6c8c4 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -55,6 +55,7 @@ PJ_DEF(void) pjsua_default_config(pjsua_config *cfg)
cfg->media_thread_cnt = 1;
cfg->udp_port = 5060;
cfg->start_rtp_port = 4000;
+ cfg->msg_logging = PJ_TRUE;
cfg->max_calls = 4;
cfg->conf_ports = 0;
@@ -721,6 +722,8 @@ static void copy_acc_config(pj_pool_t *pool,
{
unsigned j;
+ pj_memcpy(dst_acc, src_acc, sizeof(pjsua_acc_config));
+
pj_strdup_with_null(pool, &dst_acc->id, &src_acc->id);
pj_strdup_with_null(pool, &dst_acc->reg_uri, &src_acc->reg_uri);
pj_strdup_with_null(pool, &dst_acc->contact, &src_acc->contact);
@@ -742,7 +745,7 @@ static void copy_acc_config(pj_pool_t *pool,
/*
* Copy configuration.
*/
-static void copy_config(pj_pool_t *pool, pjsua_config *dst,
+void pjsua_copy_config( pj_pool_t *pool, pjsua_config *dst,
const pjsua_config *src)
{
unsigned i;
@@ -761,7 +764,7 @@ static void copy_config(pj_pool_t *pool, pjsua_config *dst,
}
pj_strdup_with_null(pool, &dst->outbound_proxy, &src->outbound_proxy);
- pj_strdup_with_null(pool, &dst->uri_to_call, &src->uri_to_call);
+ //pj_strdup_with_null(pool, &dst->uri_to_call, &src->uri_to_call);
for (i=0; i<src->acc_cnt; ++i) {
pjsua_acc_config *dst_acc = &dst->acc_config[i];
@@ -813,6 +816,10 @@ static pj_status_t logging_init()
}
}
+ /* Enable SIP message logging */
+ if (pjsua.config.msg_logging)
+ pjsip_endpt_register_module(pjsua.endpt, &pjsua_msg_logger);
+
return PJ_SUCCESS;
}
@@ -863,7 +870,7 @@ PJ_DECL(pj_status_t) pjsua_init(const pjsua_config *cfg,
}
/* Copy configuration */
- copy_config(pjsua.pool, &pjsua.config, cfg);
+ pjsua_copy_config(pjsua.pool, &pjsua.config, cfg);
/* Copy callback */
pj_memcpy(&pjsua.cb, cb, sizeof(pjsua_callback));
@@ -1026,7 +1033,7 @@ on_error:
/*
* Find account for incoming request.
*/
-int pjsua_find_account_for_incoming(pjsip_rx_data *rdata)
+PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
{
pjsip_uri *uri;
pjsip_sip_uri *sip_uri;
@@ -1034,11 +1041,11 @@ int pjsua_find_account_for_incoming(pjsip_rx_data *rdata)
uri = rdata->msg_info.to->uri;
- /* Just return last account if To URI is not SIP: */
+ /* Just return default account if To URI is not SIP: */
if (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
!PJSIP_URI_SCHEME_IS_SIPS(uri))
{
- return pjsua.config.acc_cnt;
+ return pjsua.default_acc;
}
@@ -1068,20 +1075,60 @@ int pjsua_find_account_for_incoming(pjsip_rx_data *rdata)
}
}
- /* Still no match, just return last account */
- return pjsua.config.acc_cnt;
+ /* Still no match, use default account */
+ return pjsua.default_acc;
}
/*
* Find account for outgoing request.
*/
-int pjsua_find_account_for_outgoing(const pj_str_t *url)
+PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *str_url)
{
- PJ_UNUSED_ARG(url);
+ pj_str_t tmp;
+ pjsip_uri *uri;
+ pjsip_sip_uri *sip_uri;
+ unsigned i;
- /* Just use account #0 */
- return 0;
+ pj_strdup_with_null(pjsua.pool, &tmp, str_url);
+
+ uri = pjsip_parse_uri(pjsua.pool, tmp.ptr, tmp.slen, 0);
+ if (!uri)
+ return pjsua.config.acc_cnt-1;
+
+ if (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
+ !PJSIP_URI_SCHEME_IS_SIPS(uri))
+ {
+ /* Return the first account with proxy */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+ if (!pjsua.acc[i].valid)
+ continue;
+ if (pjsua.config.acc_config[i].proxy.slen)
+ break;
+ }
+
+ if (i != PJ_ARRAY_SIZE(pjsua.acc))
+ return i;
+
+ /* Not found, use default account */
+ return pjsua.default_acc;
+ }
+
+ sip_uri = pjsip_uri_get_uri(uri);
+
+ /* Find matching domain */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+ if (!pjsua.acc[i].valid)
+ continue;
+ if (pj_stricmp(&pjsua.acc[i].host_part, &sip_uri->host)==0)
+ break;
+ }
+
+ if (i != PJ_ARRAY_SIZE(pjsua.acc))
+ return i;
+
+ /* Just use default account */
+ return pjsua.default_acc;
}
@@ -1192,6 +1239,10 @@ static pj_status_t init_acc(unsigned acc_index)
pj_list_push_back(&acc->route_set, r);
}
+ /* Mark account as valid */
+ pjsua.acc[acc_index].valid = PJ_TRUE;
+
+
return PJ_SUCCESS;
}
@@ -1199,23 +1250,34 @@ static pj_status_t init_acc(unsigned acc_index)
* Add a new account.
*/
PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg,
- int *acc_index)
+ pjsua_acc_id *acc_index)
{
+ unsigned index;
pj_status_t status;
- PJ_ASSERT_RETURN(pjsua.config.acc_cnt<PJ_ARRAY_SIZE(pjsua.config.acc_config),
+ PJ_ASSERT_RETURN(pjsua.config.acc_cnt <
+ PJ_ARRAY_SIZE(pjsua.config.acc_config),
PJ_ETOOMANY);
- copy_acc_config(pjsua.pool, &pjsua.config.acc_config[pjsua.config.acc_cnt], cfg);
+ /* Find empty account index. */
+ for (index=0; index < PJ_ARRAY_SIZE(pjsua.acc); ++index) {
+ if (pjsua.acc[index].valid == PJ_FALSE)
+ break;
+ }
+
+ /* Expect to find a slot */
+ PJ_ASSERT_RETURN(index < PJ_ARRAY_SIZE(pjsua.acc), PJ_EBUG);
+
+ copy_acc_config(pjsua.pool, &pjsua.config.acc_config[index], cfg);
- status = init_acc(pjsua.config.acc_cnt);
+ status = init_acc(index);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error adding account", status);
return status;
}
if (acc_index)
- *acc_index = pjsua.config.acc_cnt;
+ *acc_index = index;
pjsua.config.acc_cnt++;
@@ -1223,6 +1285,25 @@ PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg,
}
+/*
+ * Delete account.
+ */
+PJ_DEF(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_index)
+{
+ PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
+ /* Delete registration */
+ if (pjsua.acc[acc_index].regc != NULL)
+ pjsua_acc_set_registration(acc_index, PJ_FALSE);
+
+ /* Invalidate */
+ pjsua.acc[acc_index].valid = PJ_FALSE;
+
+ return PJ_SUCCESS;
+}
+
/*
* Start pjsua stack.
@@ -1266,7 +1347,7 @@ PJ_DEF(pj_status_t) pjsua_start(void)
pj_str_t tmp, id;
tmp.ptr = buf;
- tmp.slen = pj_ansi_sprintf(tmp.ptr, "<sip:%s:%d>",
+ tmp.slen = pj_ansi_sprintf(tmp.ptr, "Local <sip:%s:%d>",
pjsua.config.sip_host.ptr,
pjsua.config.sip_port);
pj_strdup_with_null( pjsua.pool, &id, &tmp);
@@ -1283,6 +1364,17 @@ PJ_DEF(pj_status_t) pjsua_start(void)
}
+ /* Add another account as the last one.
+ * This account corresponds to local endpoint, and is user-less.
+ * This is also the default account.
+ */
+ if (pjsua.config.acc_cnt < PJ_ARRAY_SIZE(pjsua.config.acc_config)) {
+ pjsua.default_acc = pjsua.config.acc_cnt;
+ pjsua.acc[pjsua.default_acc].auto_gen = 1;
+ pjsua.config.acc_cnt++;
+ }
+
+
/* Initialize accounts: */
for (i=0; i<(int)pjsua.config.acc_cnt; ++i) {
status = init_acc(i);
@@ -1293,7 +1385,6 @@ PJ_DEF(pj_status_t) pjsua_start(void)
}
-
/* Create worker thread(s), if required: */
for (i=0; i<(int)pjsua.config.thread_cnt; ++i) {
@@ -1333,6 +1424,9 @@ PJ_DEF(pj_status_t) pjsua_start(void)
}
+ /* Refresh presence */
+ pjsua_pres_refresh();
+
PJ_LOG(3,(THIS_FILE, "PJSUA version %s started", PJ_VERSION));
return PJ_SUCCESS;
@@ -1368,22 +1462,55 @@ PJ_DEF(unsigned) pjsua_conf_max_ports(void)
/**
- * Enum all conference ports.
+ * Enum all conference port ID.
*/
-PJ_DEF(pj_status_t) pjsua_conf_enum_ports( unsigned *count,
- pjmedia_conf_port_info info[])
+PJ_DEF(pj_status_t) pjsua_conf_enum_port_ids( pjsua_conf_port_id id[],
+ unsigned *count)
{
- return pjmedia_conf_get_ports_info(pjsua.mconf, count, info);
+ return pjmedia_conf_enum_ports( pjsua.mconf, (unsigned*)id, count);
}
+/**
+ * Get information about the specified conference port
+ */
+PJ_DEF(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id id,
+ pjsua_conf_port_info *info)
+{
+ pjmedia_conf_port_info cinfo;
+ unsigned i, count;
+ pj_status_t status;
+
+ status = pjmedia_conf_get_port_info( pjsua.mconf, id, &cinfo);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_memset(info, 0, sizeof(*info));
+ info->slot_id = id;
+ info->name = cinfo.name;
+ info->clock_rate = cinfo.clock_rate;
+ info->channel_count = cinfo.channel_count;
+ info->samples_per_frame = cinfo.samples_per_frame;
+ info->bits_per_sample = cinfo.bits_per_sample;
+
+ /* Build array of listeners */
+ count = pjsua.config.conf_ports;
+ for (i=0; i<count; ++i) {
+ if (cinfo.listener[i]) {
+ info->listeners[info->listener_cnt++] = i;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
/**
* Connect conference port.
*/
-PJ_DEF(pj_status_t) pjsua_conf_connect( unsigned src_port,
- unsigned dst_port)
+PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id src_port,
+ pjsua_conf_port_id dst_port)
{
return pjmedia_conf_connect_port(pjsua.mconf, src_port, dst_port, 0);
}
@@ -1392,8 +1519,8 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( unsigned src_port,
/**
* Connect conference port connection.
*/
-PJ_DEF(pj_status_t) pjsua_conf_disconnect( unsigned src_port,
- unsigned dst_port)
+PJ_DEF(pj_status_t) pjsua_conf_disconnect( pjsua_conf_port_id src_port,
+ pjsua_conf_port_id dst_port)
{
return pjmedia_conf_disconnect_port(pjsua.mconf, src_port, dst_port);
}
@@ -1434,7 +1561,7 @@ PJ_DEF(pj_status_t) pjsua_player_create( const pj_str_t *filename,
pjsua.player[pjsua.player_cnt].port = port;
pjsua.player[pjsua.player_cnt].slot = slot;
- if (*id)
+ if (id)
*id = pjsua.player_cnt;
++pjsua.player_cnt;
@@ -1446,7 +1573,7 @@ PJ_DEF(pj_status_t) pjsua_player_create( const pj_str_t *filename,
/**
* Get conference port associated with player.
*/
-PJ_DEF(int) pjsua_player_get_conf_port(pjsua_player_id id)
+PJ_DEF(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id)
{
PJ_ASSERT_RETURN(id>=0 && id < PJ_ARRAY_SIZE(pjsua.player), PJ_EINVAL);
return pjsua.player[id].slot;
@@ -1530,7 +1657,7 @@ PJ_DEF(pj_status_t) pjsua_recorder_create( const pj_str_t *filename,
/**
* Get conference port associated with recorder.
*/
-PJ_DEF(int) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
+PJ_DEF(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
{
PJ_ASSERT_RETURN(id>=0 && id < PJ_ARRAY_SIZE(pjsua.recorder), PJ_EINVAL);
return pjsua.recorder[id].slot;
diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c
index efd8cbf6..807f2fac 100644
--- a/pjsip/src/pjsua-lib/pjsua_im.c
+++ b/pjsip/src/pjsua-lib/pjsua_im.c
@@ -185,6 +185,7 @@ static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata)
{
pj_str_t from, to;
pjsip_accept_hdr *accept_hdr;
+ pjsip_contact_hdr *contact_hdr;
pjsip_msg *msg;
pj_status_t status;
@@ -221,11 +222,23 @@ static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata)
status = pjsip_endpt_respond( pjsua.endpt, NULL, rdata, 200, NULL,
NULL, NULL, NULL);
- /* Build the From text. */
+ /* For the source URI, we use Contact header if present, since
+ * Contact header contains the port number information. If this is
+ * not available, then use From header.
+ */
from.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
- from.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
- rdata->msg_info.from->uri,
- from.ptr, PJSIP_MAX_URL_SIZE);
+ contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg,
+ PJSIP_H_CONTACT, NULL);
+ if (contact_hdr) {
+ from.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
+ contact_hdr->uri,
+ from.ptr, PJSIP_MAX_URL_SIZE);
+ } else {
+ from.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
+ rdata->msg_info.from->uri,
+ from.ptr, PJSIP_MAX_URL_SIZE);
+ }
+
if (from.slen < 1)
from = pj_str("<--URI is too long-->");
@@ -336,6 +349,7 @@ PJ_DEF(pj_status_t) pjsua_im_send(int acc_index, const pj_str_t *dst_uri,
PJ_DEF(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri,
pj_bool_t is_typing)
{
+ const pj_str_t STR_CONTACT = { "Contact", 7 };
pjsip_tx_data *tdata;
pj_status_t status;
@@ -350,6 +364,18 @@ PJ_DEF(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri,
}
+ /* Add accept header. */
+ pjsip_msg_add_hdr( tdata->msg,
+ (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));
+
+
+ /* Add contact. */
+ pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)
+ pjsip_generic_string_hdr_create(tdata->pool,
+ &STR_CONTACT,
+ &pjsua.config.acc_config[acc_index].contact));
+
+
/* Create "application/im-iscomposing+xml" msg body. */
tdata->msg->body = pjsip_iscomposing_create_body( tdata->pool, is_typing,
NULL, NULL, -1);
diff --git a/pjsip/src/pjsua-lib/pjsua_imp.h b/pjsip/src/pjsua-lib/pjsua_imp.h
index ec1918d3..117a2d12 100644
--- a/pjsip/src/pjsua-lib/pjsua_imp.h
+++ b/pjsip/src/pjsua-lib/pjsua_imp.h
@@ -32,6 +32,7 @@ struct pjsua_call
{
unsigned index; /**< Index in pjsua array. */
pjsip_inv_session *inv; /**< The invite session. */
+ pjsip_status_code last_code; /**<Last status code seen. */
pj_time_val start_time;/**< First INVITE sent/received. */
pj_time_val res_time; /**< First response sent/received. */
pj_time_val conn_time; /**< Connected/confirmed time. */
@@ -61,7 +62,6 @@ struct pjsua_buddy
pj_str_t display; /**< Buddy display name. */
pj_str_t host; /**< Buddy host. */
unsigned port; /**< Buddy port. */
- int acc_index; /**< Which account to use. */
pj_bool_t monitor; /**< Should we monitor? */
pjsip_evsub *sub; /**< Buddy presence subscription */
pjsip_pres_status status; /**< Buddy presence status. */
@@ -89,6 +89,8 @@ typedef struct pjsua_srv_pres pjsua_srv_pres;
*/
struct pjsua_acc
{
+ pj_bool_t valid; /**< Is this account valid? */
+ pj_bool_t auto_gen; /**< Is this account generated. */
int index; /**< Index in accounts array. */
pj_str_t user_part; /**< User part of local URI. */
pj_str_t host_part; /**< Host part of local URI. */
@@ -159,6 +161,7 @@ struct pjsua
} recorder[32];
/* Account: */
+ int default_acc; /**< Default account to use. */
pjsua_acc acc[PJSUA_MAX_ACC]; /** Client regs array. */
@@ -175,7 +178,6 @@ struct pjsua
unsigned call_cnt; /**< Number of calls. */
pjsua_call calls[PJSUA_MAX_CALLS]; /** Calls array. */
-
/* SIMPLE and buddy status: */
pjsua_buddy buddies[PJSUA_MAX_BUDDIES];
};
@@ -185,17 +187,8 @@ struct pjsua
extern struct pjsua pjsua;
-
-/**
- * Find account for incoming request.
- */
-int pjsua_find_account_for_incoming(pjsip_rx_data *rdata);
-
-
-/**
- * Find account for outgoing request.
- */
-int pjsua_find_account_for_outgoing(const pj_str_t *url);
+void pjsua_copy_config( pj_pool_t *pool, pjsua_config *dst,
+ const pjsua_config *src);
/**
@@ -225,6 +218,11 @@ pj_status_t pjsua_pres_init();
/**
+ * Refresh both presence client and server subscriptions.
+ */
+void pjsua_pres_refresh(void);
+
+/**
* Terminate all subscriptions
*/
void pjsua_pres_shutdown(void);
@@ -255,6 +253,7 @@ void pjsua_im_process_pager(int call_id, const pj_str_t *from,
const pj_str_t *to, pjsip_rx_data *rdata);
+extern pjsip_module pjsua_msg_logger;
#endif /* __PJSUA_IMP_H__ */
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index c76d3cbb..b24ffd3c 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -97,7 +97,7 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata)
/* Incoming SUBSCRIBE: */
/* Find which account for the incoming request. */
- acc_index = pjsua_find_account_for_incoming(rdata);
+ acc_index = pjsua_acc_find_for_incoming(rdata);
acc_config = &pjsua.config.acc_config[acc_index];
/* Create UAS dialog: */
@@ -310,7 +310,8 @@ static void subscribe_buddy_presence(unsigned index)
pjsip_tx_data *tdata;
pj_status_t status;
- acc_index = pjsua.buddies[index].acc_index;
+ acc_index = pjsua_acc_find_for_outgoing(&pjsua.config.buddy_uri[index]);
+
acc_config = &pjsua.config.acc_config[acc_index];
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
@@ -439,12 +440,13 @@ PJ_DEF(unsigned) pjsua_get_buddy_count(void)
/**
* Get buddy info.
*/
-PJ_DEF(pj_status_t) pjsua_buddy_get_info(unsigned index,
+PJ_DEF(pj_status_t) pjsua_buddy_get_info(pjsua_buddy_id index,
pjsua_buddy_info *info)
{
pjsua_buddy *buddy;
- PJ_ASSERT_RETURN(index < pjsua.config.buddy_cnt, PJ_EINVAL);
+ PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_EINVAL);
pj_memset(info, 0, sizeof(pjsua_buddy_info));
@@ -471,7 +473,6 @@ PJ_DEF(pj_status_t) pjsua_buddy_get_info(unsigned index,
info->status_text = pj_str("Offline");
}
- info->acc_index = buddy->acc_index;
return PJ_SUCCESS;
}
@@ -480,17 +481,27 @@ PJ_DEF(pj_status_t) pjsua_buddy_get_info(unsigned index,
* Add new buddy.
*/
PJ_DEF(pj_status_t) pjsua_buddy_add( const pj_str_t *uri,
- int *buddy_index)
+ pjsua_buddy_id *buddy_index)
{
pjsip_name_addr *url;
pjsip_sip_uri *sip_uri;
int index;
pj_str_t tmp;
- PJ_ASSERT_RETURN(pjsua.config.buddy_cnt <= PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_ASSERT_RETURN(pjsua.config.buddy_cnt <=
+ PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_ETOOMANY);
+
+ /* Find empty slot */
+ for (index=0; index<PJ_ARRAY_SIZE(pjsua.config.buddy_uri); ++index) {
+ if (pjsua.config.buddy_uri[index].slen == 0)
+ break;
+ }
+
+ /* Expect to find an empty slot */
+ PJ_ASSERT_RETURN(index < PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
PJ_ETOOMANY);
- index = pjsua.config.buddy_cnt;
/* Get name and display name for buddy */
pj_strdup_with_null(pjsua.pool, &tmp, uri);
@@ -511,10 +522,6 @@ PJ_DEF(pj_status_t) pjsua_buddy_add( const pj_str_t *uri,
if (pjsua.buddies[index].port == 0)
pjsua.buddies[index].port = 5060;
- /* Find account for outgoing preence subscription */
- pjsua.buddies[index].acc_index =
- pjsua_find_account_for_outgoing(&pjsua.config.buddy_uri[index]);
-
if (buddy_index)
*buddy_index = index;
@@ -525,24 +532,52 @@ PJ_DEF(pj_status_t) pjsua_buddy_add( const pj_str_t *uri,
-PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( unsigned index,
+/**
+ * Delete buddy.
+ */
+PJ_DEF(pj_status_t) pjsua_buddy_del(pjsua_buddy_id index)
+{
+ PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_EINVAL);
+
+ if (pjsua.config.buddy_uri[index].slen == 0)
+ return PJ_SUCCESS;
+
+ /* Unsubscribe presence */
+ pjsua_buddy_subscribe_pres(index, PJ_FALSE);
+
+ /* Remove buddy */
+ pjsua.config.buddy_uri[index].slen = 0;
+ pjsua.config.buddy_cnt--;
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( pjsua_buddy_id index,
pj_bool_t monitor)
{
pjsua_buddy *buddy;
- PJ_ASSERT_RETURN(index < pjsua.config.buddy_cnt, PJ_EINVAL);
+ PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_EINVAL);
buddy = &pjsua.buddies[index];
buddy->monitor = monitor;
+ pjsua_pres_refresh();
return PJ_SUCCESS;
}
-PJ_DEF(pj_status_t) pjsua_acc_set_online_status( unsigned acc_index,
+PJ_DEF(pj_status_t) pjsua_acc_set_online_status( pjsua_acc_id acc_index,
pj_bool_t is_online)
{
- PJ_ASSERT_RETURN(acc_index < pjsua.config.acc_cnt, PJ_EINVAL);
+ PJ_ASSERT_RETURN(acc_index < (int)PJ_ARRAY_SIZE(pjsua.acc),
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
pjsua.acc[acc_index].online_status = is_online;
+ pjsua_pres_refresh();
return PJ_SUCCESS;
}
diff --git a/pjsip/src/pjsua-lib/pjsua_reg.c b/pjsip/src/pjsua-lib/pjsua_reg.c
index f85bcd77..54dbcbd2 100644
--- a/pjsip/src/pjsua-lib/pjsua_reg.c
+++ b/pjsip/src/pjsua-lib/pjsua_reg.c
@@ -95,16 +95,21 @@ PJ_DEF(unsigned) pjsua_get_acc_count(void)
/**
* Get account info.
*/
-PJ_DEF(pj_status_t) pjsua_acc_get_info( unsigned acc_index,
+PJ_DEF(pj_status_t) pjsua_acc_get_info( pjsua_acc_id acc_index,
pjsua_acc_info *info)
{
pjsua_acc *acc = &pjsua.acc[acc_index];
pjsua_acc_config *acc_cfg = &pjsua.config.acc_config[acc_index];
- PJ_ASSERT_RETURN(acc_index < pjsua.config.acc_cnt, PJ_EINVAL);
-
+ PJ_ASSERT_RETURN(info != NULL, PJ_EINVAL);
+
pj_memset(info, 0, sizeof(pjsua_acc_info));
+ PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
+
info->index = acc_index;
info->acc_id = acc_cfg->id;
info->has_registration = (acc->regc != NULL);
@@ -114,9 +119,12 @@ PJ_DEF(pj_status_t) pjsua_acc_get_info( unsigned acc_index,
info->status = acc->reg_last_err;
pj_strerror(acc->reg_last_err, info->buf, sizeof(info->buf));
info->status_text = pj_str(info->buf);
- } else {
+ } else if (acc->reg_last_code) {
info->status = acc->reg_last_code;
info->status_text = *pjsip_get_status_text(acc->reg_last_code);
+ } else {
+ info->status = 0;
+ info->status_text = pj_str("In Progress");
}
if (acc->regc) {
@@ -129,14 +137,57 @@ PJ_DEF(pj_status_t) pjsua_acc_get_info( unsigned acc_index,
}
+PJ_DEF(pj_status_t) pjsua_acc_enum_info( pjsua_acc_info info[],
+ unsigned *count )
+{
+ unsigned i, c;
+
+ for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+ if (!pjsua.acc[i].valid)
+ continue;
+
+ pjsua_acc_get_info(i, &info[c]);
+ ++c;
+ }
+
+ *count = c;
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Enum accounts id.
+ */
+PJ_DEF(pj_status_t) pjsua_acc_enum_id( pjsua_acc_id ids[],
+ unsigned *count )
+{
+ unsigned i, c;
+
+ for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+ if (!pjsua.acc[i].valid)
+ continue;
+ ids[c] = i;
+ ++c;
+ }
+
+ *count = c;
+ return PJ_SUCCESS;
+}
+
+
/*
* Update registration. If renew is false, then unregistration will be performed.
*/
-PJ_DECL(pj_status_t) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew)
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(pjsua_acc_id acc_index,
+ pj_bool_t renew)
{
pj_status_t status = 0;
pjsip_tx_data *tdata = 0;
+ PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
if (renew) {
if (pjsua.acc[acc_index].regc == NULL) {
status = pjsua_regc_init(acc_index);
diff --git a/pjsip/src/pjsua-lib/pjsua_settings.c b/pjsip/src/pjsua-lib/pjsua_settings.c
index be615359..db30312d 100644
--- a/pjsip/src/pjsua-lib/pjsua_settings.c
+++ b/pjsip/src/pjsua-lib/pjsua_settings.c
@@ -211,7 +211,8 @@ static int my_atoi(const char *cs)
/* Parse arguments. */
PJ_DEF(pj_status_t) pjsua_parse_args(int argc, char *argv[],
- pjsua_config *cfg)
+ pjsua_config *cfg,
+ pj_str_t *uri_to_call)
{
int c;
int option_index;
@@ -595,22 +596,29 @@ PJ_DEF(pj_status_t) pjsua_parse_args(int argc, char *argv[],
}
if (pj_optind != argc) {
+ pj_str_t uri_arg;
if (pjsua_verify_sip_url(argv[pj_optind]) != PJ_SUCCESS) {
PJ_LOG(1,(THIS_FILE, "Invalid SIP URI %s", argv[pj_optind]));
return -1;
}
- cfg->uri_to_call = pj_str(argv[pj_optind]);
+ uri_arg = pj_str(argv[pj_optind]);
+ if (uri_to_call)
+ *uri_to_call = uri_arg;
pj_optind++;
/* Add URI to call to buddy list if it's not already there */
for (i=0; i<cfg->buddy_cnt; ++i) {
- if (pj_stricmp(&cfg->buddy_uri[i], &cfg->uri_to_call)==0)
+ if (pj_stricmp(&cfg->buddy_uri[i], &uri_arg)==0)
break;
}
if (i == cfg->buddy_cnt && cfg->buddy_cnt < PJSUA_MAX_BUDDIES) {
- cfg->buddy_uri[cfg->buddy_cnt++] = cfg->uri_to_call;
+ cfg->buddy_uri[cfg->buddy_cnt++] = uri_arg;
}
+
+ } else {
+ if (uri_to_call)
+ uri_to_call->slen = 0;
}
if (pj_optind != argc) {
@@ -869,7 +877,7 @@ static void dump_media_session(const char *indent,
}
}
-PJ_DEF(void) pjsua_dump_call(int call_index, int with_media,
+PJ_DEF(void) pjsua_call_dump(int call_index, int with_media,
char *buffer, unsigned maxlen,
const char *indent)
{
@@ -975,7 +983,7 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
for (i=0; i<pjsua.config.max_calls; ++i) {
if (pjsua.calls[i].inv) {
- pjsua_dump_call(i, detail, buf, sizeof(buf), " ");
+ pjsua_call_dump(i, detail, buf, sizeof(buf), " ");
PJ_LOG(3,(THIS_FILE, "%s", buf));
}
}
@@ -993,13 +1001,14 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
* Load settings.
*/
PJ_DECL(pj_status_t) pjsua_load_settings(const char *filename,
- pjsua_config *cfg)
+ pjsua_config *cfg,
+ pj_str_t *uri_to_call)
{
int argc = 3;
char *argv[4] = { "pjsua", "--config-file", NULL, NULL};
argv[2] = (char*)filename;
- return pjsua_parse_args(argc, argv, cfg);
+ return pjsua_parse_args(argc, argv, cfg, uri_to_call);
}
@@ -1297,8 +1306,130 @@ PJ_DEF(pj_status_t) pjsua_save_settings(const char *filename,
/**
* Get pjsua running config.
*/
-PJ_DEF(const pjsua_config*) pjsua_get_config(void)
+PJ_DEF(void) pjsua_get_config(pj_pool_t *pool,
+ pjsua_config *cfg)
{
- return &pjsua.config;
+ unsigned i;
+
+ pjsua_copy_config(pool, cfg, &pjsua.config);
+
+ /* Compact buddy uris. */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.buddy_uri)-1; ++i) {
+ if (pjsua.config.buddy_uri[i].slen == 0) {
+ unsigned j;
+
+ for (j=i+1; j<PJ_ARRAY_SIZE(pjsua.config.buddy_uri); ++j) {
+ if (pjsua.config.buddy_uri[j].slen != 0)
+ break;
+ }
+
+ if (j == PJ_ARRAY_SIZE(pjsua.config.buddy_uri))
+ break;
+ else
+ pjsua.config.buddy_uri[i] = pjsua.config.buddy_uri[j];
+ }
+ }
+
+ /* Compact accounts. */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.acc_config)-1; ++i) {
+
+ if (pjsua.acc[i].valid == PJ_FALSE || pjsua.acc[i].auto_gen) {
+ unsigned j;
+
+ for (j=i+1; j<PJ_ARRAY_SIZE(pjsua.config.acc_config); ++j) {
+ if (pjsua.acc[j].valid && !pjsua.acc[j].auto_gen)
+ break;
+ }
+
+ if (j == PJ_ARRAY_SIZE(pjsua.config.acc_config)) {
+ break;
+ } else {
+ pj_memcpy(&pjsua.config.acc_config[i] ,
+ &pjsua.config.acc_config[j],
+ sizeof(pjsua_acc_config));
+ }
+ }
+
+ }
+
+ /* Remove auto generated account from config */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.acc_config); ++i) {
+ if (pjsua.acc[i].auto_gen)
+ --cfg->acc_cnt;
+ }
}
+
+
+/*****************************************************************************
+ * This is a very simple PJSIP module, whose sole purpose is to display
+ * incoming and outgoing messages to log. This module will have priority
+ * higher than transport layer, which means:
+ *
+ * - incoming messages will come to this module first before reaching
+ * transaction layer.
+ *
+ * - outgoing messages will come to this module last, after the message
+ * has been 'printed' to contiguous buffer by transport layer and
+ * appropriate transport instance has been decided for this message.
+ *
+ */
+
+/* Notification on incoming messages */
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+ PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"
+ "%s\n"
+ "--end msg--",
+ rdata->msg_info.len,
+ pjsip_rx_data_get_info(rdata),
+ rdata->pkt_info.src_name,
+ rdata->pkt_info.src_port,
+ rdata->msg_info.msg_buf));
+
+ /* Always return false, otherwise messages will not get processed! */
+ return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+
+ /* Important note:
+ * tp_info field is only valid after outgoing messages has passed
+ * transport layer. So don't try to access tp_info when the module
+ * has lower priority than transport layer.
+ */
+
+ PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"
+ "%s\n"
+ "--end msg--",
+ (tdata->buf.cur - tdata->buf.start),
+ pjsip_tx_data_get_info(tdata),
+ tdata->tp_info.dst_name,
+ tdata->tp_info.dst_port,
+ tdata->buf.start));
+
+ /* Always return success, otherwise message will not get sent! */
+ return PJ_SUCCESS;
+}
+
+/* The module instance. */
+pjsip_module pjsua_msg_logger =
+{
+ NULL, NULL, /* prev, next. */
+ { "mod-pjsua-log", 13 }, /* Name. */
+ -1, /* Id */
+ PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority */
+ NULL, /* load() */
+ NULL, /* start() */
+ NULL, /* stop() */
+ NULL, /* unload() */
+ &logging_on_rx_msg, /* on_rx_request() */
+ &logging_on_rx_msg, /* on_rx_response() */
+ &logging_on_tx_msg, /* on_tx_request. */
+ &logging_on_tx_msg, /* on_tx_response() */
+ NULL, /* on_tsx_state() */
+
+};
+