]> sjero.net Git - linphone/blob - console/commands.c
multicall in gtk and bugfixes
[linphone] / console / commands.c
1 /****************************************************************************
2  *
3  *  $Id: commands.c,v 1.39 2008/07/03 15:08:34 smorlat Exp $
4  *
5  *  Copyright (C) 2006-2009  Sandro Santilli <strk@keybit.net>
6  *  Copyright (C) 2004  Simon MORLAT <simon.morlat@linphone.org>
7  *
8 ****************************************************************************
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  *
24  ****************************************************************************/
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #ifndef _WIN32_WCE
30 #include <errno.h>
31 #include <unistd.h>
32 #endif /*_WIN32_WCE*/
33 #include <limits.h>
34 #include <ctype.h>
35 #include <linphonecore.h>
36 #include "linphonec.h"
37 #include "private.h"
38 #include "lpconfig.h"
39
40 #ifndef WIN32
41 #include <sys/wait.h>
42 #endif
43
44 #define AUDIO 0
45 #define VIDEO 1
46
47 /***************************************************************************
48  *
49  *  Forward declarations 
50  *
51  ***************************************************************************/
52
53 extern char *lpc_strip_blanks(char *input);
54
55 /* Command handlers */
56 static int lpc_cmd_help(LinphoneCore *, char *);
57 static int lpc_cmd_proxy(LinphoneCore *, char *);
58 static int lpc_cmd_call(LinphoneCore *, char *);
59 static int lpc_cmd_calls(LinphoneCore *, char *);
60 static int lpc_cmd_chat(LinphoneCore *, char *);
61 static int lpc_cmd_answer(LinphoneCore *, char *);
62 static int lpc_cmd_autoanswer(LinphoneCore *, char *);
63 static int lpc_cmd_terminate(LinphoneCore *, char *);
64 static int lpc_cmd_call_logs(LinphoneCore *, char *);
65 static int lpc_cmd_ipv6(LinphoneCore *, char *);
66 static int lpc_cmd_transfer(LinphoneCore *, char *);
67 static int lpc_cmd_quit(LinphoneCore *, char *);
68 static int lpc_cmd_nat(LinphoneCore *, char *);
69 static int lpc_cmd_stun(LinphoneCore *, char *);
70 static int lpc_cmd_firewall(LinphoneCore *, char *);
71 static int lpc_cmd_friend(LinphoneCore *, char*);
72 static int lpc_cmd_soundcard(LinphoneCore *, char *);
73 static int lpc_cmd_webcam(LinphoneCore *, char *);
74 static int lpc_cmd_staticpic(LinphoneCore *, char *);
75 static int lpc_cmd_play(LinphoneCore *, char *);
76 static int lpc_cmd_record(LinphoneCore *, char *);
77 static int lpc_cmd_register(LinphoneCore *, char *);
78 static int lpc_cmd_unregister(LinphoneCore *, char *);
79 static int lpc_cmd_duration(LinphoneCore *lc, char *args);
80 static int lpc_cmd_status(LinphoneCore *lc, char *args);
81 static int lpc_cmd_ports(LinphoneCore *lc, char *args);
82 static int lpc_cmd_speak(LinphoneCore *lc, char *args);
83 static int lpc_cmd_acodec(LinphoneCore *lc, char *args);
84 static int lpc_cmd_vcodec(LinphoneCore *lc, char *args);
85 static int lpc_cmd_codec(int type, LinphoneCore *lc, char *args);
86 static int lpc_cmd_echocancellation(LinphoneCore *lc, char *args);
87 static int lpc_cmd_pause(LinphoneCore *lc, char *args);
88 static int lpc_cmd_resume(LinphoneCore *lc, char *args);
89 static int lpc_cmd_mute_mic(LinphoneCore *lc, char *args);
90 static int lpc_cmd_unmute_mic(LinphoneCore *lc, char *args);
91 static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args);
92
93 /* Command handler helpers */
94 static void linphonec_proxy_add(LinphoneCore *lc);
95 static void linphonec_proxy_display(LinphoneProxyConfig *lc);
96 static void linphonec_proxy_list(LinphoneCore *lc);
97 static void linphonec_proxy_remove(LinphoneCore *lc, int index);
98 static  int linphonec_proxy_use(LinphoneCore *lc, int index);
99 static void linphonec_proxy_show(LinphoneCore *lc,int index);
100 static void linphonec_friend_display(LinphoneFriend *fr);
101 static int linphonec_friend_list(LinphoneCore *lc, char *arg);
102 static void linphonec_display_command_help(LPC_COMMAND *cmd);
103 static int linphonec_friend_call(LinphoneCore *lc, unsigned int num);
104 #ifndef WIN32
105 static int linphonec_friend_add(LinphoneCore *lc, const char *name, const char *addr);
106 #endif
107 static int linphonec_friend_delete(LinphoneCore *lc, int num);
108 static int linphonec_friend_delete(LinphoneCore *lc, int num);
109 static void linphonec_codec_list(int type, LinphoneCore *lc);
110 static void linphonec_codec_enable(int type, LinphoneCore *lc, int index);
111 static void linphonec_codec_disable(int type, LinphoneCore *lc, int index);
112
113
114
115 /* Command table management */
116 static LPC_COMMAND *lpc_find_command(const char *name);
117
118 void linphonec_out(const char *fmt,...);
119
120
121
122 /***************************************************************************
123  *
124  *  Global variables
125  *
126  ***************************************************************************/
127
128 /*
129  * Commands table.
130  */
131 LPC_COMMAND commands[] = {
132         { "help", lpc_cmd_help, "Print commands help", NULL },
133         { "call", lpc_cmd_call, "Call a SIP uri",
134                 "'call <sip-url>' \t: initiate a call to the specified destination.\n"
135                 "'call show' \t: show all the current calls with their id and status.\n"
136                 },
137         { "calls", lpc_cmd_calls, "Show all the current calls with their id and status.\n",
138                 NULL
139                 },
140         { "chat", lpc_cmd_chat, "Chat with a SIP uri",
141                 "'chat <sip-url> \"message\"' "
142                 ": send a chat message \"message\" to the specified destination."
143                 },
144         { "terminate", lpc_cmd_terminate, "Terminate a call",
145                 "'terminate' : Terminate the current call\n"
146                 "'terminate <call id>' : Terminate the call with supplied id\n"
147                 "'terminate <all>' : Terminate all the current calls\n"
148                 },
149         { "answer", lpc_cmd_answer, "Answer a call",
150                 "'answer' : Answer the current incoming call\n"
151                 "'answer <call id>' : Answer the call with given id\n"
152         },
153         { "autoanswer", lpc_cmd_autoanswer, "Show/set auto-answer mode",
154                 "'autoanswer'       \t: show current autoanswer mode\n"
155                 "'autoanswer enable'\t: enable autoanswer mode\n"
156                 "'autoanswer disable'\t: disable autoanswer modeĀ \n"},
157         { "proxy", lpc_cmd_proxy, "Manage proxies",
158                 "'proxy list' : list all proxy setups.\n"
159                 "'proxy add' : add a new proxy setup.\n"
160                 "'proxy remove <index>' : remove proxy setup with number index.\n"
161                 "'proxy use <index>' : use proxy with number index as default proxy.\n"
162                 "'proxy unuse' : don't use a default proxy.\n"
163                 "'proxy show <index>' : show configuration and status of the proxy numbered by index.\n"
164                 "'proxy show default' : show configuration and status of the default proxy.\n"
165         },
166         { "soundcard", lpc_cmd_soundcard, "Manage soundcards",
167                 "'soundcard list' : list all sound devices.\n"
168                 "'soundcard show' : show current sound devices configuration.\n"
169                 "'soundcard use <index>' : select a sound device.\n"
170                 "'soundcard use files' : use .wav files instead of soundcard\n"
171         },
172         { "webcam", lpc_cmd_webcam, "Manage webcams",
173                 "'webcam list' : list all known devices.\n"
174                 "'webcam use <index>' : select a video device.\n"
175         },
176         { "staticpic", lpc_cmd_staticpic, "Manage static pictures when nowebcam",
177                 "'staticpic set' : Set path to picture that should be used.\n"
178                 "'staticpic fps' : Get/set frames per seconds for picture emission.\n"
179         },
180         { "ipv6", lpc_cmd_ipv6, "Use IPV6",
181                 "'ipv6 status' : show ipv6 usage status.\n"
182                 "'ipv6 enable' : enable the use of the ipv6 network.\n"
183                 "'ipv6 disable' : do not use ipv6 network."
184         },
185         { "transfer", lpc_cmd_transfer,
186                 "Transfer a call to a specified destination.",
187                 "'transfer <sip-uri>' : transfers the current active call to the destination sip-uri"
188                 "'transfer <call id> <sip-uri>': transfers the call with 'id' to the destination sip-uri"
189         },
190         { "nat", lpc_cmd_nat, "Set nat address",
191                 "'nat'        : show nat settings.\n"
192                 "'nat <addr>' : set nat address.\n"
193         },
194         { "stun", lpc_cmd_stun, "Set stun server address",
195                 "'stun'        : show stun settings.\n"
196                 "'stun <addr>' : set stun server address.\n"
197         },
198         { "firewall", lpc_cmd_firewall, "Set firewall policy",
199                 "'firewall'        : show current firewall policy.\n"
200                 "'firewall none'   : use direct connection.\n"
201                 "'firewall nat'    : use nat address given with the 'nat' command.\n"
202                 "'firewall stun'   : use stun server given with the 'stun' command.\n"
203         },
204         { "call-logs", lpc_cmd_call_logs, "Calls history", NULL },
205         { "friend", lpc_cmd_friend, "Manage friends",
206                 "'friend list [<pattern>]'    : list friends.\n"
207                 "'friend call <index>'        : call a friend.\n"
208                 "'friend add <name> <addr>'   : add friend, <name> must be quoted to include\n"
209             "                               spaces, <addr> has \"sip:\" added if it isn't\n"
210             "                               there.  Don't use '<' '>' around <addr>.\n"
211                 "'friend delete <index>'      : remove friend, 'all' removes all\n"
212         },
213         { "play", lpc_cmd_play, "play from a wav file",
214                 "This feature is available only in file mode (see 'help soundcard')\n"
215                 "'play <wav file>'    : play a wav file."
216         },
217         { "record", lpc_cmd_record, "record to a wav file",
218                 "This feature is available only in file mode (see 'help soundcard')\n"
219                 "'record <wav file>'    : record into wav file."
220         },
221         { "quit", lpc_cmd_quit, "Exit linphonec", NULL },
222         { "register", lpc_cmd_register, "Register in one line to a proxy" , "register <sip identity> <sip proxy> <password>"},
223         { "unregister", lpc_cmd_unregister, "Unregister from default proxy", NULL       },
224         { "duration", lpc_cmd_duration, "Print duration in seconds of the last call.", NULL },
225         { "status", lpc_cmd_status, "Print various status information", 
226                         "'status register'  \t: print status concerning registration\n"
227                         "'status autoanswer'\t: tell whether autoanswer mode is enabled\n"
228                         "'status hook'      \t: print hook status\n" },
229         { "ports", lpc_cmd_ports, "Network ports configuration", 
230                         "'ports'  \t: prints current used ports.\n"
231                         "'ports sip <port number>'\t: Sets the sip port.\n" },
232         { "speak", lpc_cmd_speak, "Speak a sentence using espeak TTS engine",
233                         "This feature is available only in file mode. (see 'help soundcard')\n"
234                         "'speak <voice name> <sentence>'        : speak a text using the specified espeak voice.\n"
235                         "Example for english voice: 'speak default Hello my friend !'"
236         },
237     { "codec", lpc_cmd_acodec, "Audio codec configuration",
238             "'codec list' : list audio codecs\n"
239             "'codec enable <index>' : enable available audio codec\n"
240             "'codec disable <index>' : disable audio codec" },
241     { "vcodec", lpc_cmd_vcodec, "Video codec configuration",
242             "'vcodec list' : list video codecs\n"
243             "'vcodec enable <index>' : enable available video codec\n"
244             "'vcodec disable <index>' : disable video codec" },
245         { "ec", lpc_cmd_echocancellation, "Echo cancellation",
246             "'ec on [<delay>] [<tail>] [<framesize>]' : turn EC on with given delay, tail length and framesize\n"
247             "'ec off' : turn echo cancellation (EC) off\n"
248             "'ec show' : show EC status" },
249         { "pause", lpc_cmd_pause, "pause a call",
250                 "'pause' : pause the current call\n"},
251         { "resume", lpc_cmd_resume, "resume a call",
252                 "'resume' : resume the unique call\n"
253                 "'resume <call id>' : hold off the call with given id\n"},
254         { "mute", lpc_cmd_mute_mic, 
255           "Mute microphone and suspend voice transmission."},
256         { "unmute", lpc_cmd_unmute_mic, 
257                   "Unmute microphone and resume voice transmission."},
258         { "nortp-on-audio-mute", lpc_cmd_rtp_no_xmit_on_audio_mute,
259                   "Set the rtp_no_xmit_on_audio_mute configuration parameter",
260                   "   If set to 1 then rtp transmission will be muted when\n"
261                   "   audio is muted , otherwise rtp is always sent."}, 
262     { (char *)NULL, (lpc_cmd_handler)NULL, (char *)NULL, (char *)NULL }
263 };
264
265 /***************************************************************************
266  *
267  *  Public interface 
268  *
269  ***************************************************************************/
270
271 /*
272  * Main command dispatcher.
273  * WARNING: modifies second argument!
274  *
275  * Always return 1 currently.
276  */
277 int
278 linphonec_parse_command_line(LinphoneCore *lc, char *cl)
279 {
280         char *ptr=cl;
281         char *args=NULL;
282         LPC_COMMAND *cmd;
283
284         /* Isolate first word and args */
285         while(*ptr && !isspace(*ptr)) ++ptr;
286         if (*ptr)
287         {
288                 *ptr='\0';
289                 /* set args to first nonblank */
290                 args=ptr+1;
291                 while(*args && isspace(*args)) ++args;
292         }
293
294         /* Handle DTMF */
295         if ( isdigit(*cl) || *cl == '#' || *cl == '*' )
296         {
297                 while ( isdigit(*cl) || *cl == '#' || *cl == '*' )
298                 {
299                         linphone_core_send_dtmf(lc, *cl);
300                         linphone_core_play_dtmf (lc,*cl,100);
301                         ms_sleep(1); // be nice
302                         ++cl;
303                 }
304
305                 // discard spurious trailing chars
306                 return 1;
307         }
308
309         /* Handle other kind of commands */
310         cmd=lpc_find_command(cl);
311         if ( !cmd )
312         {
313                 linphonec_out("'%s': Cannot understand this.\n", cl);
314                 return 1;
315         }
316
317         if ( ! cmd->func(lc, args) )
318         {
319                 linphonec_out("Syntax error.\n");
320                 linphonec_display_command_help(cmd);
321         }
322
323         return 1;
324 }
325
326 /*
327  * Generator function for command completion.
328  * STATE let us know whether to start from scratch;
329  * without any state (STATE==0), then we start at the
330  * top of the list.
331  */
332 char *
333 linphonec_command_generator(const char *text, int state)
334 {
335         static int index, len;
336         char *name;
337
338         if ( ! state )
339         {
340                 index=0;
341                 len=strlen(text);
342         }
343
344         /*
345          * Return the next name which partially matches
346          * from the commands list
347          */
348         while ((name=commands[index].name))
349         {
350                 ++index; /* so next call get next command */
351
352                 if (strncmp(name, text, len) == 0)
353                 {
354                         return ortp_strdup(name);
355                 }
356         }
357
358         return NULL;
359 }
360
361
362 /***************************************************************************
363  *
364  *  Command handlers 
365  *
366  ***************************************************************************/
367
368 static int
369 lpc_cmd_help(LinphoneCore *lc, char *arg)
370 {
371         int i=0;
372         LPC_COMMAND *cmd;
373
374         if (!arg || !*arg)
375         {
376                 linphonec_out("Commands are:\n");
377                 linphonec_out("---------------------------\n");
378
379                 while (commands[i].help)
380                 {
381                         linphonec_out("%10.10s\t%s\n", commands[i].name,
382                                 commands[i].help);
383                         i++;
384                 }
385                 
386                 linphonec_out("---------------------------\n");
387                 linphonec_out("Type 'help <command>' for more details.\n");
388
389                 return 1;
390         }
391
392         cmd=lpc_find_command(arg);
393         if ( !cmd )
394         {
395                 linphonec_out("No such command.\n");
396                 return 1;
397         }
398
399         linphonec_display_command_help(cmd);
400         return 1;
401
402 }
403
404 static char callee_name[256]={0};
405 static char caller_name[256]={0};
406
407 static const char *get_call_status(LinphoneCall *call){
408         switch(linphone_call_get_state(call)){
409                 case LinphoneCallPaused:
410                         if (linphone_call_get_refer_to (call)!=NULL){
411                                 return "Paused (transfered)";
412                         }else{
413                                 return "Paused";
414                         }
415                 break;
416                 case LinphoneCallPausedByRemote:
417                         return "Paused by remote";
418                 break;
419                 case LinphoneCallIncomingReceived:
420                         return "Pending";
421                 break;
422                 case LinphoneCallOutgoingInit:
423                 case LinphoneCallOutgoingProgress:
424                         return "Dialing out";
425                 break;
426                 case LinphoneCallOutgoingEarlyMedia:
427                 case LinphoneCallOutgoingRinging:
428                         return "Remote ringing";
429                 break;
430                 default:
431                         if (linphone_call_has_transfer_pending(call)){
432                                 return "Running (transfer pending)";
433                         }else
434                                 return "Running";
435         }
436         return "";
437 }
438
439 static int
440 lpc_cmd_call(LinphoneCore *lc, char *args)
441 {
442         if ( ! args || ! *args )
443         {
444                 return 0;
445         }
446         {
447                 LinphoneCall *call;
448                 if ( linphone_core_in_call(lc) )
449                 {
450                         linphonec_out("Terminate or hold on the current call first.\n");
451                         return 1;
452                 }
453                 if ( NULL == (call=linphone_core_invite(lc, args)) )
454                 {
455                         linphonec_out("Error from linphone_core_invite.\n");
456                 }
457                 else
458                 {
459                         snprintf(callee_name,sizeof(callee_name),"%s",args);
460                 }
461         }
462         return 1;
463 }
464
465 static int 
466 lpc_cmd_calls(LinphoneCore *lc, char *args){
467         const MSList *calls = linphone_core_get_calls(lc);
468         if(calls)
469         {
470                 const MSList *p_calls = calls;
471                 linphonec_out("ID\t\tDestination\t\t\t\tStatus\n---------------------------------------------------------------------\n");
472                 while(p_calls != NULL)                  
473                 {
474                         LinphoneCall *call=(LinphoneCall*)p_calls->data;
475                         char *tmp=linphone_call_get_remote_address_as_string(call);
476                         linphonec_out("%li\t%s\t\t\t%s\r\n",
477                                                   (long)linphone_call_get_user_pointer (call),
478                                         tmp,
479                                         get_call_status(call));
480                         p_calls = p_calls->next;
481                         ms_free(tmp);
482                 }
483         }else
484         {
485                 linphonec_out("No active call.\n");
486         }
487         return 1;
488 }
489
490
491 static int
492 lpc_cmd_chat(LinphoneCore *lc, char *args)
493 {
494         char *arg1 = args;
495         char *arg2 = NULL;
496         char *ptr = args;
497
498         if (!args) return 0;
499
500         /* Isolate first and second arg */
501         while(*ptr && !isspace(*ptr)) ++ptr;
502         if ( *ptr )
503         {
504                 *ptr='\0';
505                 arg2=ptr+1;
506                 while(*arg2 && isspace(*arg2)) ++arg2;
507         }
508         else
509         {
510                 /* missing one parameter */
511                 return 0;
512         }
513         LinphoneChatRoom *cr = linphone_core_create_chat_room(lc,arg1);
514         linphone_chat_room_send_message(cr,arg2);
515         linphone_chat_room_destroy(cr);
516
517         return 1;
518 }
519
520 const char *linphonec_get_callee(){
521         return callee_name;
522 }
523
524 const char *linphonec_get_caller(){
525         return caller_name;
526 }
527
528 void linphonec_set_caller(const char *caller){
529         snprintf(caller_name,sizeof(caller_name)-1,"%s",caller);
530 }
531
532 static int
533 lpc_cmd_transfer(LinphoneCore *lc, char *args)
534 {
535         if (args){
536                 LinphoneCall *call;
537                 const char *refer_to=NULL;
538                 char arg1[256]={0};
539                 char arg2[266]={0};
540                 int n=sscanf(args,"%s %s",arg1,arg2);
541                 if (n==1 || isalpha(*arg1)){
542                         call=linphone_core_get_current_call(lc);
543                         if (call==NULL && linphone_core_get_calls_nb (lc)==1){
544                                 call=(LinphoneCall*)linphone_core_get_calls(lc)->data;
545                         }
546                         refer_to=args;
547                         if (call==NULL){
548                                 linphonec_out("No active call, please specify a call id among the ones listed by 'calls' command.\n");
549                                 return 0;
550                         }
551                 }else{
552                         long id=atoi(arg1);
553                         refer_to=args+strlen(arg1)+1;
554                         call=linphonec_get_call(id);
555                         if (call==NULL) return 0;
556                 }
557                 linphone_core_transfer_call(lc, call, refer_to);
558         }else{
559                 linphonec_out("Transfer command requires at least one argument\n");
560                 return 0;
561         }
562         return 1;
563 }
564
565 static int
566 lpc_cmd_terminate(LinphoneCore *lc, char *args)
567 {
568         if (linphone_core_get_calls(lc)==NULL){
569                 linphonec_out("No active calls");
570                 return 1;
571         }
572         if (!args)
573         {
574                 if ( -1 == linphone_core_terminate_call(lc, NULL) ){
575                         linphonec_out("Could not stop the active call.\n");
576                 }
577                 return 1;
578         }
579         
580         if(strcmp(args,"all")==0){
581                 linphonec_out("We are going to stop all the calls.\n");
582                 linphone_core_terminate_all_calls(lc);
583                 return 1;
584         }else{
585                 /*the argument is a linphonec call id */
586                 long id=atoi(args);
587                 LinphoneCall *call=linphonec_get_call(id);
588                 if (call){
589                         if (linphone_core_terminate_call(lc,call)==-1){
590                                 linphonec_out("Could not stop the call with id %li",id);
591                         }
592                 }else return 0;
593                 return 1;
594         }
595         return 0;
596         
597 }
598
599 static int
600 lpc_cmd_answer(LinphoneCore *lc, char *args){
601         if (!args)
602         {
603                 int nb=ms_list_size(linphone_core_get_calls(lc));
604                 if (nb==1){
605                         //if just one call is present answer the only one in passing NULL to the linphone_core_accept_call ...
606                         if ( -1 == linphone_core_accept_call(lc, NULL) )
607                         {
608                                 linphonec_out("Fail to accept incoming call\n");
609                         }
610                 }else if (nb==0){
611                         linphonec_out("There are no calls to answer.\n");
612                 }else{
613                         linphonec_out("Multiple calls in progress, please specify call id.\n");
614                         return 0;
615                 }
616                 return 1;
617         }else{
618                 long id;
619                 if (sscanf(args,"%li",&id)==1){
620                         LinphoneCall *call=linphonec_get_call (id);
621                         if (linphone_core_accept_call (lc,call)==-1){
622                                 linphonec_out("Fail to accept call %i\n",id);
623                         }
624                 }else return 0;
625                 return 1;
626         }
627         return 0;
628 }
629
630 static int
631 lpc_cmd_autoanswer(LinphoneCore *lc, char *args)
632 {
633         if ( ! args )
634         {
635                 if ( linphonec_get_autoanswer() ) {
636                         linphonec_out("Auto answer is enabled. Use 'autoanswer disable' to disable.\n");
637                 } else {
638                         linphonec_out("Auto answer is disabled. Use 'autoanswer enable' to enable.\n");
639                 }
640                 return 1;
641         }
642
643         if (strstr(args,"enable")){
644                 linphonec_set_autoanswer(TRUE);
645                 linphonec_out("Auto answer enabled.\n");
646         }else if (strstr(args,"disable")){
647                 linphonec_set_autoanswer(FALSE);
648                 linphonec_out("Auto answer disabled.\n");
649         }else return 0;
650         return 1;
651 }
652
653 static int
654 lpc_cmd_quit(LinphoneCore *lc, char *args)
655 {
656         linphonec_main_loop_exit();
657         return 1;
658 }
659
660 static int
661 lpc_cmd_nat(LinphoneCore *lc, char *args)
662 {
663         bool_t use;
664         const char *nat;
665
666         if ( args ) args=lpc_strip_blanks(args);
667
668         if ( args && *args )
669         {
670                 linphone_core_set_nat_address(lc, args);
671                 /* linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_USE_NAT_ADDRESS); */
672         }
673
674         nat = linphone_core_get_nat_address(lc);
675         use = linphone_core_get_firewall_policy(lc)==LinphonePolicyUseNatAddress;
676         linphonec_out("Nat address: %s%s\n", nat ? nat : "unspecified" , use ? "" : " (disabled - use 'firewall nat' to enable)");
677
678         return 1;
679 }
680
681 static int
682 lpc_cmd_stun(LinphoneCore *lc, char *args)
683 {
684         bool_t use;
685         const char *stun;
686
687         if ( args ) args=lpc_strip_blanks(args);
688
689         if ( args && *args )
690         {
691                 linphone_core_set_stun_server(lc, args);
692                 /* linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_USE_STUN); */
693         }
694
695         stun = linphone_core_get_stun_server(lc);
696         use = linphone_core_get_firewall_policy(lc)==LinphonePolicyUseStun;
697         linphonec_out("Stun server: %s%s\n", stun ? stun : "unspecified" , use? "" : " (disabled - use 'firewall stun' to enable)");
698
699         return 1;
700 }
701
702 static int
703 lpc_cmd_firewall(LinphoneCore *lc, char *args)
704 {
705         const char* setting=NULL;
706
707         if ( args ) args=lpc_strip_blanks(args);
708
709         if ( args && *args )
710         {
711                 if (strcmp(args,"none")==0)
712                 {
713                         linphone_core_set_firewall_policy(lc,LinphonePolicyNoFirewall);
714                 }
715                 else if (strcmp(args,"stun")==0)
716                 {
717                         setting = linphone_core_get_stun_server(lc);
718                         if ( ! setting )
719                         {
720                                 linphonec_out("No stun server address is defined, use 'stun <address>' first\n");
721                                 return 1;
722                         }
723                         linphone_core_set_firewall_policy(lc,LinphonePolicyUseStun);
724                 }
725                 else if (strcmp(args,"nat")==0)
726                 {
727                         setting = linphone_core_get_nat_address(lc);
728                         if ( ! setting )
729                         {
730                                 linphonec_out("No nat address is defined, use 'nat <address>' first");
731                                 return 1;
732                         }
733                         linphone_core_set_firewall_policy(lc,LinphonePolicyUseNatAddress);
734                 }
735         }
736
737         switch(linphone_core_get_firewall_policy(lc))
738         {
739                 case LinphonePolicyNoFirewall:
740                         linphonec_out("No firewall\n");
741                         break;
742                 case LinphonePolicyUseStun:
743                         linphonec_out("Using stun server %s to discover firewall address\n", setting ? setting : linphone_core_get_stun_server(lc));
744                         break;
745                 case LinphonePolicyUseNatAddress:
746                         linphonec_out("Using supplied nat address %s.\n", setting ? setting : linphone_core_get_nat_address(lc));
747                         break;
748         }
749         return 1;
750 }
751
752 #ifndef WIN32
753 /* Helper function for processing freind names */
754 static int
755 lpc_friend_name(char **args, char **name)
756 {
757         /* Use space as a terminator unless quoted */
758         if (('"' == **args) || ('\'' == **args)){
759                 char *end;
760                 char delim = **args;
761                 (*args)++;
762                 end = (*args);
763                 while ((delim != *end) && ('\0' != *end)) end++;
764                 if ('\0' == *end) {
765                         fprintf(stderr, "Mismatched quotes\n");
766                         return 0;
767                 }
768                 *name = *args;
769                 *end = '\0';
770                 *args = ++end;
771         } else {
772                 *name = strsep(args, " ");
773                 
774                 if (NULL == *args) { /* Means there was no separator */
775                         fprintf(stderr, "Either name or address is missing\n");
776                         return 0;
777                 }
778                 if (NULL == *name) return 0;
779         }
780         return 1;
781 }
782 #endif
783
784 static int
785 lpc_cmd_friend(LinphoneCore *lc, char *args)
786 {
787         int friend_num;
788
789         if ( args ) args=lpc_strip_blanks(args);
790
791         if ( ! args || ! *args ) return 0;
792
793         if ( !strncmp(args, "list", 4) )
794         {
795                 return linphonec_friend_list(lc, args+4);
796                 return 1;
797         }
798         else if ( !strncmp(args, "call", 4) )
799         {
800                 args+=4;
801                 if ( ! *args ) return 0;
802                 friend_num = strtol(args, NULL, 10);
803 #ifndef _WIN32_WCE              
804                 if ( errno == ERANGE ) {
805                         linphonec_out("Invalid friend number\n");
806                         return 0;
807                 }
808 #endif /*_WIN32_WCE*/
809                 linphonec_friend_call(lc, friend_num);
810                 return 1;
811         }
812         else if ( !strncmp(args, "delete", 6) )
813         {
814                 args+=6;
815                 if ( ! *args ) return 0;
816                 while (*args == ' ') args++;
817                 if ( ! *args ) return 0;
818                 if (!strncmp(args, "all", 3))
819                 {
820                         friend_num = -1;
821                 } 
822                 else
823                 {
824                         friend_num = strtol(args, NULL, 10);
825 #ifndef _WIN32_WCE              
826                         if ( errno == ERANGE ) {
827                                 linphonec_out("Invalid friend number\n");
828                                 return 0;
829                         }
830 #endif /*_WIN32_WCE*/
831                 }
832                 linphonec_friend_delete(lc, friend_num);
833                 return 1;
834         }
835         else if ( !strncmp(args, "add", 3) )
836         {
837 #ifndef WIN32
838                 char  *name;
839                 char  addr[80];
840                 char *addr_p = addr;
841                 char *addr_orig;
842
843                 args+=3;
844                 if ( ! *args ) return 0;
845                 while (*args == ' ') args++;
846                 if ( ! *args ) return 0;
847
848                 if (!lpc_friend_name(&args,  &name)) return 0;
849
850                 while (*args == ' ') args++;
851                 if ( ! *args ) return 0;
852                 if (isdigit(*args)) {
853                         strcpy (addr, "sip:");
854                         addr_p = addr + strlen("sip:");
855                 }
856                 addr_orig = strsep(&args, " ");
857                 if (1 >= strlen(addr_orig)) {
858                         fprintf(stderr, "A single-digit address is not valid\n");
859                         return 0;
860                 }
861                 strcpy(addr_p, addr_orig);
862                 linphonec_friend_add(lc, name, addr);
863 #else
864                 LinphoneFriend *new_friend;
865                 new_friend = linphone_friend_new_with_addr(args);
866                 linphone_core_add_friend(lc, new_friend);
867 #endif
868                 return 1;
869         }
870         return 0;
871 }
872
873 static int lpc_cmd_play(LinphoneCore *lc, char *args){
874         if ( args ) args=lpc_strip_blanks(args);
875         if ( ! args || ! *args ) return 0;
876         linphone_core_set_play_file(lc,args);
877         return 1;
878 }
879
880 static int lpc_cmd_record(LinphoneCore *lc, char *args){
881         if ( args ) args=lpc_strip_blanks(args);
882         if ( ! args || ! *args ) return 0;
883         linphone_core_set_record_file(lc,args);
884         return 1;
885 }
886
887 /*
888  * Modified input
889  */
890 static int
891 lpc_cmd_proxy(LinphoneCore *lc, char *args)
892 {
893         char *arg1 = args;
894         char *arg2 = NULL;
895         char *ptr = args;
896         int proxynum;
897
898         if ( ! arg1 ) return 0;
899
900         /* Isolate first and second arg */
901         while(*ptr && !isspace(*ptr)) ++ptr;
902         if ( *ptr )
903         {
904                 *ptr='\0';
905                 arg2=ptr+1;
906                 while(*arg2 && isspace(*arg2)) ++arg2;
907         }
908
909         if (strcmp(arg1,"add")==0)
910         {
911 #ifdef HAVE_READLINE
912                 rl_inhibit_completion=1;
913 #endif
914                 linphonec_proxy_add(lc);
915 #ifdef HAVE_READLINE
916                 rl_inhibit_completion=0;
917 #endif
918         }
919         else if (strcmp(arg1,"list")==0)
920         {
921                 linphonec_proxy_list(lc);
922         }
923         else if (strcmp(arg1,"remove")==0)
924         {
925                 linphonec_proxy_remove(lc,atoi(arg2));
926         }
927         else if (strcmp(arg1,"use")==0)
928         {
929                 if ( arg2 && *arg2 )
930                 {
931                         proxynum=atoi(arg2);
932                         if ( linphonec_proxy_use(lc, proxynum) )
933                                 linphonec_out("Default proxy set to %d.\n", proxynum);
934                 }
935                 else
936                 {
937                         proxynum=linphone_core_get_default_proxy(lc, NULL);
938                         if ( proxynum == -1 ) linphonec_out("No default proxy.\n");
939                         else linphonec_out("Current default proxy is %d.\n", proxynum);
940                 }
941         }else if (strcmp(arg1, "unuse")==0){
942                 linphone_core_set_default_proxy(lc, NULL);
943                 linphonec_out("Use no proxy.\n");
944         }
945
946         else if (strcmp(arg1, "show")==0)
947         {
948                 if (arg2 && *arg2)
949                 {
950                         if (strstr(arg2,"default"))
951                         {
952                 proxynum=linphone_core_get_default_proxy(lc, NULL);
953                 if ( proxynum < 0 ) {
954                         linphonec_out("No default proxy defined\n");
955                         return 1;
956                 }
957                 linphonec_proxy_show(lc,proxynum);
958                         }
959                         else
960                         {
961                 linphonec_proxy_show(lc, atoi(arg2));
962                         }
963                 }
964                 else return 0; /* syntax error */
965         }
966
967         else
968         {
969                 return 0; /* syntax error */
970         }
971
972         return 1;
973 }
974
975 static int
976 lpc_cmd_call_logs(LinphoneCore *lc, char *args)
977 {
978         const MSList *elem=linphone_core_get_call_logs(lc);
979         for (;elem!=NULL;elem=ms_list_next(elem))
980         {
981                 LinphoneCallLog *cl=(LinphoneCallLog*)elem->data;
982                 char *str=linphone_call_log_to_str(cl);
983                 linphonec_out("%s\n",str);
984                 ms_free(str);
985         }
986         return 1;
987 }
988
989 static int
990 lpc_cmd_ipv6(LinphoneCore *lc, char *arg1)
991 {
992         if ( ! arg1 )
993         {
994                 return 0; /* syntax error */
995         }
996
997         if (strcmp(arg1,"status")==0)
998         {
999                 linphonec_out("ipv6 use enabled: %s\n",linphone_core_ipv6_enabled(lc) ? "true":"false");
1000         }
1001         else if (strcmp(arg1,"enable")==0)
1002         {
1003                 linphone_core_enable_ipv6(lc,TRUE);
1004                 linphonec_out("ipv6 use enabled.\n");
1005         }
1006         else if (strcmp(arg1,"disable")==0)
1007         {
1008                 linphone_core_enable_ipv6(lc,FALSE);
1009                 linphonec_out("ipv6 use disabled.\n");
1010         }
1011         else
1012         {
1013                 return 0; /* syntax error */
1014         }
1015         return 1;
1016 }
1017
1018 static int devname_to_index(LinphoneCore *lc, const char *devname){
1019         const char **p;
1020         int i;
1021         for(i=0,p=linphone_core_get_sound_devices(lc);*p!=NULL;++p,++i){
1022                 if (strcmp(devname,*p)==0) return i;
1023         }
1024         return -1;
1025 }
1026
1027 static const char *index_to_devname(LinphoneCore *lc, int index){
1028         const char **p;
1029         int i;
1030         for(i=0,p=linphone_core_get_sound_devices(lc);*p!=NULL;++p,++i){
1031                 if (i==index) return *p;
1032         }
1033         return NULL;
1034 }
1035
1036 static int lpc_cmd_soundcard(LinphoneCore *lc, char *args)
1037 {
1038         int i, index;
1039         const char **dev;
1040         char *arg1 = args;
1041         char *arg2 = NULL;
1042         char *ptr = args;
1043
1044         if (!args) return 0; /* syntax error */
1045
1046         /* Isolate first and second arg */
1047         while(*ptr && !isspace(*ptr)) ++ptr;
1048         if ( *ptr )
1049         {
1050                 *ptr='\0';
1051                 arg2=ptr+1;
1052                 while(*arg2 && isspace(*arg2)) ++arg2;
1053         }
1054
1055         if (strcmp(arg1, "list")==0)
1056         {
1057                 dev=linphone_core_get_sound_devices(lc);
1058                 for(i=0; dev[i]!=NULL; ++i){
1059                         linphonec_out("%i: %s\n",i,dev[i]);
1060                 }
1061                 return 1;
1062         }
1063
1064         if (strcmp(arg1, "show")==0)
1065         {
1066                 linphonec_out("Ringer device: %s\n",
1067                         linphone_core_get_ringer_device(lc));
1068                 linphonec_out("Playback device: %s\n",
1069                         linphone_core_get_playback_device(lc));
1070                 linphonec_out("Capture device: %s\n",
1071                         linphone_core_get_capture_device(lc));
1072                 return 1;
1073         }
1074
1075         if (strcmp(arg1, "use")==0 && arg2)
1076         {
1077                 if (strcmp(arg2, "files")==0)
1078                 {
1079                         linphonec_out("Using wav files instead of soundcard.\n");
1080                         linphone_core_use_files(lc,TRUE);
1081                         return 1;
1082                 }
1083
1084                 dev=linphone_core_get_sound_devices(lc);
1085                 index=atoi(arg2); /* FIXME: handle not-a-number */
1086                 for(i=0;dev[i]!=NULL;i++)
1087                 {
1088                         if (i!=index) continue;
1089
1090                         linphone_core_set_ringer_device(lc,dev[i]);
1091                         linphone_core_set_playback_device(lc,dev[i]);
1092                         linphone_core_set_capture_device(lc,dev[i]);
1093                         linphonec_out("Using sound device %s\n",dev[i]);
1094                         return 1;
1095                 }
1096                 linphonec_out("No such sound device\n");
1097                 return 1;
1098         }
1099         if (strcmp(arg1, "capture")==0)
1100         {
1101                 const char *devname=linphone_core_get_capture_device(lc);
1102                 if (!arg2){
1103                         linphonec_out("Using capture device #%i (%s)\n",
1104                                         devname_to_index(lc,devname),devname);
1105                 }else{
1106                         index=atoi(arg2); /* FIXME: handle not-a-number */
1107                         devname=index_to_devname(lc,index);
1108                         if (devname!=NULL){
1109                                 linphone_core_set_capture_device(lc,devname);
1110                                 linphonec_out("Using capture sound device %s\n",devname);
1111                                 return 1;
1112                         }
1113                         linphonec_out("No such sound device\n");
1114                 }
1115                 return 1;
1116         }
1117         if (strcmp(arg1, "playback")==0)
1118         {
1119                 const char *devname=linphone_core_get_playback_device(lc);
1120                 if (!arg2){
1121                         linphonec_out("Using playback device #%i (%s)\n",
1122                                         devname_to_index(lc,devname),devname);
1123                 }else{
1124                         index=atoi(arg2); /* FIXME: handle not-a-number */
1125                         devname=index_to_devname(lc,index);
1126                         if (devname!=NULL){
1127                                 linphone_core_set_playback_device(lc,devname);
1128                                 linphonec_out("Using playback sound device %s\n",devname);
1129                                 return 1;
1130                         }
1131                         linphonec_out("No such sound device\n");
1132                 }
1133                 return 1;
1134         }
1135         if (strcmp(arg1, "ring")==0)
1136         {
1137                 const char *devname=linphone_core_get_ringer_device(lc);
1138                 if (!arg2){
1139                         linphonec_out("Using ring device #%i (%s)\n",
1140                                         devname_to_index(lc,devname),devname);
1141                 }else{
1142                         index=atoi(arg2); /* FIXME: handle not-a-number */
1143                         devname=index_to_devname(lc,index);
1144                         if (devname!=NULL){
1145                                 linphone_core_set_ringer_device(lc,devname);
1146                                 linphonec_out("Using ring sound device %s\n",devname);
1147                                 return 1;
1148                         }
1149                         linphonec_out("No such sound device\n");
1150                 }
1151                 return 1;
1152         }
1153         return 0; /* syntax error */
1154 }
1155
1156 static int lpc_cmd_webcam(LinphoneCore *lc, char *args)
1157 {
1158         int i, index;
1159         const char **dev;
1160         char *arg1 = args;
1161         char *arg2 = NULL;
1162         char *ptr = args;
1163
1164         if (!args) return 0; /* syntax error */
1165
1166         /* Isolate first and second arg */
1167         while(*ptr && !isspace(*ptr)) ++ptr;
1168         if ( *ptr )
1169         {
1170                 *ptr='\0';
1171                 arg2=ptr+1;
1172                 while(*arg2 && isspace(*arg2)) ++arg2;
1173         }
1174
1175         if (strcmp(arg1, "list")==0)
1176         {
1177                 dev=linphone_core_get_video_devices(lc);
1178                 for(i=0; dev[i]!=NULL; ++i){
1179                         linphonec_out("%i: %s\n",i,dev[i]);
1180                 }
1181                 return 1;
1182         }
1183
1184         if (strcmp(arg1, "use")==0 && arg2)
1185         {
1186                 dev=linphone_core_get_video_devices(lc);
1187                 index=atoi(arg2); /* FIXME: handle not-a-number */
1188                 for(i=0;dev[i]!=NULL;i++)
1189                 {
1190                         if (i!=index) continue;
1191
1192                         linphone_core_set_video_device(lc, dev[i]);
1193                         linphonec_out("Using video device %s\n",dev[i]);
1194                         return 1;
1195                 }
1196                 linphonec_out("No such video device\n");
1197                 return 1;
1198         }
1199         return 0; /* syntax error */
1200 }
1201
1202 static int
1203 lpc_cmd_staticpic(LinphoneCore *lc, char *args)
1204 {
1205         char *arg1 = args;
1206         char *arg2 = NULL;
1207         char *ptr = args;
1208
1209         if (!args) return 0;  /* Syntax error */
1210
1211         /* Isolate first and second arg */
1212         while(*ptr && !isspace(*ptr)) ++ptr;
1213         if ( *ptr )
1214         {
1215                 *ptr='\0';
1216                 arg2=ptr+1;
1217                 while(*arg2 && isspace(*arg2)) ++arg2;
1218         }
1219
1220         if (strcmp(arg1, "set")==0 && arg2) {
1221                 linphone_core_set_static_picture(lc, arg2);
1222                 return 1;
1223         }
1224
1225         if (strcmp(arg1, "fps")==0) {
1226           if (arg2) {
1227                 float fps = atof(arg2); /* FIXME: Handle not-a-float */
1228                 linphone_core_set_static_picture_fps(lc, fps);
1229                 return 1;
1230           } else {
1231                 float fps;
1232                 fps = linphone_core_get_static_picture_fps(lc);
1233                 linphonec_out("Current FPS %f\n", fps);
1234                 return 1;
1235           }
1236         }
1237
1238         return 0; /* Syntax error */
1239 }
1240
1241 static int lpc_cmd_pause(LinphoneCore *lc, char *args){
1242
1243         if(linphone_core_in_call(lc))
1244         {
1245                 linphone_core_pause_call(lc,linphone_core_get_current_call(lc));
1246                 return 1;
1247         }
1248         linphonec_out("you can only pause when a call is in process\n");
1249     return 0;
1250 }
1251
1252 static int lpc_cmd_resume(LinphoneCore *lc, char *args){
1253         
1254         if(linphone_core_in_call(lc))
1255         {
1256                 linphonec_out("There is already a call in process pause or stop it first");
1257                 return 1;
1258         }
1259         if (args)
1260         {
1261                 long id;
1262                 int n = sscanf(args, "%li", &id);
1263                 if (n == 1){
1264                         LinphoneCall *call=linphonec_get_call (id);
1265                         if (call){
1266                                 if(linphone_core_resume_call(lc,call)==-1){
1267                                         linphonec_out("There was a problem to resume the call check the remote address you gave %s\n",args);
1268                                 }
1269                         }
1270                         return 1;
1271                 }else return 0;
1272         }
1273         else
1274         {
1275                 const MSList *calls = linphone_core_get_calls(lc);
1276                 int nbcalls=ms_list_size(calls);
1277                 if( nbcalls == 1)
1278                 {
1279                         if(linphone_core_resume_call(lc,calls->data) < 0)
1280                         {
1281                                 linphonec_out("There was a problem to resume the unique call.\n");
1282                         }
1283                         return 1;
1284                 }else if (nbcalls==0){
1285                         linphonec_out("There is no calls at this time.\n");
1286                         return 1;
1287                 }else{
1288                         linphonec_out("There are %i calls at this time, please specify call id as given with 'calls' command.\n");
1289                 }
1290         }
1291         return 0;
1292     
1293 }
1294
1295 /***************************************************************************
1296  *
1297  *  Commands helper functions
1298  *
1299  ***************************************************************************/
1300
1301
1302 static void
1303 linphonec_proxy_add(LinphoneCore *lc)
1304 {
1305         bool_t enable_register=FALSE;
1306         LinphoneProxyConfig *cfg;
1307
1308         linphonec_out("Adding new proxy setup. Hit ^D to abort.\n");
1309
1310         /*
1311          * SIP Proxy address
1312          */
1313         while (1)
1314         {
1315                 char *input=linphonec_readline("Enter proxy sip address: ");
1316                 char *clean;
1317
1318                 if ( ! input ) {
1319                         linphonec_out("Aborted.\n");
1320                         return;
1321                 }
1322
1323                 /* Strip blanks */
1324                 clean=lpc_strip_blanks(input);
1325                 if ( ! *clean ) {
1326                         free(input);
1327                         continue;
1328                 }
1329
1330                 cfg=linphone_proxy_config_new();
1331                 if (linphone_proxy_config_set_server_addr(cfg,clean)<0)
1332                 {
1333                         linphonec_out("Invalid sip address (sip:sip.domain.tld).\n");
1334                         free(input);
1335                         linphone_proxy_config_destroy(cfg);
1336                         continue;
1337                 }
1338                 free(input);
1339                 break;
1340         }
1341
1342         /*
1343          * SIP Proxy identity
1344          */
1345         while (1)
1346         {
1347                 char *input=linphonec_readline("Your identity for this proxy: ");
1348                 char *clean;
1349
1350                 if ( ! input ) {
1351                         linphonec_out("Aborted.\n");
1352                         linphone_proxy_config_destroy(cfg);
1353                         return;
1354                 }
1355
1356                 /* Strip blanks */
1357                 clean=lpc_strip_blanks(input);
1358                 if ( ! *clean ) {
1359                         free(input);
1360                         continue;
1361                 }
1362
1363                 linphone_proxy_config_set_identity(cfg, clean);
1364                 if ( ! cfg->reg_identity )
1365                 {
1366                         linphonec_out("Invalid identity (sip:name@sip.domain.tld).\n");
1367                         free(input);
1368                         continue;
1369                 }
1370                 free(input);
1371                 break;
1372         }
1373
1374         /*
1375          * SIP Proxy enable register
1376          */
1377         while (1)
1378         {
1379                 char *input=linphonec_readline("Do you want to register on this proxy (yes/no): ");
1380                 char *clean;
1381
1382                 if ( ! input ) {
1383                         linphonec_out("Aborted.\n");
1384                         linphone_proxy_config_destroy(cfg);
1385                         return;
1386                 }
1387
1388                 /* Strip blanks */
1389                 clean=lpc_strip_blanks(input);
1390                 if ( ! *clean ) {
1391                         free(input);
1392                         continue;
1393                 }
1394
1395                 if ( ! strcmp(clean, "yes") ) enable_register=TRUE;
1396                 else if ( ! strcmp(clean, "no") ) enable_register=FALSE;
1397                 else {
1398                         linphonec_out("Please answer with 'yes' or 'no'\n");
1399                         free(input);
1400                         continue;
1401                 }
1402                 linphone_proxy_config_enableregister(cfg, enable_register);
1403                 free(input);
1404                 break;
1405         }
1406
1407         /*
1408          * SIP Proxy registration expiration
1409          */
1410         if ( enable_register==TRUE )
1411         {
1412                 long int expires=0;
1413                 while (1)
1414                 {
1415                         char *input=linphonec_readline("Specify register expiration time"
1416                                 " in seconds (default is 600): ");
1417
1418                         if ( ! input ) {
1419                                 linphonec_out("Aborted.\n");
1420                                 linphone_proxy_config_destroy(cfg);
1421                                 return;
1422                         }
1423
1424                         expires=strtol(input, (char **)NULL, 10);
1425                         if ( expires == LONG_MIN || expires == LONG_MAX )
1426                         {
1427                                 linphonec_out("Invalid value: %s\n", strerror(errno));
1428                                 free(input);
1429                                 continue;
1430                         }
1431
1432                         linphone_proxy_config_expires(cfg, expires);
1433                         linphonec_out("Expiration: %d seconds\n", cfg->expires);
1434
1435                         free(input);
1436                         break;
1437                 }
1438         }
1439
1440         /*
1441          * SIP proxy route
1442          */
1443         while (1)
1444         {
1445                 char *input=linphonec_readline("Specify route if needed: ");
1446                 char *clean;
1447
1448                 if ( ! input ) {
1449                         linphonec_out("Aborted.\n");
1450                         linphone_proxy_config_destroy(cfg);
1451                         return;
1452                 }
1453
1454                 /* Strip blanks */
1455                 clean=lpc_strip_blanks(input);
1456                 if ( ! *clean ) {
1457                         free(input);
1458                         linphonec_out("No route specified.\n");
1459                         break;
1460                 }
1461
1462                 linphone_proxy_config_set_route(cfg, clean);
1463                 if ( ! cfg->reg_route )
1464                 {
1465                         linphonec_out("Invalid route.\n");
1466                         free(input);
1467                         continue;
1468                 }
1469
1470                 free(input);
1471                 break;
1472         }
1473
1474         /*
1475          * Final confirmation 
1476          */
1477         while (1)
1478         {
1479                 char *input;
1480                 char *clean;
1481
1482                 linphonec_out("--------------------------------------------\n");
1483                 linphonec_proxy_display(cfg);
1484                 linphonec_out("--------------------------------------------\n");
1485                 input=linphonec_readline("Accept the above proxy configuration (yes/no) ?: ");
1486
1487
1488                 if ( ! input ) {
1489                         linphonec_out("Aborted.\n");
1490                         linphone_proxy_config_destroy(cfg);
1491                         return;
1492                 }
1493
1494                 /* Strip blanks */
1495                 clean=lpc_strip_blanks(input);
1496                 if ( ! *clean ) {
1497                         free(input);
1498                         continue;
1499                 }
1500
1501                 if ( ! strcmp(clean, "yes") ) break;
1502                 else if ( ! strcmp(clean, "no") )
1503                 {
1504                         linphonec_out("Declined.\n");
1505                         linphone_proxy_config_destroy(cfg);
1506                         free(input);
1507                         return;
1508                 }
1509
1510                 linphonec_out("Please answer with 'yes' or 'no'\n");
1511                 free(input);
1512                 continue;
1513         }
1514
1515
1516         linphone_core_add_proxy_config(lc,cfg);
1517
1518         /* automatically set the last entered proxy as the default one */
1519         linphone_core_set_default_proxy(lc,cfg);
1520
1521         linphonec_out("Proxy added.\n");
1522 }
1523
1524 static void
1525 linphonec_proxy_display(LinphoneProxyConfig *cfg)
1526 {
1527         linphonec_out("sip address: %s\nroute: %s\nidentity: %s\nregister: %s\nexpires: %i\nregistered: %s\n",
1528                         cfg->reg_proxy,
1529                         (cfg->reg_route!=NULL)?cfg->reg_route:"",
1530                         (cfg->reg_identity!=NULL)?cfg->reg_identity:"",
1531                         (cfg->reg_sendregister)?"yes":"no",
1532                         cfg->expires,
1533                         linphone_proxy_config_is_registered(cfg) ? "yes" : "no");
1534 }
1535
1536 static void linphonec_proxy_show(LinphoneCore *lc, int index)
1537 {
1538         const MSList *elem;
1539         int i;
1540         for(elem=linphone_core_get_proxy_config_list(lc),i=0;elem!=NULL;elem=elem->next,++i){
1541                 if (index==i){
1542                         LinphoneProxyConfig *cfg=(LinphoneProxyConfig *)elem->data;
1543                         linphonec_proxy_display(cfg);
1544                         return;
1545                 }
1546         }
1547         linphonec_out("No proxy with index %i\n", index);
1548 }
1549
1550 static void
1551 linphonec_proxy_list(LinphoneCore *lc)
1552 {
1553         const MSList *proxies;
1554         int n;
1555         int def=linphone_core_get_default_proxy(lc,NULL);
1556         
1557         proxies=linphone_core_get_proxy_config_list(lc);
1558         for(n=0;proxies!=NULL;proxies=ms_list_next(proxies),n++){
1559                 if (n==def)
1560                         linphonec_out("****** Proxy %i - this is the default one - *******\n",n);
1561                 else 
1562                         linphonec_out("****** Proxy %i *******\n",n);
1563                 linphonec_proxy_display((LinphoneProxyConfig*)proxies->data);
1564         }
1565         if ( ! n ) linphonec_out("No proxies defined\n");
1566 }
1567
1568 static void
1569 linphonec_proxy_remove(LinphoneCore *lc, int index)
1570 {
1571         const MSList *proxies;
1572         LinphoneProxyConfig *cfg;
1573         proxies=linphone_core_get_proxy_config_list(lc);
1574         cfg=(LinphoneProxyConfig*)ms_list_nth_data(proxies,index);
1575         if (cfg==NULL){
1576                 linphonec_out("No such proxy.\n");
1577                 return;
1578         }
1579         linphone_core_remove_proxy_config(lc,cfg);
1580         linphonec_out("Proxy %s removed.\n", cfg->reg_proxy);
1581         linphone_proxy_config_destroy(cfg);
1582 }
1583
1584 static int
1585 linphonec_proxy_use(LinphoneCore *lc, int index)
1586 {
1587         const MSList *proxies;
1588         LinphoneProxyConfig *cfg;
1589         proxies=linphone_core_get_proxy_config_list(lc);
1590         cfg=(LinphoneProxyConfig*)ms_list_nth_data(proxies,index);
1591         if (cfg==NULL){
1592                 linphonec_out("No such proxy (try 'proxy list').");
1593                 return 0;
1594         }
1595         linphone_core_set_default_proxy(lc,cfg);
1596         return 1;
1597 }
1598
1599 static void
1600 linphonec_friend_display(LinphoneFriend *fr)
1601 {
1602         LinphoneAddress *uri=linphone_address_clone(linphone_friend_get_address(fr));
1603         char *str;
1604         
1605         linphonec_out("name: %s\n", linphone_address_get_display_name(uri));
1606         linphone_address_set_display_name(uri,NULL);
1607         str=linphone_address_as_string(uri);
1608         linphonec_out("address: %s\n", str);
1609 }
1610
1611 static int
1612 linphonec_friend_list(LinphoneCore *lc, char *pat)
1613 {
1614         const MSList *friend;
1615         int n;
1616
1617         if (pat) {
1618                 pat=lpc_strip_blanks(pat);
1619                 if (!*pat) pat = NULL;
1620         }
1621
1622         friend = linphone_core_get_friend_list(lc);
1623         for(n=0; friend!=NULL; friend=ms_list_next(friend), ++n )
1624         {
1625                 if ( pat ) {
1626                         const char *name = linphone_address_get_display_name(
1627                             linphone_friend_get_address((LinphoneFriend*)friend->data));
1628                         if (name && ! strstr(name, pat) ) continue;
1629                 }
1630                 linphonec_out("****** Friend %i *******\n",n);
1631                 linphonec_friend_display((LinphoneFriend*)friend->data);
1632         }
1633
1634         return 1;
1635 }
1636
1637 static int
1638 linphonec_friend_call(LinphoneCore *lc, unsigned int num)
1639 {
1640         const MSList *friend = linphone_core_get_friend_list(lc);
1641         unsigned int n;
1642         char *addr;
1643
1644         for(n=0; friend!=NULL; friend=ms_list_next(friend), ++n )
1645         {
1646                 if ( n == num )
1647                 {
1648                         int ret;
1649                         addr = linphone_address_as_string(linphone_friend_get_address((LinphoneFriend*)friend->data));
1650                         ret=lpc_cmd_call(lc, addr);
1651                         ms_free(addr);
1652                         return ret;
1653                 }
1654         }
1655         linphonec_out("No such friend %u\n", num);
1656         return 1;
1657 }
1658
1659 #ifndef WIN32
1660 static int
1661 linphonec_friend_add(LinphoneCore *lc, const char *name, const char *addr)
1662 {
1663         LinphoneFriend *newFriend;
1664
1665         char url[PATH_MAX];
1666
1667         snprintf(url, PATH_MAX, "%s <%s>", name, addr);
1668         newFriend = linphone_friend_new_with_addr(url);
1669         linphone_core_add_friend(lc, newFriend);
1670         return 0;
1671 }
1672 #endif
1673
1674 static int
1675 linphonec_friend_delete(LinphoneCore *lc, int num)
1676 {
1677         const MSList *friend = linphone_core_get_friend_list(lc);
1678         unsigned int n;
1679
1680         for(n=0; friend!=NULL; friend=ms_list_next(friend), ++n )
1681         {
1682                 if ( n == num )
1683                 {
1684                         linphone_core_remove_friend(lc, friend->data);
1685                         return 0;
1686                 }
1687         }
1688
1689         if (-1 == num) 
1690         {
1691                 unsigned int i;
1692                 for (i = 0 ; i < n ; i++)
1693                         linphonec_friend_delete(lc, 0);
1694                 return 0;
1695         }
1696
1697         linphonec_out("No such friend %u\n", num);
1698         return 1;
1699 }
1700
1701 static void
1702 linphonec_display_command_help(LPC_COMMAND *cmd)
1703 {
1704         if ( cmd->doc ) linphonec_out ("%s\n", cmd->doc);
1705         else linphonec_out("%s\n", cmd->help);
1706 }
1707
1708
1709 static int lpc_cmd_register(LinphoneCore *lc, char *args){
1710         char identity[512];
1711         char proxy[512];
1712         char passwd[512];
1713         LinphoneProxyConfig *cfg;
1714         const MSList *elem;
1715     
1716         if (!args)
1717         {
1718                 /* it means that you want to register the default proxy */
1719                 LinphoneProxyConfig *cfg=NULL;
1720                 linphone_core_get_default_proxy(lc,&cfg);
1721                 if (cfg)
1722                 {
1723                         if(!linphone_proxy_config_is_registered(cfg)) {
1724                                 linphone_proxy_config_enable_register(cfg,TRUE);
1725                                 linphone_proxy_config_done(cfg);
1726                         }else{
1727                                 linphonec_out("default proxy already registered\n");
1728                         }
1729                 }else{
1730                         linphonec_out("we do not have a default proxy\n");
1731                         return 0;
1732                 }
1733                 return 1;
1734         }
1735         passwd[0]=proxy[0]=identity[0]='\0';
1736         sscanf(args,"%s %s %s",identity,proxy,passwd);
1737         if (proxy[0]=='\0' || identity[0]=='\0'){
1738                 linphonec_out("Missing parameters, see help register\n");
1739                 return 1;
1740         }
1741         if (passwd[0]!='\0'){
1742                 LinphoneAddress *from;
1743                 LinphoneAuthInfo *info;
1744                 if ((from=linphone_address_new(identity))!=NULL){
1745                         char realm[128];
1746                         snprintf(realm,sizeof(realm)-1,"\"%s\"",linphone_address_get_domain(from));
1747                         info=linphone_auth_info_new(linphone_address_get_username(from),NULL,passwd,NULL,NULL);
1748                         linphone_core_add_auth_info(lc,info);
1749                         linphone_address_destroy(from);
1750                         linphone_auth_info_destroy(info);
1751                 }
1752         }
1753         elem=linphone_core_get_proxy_config_list(lc);
1754         if (elem) {
1755                 cfg=(LinphoneProxyConfig*)elem->data;
1756                 linphone_proxy_config_edit(cfg);
1757         }
1758         else cfg=linphone_proxy_config_new();
1759         linphone_proxy_config_set_identity(cfg,identity);
1760         linphone_proxy_config_set_server_addr(cfg,proxy);
1761         linphone_proxy_config_enable_register(cfg,TRUE);
1762         if (elem) linphone_proxy_config_done(cfg);
1763         else linphone_core_add_proxy_config(lc,cfg);
1764         linphone_core_set_default_proxy(lc,cfg);
1765         return 1;
1766 }
1767
1768 static int lpc_cmd_unregister(LinphoneCore *lc, char *args){
1769         LinphoneProxyConfig *cfg=NULL;
1770         linphone_core_get_default_proxy(lc,&cfg);
1771         if (cfg && linphone_proxy_config_is_registered(cfg)) {
1772                 linphone_proxy_config_edit(cfg);
1773                 linphone_proxy_config_enable_register(cfg,FALSE);
1774                 linphone_proxy_config_done(cfg);
1775         }else{
1776                 linphonec_out("unregistered\n");
1777         }
1778         return 1;
1779 }
1780
1781 static int lpc_cmd_duration(LinphoneCore *lc, char *args){
1782         LinphoneCallLog *cl;
1783         const MSList *elem=linphone_core_get_call_logs(lc);
1784         for(;elem!=NULL;elem=elem->next){
1785                 if (elem->next==NULL){
1786                         cl=(LinphoneCallLog*)elem->data;
1787                         linphonec_out("%i seconds\n",cl->duration);
1788                 }
1789         }
1790         return 1;
1791 }
1792
1793 static int lpc_cmd_status(LinphoneCore *lc, char *args)
1794 {
1795         LinphoneProxyConfig *cfg;
1796         
1797         if ( ! args ) return 0;
1798         linphone_core_get_default_proxy(lc,&cfg);
1799         if (strstr(args,"register"))
1800         {
1801                 if (cfg)
1802                 {
1803                         if (linphone_proxy_config_is_registered(cfg)){
1804                                 linphonec_out("registered, identity=%s duration=%i\n",
1805                                         linphone_proxy_config_get_identity(cfg),
1806                                         linphone_proxy_config_get_expires(cfg));
1807                         }else if (linphone_proxy_config_register_enabled(cfg)){
1808                                 linphonec_out("registered=-1\n");
1809                         }else linphonec_out("registered=0\n");
1810                 }
1811                 else linphonec_out("registered=0\n");
1812         }
1813         else if (strstr(args,"autoanswer"))
1814         {
1815                 if (cfg && linphone_proxy_config_is_registered(cfg))
1816                         linphonec_out("autoanswer=%i\n",linphonec_get_autoanswer());
1817                 else linphonec_out("unregistered\n");
1818         }
1819         else if (strstr(args,"hook"))
1820         {
1821                 LinphoneCall *call=linphone_core_get_current_call (lc);
1822                 LinphoneCallState call_state=LinphoneCallIdle;
1823                 if (call) call_state=linphone_call_get_state(call);
1824
1825                 switch(call_state){
1826                         case LinphoneCallOutgoingInit:
1827                         case LinphoneCallOutgoingProgress:
1828                                 linphonec_out("hook=dialing\n");
1829                         break;
1830                         case LinphoneCallIdle:
1831                                 linphonec_out("hook=offhook\n");
1832                         break;
1833                         case LinphoneCallStreamsRunning:
1834                         case LinphoneCallConnected:
1835                                 if (linphone_call_get_dir(call)==LinphoneCallOutgoing){
1836                                         linphonec_out("Call out, hook=%s duration=%i, muted=%s rtp-xmit-muted=%s\n", linphonec_get_callee(),
1837                                               linphone_core_get_current_call_duration(lc),
1838                                               linphone_core_is_mic_muted (lc) ? "yes" : "no",
1839                                               linphone_core_is_rtp_muted(lc) ? "yes"  : "no");
1840                                 }else{
1841                                         linphonec_out("hook=answered duration=%i\n" ,
1842                                                 linphone_core_get_current_call_duration(lc));
1843                                 }
1844                                 break;
1845                         case LinphoneCallIncomingReceived:
1846                                 linphonec_out("Incoming call from %s\n",linphonec_get_caller());
1847                                 break;
1848                         default:
1849                                 break;
1850                 }
1851                 
1852         }
1853         else return 0;
1854
1855         return 1;
1856 }
1857
1858 static int lpc_cmd_ports(LinphoneCore *lc, char *args)
1859 {
1860         int port;
1861         if ( ! args ){
1862                 linphonec_out("sip port = %i\naudio rtp port = %i\nvideo rtp port = %i\n",
1863                         linphone_core_get_sip_port(lc),
1864                         linphone_core_get_audio_port(lc),
1865                         linphone_core_get_video_port(lc));
1866                 return 1;
1867         }
1868         if (sscanf(args,"sip %i",&port)==1){
1869                 linphonec_out("Setting sip port to %i\n",port);
1870                 linphone_core_set_sip_port(lc,port);
1871         }else return 0;
1872
1873         return 1;
1874 }
1875
1876 static int lpc_cmd_speak(LinphoneCore *lc, char *args){
1877 #ifndef WIN32
1878         char voice[64];
1879         char *sentence;
1880         char cl[128];
1881         char *wavfile;
1882         int status;
1883         FILE *file;
1884         
1885     if (!args) return 0;
1886         memset(voice,0,sizeof(voice));
1887         sscanf(args,"%s63",voice);
1888         sentence=args+strlen(voice);
1889         wavfile=tempnam("/tmp/","linphonec-espeak-");
1890         snprintf(cl,sizeof(cl),"espeak -v %s -s 100 -w %s --stdin",voice,wavfile);
1891         file=popen(cl,"w");
1892         if (file==NULL){
1893                 ms_error("Could not open pipe to espeak !");
1894                 return 1;
1895         }
1896         fprintf(file,"%s",sentence);
1897         status=pclose(file);
1898         if (WEXITSTATUS(status)==0){
1899                 linphone_core_set_play_file(lc,wavfile);
1900         }else{
1901                 linphonec_out("espeak command failed.");
1902         }
1903 #else
1904         linphonec_out("Sorry, this command is not implemented in windows version.");
1905 #endif
1906         return 1;
1907 }
1908
1909 static int lpc_cmd_acodec(LinphoneCore *lc, char *args){
1910     return lpc_cmd_codec(AUDIO, lc, args);
1911 }
1912
1913 static int lpc_cmd_vcodec(LinphoneCore *lc, char *args){
1914     return lpc_cmd_codec(VIDEO, lc, args);
1915 }
1916
1917 static int lpc_cmd_codec(int type, LinphoneCore *lc, char *args){
1918         char *arg1 = args;
1919         char *arg2 = NULL;
1920         char *ptr = args;
1921
1922         if (!args) return 0;
1923
1924         /* Isolate first and second arg */
1925         while(*ptr && !isspace(*ptr)) ++ptr;
1926         if ( *ptr )
1927         {
1928                 *ptr='\0';
1929                 arg2=ptr+1;
1930                 while(*arg2 && isspace(*arg2)) ++arg2;
1931         }
1932
1933         if (strcmp(arg1,"enable")==0)
1934         {
1935 #ifdef HAVE_READLINE
1936                 rl_inhibit_completion=1;
1937 #endif
1938         if (!strcmp(arg2,"all")) linphonec_codec_enable(type,lc,-1);
1939         else linphonec_codec_enable(type,lc,atoi(arg2));
1940 #ifdef HAVE_READLINE
1941                 rl_inhibit_completion=0;
1942 #endif
1943         }
1944         else if (strcmp(arg1,"list")==0)
1945         {
1946                 linphonec_codec_list(type,lc);
1947         }
1948         else if (strcmp(arg1,"disable")==0)
1949         {
1950         if (!strcmp(arg2,"all")) linphonec_codec_disable(type,lc,-1);
1951         else linphonec_codec_disable(type,lc,atoi(arg2));
1952         }
1953         else
1954         {
1955                 return 0; /* syntax error */
1956         }
1957
1958         return 1;
1959 }
1960
1961 static void linphonec_codec_list(int type, LinphoneCore *lc){
1962         PayloadType *pt;
1963     codecs_config_t *config=&lc->codecs_conf;
1964         int index=0;
1965         MSList *node=NULL;
1966
1967     if (type == AUDIO) {
1968       node=config->audio_codecs;
1969     } else if(type==VIDEO) {
1970       node=config->video_codecs;
1971     }
1972
1973         for(;node!=NULL;node=ms_list_next(node)){
1974                 pt=(PayloadType*)(node->data);
1975         linphonec_out("%2d: %s (%d) %s\n", index, pt->mime_type, pt->clock_rate, 
1976                     linphone_core_payload_type_enabled(lc,pt) ? "enabled" : "disabled");
1977                 index++;
1978         }
1979 }
1980
1981 static void linphonec_codec_enable(int type, LinphoneCore *lc, int sel_index){
1982         PayloadType *pt;
1983     codecs_config_t *config=&lc->codecs_conf;
1984         int index=0;
1985         MSList *node=NULL;
1986
1987     if (type == AUDIO) {
1988       node=config->audio_codecs;
1989     } else if(type==VIDEO) {
1990       node=config->video_codecs;
1991     }
1992
1993     for(;node!=NULL;node=ms_list_next(node)){
1994         if (index == sel_index || sel_index == -1) {
1995                     pt=(PayloadType*)(node->data);
1996             pt->flags|=PAYLOAD_TYPE_ENABLED;
1997             linphonec_out("%2d: %s (%d) %s\n", index, pt->mime_type, pt->clock_rate, "enabled");
1998         }
1999                 index++;
2000         }
2001 }
2002
2003 static void linphonec_codec_disable(int type, LinphoneCore *lc, int sel_index){
2004         PayloadType *pt;
2005     codecs_config_t *config=&lc->codecs_conf;
2006         int index=0;
2007         MSList *node=NULL;
2008
2009     if (type == AUDIO) {
2010       node=config->audio_codecs;
2011     } else if(type==VIDEO) {
2012       node=config->video_codecs;
2013     }
2014
2015         for(;node!=NULL;node=ms_list_next(node)){
2016         if (index == sel_index || sel_index == -1) {
2017                 pt=(PayloadType*)(node->data);
2018             pt->flags&=~PAYLOAD_TYPE_ENABLED;
2019             linphonec_out("%2d: %s (%d) %s\n", index, pt->mime_type, pt->clock_rate, "disabled");
2020         }
2021                 index++;
2022         }
2023 }
2024
2025 static int lpc_cmd_echocancellation(LinphoneCore *lc, char *args){
2026         char *arg1 = args;
2027         char *arg2 = NULL;
2028         char *ptr = args;
2029
2030         if (!args) return 0;
2031
2032         /* Isolate first and second arg */
2033         while(*ptr && !isspace(*ptr)) ++ptr;
2034         if ( *ptr )
2035         {
2036                 *ptr='\0';
2037                 arg2=ptr+1;
2038                 while(*arg2 && isspace(*arg2)) ++arg2;
2039         }
2040
2041         if (strcmp(arg1,"on")==0){
2042         int delay, tail_len, frame_size;
2043         int n;
2044
2045         linphone_core_enable_echo_cancellation(lc,1);
2046
2047         if (arg2 != 0) {
2048             n = sscanf(arg2, "%d %d %d", &delay, &tail_len, &frame_size);
2049
2050             if (n == 1) {   
2051                 lp_config_set_int(lc->config,"sound","ec_delay",delay);
2052             }
2053             else if (n == 2) {
2054                 lp_config_set_int(lc->config,"sound","ec_delay",delay);
2055                 lp_config_set_int(lc->config,"sound","ec_tail_len",tail_len);
2056             }
2057             else if (n == 3) {
2058                 lp_config_set_int(lc->config,"sound","ec_delay",delay);
2059                 lp_config_set_int(lc->config,"sound","ec_tail_len",tail_len);
2060                 lp_config_set_int(lc->config,"sound","ec_framesize",frame_size);
2061             }
2062         }
2063     }
2064     else if (strcmp(arg1,"off")==0){
2065         linphone_core_enable_echo_cancellation(lc,0);
2066     }
2067     else if (strcmp(arg1,"show")==0){
2068         linphonec_out("echo cancellation is %s; delay %d, tail length %d, frame size %d\n", 
2069             linphone_core_echo_cancellation_enabled(lc) ? "on" : "off",
2070             lp_config_get_int(lc->config,"sound","ec_delay",0),
2071             lp_config_get_int(lc->config,"sound","ec_tail_len",0),
2072             lp_config_get_int(lc->config,"sound","ec_framesize",0));        
2073     }
2074     else {
2075         return 0;
2076     }
2077
2078     return 1;
2079 }
2080
2081 static int lpc_cmd_mute_mic(LinphoneCore *lc, char *args)
2082 {
2083         linphone_core_mute_mic(lc, 1);
2084         return 1;
2085 }
2086
2087 static int lpc_cmd_unmute_mic(LinphoneCore *lc, char *args){
2088         linphone_core_mute_mic(lc, 0);
2089         return 1;
2090 }
2091
2092 static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args)
2093 {
2094         bool_t rtp_xmit_off=FALSE;
2095         char *status;
2096
2097         if(args){
2098                 if(strstr(args,"1"))rtp_xmit_off=TRUE;
2099                 if(linphone_core_get_current_call (lc)==NULL)
2100                         linphone_core_set_rtp_no_xmit_on_audio_mute(lc,rtp_xmit_off);
2101                 else 
2102                         linphonec_out("nortp-on-audio-mute: call in progress - cannot change state\n");
2103         }
2104         rtp_xmit_off=linphone_core_get_rtp_no_xmit_on_audio_mute(lc);
2105         if (rtp_xmit_off) status="off";
2106         else status="on";
2107         linphonec_out("rtp transmit %s when audio muted\n",status);
2108         return 1;
2109 }
2110
2111
2112 /***************************************************************************
2113  *
2114  *  Command table management funx
2115  *
2116  ***************************************************************************/
2117
2118 /*
2119  * Find a command given its name
2120  */
2121 static LPC_COMMAND *
2122 lpc_find_command(const char *name)
2123 {
2124         int i;
2125
2126         for (i=0; commands[i].name; ++i)
2127         {
2128                 if (strcmp(name, commands[i].name) == 0)
2129                         return &commands[i];
2130         }
2131
2132         return (LPC_COMMAND *)NULL;
2133 }
2134
2135
2136 /****************************************************************************
2137  *
2138  * $Log: commands.c,v $
2139  * Revision 1.39  2008/07/03 15:08:34  smorlat
2140  * api cleanups, interface in progress.
2141  *
2142  * Revision 1.38  2008/06/17 20:38:59  smorlat
2143  * added missing file.
2144  *
2145  * Revision 1.37  2008/04/09 09:26:00  smorlat
2146  * merge various patches
2147  * H264 support.
2148  *
2149  * Revision 1.36  2007/08/01 14:47:53  strk
2150  *         * console/commands.c: Clean up commands 'nat', 'stun'
2151  *           and 'firewall' to be more intuitive.
2152  *
2153  * Revision 1.35  2007/06/27 09:01:25  smorlat
2154  * logging improvements.
2155  *
2156  * Revision 1.34  2007/02/20 10:17:13  smorlat
2157  * linphonec friends patch2
2158  *
2159  * Revision 1.31  2006/09/22 07:22:47  smorlat
2160  * linphonecore api changes.
2161  *
2162  * Revision 1.30  2006/09/08 15:32:57  smorlat
2163  * support for using files instead of soundcard (used by linphonec only)
2164  *
2165  * Revision 1.29  2006/08/28 14:29:07  smorlat
2166  * fix bug.
2167  *
2168  * Revision 1.28  2006/08/21 12:49:59  smorlat
2169  * merged several little patches.
2170  *
2171  * Revision 1.27  2006/07/17 18:45:00  smorlat
2172  * support for several event queues in ortp.
2173  * glib dependency removed from coreapi/ and console/
2174  *
2175  * Revision 1.26  2006/04/14 15:16:36  smorlat
2176  * soundcard use did nothing !
2177  *
2178  * Revision 1.25  2006/04/06 20:09:33  smorlat
2179  * add linphonec command to see and select sound devices.
2180  *
2181  * Revision 1.24  2006/03/04 11:17:10  smorlat
2182  * mediastreamer2 in progress.
2183  *
2184  * Revision 1.23  2006/02/20 21:14:01  strk
2185  * Handled syntax errors with 'friend' command
2186  *
2187  * Revision 1.22  2006/02/20 10:20:29  strk
2188  * Added substring-based filter support for command 'friend list'
2189  *
2190  * Revision 1.21  2006/02/02 15:39:18  strk
2191  * - Added 'friend list' and 'friend call' commands
2192  * - Allowed for multiple DTFM send in a single line
2193  * - Added status-specific callback (bare version)
2194  *
2195  * Revision 1.20  2006/01/26 11:54:34  strk
2196  * More robust 'nat' command handler (strip blanks in args)
2197  *
2198  * Revision 1.19  2006/01/26 09:48:05  strk
2199  * Added limits.h include
2200  *
2201  * Revision 1.18  2006/01/26 02:18:05  strk
2202  * Added new commands 'nat use' and 'nat unuse'.
2203  * These will required a pending patch to linphonecore.c
2204  * in order to work.
2205  *
2206  * Revision 1.17  2006/01/20 14:12:33  strk
2207  * Added linphonec_init() and linphonec_finish() functions.
2208  * Handled SIGINT and SIGTERM to invoke linphonec_finish().
2209  * Handling of auto-termination (-t) moved to linphonec_finish().
2210  * Reworked main (input read) loop to not rely on 'terminate'
2211  * and 'run' variable (dropped). configfile_name allocated on stack
2212  * using PATH_MAX limit. Changed print_usage signature to allow
2213  * for an exit_status specification.
2214  *
2215  * Revision 1.16  2006/01/18 09:25:32  strk
2216  * Command completion inhibited in proxy addition and auth request prompts.
2217  * Avoided use of linphonec_readline's internal filename completion.
2218  *
2219  * Revision 1.15  2006/01/14 13:29:32  strk
2220  * Reworked commands interface to use a table structure,
2221  * used by command line parser and help function.
2222  * Implemented first level of completion (commands).
2223  * Added notification of invalid "answer" and "terminate"
2224  * commands (no incoming call, no active call).
2225  * Forbidden "call" intialization when a call is already active.
2226  * Cleaned up all commands, adding more feedback and error checks.
2227  *
2228  * Revision 1.14  2006/01/13 13:00:29  strk
2229  * Added linphonec.h. Code layout change (added comments, forward decl,
2230  * globals on top, copyright notices and Logs). Handled out-of-memory
2231  * condition on history management. Removed assumption on sizeof(char).
2232  * Fixed bug in authentication prompt (introduced by linphonec_readline).
2233  * Added support for multiple authentication requests (up to MAX_PENDING_AUTH).
2234  *
2235  *
2236  ****************************************************************************/