当我尝试使用以下代码拨打电话时。
-(int)make_callWithURI:(char *) destURI{
/* Make call! : */
pj_str_t tmp;
pj_status_t status;
int regid = app_config.account_id;
int callNo = -1;
tmp = pj_str(destURI);
status = pjsua_call_make_call( regid, &tmp, 0, NULL, NULL, &callNo);
if (status != PJ_SUCCESS){
error_exit("Error making call", status);
return -1;
}
return callNo;
}
但是在pjsua_call_make_call()行获取信号SIGABRT
错误日志::
16:18:04.862 dlg0x14d8000a8 .. mod-pjsua的会议数量为2
列出项目
** 16:18:04.862 pjsua_call.c。错误初始化媒体频道:对象正忙(PJ_EBUSY)[status = 70011]
16:18:04.862 dlg0x14d8000a8 ..会议计数由mod-pjsua决定为1
16:18:04.862 dlg0x14d8000a8 .Dialog被摧毁
16:18:04.863 pjsua_media.c。电话0:取消媒体宣传..
断言失败:(entry-> cb!=((void *)0)),函数schedule_w_grp_lock,file ../src/pj/timer.c,第501行。**
请告诉我为什么会出现这个问题。我已使用默认配置初始化媒体:
//initialize media config with default configuration
pjsua_media_config_default(&cfg->pjsua_media_cfg);
答案 0 :(得分:0)
**> Please check this registration scenarios**
pj_status_t sip_startup(app_config_t *app_config)
{
pj_status_t status;
long val;
char tmp[80];
pjsua_transport_id transport_id = -1;
const char *srv;
const char *ip_addr;
NSArray * array;
NSString *dns;
SiphonApplication *app = (SiphonApplication *)[SiphonApplication sharedApplication];
/* Create pjsua first! */
status = pjsua_create();
if (status != PJ_SUCCESS)
return status;
/* Create pool for application */
app_config->pool = pjsua_pool_create("pjsua", 1000, 1000);
/* Initialize default config */
pjsua_config_default(&(app_config->cfg));
pj_ansi_snprintf(tmp, 80, "Siphon PjSip v%s/%s", pj_get_version(), PJ_OS_NAME);
pj_strdup2_with_null(app_config->pool, &(app_config->cfg.user_agent), tmp);
pjsua_logging_config_default(&(app_config->log_cfg));
val = [[NSUserDefaults standardUserDefaults] integerForKey:
@"logLevel"];
#ifdef RELEASE_VERSION
app_config->log_cfg.msg_logging = PJ_FALSE;
app_config->log_cfg.console_level = 0;
app_config->log_cfg.level = 0;
#else
app_config->log_cfg.msg_logging = (val!=0 ? PJ_TRUE : PJ_FALSE);
app_config->log_cfg.console_level = val;
app_config->log_cfg.level = val;
if (val != 0)
{
#if defined(CYDIA) && (CYDIA == 1)
NSArray *filePaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *path = [NSString stringWithFormat:@"%@/Siphon", [filePaths objectAtIndex:0]];
#else
NSArray *filePaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *path = [filePaths objectAtIndex: 0];
#endif
//NSString *path = NSTemporaryDirectory();
path = [path stringByAppendingString: @"/log.txt"];
app_config->log_cfg.log_filename = pj_strdup3(app_config->pool,
[path UTF8String]);
}
#endif
pjsua_media_config_default(&(app_config->media_cfg));
// TODO select clock rate with enabled codec (8000 if nb codec only, or 16000 and more if wb codec)
//app_config->media_cfg.clock_rate = 8000;
//app_config->media_cfg.snd_clock_rate = 8000;
app_config->media_cfg.clock_rate = 16000;
app_config->media_cfg.snd_clock_rate = 16000;
//app_config->media_cfg.ec_options = 0;//0=default,1=speex, 2=suppressor
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"enableEC"])
app_config->media_cfg.ec_tail_len = 0;
// Enable/Disable VAD/silence detector
app_config->media_cfg.no_vad = [[NSUserDefaults standardUserDefaults]
boolForKey:@"disableVad"];
app_config->media_cfg.snd_auto_close_time = 0;
//app_config->media_cfg.quality = 2;
//app_config->media_cfg.channel_count = 2;
app_config->media_cfg.enable_ice = [[NSUserDefaults standardUserDefaults]
boolForKey:@"enableICE"];
pjsua_transport_config_default(&(app_config->udp_cfg));
val = [[NSUserDefaults standardUserDefaults] integerForKey: @"localPort"];
if (val < 0 || val > 65535)
{
PJ_LOG(1,(THIS_FILE,
"Error: local-port argument value (expecting 0-65535"));
[app displayParameterError:
@"Invalid value for Local Port (expecting 1-65535)."];
status = PJ_EINVAL;
goto error;
}
app_config->udp_cfg.port = val;
pjsua_transport_config_default(&(app_config->rtp_cfg));
app_config->rtp_cfg.port = [[NSUserDefaults standardUserDefaults]
integerForKey: @"rtpPort"];
if (app_config->rtp_cfg.port == 0)
{
enum { START_PORT=4000 };
unsigned range;
range = (65535-START_PORT-PJSUA_MAX_CALLS*4);
app_config->rtp_cfg.port = START_PORT +
((pj_rand() % range) & 0xFFFE);
}
if (app_config->rtp_cfg.port < 1 || app_config->rtp_cfg.port > 65535)
{
PJ_LOG(1,(THIS_FILE,
"Error: rtp-port argument value (expecting 1-65535)"));
[app displayParameterError:
@"Invalid value for RTP port (expecting 1-65535)."];
status = PJ_EINVAL;
goto error;
}
#if 1 // TEST pour le vpn
ip_addr = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"boundAddr"] UTF8String];
if (ip_addr && strlen(ip_addr))
{
pj_strdup2_with_null(app_config->pool,
&(app_config->udp_cfg.bound_addr),
ip_addr);
pj_strdup2_with_null(app_config->pool,
&(app_config->rtp_cfg.bound_addr),
ip_addr);
}
ip_addr = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"publicAddr"] UTF8String];
if (ip_addr && strlen(ip_addr))
{
pj_strdup2_with_null(app_config->pool,
&(app_config->udp_cfg.public_addr),
ip_addr);
pj_strdup2_with_null(app_config->pool,
&(app_config->rtp_cfg.public_addr),
ip_addr);
}
#endif
/* Initialize application callbacks */
app_config->cfg.cb.on_call_state = &on_call_state;
app_config->cfg.cb.on_call_media_state = &on_call_media_state;
app_config->cfg.cb.on_incoming_call = &on_incoming_call;
app_config->cfg.cb.on_reg_state = &on_reg_state;
#if defined(MWI) && MWI==1
app_config->cfg.cb.on_mwi_info = &on_mwi_info;
app_config->cfg.enable_unsolicited_mwi = PJ_TRUE;
#endif
srv = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"stunServer"] UTF8String];
if (srv && strlen(srv))
{
if (app_config->cfg.stun_srv_cnt==PJ_ARRAY_SIZE(app_config->cfg.stun_srv))
{
PJ_LOG(1,(THIS_FILE, "Error: too many STUN servers"));
return PJ_ETOOMANY;
}
pj_strdup2_with_null(app_config->pool,
&(app_config->cfg.stun_srv[app_config->cfg.stun_srv_cnt++]),
srv);
}
// app_config->cfg.outbound_proxy[0] = pj_str(outbound_proxy);
// app_config->cfg.outbound_proxy_cnt = 1;
dns = [[NSUserDefaults standardUserDefaults] stringForKey: @"dnsServer"];
array = [dns componentsSeparatedByString:@","];
NSEnumerator *enumerator = [array objectEnumerator];
NSString *anObject;
while (anObject = [enumerator nextObject])
{
NSMutableString *mutableStr = [anObject mutableCopy];
CFStringTrimWhitespace((CFMutableStringRef)mutableStr);
srv = [mutableStr UTF8String];
if (srv && strlen(srv))
{
if (app_config->cfg.nameserver_count==PJ_ARRAY_SIZE(app_config->cfg.nameserver))
{
PJ_LOG(1,(THIS_FILE, "Error: too many DNS servers"));
[mutableStr release];
break;
}
pj_strdup2_with_null(app_config->pool,
&(app_config->cfg.nameserver[app_config->cfg.nameserver_count++]),
srv);
}
[mutableStr release];
}
//[enumerator release];
//[array release];
/* Initialize pjsua */
status = pjsua_init(&app_config->cfg, &app_config->log_cfg,
&app_config->media_cfg);
if (status != PJ_SUCCESS)
goto error;
/* Initialize Ring and Ringback */
sip_ring_init(app_config);
/* Add UDP transport. */
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP,
&app_config->udp_cfg, &transport_id);
if (status != PJ_SUCCESS)
goto error;
/* Add RTP transports */
// status = pjsua_media_transports_create(&app_config->rtp_cfg);
// if (status != PJ_SUCCESS)
// goto error;
#if LOCAL_ACCOUNT
{
if (status == PJ_SUCCESS && transport_id != -1)
{
/* Add local account */
pjsua_acc_add_local(transport_id, PJ_TRUE, &aid);
}
}
#endif
/* */
sip_manage_codec();
/* Initialization is done, now start pjsua */
status = pjsua_start();
if (status != PJ_SUCCESS)
goto error;
return status;
error:
sip_cleanup(app_config);
return status;
}
/* */
pj_status_t sip_cleanup(app_config_t *app_config)
{
pj_status_t status;
/* Cleanup Ring and Ringback */
sip_ring_deinit(app_config);
if (app_config->pool)
{
pj_pool_release(app_config->pool);
app_config->pool = NULL;
}
/* Destroy pjsua */
status = pjsua_destroy();
pj_bzero(app_config, sizeof(app_config_t));
return status;
}
/* */
pj_status_t sip_connect(pj_pool_t *pool, pjsua_acc_id *acc_id)
{
pj_status_t status;
pjsua_acc_config acc_cfg;
const char *uname;
const char *authname;
const char *contactname;
const char *passwd;
const char *server;
SiphonApplication *app = (SiphonApplication *)[SiphonApplication sharedApplication];
// TODO Verify if wifi is connected, if not verify if user wants edge connection
uname = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"username"] UTF8String];
authname = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"authname"] UTF8String];
contactname = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"contact"] UTF8String];
passwd = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"password"] UTF8String];
server = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"server"] UTF8String];
pjsua_acc_config_default(&acc_cfg);
// ID
acc_cfg.id.ptr = (char*) pj_pool_alloc(/*app_config.*/pool, PJSIP_MAX_URL_SIZE);
if (contactname && strlen(contactname))
acc_cfg.id.slen = pj_ansi_snprintf(acc_cfg.id.ptr, PJSIP_MAX_URL_SIZE,
"\"%s\"<sip:%s@%s>", contactname, uname, server);
else
acc_cfg.id.slen = pj_ansi_snprintf(acc_cfg.id.ptr, PJSIP_MAX_URL_SIZE,
"sip:%s@%s", uname, server);
if ((status = pjsua_verify_sip_url(acc_cfg.id.ptr)) != 0)
{
PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%s' in local id argument",
acc_cfg.id));
[app displayParameterError: @"Invalid value for username or server."];
return status;
}
// Registrar
acc_cfg.reg_uri.ptr = (char*) pj_pool_alloc(/*app_config.*/pool,
PJSIP_MAX_URL_SIZE);
acc_cfg.reg_uri.slen = pj_ansi_snprintf(acc_cfg.reg_uri.ptr,
PJSIP_MAX_URL_SIZE, "sip:%s", server);
if ((status = pjsua_verify_sip_url(acc_cfg.reg_uri.ptr)) != 0)
{
PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%s' in registrar argument",
acc_cfg.reg_uri));
[app displayParameterError: @"Invalid value for server parameter."];
return status;
}
//acc_cfg.id = pj_str(id);
//acc_cfg.reg_uri = pj_str(registrar);
acc_cfg.cred_count = 1;
acc_cfg.cred_info[0].scheme = pj_str("Digest");
acc_cfg.cred_info[0].realm = pj_str("*");//pj_str(realm);
if (authname && strlen(authname))
acc_cfg.cred_info[0].username = pj_str((char *)authname);
else
acc_cfg.cred_info[0].username = pj_str((char *)uname);
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"enableMJ"])
acc_cfg.cred_info[0].data_type = PJSIP_CRED_DATA_DIGEST;
else
acc_cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
acc_cfg.cred_info[0].data = pj_str((char *)passwd);
acc_cfg.publish_enabled = PJ_TRUE;
#if defined(MWI) && MWI==1
acc_cfg.mwi_enabled = PJ_TRUE;
#endif
acc_cfg.allow_contact_rewrite = [[NSUserDefaults standardUserDefaults]
boolForKey:@"enableNat"];
// FIXME: gestion du message 423 dans pjsip
acc_cfg.reg_timeout = [[NSUserDefaults standardUserDefaults] integerForKey:
@"regTimeout"];
if (acc_cfg.reg_timeout < 1 || acc_cfg.reg_timeout > 3600)
{
PJ_LOG(1,(THIS_FILE,
"Error: invalid value for timeout (expecting 1-3600)"));
[app displayParameterError:
@"Invalid value for timeout (expecting 1-3600)."];
return PJ_EINVAL;
}
// Keep alive interval
acc_cfg.ka_interval = [[NSUserDefaults standardUserDefaults] integerForKey:
@"kaInterval"];
// proxies server
NSString *proxies = [[NSUserDefaults standardUserDefaults] stringForKey: @"proxyServer"];
NSArray *array = [proxies componentsSeparatedByString:@","];
NSEnumerator *enumerator = [array objectEnumerator];
NSString *anObject;
while (anObject = [enumerator nextObject])
{
NSMutableString *mutableStr = [anObject mutableCopy];
CFStringTrimWhitespace((CFMutableStringRef)mutableStr);
const char *proxy = [mutableStr UTF8String];
if (proxy && strlen(proxy))
{
if (acc_cfg.proxy_cnt==PJ_ARRAY_SIZE(acc_cfg.proxy))
{
PJ_LOG(1,(THIS_FILE, "Error: too many proxy servers"));
[mutableStr release];
break;
}
pj_str_t pj_proxy;
pj_proxy.slen = strlen(proxy) + 8;
pj_proxy.ptr = (char*) pj_pool_alloc(pool, pj_proxy.slen);
pj_proxy.slen = pj_ansi_snprintf(pj_proxy.ptr, pj_proxy.slen, "sip:%s;lr", proxy);
if ((status = pjsua_verify_sip_url(pj_proxy.ptr)) != 0)
{
PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%*.s' in proxy argument (%d)",
pj_proxy.slen, pj_proxy.ptr, status));
[mutableStr release];
[app displayParameterError: @"Invalid value for proxy parameter."];
continue;
}
acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_proxy;
}
[mutableStr release];
}
#if LOCAL_ACCOUNT
*acc_id = aid;
#else
status = pjsua_acc_add(&acc_cfg, PJ_TRUE, acc_id);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Error adding new account", status);
[app displayParameterError: @"Error adding new account."];
}
#endif
return status;
}
/* */
pj_status_t sip_disconnect(pjsua_acc_id *acc_id)
{
pj_status_t status = PJ_SUCCESS;
if (pjsua_acc_is_valid(*acc_id))
{
status = pjsua_acc_del(*acc_id);
if (status == PJ_SUCCESS)
*acc_id = PJSUA_INVALID_ID;
}
return status;
}
/* */
pj_status_t sip_dial_with_uri(pjsua_acc_id acc_id, const char *uri,
pjsua_call_id *call_id)
{
// FIXME: récupérer le domain à partir du compte (acc_id);
// TODO be careful app already mustn't be in communication!
// TODO if not SIP connected, use GSM ? NSURL with 'tel' protocol
pj_status_t status = PJ_SUCCESS;
pj_str_t pj_uri;
// pjsua_msg_data msg_data;
// pjsip_generic_string_hdr subject;
// pj_str_t hvalue, hname;
PJ_LOG(5,(THIS_FILE, "Calling URI \"%s\".", uri));
status = pjsua_verify_sip_url(uri);
if (status != PJ_SUCCESS)
{
PJ_LOG(1,(THIS_FILE, "Invalid URL \"%s\".", uri));
pjsua_perror(THIS_FILE, "Invalid URL", status);
return status;
}
pj_uri = pj_str((char *)uri);
//status = pjsua_set_null_snd_dev();
status = pjsua_snd_is_active();
// hname = pj_str("Subject");
// hvalue = pj_str("phone call");
//
// pjsua_msg_data_init(&msg_data);
// pjsip_generic_string_hdr_init2(&subject, &hname, &hvalue);
// pj_list_push_back(&msg_data.hdr_list, &subject);
//
// status = pjsua_call_make_call(acc_id, &pj_uri, 0, NULL, &msg_data, call_id);
status = pjsua_call_make_call(acc_id, &pj_uri, 0, NULL, NULL, call_id);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Error making call", status);
}
return status;
}
pj_status_t sip_dial(pjsua_acc_id acc_id, const char *number,
pjsua_call_id *call_id)
{
// FIXME: récupérer le domain à partir du compte (acc_id);f
// TODO be careful app already mustn't be in communication!
// TODO if not SIP connected, use GSM ? NSURL with 'tel' protocol
char uri[256];
const char *sip_domain;
sip_domain = [[[NSUserDefaults standardUserDefaults] stringForKey:
@"server"] UTF8String];
pj_ansi_snprintf(uri, 256, "sip:%s@%s", number, sip_domain);
return sip_dial_with_uri(acc_id, uri, call_id);
}
/* */
pj_status_t sip_answer(pjsua_call_id *call_id)
{
pj_status_t status;
status = pjsua_set_null_snd_dev();
status = pjsua_call_answer(*call_id, 200, NULL, NULL);
if (status != PJ_SUCCESS)
{
*call_id = PJSUA_INVALID_ID;
}
return status;
}
/* */
pj_status_t sip_hangup(pjsua_call_id *call_id)
{
pj_status_t status = PJ_SUCCESS;
//pjsua_call_hangup_all();
/* TODO Hangup current calls */
if (*call_id != PJSUA_INVALID_ID)
status = pjsua_call_hangup(*call_id, 0, NULL, NULL);
*call_id = PJSUA_INVALID_ID;
return status;
}
#if SETTINGS
/* */
pj_status_t sip_add_account(NSDictionary *account, pjsua_acc_id *acc_id)
{
pj_status_t status;
pjsua_acc_config acc_cfg;
const char *uname;
const char *passwd;
const char *server;
const char *proxy;
SiphonApplication *app = (SiphonApplication *)[SiphonApplication sharedApplication];
app_config_t *app_config = [app pjsipConfig];
// TODO Verify if wifi is connected, if not verify if user wants edge connection
uname = [[account objectForKey: @"username"] UTF8String];
passwd = [[account objectForKey: @"password"] UTF8String];
server = [[account objectForKey: @"server"] UTF8String];
proxy = [[account objectForKey: @"proxyServer"] UTF8String];
pjsua_acc_config_default(&acc_cfg);
// ID
acc_cfg.id.ptr = (char*) pj_pool_alloc(app_config->pool, PJSIP_MAX_URL_SIZE);
acc_cfg.id.slen = pj_ansi_snprintf(acc_cfg.id.ptr, PJSIP_MAX_URL_SIZE,
"sip:%s@%s", uname, server);
// FIXME : verify in settings view
if ((status = pjsua_verify_sip_url(acc_cfg.id.ptr)) != 0)
{
PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%s' in local id argument",
acc_cfg.id));
[app displayParameterError: @"Invalid value for username or server."];
return status;
}
// Registrar
acc_cfg.reg_uri.ptr = (char*) pj_pool_alloc(app_config->pool,
PJSIP_MAX_URL_SIZE);
acc_cfg.reg_uri.slen = pj_ansi_snprintf(acc_cfg.reg_uri.ptr,
PJSIP_MAX_URL_SIZE, "sip:%s", server);
// FIXME : verify in settings view
if ((status = pjsua_verify_sip_url(acc_cfg.reg_uri.ptr)) != 0)
{
PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%s' in registrar argument",
acc_cfg.reg_uri));
[app displayParameterError: @"Invalid value for server parameter."];
return status;
}
//acc_cfg.id = pj_str(id);
//acc_cfg.reg_uri = pj_str(registrar);
acc_cfg.cred_count = 1;
acc_cfg.cred_info[0].scheme = pj_str("Digest");
acc_cfg.cred_info[0].realm = pj_str("*");//pj_str(realm);
acc_cfg.cred_info[0].username = pj_str((char *)uname);
acc_cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
acc_cfg.cred_info[0].data = pj_str((char *)passwd);
acc_cfg.publish_enabled = PJ_TRUE;
acc_cfg.allow_contact_rewrite = [[account objectForKey:@"enableNat"] boolValue];
// FIXME: gestion du message 423 dans pjsip
acc_cfg.reg_timeout = [[account objectForKey: @"regTimeout"] intValue];
// FIXME : verify in settings view
if (acc_cfg.reg_timeout < 1 || acc_cfg.reg_timeout > 3600)
{
PJ_LOG(1,(THIS_FILE,
"Error: invalid value for timeout (expecting 1-3600)"));
[app displayParameterError:
@"Invalid value for timeout (expecting 1-3600)."];
return PJ_EINVAL;
}
pj_str_t pj_proxy = pj_str((char *)proxy);
if (pj_strlen(&pj_proxy) > 0)
{
acc_cfg.proxy[0].ptr = (char*) pj_pool_alloc(app_config->pool,
PJSIP_MAX_URL_SIZE);
acc_cfg.proxy[0].slen = pj_ansi_snprintf(acc_cfg.proxy[0].ptr,
PJSIP_MAX_URL_SIZE, "sip:%s;lr", proxy);
// FIXME verify in settings view
if ((status = pjsua_verify_sip_url(acc_cfg.proxy[0].ptr)) != 0)
{
PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%s' in proxy argument",
acc_cfg.reg_uri));
[app displayParameterError: @"Invalid value for proxy parameter."];
return status;
}
acc_cfg.proxy_cnt = 1;
}
status = pjsua_acc_add(&acc_cfg, PJ_TRUE, acc_id);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Error adding new account", status);
[app displayParameterError: @"Error adding new account."];
}
return status;
}
#endif