📄 minisiptextui.cxx
字号:
/* * 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 Library 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. *//* Copyright (C) 2004 * * Authors: Erik Eliasson <eliasson@it.kth.se> * Johan Bilien <jobi@via.ecp.fr>*/#include<config.h>#include<stdio.h>#include<vector>#include"MinisipTextUI.h"#include<libmutil/MemObject.h>#include<libmutil/trim.h>#include<libmutil/termmanip.h>#include<libmsip/SipDialogContainer.h>#include<libmsip/SipCommandString.h>#include"../../../sip/DefaultDialogHandler.h"extern TextUI *debugtextui;#ifdef DEBUG_OUTPUTextern bool sipdebug_print_packets;#endifMinisipTextUI::MinisipTextUI(): TextUI(), autoanswer(false){ inCall=false; p2tmode=false;#ifdef DEBUG_OUTPUT mdbg << "Setting global MinisipTextUI"<< end; debugtextui=this;#endif addCommand("answer"); addCommand("disable autoanswer"); addCommand("enable autoanswer"); addCommand("enable debugmsgs"); addCommand("disable debugmsgs"); addCommand("hangup"); addCommand("hide packets"); addCommand("register"); addCommand("show all"); addCommand("show calls"); addCommand("show transactions"); addCommand("show packets"); addCommand("cmd"); addCommand("accept"); //accept incoming P2T Session addCommand("deny"); //deny incoming P2T Session addCommand("im"); //deny incoming P2T Session// addCommand("quit"); addCompletionCallback("call", this); addCompletionCallback("im", this); state="IDLE"; setPrompt("IDLE"); }void MinisipTextUI::run(){ guimain();}void MinisipTextUI::displayErrorMessage(string msg){ displayMessage(msg, red);}minilist<std::string> MinisipTextUI::textuiCompletionSuggestion(string match){ minilist<std::string> ret;//TODO: implement it with the new phonebook./* if (!config.isNull()){ list<string> phonebooks = config->phonebooks; for (list<string>::iterator i=phonebooks.begin(); i!=phonebooks.end(); i++){ if ((*i).size()<=7) return ret;; XMLParser *parser; if ((*i).substr(0,7)=="file://"){ // cerr << "Creating XML file parser"<< endl; parser = new XMLFileParser((*i).substr(7)); }else{ continue; } string phonebook; int phonebooks=0; do{ string q = "phonebook["+itoa(phonebooks)+"]/name"; phonebook=parser->getValue(q,""); if (phonebook!=""){ string contact; int contacts=0; do{ string q = "phonebook["+itoa(phonebooks)+"]/contact["+itoa(contacts)+"]/name"; contact = parser->getValue(q,""); if (contact!=""){ int pops=0; string qbase; string desc; do{ string qbase = "phonebook["+itoa(phonebooks)+"]/contact["+itoa(contacts)+"]/pop["+itoa(pops)+"]/"; desc = parser->getValue(qbase+"desc",""); if (desc!=""){ string uri = parser->getValue(qbase+"uri",""); ret.push_back("call "+uri); } pops++; }while(desc!=""); } contacts++; }while(contact!=""); } phonebooks++; }while(phonebook!=""); delete parser; } }*/ return ret;}void MinisipTextUI::handleCommand(CommandString cmd){#ifdef DEBUG_OUTPUT mdbg << FG_MAGENTA << "MinisipTextUI::handleCommand: Got "<<cmd.getString() << PLAIN <<end;#endif if (cmd.getOp()=="register_ok"){ displayMessage("Register to proxy "+cmd.getParam()+" OK", green); } if (cmd.getOp()==SipCommandString::incoming_im){ displayMessage("IM to <"+cmd.getParam3()+"> from <"+cmd.getParam2()+">: "+cmd.getParam(), bold); } if (cmd.getOp()=="invite_ok"){ state="INCALL"; setPrompt(state); displayMessage("PROGRESS: remote participant accepted the call...", blue); } if (cmd.getOp()=="remote_ringing"){ state="REMOTE RINGING"; setPrompt(state); displayMessage("PROGRESS: the remove UA is ringing...", blue); } if (autoanswer && cmd.getOp()==SipCommandString::incoming_available){ CommandString command(callId, SipCommandString::accept_invite); callback->guicb_handleCommand(command); state="INCALL"; setPrompt(state); displayMessage("Autoanswered call from "+ cmd.getParam()); return; } if (cmd.getOp()==SipCommandString::remote_user_not_found && !p2tmode){ state="IDLE"; setPrompt(state); displayMessage("User "+cmd.getParam()+" not found.",red); callId=""; //FIXME: should check the callId of cmd. } if (cmd.getOp()==SipCommandString::remote_hang_up){ state="IDLE"; setPrompt(state); displayMessage("Remote user ended the call.",red); callId=""; //FIXME: should check the callId of cmd. } if (cmd.getOp()==SipCommandString::transport_error && !p2tmode){ state="IDLE"; setPrompt(state); displayMessage("The call could not be completed because of a network error.", red); callId=""; //FIXME: should check the callId of cmd. } if (cmd.getOp()=="error_message"){ displayMessage("ERROR: "+cmd.getParam(), red); } if (cmd.getOp()=="remote_reject" && !p2tmode){ state="IDLE"; setPrompt(state); callId=""; displayMessage("The remote user rejected the call.", red); } if (cmd.getOp()==SipCommandString::incoming_available){ if(!inCall){ state="ANSWER?"; setPrompt(state); callId=cmd.getDestinationId(); displayMessage("The incoming call from "+cmd.getParam(), blue); } else{ displayMessage("You missed call from "+cmd.getParam(), red); CommandString hup(cmd.getDestinationId(), SipCommandString::reject_invite); callback->guicb_handleCommand(hup); } } //P2T commands if (cmd.getOp()=="p2tFloorGranted"){ displayMessage("Floor is granted!!!", blue); }else if (cmd.getOp()=="p2tFloorTaken"){ displayMessage("Floor is granted to "+cmd.getParam(),blue); } else if (cmd.getOp()=="p2tFloorReleased"){ displayMessage("Floor available!", blue); state="P2T CONNECTED"; setPrompt(state); } else if (cmd.getOp()=="p2tFloorRevokeActive"){ displayMessage("Maximum Floortime reached. Revoking floor...", red); state="P2T CONNECTED"; setPrompt(state); } /**** * p2tFloorRevokePassiv * DestinationID: GroupIdentity * Param: user SIP URI * Param2: warning code * Description: remote user revoked floor. ****/ else if (cmd.getOp()=="p2tFloorRevokePassiv"){ if(cmd.getParam2()=="1"){ displayMessage("User " + cmd.getParam() + ":", bold); displayMessage("Please stop talking. Maximum floortime reached.", blue); } else if(cmd.getParam2()=="3"){ displayMessage("User " + cmd.getParam() + " stopped listening!", red); } } /**** * p2tAddUser * DestinationID: CallId (SipDialogP2Tuser) * Param1: SIP URI * Description: a remote user wants to be added to a P2T Session. * This command is received when the SipDialogP2Tuser * is in the RINGING state and waits for an accept. ****/ else if (cmd.getOp()=="p2tAddUser"){ if(inCall==true && p2tmode==true){ //send automatically an accept back CommandString command(cmd.getDestinationId(), SipCommandString::accept_invite); callback->guicb_handleCommand(command); if(grpList->isParticipant(cmd.getParam())==false){ grpList->addUser(cmd.getParam()); displayMessage("User " + cmd.getParam() + " added!", blue); } } else if(inCall==true && p2tmode==false){ //do nothing, because //the user has first to accept or deny //a incoming P2T Session. The answer will //be sent there to this user } } /**** * p2tRemoveUser * DestinationID: GroupId (SipDialogP2T) * Param1: SIP URI * Param2: reason * Description: a remote user wants to be added to a P2T Session. * This command is received when the SipDialogP2Tuser * is in the RINGING state and waits for an accept. ****/ else if (cmd.getOp()=="p2tRemoveUser"){ if(inCall==true && p2tmode==true){ displayMessage("User " + cmd.getParam() + " removed ("+ cmd.getParam2() +").", red); grpList->removeUser(cmd.getParam()); } } /**** * p2tModifyUser * DestinationID: GroupId (SipDialogP2T) * Param1: SIP URI * Param2: status * Description: information about a state (in the floor control) * of a user. ****/ else if (cmd.getOp()=="p2tModifyUser"){ if(inCall==true && p2tmode==true){ int status=0; for(uint32_t k=0;k<cmd.getParam2().size();k++) status = (status*10) + (cmd.getParam2()[k]-'0'); grpList->getUser(cmd.getParam())->setStatus(status); } } /**** * p2tInvitation * DestinationID: GroupID (SipDialogP2T) * Param1: Group Member List (XML-code) * Param2: uri inviting user * * Description: an invitation to a P2T Session ****/ else if (cmd.getOp()=="p2tInvitation"){ //if already in a call, send DENY back if(inCall){ //Close SipDialogP2T //CommandString cmd_term(cmd.getDestinationId(), "p2tTerminate"); //callback->guicb_handleCommand(cmd_term); //inform SipDialogP2Tuser //CommandString cmd_rej(cmd.getParam3(), SipCommandString::reject_invite); //callback->guicb_handleCommand(cmd_rej); //displayMessage("You missed P2T invitation from " + cmd.getParam2() +".", red); } //aks user to accept else{ inCall=true; grpList = new GroupList(cmd.getParam()); inviting_user=cmd.getParam2(); //inviting_callId=cmd.getParam3(); p2tGroupId=grpList->getGroupIdentity(); displayMessage(inviting_user + " invited you to a P2T Session:", blue); showGroupList(); displayMessage("type 'accept' or 'deny'", blue); state="P2T ACCEPT?"; setPrompt("P2T ACCEPT?"); } } /**** * p2tSessionCreated * DestinationID: * Param1: GroupId (SipDialogP2T) * Param2: * Param3: * Description: the P2T Session is set up ****/ else if (cmd.getOp()=="p2tSessionCreated"){ p2tGroupId=cmd.getParam(); displayMessage("P2T Session "+ p2tGroupId + " created", green); grpList->setGroupIdentity(p2tGroupId); state="P2T CONNECTED"; setPrompt(state); } else if (cmd.getOp().substr(0,3)=="p2t"){ displayMessage("Received: "+cmd.getOp(), blue); }}bool MinisipTextUI::configDialog( MRef<SipSoftPhoneConfiguration *> conf ){ cout << "ERROR: MinisipTextUI::configDialog is not implemented"<< endl; return false;}void MinisipTextUI::showCalls(string command){ //list<MRef<SipDialog*> > *calls = config->sip->getDialogContainer()->getDispatcher()->getDialogs(); list<MRef<SipDialog*> > calls = config->sip->getDialogContainer()->getDispatcher()->getDialogs(); displayMessage(string("Calls:")); if (calls.size()==0) displayMessage(" (no calls)"); else{ int ii=0; for (list<MRef<SipDialog*> >::iterator i=calls.begin(); i!=calls.end(); i++,ii++){ displayMessage(string(" (")+itoa(ii)+") " + (*i)->getName() + " State: " + (*i)->getCurrentStateName()); // + " ObjectId: " + itoa( (int) (*(((*calls)[i]))) ) ); } }}void MinisipTextUI::showTransactions(string command){ list<MRef<SipDialog*> > calls = config->sip->getDialogContainer()->getDispatcher()->getDialogs(); string tno = trim(command).substr(17); int itno=0; if (trim(tno).size()==0){ displayMessage("show transaction <transaction_nr>"); }else{ itno = atoi(tno.c_str()); if (((int)calls.size())-1>=itno){ list<MRef<SipDialog*> >::iterator call = calls.begin(); for (int j=0; j < itno; j++) call++; // MRef<SipDialog*> call = (*calls)[itno]; displayMessage(string("Transactions for call ")+(*call)->getName()); list<MRef<SipTransaction*> > transactions = (*call)->getTransactions(); if (transactions.size()==0) displayMessage("(no transactions)"); else{ int n=0; for (list<MRef<SipTransaction*> >::iterator i = transactions.begin(); i!=transactions.end(); i++){ displayMessage(string(" (")+itoa(n)+") "+ (*i)->getName() + " State: " + (*i)->getCurrentStateName()#ifdef _MSC_VER );#else + " ObjecdId: " + itoa((int)*(*i)));#endif n++; } } }else{ displayMessage("Call not found", red); } }}void MinisipTextUI::showTimeouts(string command){ string to = config->timeoutProvider->getTimeouts(); displayMessage(string("Timeouts: \n")+to);}void MinisipTextUI::showDialogInfo(MRef<SipDialog*> d, bool usesStateMachine, string header){ list <TPRequest<string,MRef<StateMachine<SipSMCommand,string>*> > > torequests = config->timeoutProvider->getTimeoutRequests(); if (usesStateMachine){ displayMessage(header + d->getName() + " State: " + d->getCurrentStateName()); }else{ displayMessage(header + d->getName()); } displayMessage(" SipDialogState:",bold); cerr << BOLD << " SipDialogState: "<< PLAIN; displayMessage( string(" secure=") + (d->dialogState.secure?string("true"):string("false")) +"; localTag=" + d->dialogState.localTag +"; remoteTag=" + d->dialogState.remoteTag +"; seqNo=" + itoa(d->dialogState.seqNo) +"; remoteSeqNo=" + itoa(d->dialogState.remoteSeqNo) +"; remoteUri=" + d->dialogState.remoteUri +"; remoteTarget=" + d->dialogState.remoteTarget +"; isEarly=" + (d->dialogState.isEarly?string("true"):string("false")) ); string routeset; list<string>::iterator i; for (i=d->dialogState.routeSet.begin(); i!= d->dialogState.routeSet.end(); i++){ if (i!=d->dialogState.routeSet.begin()) routeset+= ","; routeset+= *i; } displayMessage( string(" route_set: ")+routeset); // displayMessage(" Timeouts:", bold); int ntimeouts=0; std::list<TPRequest<string,MRef<StateMachine<SipSMCommand,string>*> > >::iterator jj=torequests.begin(); for (uint32_t j=0; j< torequests.size(); j++,jj++){ if ( *d == *((*jj).get_subscriber()) ){ int ms= (*jj).get_ms_to_timeout(); string theader = ntimeouts==0?" Timeouts: ": " "; displayMessage(theader+ (*jj).get_command() + " Time: " + itoa(ms/1000) + "." + itoa(ms%1000)); ntimeouts++; } } if (ntimeouts==0){ displayMessage(" (no timeouts)"); }// displayMessage( " Transactions:", bold); list<MRef<SipTransaction*> > transactions = d->getTransactions(); if (transactions.size()==0) displayMessage(" (no transactions)"); else{ int n=0; for (list<MRef<SipTransaction*> >::iterator i = transactions.begin(); i!=transactions.end(); i++){ string header = n==0 ? " Transactions: " : " " ; displayMessage(header + string("(")+itoa(n)+") "+ (*i)->getName() + " State: " + (*i)->getCurrentStateName()); n++;// displayMessage(" Timeouts:", bold); int ntimeouts=0; std::list<TPRequest<string, MRef<StateMachine<SipSMCommand,string>*> > >::iterator jj=torequests.begin(); for (uint32_t j=0; j< torequests.size(); j++, jj++){ if ( *((*i)) == *((*jj).get_subscriber()) ){ int ms= (*jj).get_ms_to_timeout(); string header = ntimeouts==0?" Timeouts: " : " "; displayMessage(header + string(" timeout: ") + (*jj).get_command() + " Time: " + itoa(ms/1000) + "." + itoa(ms%1000)); ntimeouts++; } } if (ntimeouts==0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -