|
From: | Mark Hessling |
Subject: | [Linphone-developers] Newbie having problems with basic outgoing call on Raspberry Pi |
Date: | Mon, 30 May 2016 11:55:25 +1000 |
User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 |
Hi, I am new to liblinphone and am trying to build a simple C program to make a call. The purpose of the program is to simply make the call and identify if the callee has responded to the call; not to actually conduct a conversation. I am wanting to use this program as a simple notification mechanism. I am running this on a Raspberry Pi 2+ on the latest Raspbian distribution. Version of liblinphone is 3.6.1. The SIP server is a Fritz!Box 7390. I have used both linphonec and the GUI version of linphone to successfully call the extension number. I have combined the "Basic Call" and "Basic Registration" sample programs (with a few API function name changes to get it to compile). The problem I am having is that the call to linphone_core_iterate() that deals with the call in progress never returns after the call_state_change callback receives a LinphoneCallOutgoingEarlyMedia state. The registration with the SIP server succeeds, the call is made and the extension rings, but that is where the program appears to hang. I also have to kill -9 the process as ^C does not interrupt linphone_core_iterate(). Any help appreciated. Thanks, Mark Invocation: ./phone sip:address@hidden password '**610' The output of the test case is: ------------------------------------------------------------------------------ ALSA lib conf.c:4705:(snd_config_expand) Unknown parameters 0 ALSA lib control.c:953:(snd_ctl_open_noupdate) Invalid CTL default:0 ortp-warning-Could not attach mixer to card: Invalid argument ortp-warning-/usr/share/sounds/linphone/rings/oldphone.wav does not exist New registration state LinphoneRegistrationProgress for user id [sip:address@hidden] at proxy [<sip:fritz.box>] New registration state LinphoneRegistrationOk for user id [sip:address@hidden] at proxy [<sip:fritz.box>] Call initiated ortp-warning-cannot set noise gate mode to [0] because no volume send Call progressing Call to **610 is in progress...Call State: LinphoneCallOutgoingProgress Call State(after): LinphoneCallOutgoingProgress Call State: LinphoneCallOutgoingProgress Call State(after): LinphoneCallOutgoingProgress Call State: LinphoneCallOutgoingProgress ortp-error-payload number 103 has no rtpmap and is unknown in AV Profile, ignored. ortp-warning-No matching stream for 1 Receiving some early media ortp-warning-cannot set noise gate mode to [0] because no volume send Killed ------------------------------------------------------------------------------ I have also run with -DDEBUG but don't understand the output to diagnose myself. The last bit of that output is: ------------------------------------------------------------------------------ ortp-message-CALL_RINGING ortp-message-Contact address updated to <sip:address@hidden> ortp-message-Found payload PCMU/8000 fmtp= ortp-message-Found payload PCMA/8000 fmtp= ortp-message-Found payload telephone-event/8000 fmtp=0-15 ortp-error-payload number 103 has no rtpmap and is unknown in AV Profile, ignored. ortp-message-Doing SDP offer/answer process of type outgoing ortp-message-Processing for stream 0 ortp-message-Adding opus/48000 for compatibility, just in case. ortp-message-Adding speex/16000 for compatibility, just in case. ortp-message-Adding speex/8000 for compatibility, just in case. ortp-message-Processing for stream 1 ortp-warning-No matching stream for 1 ortp-message-Call 0x277998: moving from state LinphoneCallOutgoingProgress to LinphoneCallOutgoingEarlyMedia Receiving some early media ortp-message-Doing early media... ortp-message-ms_filter_unlink: MSRtpRecv:0x279a00,0-->MSVoidSink:0x279aa0,0 ortp-message-Audio MSTicker thread exiting ortp-message-=========================================================== ortp-message- FILTER USAGE STATISTICS ortp-message-Name Count Time/tick (ms) CPU Usage ortp-message------------------------------------------------------------ ortp-message-MSRtpRecv 12 0.0329845 99.9998 ortp-message-MSVoidSink 0 0 0 ortp-message-MSSpeexEC 0 0 0 ortp-message-MSRtpSend 0 0 0 ortp-message-=========================================================== ortp-message-Setting DSCP to 46 for audio stream. ortp-warning-cannot set noise gate mode to [0] because no volume send ortp-message-Setting DSCP to 46 for video stream. ortp-message-Local interface to reach 87.98.157.38 is 192.168.178.37. ortp-message-Audio bandwidth for this call is 80 ortp-message-cb_nict_kill_transaction (id=1) ortp-message-cb_nict_kill_transaction (id=2) ortp-message-eXosip: Reseting timer to 10s before waking up! ^Cortp-message-free transaction resource 1 1246879295 ortp-message-free nict resource ortp-message-eXosip: Keep Alive sent on UDP! ortp-message-eXosip: Reseting timer to 10s before waking up! ortp-message-eXosip: Keep Alive sent on UDP! Killed ------------------------------------------------------------------------------ Source of phone.c: ------------------------------------------------------------------------------ /* linphone Copyright (C) 2010 Belledonne Communications SARL This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef IN_LINPHONE #include "linphonecore.h" #else #include "linphone/linphonecore.h" #endif #include <signal.h> static bool_t notregistered=TRUE; static bool_t running=TRUE; static void stop(int signum){ running=FALSE; } static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){ printf("New registration state %s for user id [%s] at proxy [%s]\n" ,linphone_registration_state_to_string(cstate) ,linphone_proxy_config_get_identity(cfg) ,linphone_proxy_config_get_addr(cfg)); switch (cstate ){ case LinphoneRegistrationOk: notregistered=FALSE; break; default: break; } } /* * Call state notification callback */ static void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){ switch(cstate){ case LinphoneCallOutgoingRinging: printf("It is now ringing remotely !\n"); break; case LinphoneCallOutgoingInit: printf("Call initiated\n"); break; case LinphoneCallOutgoingProgress: printf("Call progressing\n"); break; case LinphoneCallOutgoingEarlyMedia: printf("Receiving some early media\n"); running = FALSE; break; case LinphoneCallConnected: printf("We are connected !\n"); running = FALSE; break; case LinphoneCallStreamsRunning: printf("Media streams established !\n"); break; case LinphoneCallEnd: printf("Call ended (%s).\n", linphone_reason_to_string(linphone_call_get_reason(call))); running = FALSE; break; case LinphoneCallError: printf("Call failure !"); running = FALSE; break; default: printf("Unhandled notification %i\n",cstate); running = FALSE; break; } } int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneProxyConfig* proxy_cfg; LinphoneAddress *from; LinphoneAuthInfo *info; LinphoneCore *lc; LinphoneCall *call=NULL; const char *dest=NULL; char* identity=NULL; char* password=NULL; const char* server_addr; /* takes sip uri identity from the command line arguments */ if (argc>1){ identity=argv[1]; } /* takes password from the command line arguments */ if (argc>2){ password=argv[2]; } /* takes destination from the command line arguments */ if (argc>3){ dest=argv[3]; } signal(SIGINT,stop); #ifdef DEBUG linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ #endif /* Fill the LinphoneCoreVTable with application callbacks. All are optional. Here we only use the registration_state_changed callbacks in order to get notifications about the progress of the registration. */ vtable.registration_state_changed=registration_state_changed; vtable.call_state_changed=call_state_changed; /* Instanciate a LinphoneCore object given the LinphoneCoreVTable */ lc=linphone_core_new(&vtable,NULL,NULL,NULL); /*create proxy config*/ proxy_cfg = linphone_proxy_config_new(); /*parse identity*/ from = linphone_address_new(identity); if (from==NULL){ printf("%s not a valid sip uri, must be like sip:address@hidden \n",identity); goto end; } if (password!=NULL){ info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL); /*create authentication structure from identity*/ linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/ } // configure proxy entries linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/ server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/ linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/ linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/ linphone_address_destroy(from); /*release resource*/ linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/ linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/ /* main loop for receiving notifications and doing background linphonecore work: */ while(notregistered){ linphone_core_iterate(lc); /* first iterate initiates registration */ ms_usleep(50000); } call=linphone_core_invite(lc,dest); if (call==NULL){ printf("Could not place call to %s\n",dest); goto end; } else printf("Call to %s is in progress...",dest); linphone_call_ref(call); /* main loop for receiving notifications and doing background linphonecore work: */ while(running){ printf( "Call State: %s\n", linphone_call_state_to_string( linphone_call_get_state(call)) ); linphone_core_iterate(lc); printf( "Call State(after): %s\n", linphone_call_state_to_string( linphone_call_get_state(call)) ); ms_usleep(50000); } if (call && linphone_call_get_state(call)!=LinphoneCallEnd){ /* terminate the call */ printf("Terminating the call...\n"); linphone_core_terminate_call(lc,call); } /*at this stage we don't need the call object */ linphone_call_unref(call); printf("%s %d: Does not reach here!\n",__FILE__,__LINE__); linphone_core_get_default_proxy(lc,&proxy_cfg); /* get default proxy config*/ linphone_proxy_config_edit(proxy_cfg); /*start editing proxy configuration*/ linphone_proxy_config_enable_register(proxy_cfg,FALSE); /*de-activate registration for this proxy config*/ linphone_proxy_config_done(proxy_cfg); /*initiate REGISTER with expire = 0*/ while(linphone_proxy_config_get_state(proxy_cfg) != LinphoneRegistrationCleared){ linphone_core_iterate(lc); /*to make sure we receive call backs before shutting down*/ ms_usleep(50000); } end: printf("Shutting down...\n"); linphone_core_destroy(lc); printf("Exited\n"); return 0; } ------------------------------------------------------------------------------ -- ------------------------------------------------------------------------ * Mark Hessling, address@hidden http://www.rexx.org/ * Author of THE, a Free XEDIT/KEDIT editor and, Rexx/SQL, Rexx/CURL, etc. * Maintainer of Regina Rexx interpreter * Use Rexx? join the Rexx Language Association: http://www.rexxla.org/ ------------------------------------------------------------------------ |
[Prev in Thread] | Current Thread | [Next in Thread] |