callprocessor.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Inter Asterisk Exchange 2
00004  * 
00005  * The core routine which determines the processing of packets for one call.
00006  * 
00007  * Open Phone Abstraction Library (OPAL)
00008  *
00009  * Copyright (c) 2005 Indranet Technologies Ltd.
00010  *
00011  * The contents of this file are subject to the Mozilla Public License
00012  * Version 1.0 (the "License"); you may not use this file except in
00013  * compliance with the License. You may obtain a copy of the License at
00014  * http://www.mozilla.org/MPL/
00015  *
00016  * Software distributed under the License is distributed on an "AS IS"
00017  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00018  * the License for the specific language governing rights and limitations
00019  * under the License.
00020  *
00021  * The Original Code is Open Phone Abstraction Library.
00022  *
00023  * The Initial Developer of the Original Code is Indranet Technologies Ltd.
00024  *
00025  * The author of this code is Derek J Smithies
00026  *
00027  *
00028  *  $Log: callprocessor.h,v $
00029  *  Revision 1.9  2007/04/19 06:17:21  csoutheren
00030  *  Fixes for precompiled headers with gcc
00031  *
00032  *  Revision 1.8  2007/01/18 04:45:16  csoutheren
00033  *  Messy, but simple change to add additional options argument to OpalConnection constructor
00034  *  This allows the provision of non-trivial arguments for connections
00035  *
00036  *  Revision 1.7  2007/01/17 22:27:52  dereksmithies
00037  *  Correctly sends DTMF to remote node. Tidy up string handling.
00038  *
00039  *  Revision 1.6  2007/01/17 03:48:13  dereksmithies
00040  *  Tidy up comments, remove leaks, improve reporting of packet types.
00041  *
00042  *  Revision 1.5  2007/01/16 03:17:42  dereksmithies
00043  *  tidyup of comments. Remove unused variables.
00044  *  Guarantee that media frames are sent with a monotonically increasing timestamp
00045  *
00046  *  Revision 1.4  2007/01/11 03:02:15  dereksmithies
00047  *  Remove the previous audio buffering code, and switch to using the jitter
00048  *  buffer provided in Opal. Reduce the verbosity of the log mesasges.
00049  *
00050  *  Revision 1.3  2006/09/22 00:33:19  csoutheren
00051  *  Changed PAtomicInteger to PBoolean
00052  *
00053  *  Revision 1.2  2006/09/11 03:08:51  dereksmithies
00054  *  Add fixes from Stephen Cook (sitiveni@gmail.com) for new patches to
00055  *  improve call handling. Notably, IAX2 call transfer. Many thanks.
00056  *  Thanks also to the Google summer of code for sponsoring this work.
00057  *
00058  *  Revision 1.1  2006/08/09 03:46:39  dereksmithies
00059  *  Add ability to register to a remote Asterisk box. The iaxProcessor class is split
00060  *  into a callProcessor and a regProcessor class.
00061  *  Big thanks to Stephen Cook, (sitiveni@gmail.com) for this work.
00062  *
00063  *  Revision 1.7  2005/09/05 01:19:43  dereksmithies
00064  *  add patches from Adrian Sietsma to avoid multiple hangup packets at call end,
00065  *  and stop the sending of ping/lagrq packets at call end. Many thanks.
00066  *
00067  *  Revision 1.6  2005/08/26 03:07:38  dereksmithies
00068  *  Change naming convention, so all class names contain the string "IAX2"
00069  *
00070  *  Revision 1.5  2005/08/25 03:26:06  dereksmithies
00071  *  Add patch from Adrian Sietsma to correctly set the packet timestamps under windows.
00072  *  Many thanks.
00073  *
00074  *  Revision 1.4  2005/08/24 04:56:25  dereksmithies
00075  *  Add code from Adrian Sietsma to send FullFrameTexts and FullFrameDtmfs to
00076  *  the remote end.  Many Thanks.
00077  *
00078  *  Revision 1.3  2005/08/24 01:38:38  dereksmithies
00079  *  Add encryption, iax2 style. Numerous tidy ups. Use the label iax2, not iax
00080  *
00081  *  Revision 1.2  2005/08/04 08:14:17  rjongbloed
00082  *  Fixed Windows build under DevStudio 2003 of IAX2 code
00083  *
00084  *  Revision 1.1  2005/07/30 07:01:32  csoutheren
00085  *  Added implementation of IAX2 (Inter Asterisk Exchange 2) protocol
00086  *  Thanks to Derek Smithies of Indranet Technologies Ltd. for
00087  *  writing and contributing this code
00088  *
00089  *
00090  *
00091  *
00092  *
00093  *
00094  *
00095  */
00096 
00097 #ifndef CALLPROCESSOR_H
00098 #define CALLPROCESSOR_H
00099 
00100 #ifndef _PTLIB_H
00101 #include <ptlib.h>
00102 #endif
00103 
00104 #include <opal/connection.h>
00105 
00106 #include <iax2/processor.h>
00107 #include <iax2/frame.h>
00108 #include <iax2/iedata.h>
00109 #include <iax2/remote.h>
00110 #include <iax2/safestrings.h>
00111 #include <iax2/sound.h>
00112 
00113 class IAX2Connection;
00114 
00118 class IAX2CallProcessor : public IAX2Processor
00119 {
00120   PCLASSINFO(IAX2CallProcessor, IAX2Processor);
00121   
00122  public:
00123   
00125   IAX2CallProcessor(IAX2EndPoint & ep);
00126 
00128   virtual ~IAX2CallProcessor(); 
00129 
00131   void AssignConnection(IAX2Connection * _con);
00132   
00135   void PutSoundPacketToNetwork(PBYTEArray *sund);
00136   
00138   IAX2Encryption & GetEncryptionInfo() { return encryption; }
00139 
00141   virtual void Release(OpalConnection::CallEndReason releaseReason = OpalConnection::EndedByLocalUser);
00142 
00144   void ClearCall(OpalConnection::CallEndReason releaseReason = OpalConnection::EndedByLocalUser);
00145 
00150   virtual void OnReleased();
00151   
00154   void SendDtmf(const PString & dtmfs);
00155 
00159   void SendText(const PString & text);
00160 
00167   virtual PBoolean SetUpConnection();
00168 
00171   PBoolean Matches(IAX2Frame *frame) { return remote == (frame->GetRemoteInfo()); }
00172   
00175   virtual void PrintOn(ostream & strm) const;
00176   
00179   void ReportStatistics();  
00180 
00182   PBoolean MatchingLocalCallNumber(PINDEX compare) { return (compare == remote.SourceCallNumber()); }  
00183   
00185   unsigned short GetSelectedCodec() { return (unsigned short) selectedCodec; }
00186   
00191   void AcceptIncomingCall();
00192 
00203   virtual PBoolean SetAlerting(
00204          const PString & calleeName,   
00205          PBoolean withMedia                
00206          ) ;
00207 
00211   void Hangup(PString messageToSend);
00212 
00215   PBoolean IsCallTerminating() { return callStatus & callTerminating; }
00216   
00218   void SendHold();
00219 
00221   void SendHoldRelease();
00222   
00229   void SetUserName(PString & inUserName) { userName = inUserName; };
00230   
00232   PString GetUserName() const;
00233   
00240   void SetPassword(PString & inPassword) { password = inPassword; };
00241   
00243   PString GetPassword() const { return password; };
00244   
00247   void SendTransfer(
00248     const PString & calledNumber,
00249     const PString & calledContext = PString::Empty());  
00250 
00253   void StartStatusCheckTimer(PINDEX msToWait = 10000 );
00255   
00256  protected:
00257   
00259   IAX2Connection * con;
00260 
00265   PBoolean RemoteSelectedCodecOk();
00266  
00270   void CheckForHangupMessages();
00271  
00273   void ProcessNetworkFrame(IAX2Frame * src);
00274   
00277   void ProcessNetworkFrame(IAX2MiniFrame * src);
00278   
00281   void ProcessNetworkFrame(IAX2FullFrame * src);
00282   
00285   void ProcessNetworkFrame(IAX2FullFrameDtmf * src);
00286   
00289   void ProcessNetworkFrame(IAX2FullFrameVoice * src);
00290   
00293   void ProcessNetworkFrame(IAX2FullFrameVideo * src);
00294   
00297   void ProcessNetworkFrame(IAX2FullFrameSessionControl * src);
00298   
00301   void ProcessNetworkFrame(IAX2FullFrameNull * src);
00302   
00308   virtual PBoolean ProcessNetworkFrame(IAX2FullFrameProtocol * src);
00309   
00312   void ProcessNetworkFrame(IAX2FullFrameText * src);
00313   
00316   void ProcessNetworkFrame(IAX2FullFrameImage * src);
00317   
00320   void ProcessNetworkFrame(IAX2FullFrameHtml * src);
00321   
00324   void ProcessNetworkFrame(IAX2FullFrameCng * src);
00325   
00328   virtual void ProcessLists();
00329     
00331   void ConnectToRemoteNode(PString & destination);
00332   
00334   void SendDtmfMessage(char message);
00335   
00337   void SendTextMessage(PString & message);
00338 
00341   void SendSoundMessage(PBYTEArray *sound);
00342   
00344   void SendTransferMessage();
00345   
00347   void SendQuelchMessage();
00348   
00350   void SendUnQuelchMessage();
00351   
00353   void IncAudioFramesSent()   { ++audioFramesSent; }
00354   
00356   void IncAudioFramesRcvd()   { ++audioFramesRcvd; }
00357   
00359   void IncVideoFramesSent()   { ++videoFramesSent; }
00360   
00362   void IncVideoFramesRcvd()   { ++videoFramesRcvd; }
00363   
00366   void RemoteNodeHasAnswered();
00367   
00371   void CallStopSounds();
00372   
00375   void ReceivedHookFlash();
00376   
00379   void RemoteNodeIsBusy();
00380   
00383   void ProcessIncomingAudioFrame(IAX2Frame *newFrame);
00384   
00387   void ProcessIncomingVideoFrame(IAX2Frame *newFrame);
00388   
00391   void ProcessIaxCmdNew(IAX2FullFrameProtocol *src);
00392   
00395   void ProcessIaxCmdAck(IAX2FullFrameProtocol *src);
00396   
00399   void ProcessIaxCmdHangup(IAX2FullFrameProtocol *src);
00400   
00403   void ProcessIaxCmdReject(IAX2FullFrameProtocol *src);
00404   
00407   void ProcessIaxCmdAccept(IAX2FullFrameProtocol *src);
00408   
00411   void ProcessIaxCmdAuthReq(IAX2FullFrameProtocol *src);
00412   
00415   void ProcessIaxCmdAuthRep(IAX2FullFrameProtocol *src);
00416   
00419   void ProcessIaxCmdInval(IAX2FullFrameProtocol *src);
00420   
00423   void ProcessIaxCmdDpReq(IAX2FullFrameProtocol *src);
00424   
00427   void ProcessIaxCmdDpRep(IAX2FullFrameProtocol *src);
00428   
00431   void ProcessIaxCmdDial(IAX2FullFrameProtocol *src);
00432   
00435   void ProcessIaxCmdTxreq(IAX2FullFrameProtocol *src);
00436   
00439   void ProcessIaxCmdTxcnt(IAX2FullFrameProtocol *src);
00440   
00443   void ProcessIaxCmdTxacc(IAX2FullFrameProtocol *src);
00444   
00447   void ProcessIaxCmdTxready(IAX2FullFrameProtocol *src);
00448   
00451   void ProcessIaxCmdTxrel(IAX2FullFrameProtocol *src);
00452   
00455   void ProcessIaxCmdTxrej(IAX2FullFrameProtocol *src);
00456   
00459   void ProcessIaxCmdQuelch(IAX2FullFrameProtocol *src);
00460   
00463   void ProcessIaxCmdUnquelch(IAX2FullFrameProtocol *src);
00464   
00467   void ProcessIaxCmdPage(IAX2FullFrameProtocol *src);
00468   
00471   void ProcessIaxCmdMwi(IAX2FullFrameProtocol *src);
00472   
00475   void ProcessIaxCmdUnsupport(IAX2FullFrameProtocol *src);
00476   
00479   void ProcessIaxCmdTransfer(IAX2FullFrameProtocol *src);
00480   
00483   void ProcessIaxCmdProvision(IAX2FullFrameProtocol *src);
00484   
00487   void ProcessIaxCmdFwDownl(IAX2FullFrameProtocol *src);
00488   
00491   void ProcessIaxCmdFwData(IAX2FullFrameProtocol *src);
00492   
00494   PAtomicInteger audioFramesSent;
00495   
00497   PAtomicInteger audioFramesRcvd;
00498   
00500   PAtomicInteger videoFramesSent;
00501   
00503   PAtomicInteger videoFramesRcvd;
00504   
00506   SafeString remotePhoneNumber;
00507   
00509   SafeStrings callList;
00510   
00514   SafeString dtmfText;
00515 
00518   SafeStrings textList;
00519 
00521   SafeStrings dtmfNetworkList;
00522 
00524   SafeStrings hangList;
00525   
00527   PBoolean holdCall;
00528   
00530   PBoolean holdReleaseCall;
00531   
00534   IAX2SoundList   soundWaitingForTransmission;
00535   
00541   enum SoundBufferState {
00542     BufferToSmall, 
00543     Normal, 
00544     BufferToBig 
00545   };
00546   
00548   SoundBufferState soundBufferState;
00549   
00552   PINDEX lastFullFrameTimeStamp;
00553     
00555   PBoolean audioCanFlow;
00556 
00559   unsigned int selectedCodec;
00560   
00562   enum CallStatus {
00563     callNewed      =  1 << 0,   
00564     callSentRinging = 1 << 1,   
00565     callRegistered =  1 << 2,   
00566     callAuthorised =  1 << 3,   
00567     callAccepted   =  1 << 4,   
00568     callRinging    =  1 << 5,   
00569     callAnswered   =  1 << 6,   
00570     callTerminating = 1 << 7    
00571   };
00572   
00574   unsigned short callStatus;
00575   
00577   void SetCallSentRinging(PBoolean newValue = PTrue) 
00578     { if (newValue) callStatus |= callSentRinging; else callStatus &= ~callSentRinging; }
00579   
00581   void SetCallNewed(PBoolean newValue = PTrue) 
00582     { if (newValue) callStatus |= callNewed; else callStatus &= ~callNewed; }
00583   
00585   void SetCallRegistered(PBoolean newValue = PTrue) 
00586     { if (newValue) callStatus |= callRegistered; else callStatus &= ~callRegistered; }
00587   
00589   void SetCallAuthorised(PBoolean newValue = PTrue) 
00590     { if (newValue) callStatus |= callAuthorised; else callStatus &= ~callAuthorised; }
00591   
00593   void SetCallAccepted(PBoolean newValue = PTrue) 
00594     { if (newValue) callStatus |= callAccepted; else callStatus &= ~callAccepted; }
00595   
00597   void SetCallRinging(PBoolean newValue = PTrue) 
00598     { if (newValue) callStatus |= callRinging; else callStatus &= ~callRinging; }
00599   
00601   void SetCallAnswered(PBoolean newValue = PTrue) 
00602     { if (newValue) callStatus |= callAnswered; else callStatus &= ~callAnswered; }
00603 
00605   void SetCallTerminating(PBoolean newValue = PTrue) 
00606     { if (newValue) callStatus |= callTerminating; else callStatus &= ~callTerminating; }
00607   
00609   PBoolean IsCallHappening() { return callStatus > 0; }
00610   
00613   PBoolean IsCallNewed() { return callStatus & callNewed; }
00614   
00617   PBoolean IsCallSentRinging() { return callStatus & callSentRinging; }
00618   
00620   PBoolean IsCallRegistered() { return callStatus & callRegistered; }
00621   
00623   PBoolean IsCallAuthorised() { return callStatus & callAuthorised; }
00624   
00626   PBoolean IsCallAccepted() { return callStatus & callAccepted; }
00627   
00629   PBoolean IsCallRinging() { return callStatus & callRinging; }
00630   
00632   PBoolean IsCallAnswered() { return callStatus & callAnswered; }
00633   
00635   void SendAnswerMessageToRemoteNode();
00636      
00637 #ifdef DOC_PLUS_PLUS
00638 
00644   void OnStatusCheck(PTimer &, INT);
00645 #else
00646   PDECLARE_NOTIFIER(PTimer, IAX2CallProcessor, OnStatusCheck);
00647 #endif
00648   
00650   void DoStatusCheck();
00651   
00654   void RemoteNodeIsRinging();
00655 
00659   void RingingWasAcked();
00660 
00665   void AnswerWasAcked();
00666 
00670   PBoolean firstMediaFrame;
00671 
00674   PBoolean answerCallNow;
00675 
00680   PBoolean statusCheckOtherEnd;
00681 
00683   PTimer statusCheckTimer;
00684 
00687   PINDEX audioFrameDuration;
00688 
00690   PINDEX audioCompressedBytes;
00691 
00695   PBoolean audioFramesNotStarted;
00696 
00699   void CheckForRemoteCapabilities(IAX2FullFrameProtocol *src);
00700   
00703   virtual void OnNoResponseTimeout();
00704   
00706   virtual void ProcessFullFrame(IAX2FullFrame & fullFrame);
00707   
00711   PString userName;
00712   
00716   PString password;
00717   
00719   PMutex transferMutex;
00720   
00722   PBoolean doTransfer;
00723   
00725   PString transferCalledNumber;
00726   
00728   PString transferCalledContext;  
00729 };
00730 
00732 
00733 /* The comment below is magic for those who use emacs to edit this file. */
00734 /* With the comment below, the tab key does auto indent to 4 spaces.     */
00735 
00736 /*
00737  * Local Variables:
00738  * mode:c
00739  * c-file-style:linux
00740  * c-basic-offset:2
00741  * End:
00742  */
00743 
00744 
00745 #endif // CALLPROCESSOR_H

Generated on Wed May 7 00:55:30 2008 for OPAL by  doxygen 1.5.1