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/buildopts.h>
00105 
00106 #include <opal/connection.h>
00107 
00108 #include <iax2/processor.h>
00109 #include <iax2/frame.h>
00110 #include <iax2/iedata.h>
00111 #include <iax2/remote.h>
00112 #include <iax2/safestrings.h>
00113 #include <iax2/sound.h>
00114 
00115 class IAX2Connection;
00116 
00120 class IAX2CallProcessor : public IAX2Processor
00121 {
00122   PCLASSINFO(IAX2CallProcessor, IAX2Processor);
00123   
00124  public:
00125   
00127   IAX2CallProcessor(IAX2EndPoint & ep);
00128 
00130   virtual ~IAX2CallProcessor(); 
00131 
00133   void AssignConnection(IAX2Connection * _con);
00134   
00137   void PutSoundPacketToNetwork(PBYTEArray *sund);
00138   
00140   IAX2Encryption & GetEncryptionInfo() { return encryption; }
00141 
00143   virtual void Release(OpalConnection::CallEndReason releaseReason = OpalConnection::EndedByLocalUser);
00144 
00146   void ClearCall(OpalConnection::CallEndReason releaseReason = OpalConnection::EndedByLocalUser);
00147 
00152   virtual void OnReleased();
00153   
00157   void SendDtmf(const PString & dtmfs);
00158 
00162   void SendText(const PString & text);
00163 
00170   virtual PBoolean SetUpConnection();
00171 
00174   PBoolean Matches(IAX2Frame *frame) { return remote == (frame->GetRemoteInfo()); }
00175   
00178   virtual void PrintOn(ostream & strm) const;
00179   
00182   void ReportStatistics();  
00183 
00185   PBoolean MatchingLocalCallNumber(PINDEX compare) { return (compare == remote.SourceCallNumber()); }  
00186   
00188   unsigned short GetSelectedCodec() { return (unsigned short) selectedCodec; }
00189   
00194   void AcceptIncomingCall();
00195 
00206   virtual PBoolean SetAlerting(
00207          const PString & calleeName,   
00208          PBoolean withMedia                
00209          ) ;
00210 
00214   void Hangup(PString messageToSend);
00215 
00218   PBoolean IsCallTerminating() { return callStatus & callTerminating; }
00219   
00221   void SendHold();
00222 
00224   void SendHoldRelease();
00225   
00232   void SetUserName(PString & inUserName) { userName = inUserName; };
00233   
00235   PString GetUserName() const;
00236   
00243   void SetPassword(PString & inPassword) { password = inPassword; };
00244   
00246   PString GetPassword() const { return password; };
00247   
00250   void SendTransfer(
00251     const PString & calledNumber,
00252     const PString & calledContext = PString::Empty());  
00253 
00256   void StartStatusCheckTimer(PINDEX msToWait = 10000 );
00258   
00265   virtual PBoolean IncomingMessageOutOfOrder(IAX2FullFrame *ff);
00266 
00270   void SendAnswerMessageToRemoteNode();
00271 
00272  protected:
00273   
00275   IAX2Connection * con;
00276 
00281   PBoolean RemoteSelectedCodecOk();
00282  
00286   void CheckForHangupMessages();
00287  
00289   void ProcessNetworkFrame(IAX2Frame * src);
00290   
00293   void ProcessNetworkFrame(IAX2MiniFrame * src);
00294   
00297   void ProcessNetworkFrame(IAX2FullFrame * src);
00298   
00301   void ProcessNetworkFrame(IAX2FullFrameDtmf * src);
00302   
00305   void ProcessNetworkFrame(IAX2FullFrameVoice * src);
00306   
00309   void ProcessNetworkFrame(IAX2FullFrameVideo * src);
00310   
00313   void ProcessNetworkFrame(IAX2FullFrameSessionControl * src);
00314   
00317   void ProcessNetworkFrame(IAX2FullFrameNull * src);
00318   
00324   virtual PBoolean ProcessNetworkFrame(IAX2FullFrameProtocol * src);
00325   
00328   void ProcessNetworkFrame(IAX2FullFrameText * src);
00329   
00332   void ProcessNetworkFrame(IAX2FullFrameImage * src);
00333   
00336   void ProcessNetworkFrame(IAX2FullFrameHtml * src);
00337   
00340   void ProcessNetworkFrame(IAX2FullFrameCng * src);
00341   
00344   virtual void ProcessLists();
00345     
00347   void ConnectToRemoteNode(PString & destination);
00348   
00350   void SendDtmfMessage(char message);
00351   
00353   void SendTextMessage(PString & message);
00354 
00357   void SendSoundMessage(PBYTEArray *sound);
00358   
00360   void SendTransferMessage();
00361   
00363   void SendQuelchMessage();
00364   
00366   void SendUnQuelchMessage();
00367   
00369   void IncAudioFramesSent()   { ++audioFramesSent; }
00370   
00372   void IncAudioFramesRcvd()   { ++audioFramesRcvd; }
00373   
00375   void IncVideoFramesSent()   { ++videoFramesSent; }
00376   
00378   void IncVideoFramesRcvd()   { ++videoFramesRcvd; }
00379   
00382   void RemoteNodeHasAnswered();
00383   
00387   void CallStopSounds();
00388   
00391   void ReceivedHookFlash();
00392   
00395   void RemoteNodeIsBusy();
00396   
00399   void ProcessIncomingAudioFrame(IAX2Frame *newFrame);
00400   
00403   void ProcessIncomingVideoFrame(IAX2Frame *newFrame);
00404   
00407   void ProcessIaxCmdNew(IAX2FullFrameProtocol *src);
00408   
00411   void ProcessIaxCmdAck(IAX2FullFrameProtocol *src);
00412   
00415   void ProcessIaxCmdHangup(IAX2FullFrameProtocol *src);
00416   
00419   void ProcessIaxCmdReject(IAX2FullFrameProtocol *src);
00420   
00423   void ProcessIaxCmdAccept(IAX2FullFrameProtocol *src);
00424   
00427   void ProcessIaxCmdAuthReq(IAX2FullFrameProtocol *src);
00428   
00431   void ProcessIaxCmdAuthRep(IAX2FullFrameProtocol *src);
00432   
00435   void ProcessIaxCmdInval(IAX2FullFrameProtocol *src);
00436   
00439   void ProcessIaxCmdDpReq(IAX2FullFrameProtocol *src);
00440   
00443   void ProcessIaxCmdDpRep(IAX2FullFrameProtocol *src);
00444   
00447   void ProcessIaxCmdDial(IAX2FullFrameProtocol *src);
00448   
00451   void ProcessIaxCmdTxreq(IAX2FullFrameProtocol *src);
00452   
00455   void ProcessIaxCmdTxcnt(IAX2FullFrameProtocol *src);
00456   
00459   void ProcessIaxCmdTxacc(IAX2FullFrameProtocol *src);
00460   
00463   void ProcessIaxCmdTxready(IAX2FullFrameProtocol *src);
00464   
00467   void ProcessIaxCmdTxrel(IAX2FullFrameProtocol *src);
00468   
00471   void ProcessIaxCmdTxrej(IAX2FullFrameProtocol *src);
00472   
00475   void ProcessIaxCmdQuelch(IAX2FullFrameProtocol *src);
00476   
00479   void ProcessIaxCmdUnquelch(IAX2FullFrameProtocol *src);
00480   
00483   void ProcessIaxCmdPage(IAX2FullFrameProtocol *src);
00484   
00487   void ProcessIaxCmdMwi(IAX2FullFrameProtocol *src);
00488   
00491   void ProcessIaxCmdUnsupport(IAX2FullFrameProtocol *src);
00492   
00495   void ProcessIaxCmdTransfer(IAX2FullFrameProtocol *src);
00496   
00499   void ProcessIaxCmdProvision(IAX2FullFrameProtocol *src);
00500   
00503   void ProcessIaxCmdFwDownl(IAX2FullFrameProtocol *src);
00504   
00507   void ProcessIaxCmdFwData(IAX2FullFrameProtocol *src);
00508   
00510   PAtomicInteger audioFramesSent;
00511   
00513   PAtomicInteger audioFramesRcvd;
00514   
00516   PAtomicInteger videoFramesSent;
00517   
00519   PAtomicInteger videoFramesRcvd;
00520   
00522   SafeString remotePhoneNumber;
00523   
00525   SafeStrings callList;
00526   
00530   SafeString dtmfText;
00531 
00534   SafeStrings textList;
00535 
00537   SafeStrings dtmfNetworkList;
00538 
00540   SafeStrings hangList;
00541   
00543   PBoolean holdCall;
00544   
00546   PBoolean holdReleaseCall;
00547   
00550   IAX2SoundList   soundWaitingForTransmission;
00551   
00557   enum SoundBufferState {
00558     BufferToSmall, 
00559     Normal, 
00560     BufferToBig 
00561   };
00562   
00564   SoundBufferState soundBufferState;
00565   
00568   PINDEX lastFullFrameTimeStamp;
00569     
00571   PBoolean audioCanFlow;
00572 
00575   unsigned int selectedCodec;
00576   
00578   enum CallStatus {
00579     callNewed      =  1 << 0,   
00580     callSentRinging = 1 << 1,   
00581     callRegistered =  1 << 2,   
00582     callAuthorised =  1 << 3,   
00583     callAccepted   =  1 << 4,   
00584     callRinging    =  1 << 5,   
00585     callAnswered   =  1 << 6,   
00586     callTerminating = 1 << 7    
00587   };
00588   
00590   unsigned short callStatus;
00591   
00593   void SetCallSentRinging(PBoolean newValue = PTrue) 
00594     { if (newValue) callStatus |= callSentRinging; else callStatus &= ~callSentRinging; }
00595   
00597   void SetCallNewed(PBoolean newValue = PTrue) 
00598     { if (newValue) callStatus |= callNewed; else callStatus &= ~callNewed; }
00599   
00601   void SetCallRegistered(PBoolean newValue = PTrue) 
00602     { if (newValue) callStatus |= callRegistered; else callStatus &= ~callRegistered; }
00603   
00605   void SetCallAuthorised(PBoolean newValue = PTrue) 
00606     { if (newValue) callStatus |= callAuthorised; else callStatus &= ~callAuthorised; }
00607   
00609   void SetCallAccepted(PBoolean newValue = PTrue) 
00610     { if (newValue) callStatus |= callAccepted; else callStatus &= ~callAccepted; }
00611   
00613   void SetCallRinging(PBoolean newValue = PTrue) 
00614     { if (newValue) callStatus |= callRinging; else callStatus &= ~callRinging; }
00615   
00617   void SetCallAnswered(PBoolean newValue = PTrue) 
00618     { if (newValue) callStatus |= callAnswered; else callStatus &= ~callAnswered; }
00619 
00621   void SetCallTerminating(PBoolean newValue = PTrue) 
00622     { if (newValue) callStatus |= callTerminating; else callStatus &= ~callTerminating; }
00623   
00625   PBoolean IsCallHappening() { return callStatus > 0; }
00626   
00629   PBoolean IsCallNewed() { return callStatus & callNewed; }
00630   
00633   PBoolean IsCallSentRinging() { return callStatus & callSentRinging; }
00634   
00636   PBoolean IsCallRegistered() { return callStatus & callRegistered; }
00637   
00639   PBoolean IsCallAuthorised() { return callStatus & callAuthorised; }
00640   
00642   PBoolean IsCallAccepted() { return callStatus & callAccepted; }
00643   
00645   PBoolean IsCallRinging() { return callStatus & callRinging; }
00646   
00648   PBoolean IsCallAnswered() { return callStatus & callAnswered; }
00649        
00650 #ifdef DOC_PLUS_PLUS
00651 
00657   void OnStatusCheck(PTimer &, INT);
00658 #else
00659   PDECLARE_NOTIFIER(PTimer, IAX2CallProcessor, OnStatusCheck);
00660 #endif
00661   
00663   void DoStatusCheck();
00664   
00667   void RemoteNodeIsRinging();
00668 
00672   void RingingWasAcked();
00673 
00678   void AnswerWasAcked();
00679 
00683   PBoolean firstMediaFrame;
00684 
00687   PBoolean answerCallNow;
00688 
00693   PBoolean statusCheckOtherEnd;
00694 
00696   PTimer statusCheckTimer;
00697 
00700   PINDEX audioFrameDuration;
00701 
00703   PINDEX audioCompressedBytes;
00704 
00708   PBoolean audioFramesNotStarted;
00709 
00712   void CheckForRemoteCapabilities(IAX2FullFrameProtocol *src);
00713   
00716   virtual void OnNoResponseTimeout();
00717   
00719   virtual void ProcessFullFrame(IAX2FullFrame & fullFrame);
00720   
00724   PString userName;
00725   
00729   PString password;
00730   
00732   PMutex transferMutex;
00733   
00735   PBoolean doTransfer;
00736   
00738   PString transferCalledNumber;
00739   
00741   PString transferCalledContext;    
00742 };
00743 
00745 
00746 /* The comment below is magic for those who use emacs to edit this file. */
00747 /* With the comment below, the tab key does auto indent to 4 spaces.     */
00748 
00749 /*
00750  * Local Variables:
00751  * mode:c
00752  * c-basic-offset:2
00753  * End:
00754  */
00755 
00756 
00757 #endif // CALLPROCESSOR_H

Generated on Mon Sep 22 12:24:20 2008 for OPAL by  doxygen 1.5.1