pj_status_t pjsua_call_make_call( pjsua_acc_id acc_id,
pj_str_t *dest_uri,
int seq,
unsigned options,
void *user_data,
const pjsua_msg_data *msg_data,
const pjsua_call_other *other,
pjsua_call_id *p_call_id)
{
pj_pool_t *tmp_pool = NULL;
pjsip_dialog *dlg = NULL;
pjmedia_sdp_session *offer = NULL;
pjsip_inv_session *inv = NULL;
pjsua_acc *acc = NULL;
pjsua_call *call = NULL;
int call_id = -1;
pj_str_t contact = {NULL, 0};
pjsip_tx_data *tdata = NULL;
pj_status_t status;
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
pj_str_t local_uri = {NULL, 0};
# endif
# if PJ_FAKE_CALL_SUPPORT
pj_bool_t bfakeCall = (0 == dest_uri->slen) ? PJ_TRUE : PJ_FALSE;
# endif
pj_bool_t bCreateFwRule = PJ_TRUE;
# if PJ_FAKE_CALL_SUPPORT
bCreateFwRule = !bfakeCall;
# endif
#ifdef INCLUDE_RFC3325
pjsip_generic_string_hdr privacyHdr;
pjsip_p_prefered_identity_hdr *preferedIdHdr;
pj_str_t preferedId_Url_Str = {NULL, 0};
pjsip_uri *preferedIdUri = NULL;
pj_str_t hname = {"", 0};
pj_str_t hvalue = {"", 0};
#if PJ_RFC3960_SUPPORT
char localIp[40];
pj_uint16_t rtpPort;
pj_uint16_t rtcpPort;
int family;
#endif
#endif /* INCLUDE_RFC3325 */
#if PJ_FAKE_CALL_SUPPORT
if (bfakeCall)
{
dest_uri->slen = sprintf(dest_uri->ptr, "%s", "sip:192.168.1.100");
}
#endif
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Ready to make a call!");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
/* Check that account is valid */
PJ_ASSERT_RETURN(
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
-1==acc_id ||
# endif
( acc_id>=0 || acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc)), PJ_EINVAL);
/* Check arguments */
PJ_ASSERT_RETURN(dest_uri, PJ_EINVAL);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "argument:accId %d, destUri(%.*s)",
acc_id, dest_uri->slen, pj_strnull(dest_uri->ptr));
#if PJ_FAKE_CALL_SUPPORT
}
#endif
PJSUA_LOCK();
/* Create sound port if none is instantiated, to check if sound device
* can be used. But only do this with the conference bridge, as with
* audio switchboard (i.e. APS-Direct), we can only open the sound
* device once the correct format has been known
*/
/*ycw-pjsip-delete conference*/
#if 0
if (!pjsua_var.is_mswitch
#if 0 /*ycw-pjsip-20110610-delete sound device*/
&& pjsua_var.snd_port==NULL &&
pjsua_var.null_snd==NULL && !pjsua_var.no_snd
#endif
)
{
/*ycw-pjsip-20110610-delete sound device*/
#if 0
pj_status_t status;
status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
if (status != PJ_SUCCESS) {
PJSUA_UNLOCK();
return status;
}
#endif
}
#endif
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
if (acc_id >= 0)
{
# endif
acc = &pjsua_var.acc[acc_id];
if (!acc->valid
# if defined(SUPPORT_ACCOUNT_RTT) && SUPPORT_ACCOUNT_RTT!=0
|| !acc->regDuration /*ycw-pjsip-regDuration*/
# elif !defined(INCLUDE_EMERGENCY_CALL)
|| !acc->regOK
# endif
)
{
pjsua_perror(THIS_FILE, "Unable to make call because account "
"is not valid or not active", PJ_EINVALIDOP);
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Unable to make call because account "
"is not valid or not active");
PJSUA_UNLOCK();
return PJ_EINVALIDOP;
}
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
}
# endif
/* Find free call slot. */
call_id = alloc_call_id();
if (call_id == PJSUA_INVALID_ID)
{
pjsua_perror(THIS_FILE, "Error making call", PJ_ETOOMANY);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Alloc call id error");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
PJSUA_UNLOCK();
return PJ_ETOOMANY;
}
call = &pjsua_var.calls[call_id];
/* Associate session with account */
call->acc_id = acc_id;
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
if (acc)
{
# endif
call->call_hold_type = acc->cfg.call_hold_type;
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
}
else
{
call->call_hold_type = PJSUA_CALL_HOLD_TYPE_DEFAULT;
}
# endif
call->seq = seq;
/* Create temporary pool */
tmp_pool = pjsua_pool_create("tmpcall10", 512, 256);
if (NULL == tmp_pool)
{
pjsua_perror(THIS_FILE, "Error create pool", PJ_ENOMEM);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Create pool error!");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
PJSUA_UNLOCK();
return PJ_ENOMEM;
}
/* Verify that destination URI is valid before calling
* pjsua_acc_create_uac_contact, or otherwise there
* a misleading "Invalid Contact URI" error will be printed
* when pjsua_acc_create_uac_contact() fails.
*/
if (1)
{
pjsip_uri *uri;
pj_str_t dup;
pj_strdup_with_null(tmp_pool, &dup, dest_uri);
//printf("going to parse the string: %.*s\n", (int)dup.slen, pj_strnull(dup.ptr));
uri = pjsip_parse_uri(tmp_pool, dup.ptr, dup.slen, 0);
if (uri == NULL)
{
pjsua_perror(THIS_FILE, "Unable to make call", PJSIP_EINVALIDREQURI);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Parse uri error!");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
pj_pool_release(tmp_pool);
PJSUA_UNLOCK();
return PJSIP_EINVALIDREQURI;
}
}
PJ_LOG(4,(THIS_FILE, "Making call with acc #%d to %.*s", acc_id,
(int)dest_uri->slen, pj_strnull(dest_uri->ptr)));
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Making call with acc #%d to %.*s",
acc_id, (int)dest_uri->slen, pj_strnull(dest_uri->ptr));
#if PJ_FAKE_CALL_SUPPORT
}
#endif
/* Mark call start time. */
pj_gettimeofday(&call->start_time);
/* Reset first response time */
call->res_time.sec = 0;
/* Create suitable Contact header unless a Contact header has been
* set in the account.
*/
if (
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
acc &&
# endif
acc->contact.slen
)
{
contact = acc->contact;
}
else
{
status = pjsua_acc_create_uac_contact(tmp_pool, &contact, acc_id, dest_uri);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Unable to generate Contact header");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
pj_pool_release(tmp_pool);
PJSUA_UNLOCK();
return status;
}
}
/* Create outgoing dialog: */
#if 0
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
&acc->cfg.id, &contact,
dest_uri, dest_uri, &dlg);
#else
#ifdef INCLUDE_RFC3325
if (acc && (PJ_TRUE == acc->cfg.supportNAI))
{
local_uri.ptr = (char*)pj_pool_alloc(tmp_pool, PJSIP_MAX_URL_SIZE);
local_uri.slen = pj_ansi_snprintf(local_uri.ptr, PJSIP_MAX_URL_SIZE,
"\"Anonymous\"<sip:%s@%.*s>", acc->cfg.preferId.ptr,
(int)acc->srv_domain.slen, pj_strnull(acc->srv_domain.ptr));
PJ_LOG(1,(THIS_FILE, "Making Anonymous call with acc #%d to %.*s", acc_id,
(int)local_uri.slen, pj_strnull(local_uri.ptr)));
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
&local_uri, &contact,
dest_uri, dest_uri, &dlg);
options = 0; // reset
}
else
#endif /* INCLUDE_RFC3325 */
if (options == pj_call_anonymous)
{
pj_str_t anonymous_uri = {"<sip:anonymous@anonymous.invalid>", 33};
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
&anonymous_uri, &contact,
dest_uri, dest_uri, &dlg);
options = 0; // reset
}
# if (defined(NUM_VOICEAPP_CHANNELS) && 0!=NUM_VOICEAPP_CHANNELS)
else if (options == pj_call_voiceapp_anonymous)
{
pj_str_t anonymous_uri = {"<sip:anonymous@anonymous.invalid>", 33};
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
&anonymous_uri, &contact,
dest_uri, dest_uri, &dlg);
call->isVoiceapp = PJ_TRUE;
options = 0; // reset
}
else if(options == pj_call_voiceapp)
{
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
if (NULL == acc && pjsua_var.BoundIp.slen > 0)
{
local_uri.ptr = (char*)pj_pool_alloc(tmp_pool, PJSIP_MAX_URL_SIZE);
local_uri.slen = pj_ansi_snprintf(local_uri.ptr, PJSIP_MAX_URL_SIZE,
"<sip:%.*s>",
(int)pjsua_var.BoundIp.slen,
pjsua_var.BoundIp.ptr);
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
&local_uri, &contact, dest_uri, dest_uri, &dlg);
}
else
# endif
{
pj_str_t *local_str = &acc->cfg.id;
if (acc->cfg.lineId.slen > 0 )
{
CMSIP_PRINT("=========the acc has lineid,replace it!!!============\n");
local_str = &acc->cfg.lineId;
}
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
local_str, &contact,
dest_uri, dest_uri, &dlg);
}
/*call->isVoiceapp = PJ_TRUE;
options = 0;*/
}
#endif
else
{
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
if (NULL == acc && pjsua_var.BoundIp.slen > 0)
{
local_uri.ptr = (char*)pj_pool_alloc(tmp_pool, PJSIP_MAX_URL_SIZE);
local_uri.slen = pj_ansi_snprintf(local_uri.ptr, PJSIP_MAX_URL_SIZE,
"<sip:%.*s>",
(int)pjsua_var.BoundIp.slen,
pjsua_var.BoundIp.ptr);
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
&local_uri, &contact, dest_uri, dest_uri, &dlg);
}
else
# endif
{
pj_str_t *local_str = &acc->cfg.id;
if (acc->cfg.lineId.slen > 0 )
{
CMSIP_PRINT("=========the acc has lineid,replace it!!!============\n");
local_str = &acc->cfg.lineId;
}
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
local_str, &contact,
dest_uri, dest_uri, &dlg);
}
}
#endif
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Dialog creation failed", status);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Dialog creation failed");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
pj_pool_release(tmp_pool);
PJSUA_UNLOCK();
return status;
}
/* Increment the dialog's lock otherwise when invite session creation
* fails the dialog will be destroyed prematurely.
*/
pjsip_dlg_inc_lock(dlg);
/* Calculate call's secure level */
call->secure_level = get_secure_level(acc_id, dest_uri);
/* Init media channel */
status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
call->secure_level, dlg->pool,
NULL, NULL);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Error initializing media channel");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
goto on_error;
}
/* Create offer */
/*ycw-pjsip. t38*/
#if 0
status = pjsua_media_channel_create_sdp(call->index, dlg->pool, NULL,
&offer, NULL);
#else
/*ycw-pjsip-codec*/
/*We must set the sdp's codec list according to the order of the codec list of the account.*/
if (options == pj_call_t38)
{
status = pjsua_media_channel_create_sdp_t38(call->index, dlg->pool, NULL, &offer, NULL, bCreateFwRule);
options = 0;
}
else
{
status = pjsua_media_channel_create_sdp(call->index, dlg->pool, NULL, &offer, NULL, bCreateFwRule);
}
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Error creating sdp", status);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Create sdp error!");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
goto on_error;
}
# if defined(INCLUDE_PSTN_GATEWAY)
if (pj_call_pstn == options)
{
call->isPstn = PJ_TRUE;
# if (defined(PJ_MEDIA_TRANSIT_BY_PJSIP) && 0==PJ_MEDIA_TRANSIT_BY_PJSIP) && \
(defined(INCLUDE_PSTN_GATEWAY) || defined(INCLUDE_USB_VOICEMAIL))
if (PJ_FALSE == call->medTpReady)
{
status = pjsua_media_transport_create_for_single_call(call_id);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "create media transport for single call error", status);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Create media transport error!");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
goto on_error;
}
call->medTpReady = PJ_TRUE;
}
# endif
}
else
{
call->isPstn = PJ_FALSE;
}
# endif
#endif
/*ycw-pjsip. t38*/
#if defined(PJMEDIA_HAS_SRTP) && PJMEDIA_HAS_SRTP!= 0
int audio_index;
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
if (NULL == acc)
{
audio_index = find_audio_index(offer, pjsua_var.ua_cfg.use_srtp);
}
else
{
# endif
audio_index = find_audio_index(offer, pjsua_var.acc[call->acc_id].cfg.use_srtp);
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
}
# endif
#else
int audio_index = find_audio_index(offer, PJ_FALSE);
#endif
if (audio_index < 0) audio_index = 0;
call->request_channel_mode = pjsua_call_acquire_channel_mode(offer, audio_index);
/* Create the INVITE session: */
options |= PJSIP_INV_SUPPORT_100REL;
if (NULL == acc)
{
if (pjsua_var.ua_cfg.require_100rel)
{
options |= PJSIP_INV_REQUIRE_100REL;
}
if (pjsua_var.ua_cfg.use_timer != PJSUA_SIP_TIMER_INACTIVE)
{
options |= PJSIP_INV_SUPPORT_TIMER;
if (pjsua_var.ua_cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
{
options |= PJSIP_INV_REQUIRE_TIMER;
}
else if (pjsua_var.ua_cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
{
options |= PJSIP_INV_ALWAYS_USE_TIMER;
}
}
}
else
{
if (acc->cfg.require_100rel)
{
options |= PJSIP_INV_REQUIRE_100REL;
}
if (acc->cfg.use_timer != PJSUA_SIP_TIMER_INACTIVE)
{
options |= PJSIP_INV_SUPPORT_TIMER;
if (acc->cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
{
options |= PJSIP_INV_REQUIRE_TIMER;
}
else if (acc->cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
{
options |= PJSIP_INV_ALWAYS_USE_TIMER;
}
}
}
/*ycw-pjsip*/
# if defined(SUPPORT_FAX_T38) && SUPPORT_FAX_T38!=0
if (pjsua_var.enableT38)
{
options |= PJSIP_INV_ENABLE_T38;
}
# endif
status = pjsip_inv_create_uac( dlg, offer, options, &inv);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Invite session creation failed", status);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Create Invite session error!");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
goto on_error;
}
/* Init Session Timers */
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
if (NULL == acc)
{
status = pjsip_timer_init_session(inv, &pjsua_var.ua_cfg.timer_setting
#ifdef INCLUDE_TFC_ES
, TR_UAC
#endif
);
}
else
{
# endif
status = pjsip_timer_init_session(inv, &acc->cfg.timer_setting
#ifdef INCLUDE_TFC_ES
, TR_UAC
#endif
);
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
}
# endif
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Session Timer init failed", status);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Init session timer error!");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
goto on_error;
}
/* Create and associate our data in the session. */
call->inv = inv;
dlg->mod_data[pjsua_var.mod.id] = call;
inv->mod_data[pjsua_var.mod.id] = call;
/*ycw-pjsip*/
dlg->callIndex = call_id;
dlg->seq = seq;
/* Attach user data */
call->user_data = user_data;
/* If account is locked to specific transport, then lock dialog
* to this transport too.
*/
if (
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
acc &&
# endif
acc->cfg.transport_id != PJSUA_INVALID_ID)
{
pjsip_tpselector tp_sel;
pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
pjsip_dlg_set_transport(dlg, &tp_sel);
}
/* Set dialog Route-Set: */
#if !defined(INCLUDE_TFC_ES)
/*By YuChuwei, For Telefonica*/
if (
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
acc &&
# endif
!pj_list_empty(&acc->route_set))
{
pjsip_dlg_set_route_set(dlg, &acc->route_set);
}
#endif
/* Set credentials: */
if (
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
acc &&
# endif
acc->cred_cnt)
{
pjsip_auth_clt_set_credentials( &dlg->auth_sess,
acc->cred_cnt, acc->cred);
}
/* Set authentication preference */
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
if (acc)
{
# endif
pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref);
# if defined(SUPPORT_IPCALL_NO_ACCOUNT) && SUPPORT_IPCALL_NO_ACCOUNT!=0
}
# endif
#if defined(INCLUDE_SIP_INVITE_PRIORITY)
if (other)
{
inv->isWarmCall = other->isWarmCall;
}
else
{
inv->isWarmCall = 0;
}
#endif /* INCLUDE_SIP_INVITE_PRIORITY */
/* Create initial INVITE: */
status = pjsip_inv_invite(inv, &tdata);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Unable to create initial INVITE request", status);
#if PJ_FAKE_CALL_SUPPORT
if (!bfakeCall)
{
#endif
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG, "Unable to create initial INVITE request");
#if PJ_FAKE_CALL_SUPPORT
}
#endif
goto on_error;
}
#ifdef INCLUDE_RFC3325
if (acc)
{
if (acc->cfg.preferId.slen > 0)
{
preferedIdHdr = pjsip_p_asserted_identity_hdr_create(tmp_pool);
if (NULL == preferedIdHdr)
{
pjsua_perror(THIS_FILE, "No memory!", PJ_ENOMEM);
goto on_error;
}
if (PJ_TRUE == acc->cfg.supportNAI) {
preferedId_Url_Str.ptr = (char*)pj_pool_alloc(tmp_pool, PJSIP_MAX_URL_SIZE);
preferedId_Url_Str.slen = pj_ansi_snprintf(preferedId_Url_Str.ptr, PJSIP_MAX_URL_SIZE,
"\"Anonymous\"<sip:%s@%.*s>", acc->cfg.preferId.ptr,
(int)acc->srv_domain.slen, pj_strnull(acc->srv_domain.ptr));
} else {
preferedId_Url_Str.ptr = (char*)pj_pool_alloc(tmp_pool, PJSIP_MAX_URL_SIZE);
preferedId_Url_Str.slen = pj_ansi_snprintf(preferedId_Url_Str.ptr, PJSIP_MAX_URL_SIZE,
"\"%s\"<sip:%s@%.*s>", acc->cfg.preferId.ptr, acc->cfg.preferId.ptr,
(int)acc->srv_domain.slen, pj_strnull(acc->srv_domain.ptr));
}
CMSIP_PRINT("==parse prefered identity==");
preferedIdUri = (pjsip_uri*)pjsip_parse_uri(tmp_pool,
preferedId_Url_Str.ptr, preferedId_Url_Str.slen,
0);
if (NULL == preferedIdUri)
{
CMSIP_PRINT("==parse prefered identity error==");
pjsua_perror(THIS_FILE, "parse value of Prefered Identity error ",
PJ_EINVAL);
}
else
{
preferedIdHdr->uri = preferedIdUri;
pj_list_push_back(&msg_data->hdr_list, preferedIdHdr);
}
}
hname = pj_str("Privacy");
if(acc->cfg.supportNAI)
{
hvalue = pj_str("id");
}
else
{
hvalue = pj_str("none");
}
pjsip_generic_string_hdr_init2(&privacyHdr, &hname, &hvalue);
pj_list_push_back(&msg_data->hdr_list, &privacyHdr);
}
#endif /* INCLUDE_RFC3325 */
#if defined(INCLUDE_ROBIN_DNS) || defined(INCLUDE_VOIP_ROBIN_DNS)
if (acc && acc->regc && acc->regc->srv_ipinfo.server_name.slen)
{
CMSIP_PRINT("==copy server address from regc to dlg==");
pj_strdup(dlg->pool, &dlg->server_name, &acc->regc->srv_ipinfo.server_name);
memcpy(&dlg->server_addr, &acc->regc->srv_ipinfo.server_addr, sizeof(dlg->server_addr) );
dlg->cur_addr = acc->regc->srv_ipinfo.cur_addr;
}
#endif /* INCLUDE_ROBIN_DNS || INCLUDE_VOIP_ROBIN_DNS */
/* Add additional headers etc */
pjsua_process_msg_data( tdata, msg_data);
# if PJ_FAKE_CALL_SUPPORT
if (bfakeCall)
{
char contact[1][MAX_URI_LEN] = {{0}};
cmsip_send_callStatus(CMSIP_CALL_GENERIC, call_id, seq, 0, contact, 1);
status = PJ_EINVAL;
goto on_error;
}
# endif
/* Send initial INVITE: */
status = pjsip_inv_send_msg(inv, tdata);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Unable to send initial INVITE request", status);
cmsip_send_systemlog(CMSIP_SYSTEMLOG_WARN,
"Unable to send initial INVITE request for [accIndex(%d),callIndex(%d) dest(%.*s)]",
acc_id, call_id, dest_uri->slen, pj_strnull(dest_uri->ptr));
/* Upon failure to send first request, the invite
* session would have been cleared.
*/
inv = NULL;
goto on_error;
}
cmsip_send_systemlog(CMSIP_SYSTEMLOG_DEBUG,
"the initial INVITE request for [accIndex(%d),callIndex(%d) dest(%.*s)] is sent",
acc_id, call_id, dest_uri->slen, pj_strnull(dest_uri->ptr));
/* Must increment call counter now */
++pjsua_var.call_cnt;
CMSIP_PRINT("~~~~now, call count is (%d)~~~~~", pjsua_var.call_cnt);
#if defined(INCLUDE_TFC_ES) && PJ_RFC3960_SUPPORT
#if PJ_MEDIA_TRANSIT_BY_PJSIP==0
pjmedia_transport_udp_local_info(call->med_orig, localIp, &rtpPort, &rtcpPort, &family);
cmsip_send_rtpcreate(call->index,
(options==pj_call_t38)?CMSIP_MEDIA_TYPE_IMAGE:CMSIP_MEDIA_TYPE_AUDIO,
(options==pj_call_t38)?CMSIP_MEDIA_TPPROTO_UDPTL:CMSIP_MEDIA_TPPROTO_RTP_AVP,
CMSIP_MEDIA_DIR_NONE, NULL, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, localIp, strlen(localIp),
rtpPort, NULL, 0, 0, 0, family);
#else
/*BTD*/
#endif
#endif
/* Done. */
if (p_call_id)
{
*p_call_id = call_id;
}
pjsip_dlg_dec_lock(dlg);
pj_pool_release(tmp_pool);
PJSUA_UNLOCK();
return PJ_SUCCESS;
on_error:
/*If tdata has been created, must release it, or , this will cause memory leak.
By Yuchuwei*/
if (tdata)
{
pjsip_tx_data_dec_ref(tdata);
tdata = NULL;
}
if (dlg)
{
/* This may destroy the dialog */
pjsip_dlg_dec_lock(dlg);
}
if (inv != NULL)
{
pjsip_inv_terminate(inv, PJSIP_SC_OK, PJ_FALSE);
}
if (call_id != -1)
{
pjsua_media_channel_deinit(call_id);
reset_call(call_id);
# if PJ_FAKE_CALL_SUPPORT
if (bfakeCall)
{
call->busy = PJ_FALSE;
}
# endif
}
CMSIP_PRINT("==release pool==");
pj_pool_release(tmp_pool);
PJSUA_UNLOCK();
return status;
}