/**************************************************************************** * Copyright (C) 2009 Simon MORLAT * **************************************************************************** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ****************************************************************************/ #include #include #include #include #ifdef _WIN32 #include #include #include #include #include #else #include #include #include #endif #include "ortp/ortp.h" #include #define DEFAULT_REPLY_SIZE 4096 #define STATUS_REGISTERED (1<<0) #define STATUS_REGISTERING (1<<1) #define STATUS_DIALING (1<<2) #define STATUS_AUTOANSWER (1<<3) #define STATUS_IN_CONNECTED (1<<4) /* incoming call accepted */ #define STATUS_OUT_CONNECTED (1<<5) /*outgoing call accepted */ #define STATUS_IN_COMING (1<<6) /*incoming call pending */ static int make_status_value(const char *status_string){ int ret=0; if (strstr(status_string,"registered, identity=")){ ret|=STATUS_REGISTERED; } if (strstr(status_string,"registered=-1")){ ret|=STATUS_REGISTERING; } if (strstr(status_string,"autoanswer=1")){ ret|=STATUS_AUTOANSWER; } if (strstr(status_string,"dialing")){ ret|=STATUS_DIALING; } if (strstr(status_string,"Call out")){ ret|=STATUS_OUT_CONNECTED; } if (strstr(status_string,"hook=answered")){ ret|=STATUS_IN_CONNECTED; } if (strstr(status_string,"Incoming call from ")){ ret|=STATUS_IN_COMING; } return ret; } static int send_command(const char *command, char *reply, int reply_len, int print_errors){ ortp_pipe_t pp; int i; int err; char path[128]; #ifndef _WIN32 snprintf(path,sizeof(path)-1,"linphonec-%i",getuid()); #else { char username[128]; DWORD size=sizeof(username)-1; GetUserName(username,&size); snprintf(path,sizeof(path)-1,"linphonec-%s",username); } #endif if ((pp=ortp_client_pipe_connect(path))==ORTP_PIPE_INVALID){ if (print_errors) fprintf(stderr,"ERROR: Failed to connect pipe: %s\n",strerror(errno)); return -1; } if (ortp_pipe_write(pp,(uint8_t*)command,strlen(command))==-1){ if (print_errors) fprintf(stderr,"ERROR: Fail to send command to remote linphonec\n"); ortp_client_pipe_close(pp); return -1; } /*wait for replies */ i=0; while ((err=ortp_pipe_read(pp,(uint8_t*)&reply[i],reply_len-i-1))>0){ i+=err; } reply[i]='\0'; ortp_client_pipe_close(pp); return 0; } static void print_usage(void){ fprintf(stderr,"Usage:\nlinphonecsh [arguments]\n" "where action is one of\n" "\tinit\t\t: spawn a linphonec daemon (first step to make other actions)\n" "\t\t\tfollowed by the arguments sent to linphonec\n" "\tgeneric\t\t: sends a generic command to the running linphonec daemon\n" "\t\t\tfollowed by the generic command surrounded by quotes,\n\t\t\t for example \"call sip:joe@example.net\"\n" "\tregister\t: register; arguments are \n\t\t\t--host \n\t\t\t--username \n\t\t\t--password \n" "\tunregister\t: unregister\n" "\tdial\t\t: dial \n" "\tstatus\t\t: can be 'status register', 'status autoanswer' or 'status hook'\n" "\tsoundcard\t: can be 'soundcard capture', 'soundcard playback', 'soundcard ring',\n" "\t\t\t followed by an optional number representing the index of the soundcard,\n" "\t\t\t in which case the soundcard is set instead of just read.\n" "\texit\t\t: make the linphonec daemon to exit.\n" ); exit(-1); } #ifdef _WIN32 static char *argv_to_line(int argc, char *argv[]) { int i; int line_length; char *line; assert( argc>=0 ); if(argc == 0) return NULL; line_length = strlen(argv[0]); for(i=1; i