pjusa iOS 出现错误 (PJSIP_ENOCREDENTIAL) [status=171101]
pjusa with iOS getting error (PJSIP_ENOCREDENTIAL) [status=171101]
我已经将 pjsip 构建 link 到 iOS 项目中并尝试连接服务器,但即使在初始连接后它也会给出身份验证错误。
Via: SIP/2.0/UDP 10.43.63.254:5060;rport;branch=z9hG4bKPjyz5KLZ5cAoAaP.96GU5qmAQrGzODseG1
Max-Forwards: 70
From: <sip:1002@10.26.114.254>;tag=ChTUlN6dHJvWFN3YicTHmHefICLRGRdX
To: <sip:1002@10.26.114.254>
Call-ID: fWdvvDT-ublTnJ5dUQ0lNd2HHyS4qbKV
CSeq: 54957 REGISTER
Contact: <sip:1002@10.43.63.254:5060;ob>
Expires: 300
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length: 0
--end msg--
18:33:35.333 pjsua_acc.c ..Acc 0: Registration sent
18:33:35.348 pjsua_core.c .RX 649 bytes Response msg 401/REGISTER/cseq=54957 (rdata0x150fe814) from UDP 10.26.114.254:5060:
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.43.63.254:5060;rport=5060;branch=z9hG4bKPjyz5KLZ5cAoAaP.96GU5qmAQrGzODseG1
From: <sip:1002@10.26.114.254>;tag=ChTUlN6dHJvWFN3YicTHmHefICLRGRdX
To: <sip:1002@10.26.114.254>;tag=ZBZyaF3DN6Qvm
Call-ID: fWdvvDT-ublTnJ5dUQ0lNd2HHyS4qbKV
CSeq: 54957 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.4.14+git~20141119T221113Z~ca1d990cfc~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: timer, path, replaces
WWW-Authenticate: Digest realm="10.26.114.254", nonce="2e1d2722-d226-11e4-b20b-df8fe843b705", algorithm=MD5, qop="auth"
Content-Length: 0
--end msg--
18:33:35.348 sip_auth_clien ...Unable to set auth for tdta0x150d7000: can not find credential for 10.26.114.254/Digest
18:33:35.348 pjsua_acc.c ....SIP registration error: No suitable credential (PJSIP_ENOCREDENTIAL) [status=171101]
我已经阅读了很多地方但没有找到任何解决方案,这是我连接服务器的功能..
startPjsip("1002", "10.26.114.254");
和c函数
int startPjsip(char *sipUser, char* sipDomain)
{
pj_status_t status;
// Create pjsua first
status = pjsua_create();
if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status);
// Init pjsua
{
// Init the config structure
pjsua_config cfg;
pjsua_config_default (&cfg);
cfg.cb.on_incoming_call = &on_incoming_call;
cfg.cb.on_call_media_state = &on_call_media_state;
cfg.cb.on_call_state = &on_call_state;
// Init the logging config structure
pjsua_logging_config log_cfg;
pjsua_logging_config_default(&log_cfg);
log_cfg.console_level = 4;
// Init the pjsua
status = pjsua_init(&cfg, &log_cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
}
// Add UDP transport.
{
// Init transport config structure
pjsua_transport_config cfg;
pjsua_transport_config_default(&cfg);
cfg.port = 5060;
// Add TCP transport.
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
}
// Add TCP transport.
{
// Init transport config structure
pjsua_transport_config cfg;
pjsua_transport_config_default(&cfg);
cfg.port = 5060;
// Add TCP transport.
status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, &cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
}
// Initialization is done, now start pjsua
status = pjsua_start();
if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
// Register the account on local sip server
{
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
char sipId[MAX_SIP_ID_LENGTH];
sprintf(sipId, "sip:%s@%s", sipUser, sipDomain);
cfg.id = pj_str(sipId);
char regUri[MAX_SIP_REG_URI_LENGTH];
sprintf(regUri, "sip:%s", sipDomain);
cfg.reg_uri = pj_str(regUri);
cfg.cred_info[0].realm = pj_str((char *)"*");
cfg.cred_info[0].scheme = pj_str((char *)"digest");
cfg.cred_info[0].username = pj_str((char *)"1002");
cfg.cred_info[0].data_type = PJSIP_CRED_DATA_EXT_AKA;
cfg.cred_info[0].data = pj_str((char *)"1234");
status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
if (status != PJ_SUCCESS) error_exit("Error adding account", status);
}
return 0;
}
这是 pjusa 中的配置结构
/**
* This structure describes credential information.
* A credential information is a static, persistent information that identifies
* username and password required to authorize to a specific realm.
*
* Note that since PJSIP 0.7.0.1, it is possible to make a credential that is
* valid for any realms, by setting the realm to star/wildcard character,
* i.e. realm = pj_str("*");.
*/
struct pjsip_cred_info
{
pj_str_t realm; /**< Realm. Use "*" to make a credential that
can be used to authenticate against any
challenges. */
pj_str_t scheme; /**< Scheme (e.g. "digest"). */
pj_str_t username; /**< User name. */
int data_type; /**< Type of data (0 for plaintext passwd). */
pj_str_t data; /**< The data, which can be a plaintext
password or a hashed digest. */
/** Extended data */
union {
/** Digest AKA credential information. Note that when AKA credential
* is being used, the \a data field of this #pjsip_cred_info is
* not used, but it still must be initialized to an empty string.
* Please see \ref PJSIP_AUTH_AKA_API for more information.
*/
struct {
pj_str_t k; /**< Permanent subscriber key. */
pj_str_t op; /**< Operator variant key. */
pj_str_t amf; /**< Authentication Management Field */
pjsip_cred_cb cb; /**< Callback to create AKA digest. */
} aka;
} ext;
};
您正在填充凭据数组,但没有告诉 pjsip 它应该使用多少条目。在配置中设置凭据计数(在上述情况下:为 1):
/**
* Number of credentials in the credential array.
*/
unsigned cred_count;
我已经将 pjsip 构建 link 到 iOS 项目中并尝试连接服务器,但即使在初始连接后它也会给出身份验证错误。
Via: SIP/2.0/UDP 10.43.63.254:5060;rport;branch=z9hG4bKPjyz5KLZ5cAoAaP.96GU5qmAQrGzODseG1
Max-Forwards: 70
From: <sip:1002@10.26.114.254>;tag=ChTUlN6dHJvWFN3YicTHmHefICLRGRdX
To: <sip:1002@10.26.114.254>
Call-ID: fWdvvDT-ublTnJ5dUQ0lNd2HHyS4qbKV
CSeq: 54957 REGISTER
Contact: <sip:1002@10.43.63.254:5060;ob>
Expires: 300
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length: 0
--end msg--
18:33:35.333 pjsua_acc.c ..Acc 0: Registration sent
18:33:35.348 pjsua_core.c .RX 649 bytes Response msg 401/REGISTER/cseq=54957 (rdata0x150fe814) from UDP 10.26.114.254:5060:
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.43.63.254:5060;rport=5060;branch=z9hG4bKPjyz5KLZ5cAoAaP.96GU5qmAQrGzODseG1
From: <sip:1002@10.26.114.254>;tag=ChTUlN6dHJvWFN3YicTHmHefICLRGRdX
To: <sip:1002@10.26.114.254>;tag=ZBZyaF3DN6Qvm
Call-ID: fWdvvDT-ublTnJ5dUQ0lNd2HHyS4qbKV
CSeq: 54957 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.4.14+git~20141119T221113Z~ca1d990cfc~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: timer, path, replaces
WWW-Authenticate: Digest realm="10.26.114.254", nonce="2e1d2722-d226-11e4-b20b-df8fe843b705", algorithm=MD5, qop="auth"
Content-Length: 0
--end msg--
18:33:35.348 sip_auth_clien ...Unable to set auth for tdta0x150d7000: can not find credential for 10.26.114.254/Digest
18:33:35.348 pjsua_acc.c ....SIP registration error: No suitable credential (PJSIP_ENOCREDENTIAL) [status=171101]
我已经阅读了很多地方但没有找到任何解决方案,这是我连接服务器的功能..
startPjsip("1002", "10.26.114.254");
和c函数
int startPjsip(char *sipUser, char* sipDomain)
{
pj_status_t status;
// Create pjsua first
status = pjsua_create();
if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status);
// Init pjsua
{
// Init the config structure
pjsua_config cfg;
pjsua_config_default (&cfg);
cfg.cb.on_incoming_call = &on_incoming_call;
cfg.cb.on_call_media_state = &on_call_media_state;
cfg.cb.on_call_state = &on_call_state;
// Init the logging config structure
pjsua_logging_config log_cfg;
pjsua_logging_config_default(&log_cfg);
log_cfg.console_level = 4;
// Init the pjsua
status = pjsua_init(&cfg, &log_cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
}
// Add UDP transport.
{
// Init transport config structure
pjsua_transport_config cfg;
pjsua_transport_config_default(&cfg);
cfg.port = 5060;
// Add TCP transport.
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
}
// Add TCP transport.
{
// Init transport config structure
pjsua_transport_config cfg;
pjsua_transport_config_default(&cfg);
cfg.port = 5060;
// Add TCP transport.
status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, &cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
}
// Initialization is done, now start pjsua
status = pjsua_start();
if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
// Register the account on local sip server
{
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
char sipId[MAX_SIP_ID_LENGTH];
sprintf(sipId, "sip:%s@%s", sipUser, sipDomain);
cfg.id = pj_str(sipId);
char regUri[MAX_SIP_REG_URI_LENGTH];
sprintf(regUri, "sip:%s", sipDomain);
cfg.reg_uri = pj_str(regUri);
cfg.cred_info[0].realm = pj_str((char *)"*");
cfg.cred_info[0].scheme = pj_str((char *)"digest");
cfg.cred_info[0].username = pj_str((char *)"1002");
cfg.cred_info[0].data_type = PJSIP_CRED_DATA_EXT_AKA;
cfg.cred_info[0].data = pj_str((char *)"1234");
status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
if (status != PJ_SUCCESS) error_exit("Error adding account", status);
}
return 0;
}
这是 pjusa 中的配置结构
/**
* This structure describes credential information.
* A credential information is a static, persistent information that identifies
* username and password required to authorize to a specific realm.
*
* Note that since PJSIP 0.7.0.1, it is possible to make a credential that is
* valid for any realms, by setting the realm to star/wildcard character,
* i.e. realm = pj_str("*");.
*/
struct pjsip_cred_info
{
pj_str_t realm; /**< Realm. Use "*" to make a credential that
can be used to authenticate against any
challenges. */
pj_str_t scheme; /**< Scheme (e.g. "digest"). */
pj_str_t username; /**< User name. */
int data_type; /**< Type of data (0 for plaintext passwd). */
pj_str_t data; /**< The data, which can be a plaintext
password or a hashed digest. */
/** Extended data */
union {
/** Digest AKA credential information. Note that when AKA credential
* is being used, the \a data field of this #pjsip_cred_info is
* not used, but it still must be initialized to an empty string.
* Please see \ref PJSIP_AUTH_AKA_API for more information.
*/
struct {
pj_str_t k; /**< Permanent subscriber key. */
pj_str_t op; /**< Operator variant key. */
pj_str_t amf; /**< Authentication Management Field */
pjsip_cred_cb cb; /**< Callback to create AKA digest. */
} aka;
} ext;
};
您正在填充凭据数组,但没有告诉 pjsip 它应该使用多少条目。在配置中设置凭据计数(在上述情况下:为 1):
/**
* Number of credentials in the credential array.
*/
unsigned cred_count;