static int lpc_cmd_answer(LinphoneCore *, char *);
static int lpc_cmd_autoanswer(LinphoneCore *, char *);
static int lpc_cmd_terminate(LinphoneCore *, char *);
+static int lpc_cmd_redirect(LinphoneCore *, char *);
static int lpc_cmd_call_logs(LinphoneCore *, char *);
static int lpc_cmd_ipv6(LinphoneCore *, char *);
static int lpc_cmd_transfer(LinphoneCore *, char *);
static int lpc_cmd_duration(LinphoneCore *lc, char *args);
static int lpc_cmd_status(LinphoneCore *lc, char *args);
static int lpc_cmd_ports(LinphoneCore *lc, char *args);
+static int lpc_cmd_param(LinphoneCore *lc, char *args);
static int lpc_cmd_speak(LinphoneCore *lc, char *args);
static int lpc_cmd_acodec(LinphoneCore *lc, char *args);
static int lpc_cmd_vcodec(LinphoneCore *lc, char *args);
static int lpc_cmd_resume(LinphoneCore *lc, char *args);
static int lpc_cmd_mute_mic(LinphoneCore *lc, char *args);
static int lpc_cmd_unmute_mic(LinphoneCore *lc, char *args);
+static int lpc_cmd_playback_gain(LinphoneCore *lc, char *args);
static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args);
#ifdef VIDEO_ENABLED
static int lpc_cmd_camera(LinphoneCore *lc, char *args);
static int lpc_cmd_video_window(LinphoneCore *lc, char *args);
static int lpc_cmd_preview_window(LinphoneCore *lc, char *args);
static int lpc_cmd_snapshot(LinphoneCore *lc, char *args);
+static int lpc_cmd_vfureq(LinphoneCore *lc, char *arg);
#endif
static int lpc_cmd_states(LinphoneCore *lc, char *args);
static int lpc_cmd_identify(LinphoneCore *lc, char *args);
static int lpc_cmd_ringback(LinphoneCore *lc, char *args);
+static int lpc_cmd_conference(LinphoneCore *lc, char *args);
+static int lpc_cmd_zrtp_verified(LinphoneCore *lc, char *args);
+static int lpc_cmd_zrtp_unverified(LinphoneCore *lc, char *args);
/* Command handler helpers */
static void linphonec_proxy_add(LinphoneCore *lc);
static void linphonec_codec_list(int type, LinphoneCore *lc);
static void linphonec_codec_enable(int type, LinphoneCore *lc, int index);
static void linphonec_codec_disable(int type, LinphoneCore *lc, int index);
-
-
+static void lpc_display_call_states(LinphoneCore *lc);
/* Command table management */
static LPC_COMMAND *lpc_find_command(const char *name);
"'transfer <call id> <sip-uri>': transfers the call with 'id' to the destination sip-uri\n"
"'transfer <call id1> --to-call <call id2>': transfers the call with 'id1' to the destination of call 'id2' (attended transfer)\n"
},
+ { "conference", lpc_cmd_conference, "Create and manage an audio conference.",
+ "'conference add <call id> : join the call with id 'call id' into the audio conference."
+ "'conference rm <call id> : remove the call with id 'call id' from the audio conference."
+ },
{ "mute", lpc_cmd_mute_mic,
"Mute microphone and suspend voice transmission."},
#ifdef VIDEO_ENABLED
#endif
{ "unmute", lpc_cmd_unmute_mic,
"Unmute microphone and resume voice transmission."},
+ { "playbackgain", lpc_cmd_playback_gain,
+ "Adjust playback gain."},
{ "duration", lpc_cmd_duration, "Print duration in seconds of the last call.", NULL },
{ "autoanswer", lpc_cmd_autoanswer, "Show/set auto-answer mode",
"'autoanswer' \t: show current autoanswer mode\n"
"'autoanswer enable'\t: enable autoanswer mode\n"
- "'autoanswer disable'\t: disable autoanswer mode \n"},
+ "'autoanswer disable'\t: disable autoanswer mode��\n"},
{ "proxy", lpc_cmd_proxy, "Manage proxies",
"'proxy list' : list all proxy setups.\n"
"'proxy add' : add a new proxy setup.\n"
"'firewall none' : use direct connection.\n"
"'firewall nat' : use nat address given with the 'nat' command.\n"
"'firewall stun' : use stun server given with the 'stun' command.\n"
+ "'firewall ice' : use ice.\n"
+ "'firewall upnp' : use uPnP IGD.\n"
},
{ "call-logs", lpc_cmd_call_logs, "Calls history", NULL },
{ "friend", lpc_cmd_friend, "Manage friends",
{ "snapshot", lpc_cmd_snapshot, "Take a snapshot of currently received video stream",
"'snapshot <file path>': take a snapshot and records it in jpeg format into the supplied path\n"
},
+ { "vfureq", lpc_cmd_vfureq, "Request the other side to send VFU for the current call"},
#endif
{ "states", lpc_cmd_states, "Show internal states of liblinphone, registrations and calls, according to linphonecore.h definitions",
"'states global': shows global state of liblinphone \n"
{ "ports", lpc_cmd_ports, "Network ports configuration",
"'ports' \t: prints current used ports.\n"
"'ports sip <port number>'\t: Sets the sip port.\n" },
+ { "param", lpc_cmd_param, "parameter set or read as normally given in .linphonerc",
+ "'param <section> <parameter> [<value>]' \t: reads [sets] given parameter.\n"
+ "NOTES: - changes may become effective after (re)establishing a sip connection.\n"
+ " - upon exit, .linphonerc will reflect the updated state.\n" },
{ "speak", lpc_cmd_speak, "Speak a sentence using espeak TTS engine",
"This feature is available only in file mode. (see 'help soundcard')\n"
"'speak <voice name> <sentence>' : speak a text using the specified espeak voice.\n"
"'ringback <path of mono .wav file>'\t: Specifies a ringback tone to be played to remote end during incoming calls\n"
"'ringback disable'\t: Disable playing of ringback tone to callers\n"
},
+ { "redirect", lpc_cmd_redirect, "Redirect an incoming call",
+ "'redirect <redirect-uri>'\t: Redirect all pending incoming calls to the <redirect-uri>\n"
+ },
+ { "zrtp-set-verified", lpc_cmd_zrtp_verified,"Set ZRTP SAS verified.",
+ "'Set ZRTP SAS verified'\n"
+ },
+ { "zrtp-set-unverified", lpc_cmd_zrtp_unverified,"Set ZRTP SAS not verified.",
+ "'Set ZRTP SAS not verified'\n"
+ },
{ NULL,NULL,NULL,NULL}
};
}
linphonec_out("---------------------------\n");
- linphonec_out("Type 'help <command>' for more details or 'help advanced' to list additional commands.\n");
+ linphonec_out("Type 'help <command>' for more details or\n");
+ linphonec_out(" 'help advanced' to list additional commands.\n");
return 1;
}
static char callee_name[256]={0};
static char caller_name[256]={0};
-static const char *get_call_status(LinphoneCall *call){
- switch(linphone_call_get_state(call)){
- case LinphoneCallPaused:
- if (linphone_call_get_refer_to (call)!=NULL){
- return "Paused (transfered)";
- }else{
- return "Paused";
- }
- break;
- case LinphoneCallPausedByRemote:
- return "Paused by remote";
- break;
- case LinphoneCallIncomingReceived:
- return "Pending";
- break;
- case LinphoneCallOutgoingInit:
- case LinphoneCallOutgoingProgress:
- return "Dialing out";
- break;
- case LinphoneCallOutgoingEarlyMedia:
- case LinphoneCallOutgoingRinging:
- return "Remote ringing";
- break;
- default:
- if (linphone_call_has_transfer_pending(call)){
- return "Running (transfer pending)";
- }else
- return "Running";
- }
- return "";
-}
static int
lpc_cmd_call(LinphoneCore *lc, char *args)
const MSList *calls = linphone_core_get_calls(lc);
if(calls)
{
- const MSList *p_calls = calls;
- linphonec_out("ID\t\tDestination\t\t\t\tStatus\n---------------------------------------------------------------------\n");
- while(p_calls != NULL)
- {
- LinphoneCall *call=(LinphoneCall*)p_calls->data;
- char *tmp=linphone_call_get_remote_address_as_string(call);
- linphonec_out("%li\t%s\t\t\t%s\r\n",
- (long)linphone_call_get_user_pointer (call),
- tmp,
- get_call_status(call));
- p_calls = p_calls->next;
- ms_free(tmp);
- }
+ lpc_display_call_states(lc);
}else
{
linphonec_out("No active call.\n");
char arg1[256]={0};
char arg2[266]={0};
long id2=0;
- int n=sscanf(args,"%s %s %li",arg1,arg2,&id2);
+ int n=sscanf(args,"%255s %265s %li",arg1,arg2,&id2);
if (n==1 || isalpha(*arg1)){
call=linphone_core_get_current_call(lc);
if (call==NULL && ms_list_size(linphone_core_get_calls(lc))==1){
}
+static int
+lpc_cmd_redirect(LinphoneCore *lc, char *args){
+ const MSList *elem;
+ int didit=0;
+ if (!args) return 0;
+ if ((elem=linphone_core_get_calls(lc))==NULL){
+ linphonec_out("No active calls.\n");
+ return 1;
+ }
+ while(elem!=NULL){
+ LinphoneCall *call=(LinphoneCall*)elem->data;
+ if (linphone_call_get_state(call)==LinphoneCallIncomingReceived){
+ linphone_core_redirect_call(lc,call,args);
+ didit=1;
+ /*as the redirection closes the call, we need to re-check the call list that is invalidated.*/
+ elem=linphone_core_get_calls(lc);
+ }else elem=elem->next;
+ }
+ if (didit==0){
+ linphonec_out("There is no pending incoming call to redirect.");
+ }
+ return 1;
+}
+
static int
lpc_cmd_answer(LinphoneCore *lc, char *args){
if (!args)
{
linphone_core_set_firewall_policy(lc,LinphonePolicyNoFirewall);
}
+ else if (strcmp(args,"upnp")==0)
+ {
+ linphone_core_set_firewall_policy(lc,LinphonePolicyUseUpnp);
+ }
+ else if (strcmp(args,"ice")==0)
+ {
+ setting = linphone_core_get_stun_server(lc);
+ if ( ! setting )
+ {
+ linphonec_out("No stun server address is defined, use 'stun <address>' first\n");
+ return 1;
+ }
+ linphone_core_set_firewall_policy(lc,LinphonePolicyUseIce);
+ }
else if (strcmp(args,"stun")==0)
{
setting = linphone_core_get_stun_server(lc);
case LinphonePolicyUseNatAddress:
linphonec_out("Using supplied nat address %s.\n", setting ? setting : linphone_core_get_nat_address(lc));
break;
+ case LinphonePolicyUseIce:
+ linphonec_out("Using ice with stun server %s to discover firewall address\n", setting ? setting : linphone_core_get_stun_server(lc));
+ break;
+ case LinphonePolicyUseUpnp:
+ linphonec_out("Using uPnP IGD protocol\n");
+ break;
}
return 1;
}
}
+static int lpc_cmd_conference(LinphoneCore *lc, char *args){
+ long id;
+ char subcommand[32]={0};
+ int n;
+ if (args==NULL) return 0;
+ n=sscanf(args, "%31s %li", subcommand,&id);
+ if (n == 2){
+ LinphoneCall *call=linphonec_get_call(id);
+ if (call==NULL) return 1;
+ if (strcmp(subcommand,"add")==0){
+ linphone_core_add_to_conference(lc,call);
+ return 1;
+ }else if (strcmp(subcommand,"rm")==0){
+ linphone_core_remove_from_conference(lc,call);
+ return 1;
+ }else if (strcmp(subcommand,"enter")==0){
+ linphone_core_enter_conference(lc);
+ return 1;
+ }else if (strcmp(subcommand,"leave")==0){
+ linphone_core_leave_conference(lc);
+ return 1;
+ }
+ }
+ return 0;
+}
+
/***************************************************************************
*
* Commands helper functions
return 1;
}
passwd[0]=proxy[0]=identity[0]='\0';
- sscanf(args,"%s %s %s",identity,proxy,passwd);
+ sscanf(args,"%511s %511s %511s",identity,proxy,passwd);
if (proxy[0]=='\0' || identity[0]=='\0'){
linphonec_out("Missing parameters, see help register\n");
return 1;
for(;elem!=NULL;elem=elem->next){
if (elem->next==NULL){
cl=(LinphoneCallLog*)elem->data;
- linphonec_out("%i seconds\n",cl->duration);
+ linphonec_out("%i seconds\n",linphone_call_log_get_duration(cl));
}
}
return 1;
return 1;
}
+static int lpc_cmd_param(LinphoneCore *lc, char *args)
+{
+ char section[20], param[20], value[50];
+ const char *string;
+
+ if (args == NULL) {
+ return 0;
+ }
+ switch (sscanf(args,"%19s %19s %49s",section,param,value)) {
+ // case 1 might show all current settings under a section
+ case 2:
+ string = lp_config_get_string(linphone_core_get_config(lc), section, param, "(undef)");
+ linphonec_out("current value: %s\n", string);
+ break;
+ case 3:
+ if (lp_config_get_string(linphone_core_get_config(lc), section, param, NULL) != NULL) {
+ lp_config_set_string(linphone_core_get_config(lc), section, param, value);
+ // no indication of existence
+ linphonec_out("updated value: %s\n", value);
+ } else {
+ linphonec_out("only update of existing variables are allowed\n");
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
static int lpc_cmd_speak(LinphoneCore *lc, char *args){
#ifndef WIN32
char voice[64];
if (!args) return 0;
memset(voice,0,sizeof(voice));
- sscanf(args,"%s63",voice);
+ sscanf(args,"%63s",voice);
sentence=args+strlen(voice);
wavfile=tempnam("/tmp/","linphonec-espeak-");
snprintf(cl,sizeof(cl),"espeak -v %s -s 100 -w %s --stdin",voice,wavfile);
return 1;
}
+static int lpc_cmd_playback_gain(LinphoneCore *lc, char *args)
+{
+ if (args){
+ linphone_core_set_playback_gain_db(lc, atof(args));
+ return 1;
+ }
+ return 0;
+}
+
static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args)
{
bool_t rtp_xmit_off=FALSE;
VideoParams *params=is_preview ? &lpc_preview_params : &lpc_video_params;
if (!args) return 0;
- err=sscanf(args,"%s %i %i",subcommand,&a,&b);
+ err=sscanf(args,"%63s %i %i",subcommand,&a,&b);
if (err>=1){
if (strcmp(subcommand,"pos")==0){
if (err<3) return 0;
const MSList *elem;
char *tmp;
linphonec_out("Call states\n"
- "Id | Destination | State\n"
- "---------------------------------------------------------------\n");
+ "Id | Destination | State | Flags |\n"
+ "------------------------------------------------------------------------\n");
elem=linphone_core_get_calls(lc);
if (elem==NULL){
linphonec_out("(empty)\n");
}else{
for(;elem!=NULL;elem=elem->next){
+ const char *flag;
call=(LinphoneCall*)elem->data;
+ bool_t in_conference=linphone_call_params_local_conference_mode(linphone_call_get_current_params(call));
tmp=linphone_call_get_remote_address_as_string (call);
- linphonec_out("%-2i | %-35s | %s\n",(int)(long)linphone_call_get_user_pointer(call),
- tmp,linphone_call_state_to_string(linphone_call_get_state(call)));
+ flag=in_conference ? "conferencing" : "";
+ flag=linphone_call_has_transfer_pending(call) ? "transfer pending" : flag;
+ linphonec_out("%-2i | %-35s | %-15s | %s\n",(int)(long)linphone_call_get_user_pointer(call),
+ tmp,linphone_call_state_to_string(linphone_call_get_state(call))+strlen("LinphoneCall"),flag);
ms_free(tmp);
}
}
const LinphoneCallParams *cp=linphone_call_get_current_params (call);
if (args){
linphone_call_enable_camera(call,activated);
- if ((activated && !linphone_call_params_video_enabled (cp))){
- /*update the call to add the video stream*/
- LinphoneCallParams *ncp=linphone_call_params_copy(cp);
- linphone_call_params_enable_video(ncp,TRUE);
- linphone_core_update_call(lc,call,ncp);
- linphone_call_params_destroy (ncp);
- linphonec_out("Trying to bring up video stream...\n");
+ if (linphone_call_get_state(call)==LinphoneCallStreamsRunning){
+ if ((activated && !linphone_call_params_video_enabled (cp))){
+ /*update the call to add the video stream*/
+ LinphoneCallParams *ncp=linphone_call_params_copy(cp);
+ linphone_call_params_enable_video(ncp,TRUE);
+ linphone_core_update_call(lc,call,ncp);
+ linphone_call_params_destroy (ncp);
+ linphonec_out("Trying to bring up video stream...\n");
+ }
}
}
if (linphone_call_camera_enabled (call))
if (!args) return 0;
call=linphone_core_get_current_call(lc);
if (call!=NULL){
- linphone_call_take_video_snapshot (call,args);
- linphonec_out("Taking video snaphot in file %s\n", args);
+ linphone_call_take_video_snapshot(call,args);
+ linphonec_out("Taking video snapshot in file %s\n", args);
}else linphonec_out("There is no active call.\n");
return 1;
}
+static int lpc_cmd_vfureq(LinphoneCore *lc, char *arg){
+ LinphoneCall *call;
+ call=linphone_core_get_current_call(lc);
+ if (call!=NULL){
+ linphone_call_send_vfu_request(call);
+ linphonec_out("VFU request sent\n");
+ }else linphonec_out("There is no active call.\n");
+ return 1;
+}
#endif
static int lpc_cmd_identify(LinphoneCore *lc, char *args){
return 1;
}
+static int zrtp_set_verified(LinphoneCore *lc, char *args, bool_t verified){
+ LinphoneCall *call=linphone_core_get_current_call(lc);
+ if (linphone_call_params_get_media_encryption(linphone_call_get_current_params(call))==LinphoneMediaEncryptionZRTP){
+ linphone_call_set_authentication_token_verified(call,verified);
+ }
+ return 1;
+}
+static int lpc_cmd_zrtp_verified(LinphoneCore *lc, char *args){
+ return zrtp_set_verified(lc,args,TRUE);
+}
+static int lpc_cmd_zrtp_unverified(LinphoneCore *lc, char *args){
+ return zrtp_set_verified(lc,args,FALSE);
+}
+
/***************************************************************************
*
* Command table management funx