so i am writing a soft phone client with PJSUA using C. So first i tried out an example given from pjsip-homepage. Now i faced an error on registration to my asterisk-server, but i couldn't figure out why this happens. I can make successfully calls, but i can't receive any since it's not registered. I tried an python example for registration and this works fine.
Of course i have configured my asterisk on sip.con and extensions.conf that he is able to register this client, which shows by registering with python sample program.
So i appreciate your time for finding my mistake.
so here my c code:
#define PJ_IS_LITTLE_ENDIAN 1
#define PJ_IS_BIG_ENDIAN 0
#include <pjsua-lib/pjsua.h>
#include <pjlib.h>
#include <pjlib-util.h>
#include <pjnath.h>
#include <pjsip.h>
#include <pjsip_ua.h>
#include <pjsip_simple.h>
#include <pjmedia.h>
#include <pjmedia-codec.h>
#define THIS_FILE "App"
#define SIP_USER "demo-user2"
#define SIP_DOMAIN "192.168.2.59"
#define SIP_PASSWD "123456"
static void on_incoming_call( pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata );
static void on_call_state( pjsua_call_id call_id, pjsip_event *e );
static void on_call_media_state( pjsua_call_id call_id );
static void error_exit( const char *title, pj_status_t status );
int main( int argc, char *argv[] ) {
pjsua_acc_id acc_id;
pj_status_t status;
/* Create pjsua */
status = pjsua_create();
if ( status != PJ_SUCCESS ) {
error_exit( "Error in pjsua_create()", status );
}
/* If argument is specified, it's got to be a valid SIP URL */
if ( argc > 1 ) {
status = pjsua_verify_url( argv[1] );
if ( status != PJ_SUCCESS ) {
error_exit( "Invalid URL in argv", status );
}
}
/* Init pjsua */
pjsua_config cfg;
pjsua_logging_config log_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;
pjsua_logging_config_default( &log_cfg );
log_cfg.console_level = 4;
status = pjsua_init( &cfg, &log_cfg, NULL );
if ( status != PJ_SUCCESS ) {
error_exit( "Error in pjsua_init()", status );
}
/* Add UDP transport */
{
pjsua_transport_config cfg;
pjsua_transport_config_default( &cfg );
cfg.port = 5060;
status = pjsua_transport_create( PJSIP_TRANSPORT_UDP, &cfg, NULL );
if ( status != PJ_SUCCESS ) {
error_exit( "Error creating transport", status );
}
}
/* Start pjsua */
status = pjsua_start();
if ( status != PJ_SUCCESS ) {
error_exit( "Error starting pjsua", status );
}
/* Register to SIP server */
{
pjsua_acc_config cfg;
pjsua_acc_config_default( &cfg );
cfg.id = pj_str( "sip:" SIP_USER "@" SIP_DOMAIN );
cfg.reg_uri = pj_str("sip:" SIP_DOMAIN );
cfg.cred_count = 1;
cfg.cred_info[0].realm = pj_str( SIP_DOMAIN );
cfg.cred_info[0].scheme = pj_str( "*" );
cfg.cred_info[0].username = pj_str( SIP_USER );
cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
cfg.cred_info[0].data = pj_str( SIP_PASSWD );
status = pjsua_acc_add( &cfg, PJ_TRUE, &acc_id );
if ( status != PJ_SUCCESS ){
error_exit( "Error adding account", status );
}
}
/* if URL is specified, make call to the url */
if ( argc > 1 ) {
pj_str_t uri = pj_str( argv[1] );
status = pjsua_call_make_call( acc_id, &uri, 0, NULL, NULL, NULL );
if (status != PJ_SUCCESS) {
error_exit("Error making call", status);
}
}
/* Wait until user press "q" to quit. */
while ( 1 ) {
char option[10];
puts( "Press 'h' to hangup all calls, 'q' to quit" );
if ( fgets( option, sizeof(option), stdin ) == NULL ) {
puts( "EOF while reading stdin, will quit now.." );
break;
}
if ( option[0] == 'q' ) {
break;
}
if ( option[0] == 'h' ) {
pjsua_call_hangup_all();
}
}
/* Destroy pjsua */
pjsua_destroy();
return 0;
}
static void on_incoming_call( pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata ) {
pjsua_call_info ci;
PJ_UNUSED_ARG( acc_id );
PJ_UNUSED_ARG( rdata );
pjsua_call_get_info( call_id, &ci );
PJ_LOG( 3,( THIS_FILE, "Incoming call from %.*s!!", (int) ci.remote_info.slen, ci.remote_info.ptr ) );
/* Automatically answer incoming calls with 200/OK */
pjsua_call_answer( call_id, 200, NULL, NULL );
}
static void on_call_state( pjsua_call_id call_id, pjsip_event *e ) {
pjsua_call_info ci;
PJ_UNUSED_ARG( e );
pjsua_call_get_info( call_id, &ci );
PJ_LOG( 3,( THIS_FILE, "Call %d state=%.*s", call_id, (int) ci.state_text.slen, ci.state_text.ptr ) );
}
static void on_call_media_state( pjsua_call_id call_id ) {
pjsua_call_info ci;
pjsua_call_get_info( call_id, &ci );
if ( ci.media_status == PJSUA_CALL_MEDIA_ACTIVE ) {
pjsua_conf_connect( ci.conf_slot, 0 );
pjsua_conf_connect( 0, ci.conf_slot );
}
}
static void error_exit( const char *title, pj_status_t status ) {
pjsua_perror( THIS_FILE, title, status );
pjsua_destroy();
exit( 1 );
}
and here my output of my program:
19:11:53.627 os_core_unix.c !pjlib 2.4.5-svn for POSIX initialized
19:11:53.631 sip_endpoint.c .Creating endpoint instance...
19:11:53.632 pjlib .select() I/O Queue created (0x1ca0f30)
19:11:53.632 sip_endpoint.c .Module "mod-msg-print" registered
19:11:53.633 sip_transport. .Transport manager created.
19:11:53.633 pjsua_core.c .PJSUA state changed: NULL --> CREATED
19:11:53.633 sip_endpoint.c .Module "mod-pjsua-log" registered
19:11:53.633 sip_endpoint.c .Module "mod-tsx-layer" registered
19:11:53.633 sip_endpoint.c .Module "mod-stateful-util" registered
19:11:53.633 sip_endpoint.c .Module "mod-ua" registered
19:11:53.633 sip_endpoint.c .Module "mod-100rel" registered
19:11:53.634 sip_endpoint.c .Module "mod-pjsua" registered
19:11:53.634 sip_endpoint.c .Module "mod-invite" registered
19:11:53.803 alsa_dev.c ..ALSA driver found 11 devices
19:11:53.804 alsa_dev.c ..ALSA initialized
19:11:53.805 pjlib ..select() I/O Queue created (0x1ccb8ac)
19:11:53.837 sip_endpoint.c .Module "mod-evsub" registered
19:11:53.838 sip_endpoint.c .Module "mod-presence" registered
19:11:53.838 sip_endpoint.c .Module "mod-mwi" registered
19:11:53.839 sip_endpoint.c .Module "mod-refer" registered
19:11:53.839 sip_endpoint.c .Module "mod-pjsua-pres" registered
19:11:53.839 sip_endpoint.c .Module "mod-pjsua-im" registered
19:11:53.840 sip_endpoint.c .Module "mod-pjsua-options" registered
19:11:53.840 pjsua_core.c .1 SIP worker threads created
19:11:53.841 pjsua_core.c .pjsua version 2.4.5-svn for Linux-4.1.7/armv7l/glibc-2.13 initialized
19:11:53.841 pjsua_core.c .PJSUA state changed: CREATED --> INIT
19:11:53.842 pjsua_core.c SIP UDP socket reachable at 192.168.2.83:5060
19:11:53.843 udp0x1cde4c8 SIP UDP transport started, published address is 192.168.2.83:5060
19:11:53.843 pjsua_core.c PJSUA state changed: INIT --> STARTING
19:11:53.843 sip_endpoint.c .Module "mod-unsolicited-mwi" registered
19:11:53.844 pjsua_core.c .PJSUA state changed: STARTING --> RUNNING
19:11:53.844 pjsua_acc.c Adding account: id=sip:[email protected]
19:11:53.845 pjsua_acc.c .Account sip:[email protected] added with id 0
19:11:53.845 pjsua_acc.c .Acc 0: setting registration..
19:11:53.846 pjsua_core.c ...TX 499 bytes Request msg REGISTER/cseq=2433 (tdta0x1ce2858) to UDP 192.168.2.59:5060:
REGISTER sip:192.168.2.59 SIP/2.0
Via: SIP/2.0/UDP 192.168.2.83:5060;rport;branch=z9hG4bKPjkPDfnXzyPfl.tr1YUGuqWnb0xXPaMNGc
Max-Forwards: 70
From: <sip:[email protected]>;tag=z51e618QFYLeBsmdY9nVhzIvmajoODP-
To: <sip:[email protected]>
Call-ID: VViAieGUFSZ6qg9pOOuU2xaarZkBACiy
CSeq: 2433 REGISTER
Contact: <sip:[email protected]:5060;ob>
Expires: 300
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length: 0
--end msg--
19:11:53.847 pjsua_acc.c ..Acc 0: Registration sent
Press 'h' to hangup all calls, 'q' to quit
19:11:53.851 pjsua_core.c .RX 578 bytes Response msg 401/REGISTER/cseq=2433 (rdata0x1cdfafc) from UDP 192.168.2.59:5060:
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.2.83:5060;branch=z9hG4bKPjkPDfnXzyPfl.tr1YUGuqWnb0xXPaMNGc;received=192.168.2.83;rport=5060
From: <sip:[email protected]>;tag=z51e618QFYLeBsmdY9nVhzIvmajoODP-
To: <sip:[email protected]>;tag=as19db99ad
Call-ID: VViAieGUFSZ6qg9pOOuU2xaarZkBACiy
CSeq: 2433 REGISTER
Server: Asterisk PBX 13.6.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
WWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="5b64ff92"
Content-Length: 0
--end msg--
19:11:53.851 sip_auth_clien ...Unable to set auth for tdta0x1ce2858: can not find credential for asterisk/Digest
19:11:53.851 pjsua_acc.c ....SIP registration error: No suitable credential (PJSIP_ENOCREDENTIAL) [status=171101]