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 BOOL
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 BOOL SetUpConnection();
00168 
00171   BOOL Matches(IAX2Frame *frame) { return remote == (frame->GetRemoteInfo()); }
00172   
00175   virtual void PrintOn(ostream & strm) const;
00176   
00179   void ReportStatistics();  
00180 
00182   BOOL MatchingLocalCallNumber(PINDEX compare) { return (compare == remote.SourceCallNumber()); }  
00183   
00185   unsigned short GetSelectedCodec() { return (unsigned short) selectedCodec; }
00186   
00188   void SetConnected(); 
00189   
00192   void AcceptIncomingCall();
00193 
00204   virtual BOOL SetAlerting(
00205          const PString & calleeName,   
00206          BOOL withMedia                
00207          ) ;
00208 
00211   void SetEstablished(BOOL originator        
00212           );
00213 
00217   void Hangup(PString messageToSend);
00218 
00221   BOOL IsCallTerminating() { return callStatus & callTerminating; }
00222   
00224   void SendHold();
00225 
00227   void SendHoldRelease();
00228   
00235   void SetUserName(PString & inUserName) { userName = inUserName; };
00236   
00238   PString GetUserName() const;
00239   
00246   void SetPassword(PString & inPassword) { password = inPassword; };
00247   
00249   PString GetPassword() const { return password; };
00250   
00253   void SendTransfer(
00254     const PString & calledNumber,
00255     const PString & calledContext = PString::Empty());  
00256   
00257  protected:
00258   
00260   IAX2Connection * con;
00261 
00266   BOOL RemoteSelectedCodecOk();
00267  
00270   void CheckForHangupMessages();
00271  
00273   void ProcessNetworkFrame(IAX2Frame * src);
00274   
00276   void ProcessNetworkFrame(IAX2MiniFrame * src);
00277   
00279   void ProcessNetworkFrame(IAX2FullFrame * src);
00280   
00282   void ProcessNetworkFrame(IAX2FullFrameDtmf * src);
00283   
00285   void ProcessNetworkFrame(IAX2FullFrameVoice * src);
00286   
00288   void ProcessNetworkFrame(IAX2FullFrameVideo * src);
00289   
00291   void ProcessNetworkFrame(IAX2FullFrameSessionControl * src);
00292   
00294   void ProcessNetworkFrame(IAX2FullFrameNull * src);
00295   
00300   virtual BOOL ProcessNetworkFrame(IAX2FullFrameProtocol * src);
00301   
00303   void ProcessNetworkFrame(IAX2FullFrameText * src);
00304   
00306   void ProcessNetworkFrame(IAX2FullFrameImage * src);
00307   
00309   void ProcessNetworkFrame(IAX2FullFrameHtml * src);
00310   
00312   void ProcessNetworkFrame(IAX2FullFrameCng * src);
00313   
00315   virtual void ProcessLists();
00316     
00318   void ConnectToRemoteNode(PString & destination);
00319   
00321   void SendDtmfMessage(char message);
00322   
00324   void SendTextMessage(PString & message);
00325 
00328   void SendSoundMessage(PBYTEArray *sound);
00329   
00331   void SendTransferMessage();
00332   
00334   void SendQuelchMessage();
00335   
00337   void SendUnQuelchMessage();
00338   
00340   void IncAudioFramesSent()   { ++audioFramesSent; }
00341   
00343   void IncAudioFramesRcvd()   { ++audioFramesRcvd; }
00344   
00346   void IncVideoFramesSent()   { ++videoFramesSent; }
00347   
00349   void IncVideoFramesRcvd()   { ++videoFramesRcvd; }
00350   
00353   void RemoteNodeHasAnswered();
00354   
00358   void CallStopSounds();
00359   
00362   void ReceivedHookFlash();
00363   
00366   void RemoteNodeIsBusy();
00367   
00369   void ProcessIncomingAudioFrame(IAX2Frame *newFrame);
00370   
00372   void ProcessIncomingVideoFrame(IAX2Frame *newFrame);
00373   
00375   void ProcessIaxCmdNew(IAX2FullFrameProtocol *src);
00376   
00378   void ProcessIaxCmdAck(IAX2FullFrameProtocol *src);
00379   
00381   void ProcessIaxCmdHangup(IAX2FullFrameProtocol *src);
00382   
00384   void ProcessIaxCmdReject(IAX2FullFrameProtocol *src);
00385   
00387   void ProcessIaxCmdAccept(IAX2FullFrameProtocol *src);
00388   
00390   void ProcessIaxCmdAuthReq(IAX2FullFrameProtocol *src);
00391   
00393   void ProcessIaxCmdAuthRep(IAX2FullFrameProtocol *src);
00394   
00396   void ProcessIaxCmdInval(IAX2FullFrameProtocol *src);
00397   
00399   void ProcessIaxCmdDpReq(IAX2FullFrameProtocol *src);
00400   
00402   void ProcessIaxCmdDpRep(IAX2FullFrameProtocol *src);
00403   
00405   void ProcessIaxCmdDial(IAX2FullFrameProtocol *src);
00406   
00408   void ProcessIaxCmdTxreq(IAX2FullFrameProtocol *src);
00409   
00411   void ProcessIaxCmdTxcnt(IAX2FullFrameProtocol *src);
00412   
00414   void ProcessIaxCmdTxacc(IAX2FullFrameProtocol *src);
00415   
00417   void ProcessIaxCmdTxready(IAX2FullFrameProtocol *src);
00418   
00420   void ProcessIaxCmdTxrel(IAX2FullFrameProtocol *src);
00421   
00423   void ProcessIaxCmdTxrej(IAX2FullFrameProtocol *src);
00424   
00426   void ProcessIaxCmdQuelch(IAX2FullFrameProtocol *src);
00427   
00429   void ProcessIaxCmdUnquelch(IAX2FullFrameProtocol *src);
00430   
00432   void ProcessIaxCmdPage(IAX2FullFrameProtocol *src);
00433   
00435   void ProcessIaxCmdMwi(IAX2FullFrameProtocol *src);
00436   
00438   void ProcessIaxCmdUnsupport(IAX2FullFrameProtocol *src);
00439   
00441   void ProcessIaxCmdTransfer(IAX2FullFrameProtocol *src);
00442   
00444   void ProcessIaxCmdProvision(IAX2FullFrameProtocol *src);
00445   
00447   void ProcessIaxCmdFwDownl(IAX2FullFrameProtocol *src);
00448   
00450   void ProcessIaxCmdFwData(IAX2FullFrameProtocol *src);
00451   
00453   PAtomicInteger audioFramesSent;
00454   
00456   PAtomicInteger audioFramesRcvd;
00457   
00459   PAtomicInteger videoFramesSent;
00460   
00462   PAtomicInteger videoFramesRcvd;
00463   
00465   SafeString remotePhoneNumber;
00466   
00468   SafeStrings callList;
00469   
00473   SafeString dtmfText;
00474 
00477   SafeStrings textList;
00478 
00480   SafeStrings dtmfNetworkList;
00481 
00483   SafeStrings hangList;
00484   
00486   BOOL holdCall;
00487   
00489   BOOL holdReleaseCall;
00490   
00493   IAX2SoundList   soundWaitingForTransmission;
00494   
00500   enum SoundBufferState {
00501     BufferToSmall, 
00502     Normal, 
00503     BufferToBig 
00504   };
00505   
00507   SoundBufferState soundBufferState;
00508   
00511   PINDEX lastFullFrameTimeStamp;
00512     
00514   BOOL audioCanFlow;
00515 
00517   unsigned int selectedCodec;
00518   
00520   enum CallStatus {
00521     callNewed      =  1 << 0,   
00522     callSentRinging = 1 << 1,   
00523     callRegistered =  1 << 2,   
00524     callAuthorised =  1 << 3,   
00525     callAccepted   =  1 << 4,   
00526     callRinging    =  1 << 5,   
00527     callAnswered   =  1 << 6,   
00528     callTerminating = 1 << 7    
00529   };
00530   
00532   unsigned short callStatus;
00533   
00535   void SetCallSentRinging(BOOL newValue = TRUE) 
00536     { if (newValue) callStatus |= callSentRinging; else callStatus &= ~callSentRinging; }
00537   
00539   void SetCallNewed(BOOL newValue = TRUE) 
00540     { if (newValue) callStatus |= callNewed; else callStatus &= ~callNewed; }
00541   
00543   void SetCallRegistered(BOOL newValue = TRUE) 
00544     { if (newValue) callStatus |= callRegistered; else callStatus &= ~callRegistered; }
00545   
00547   void SetCallAuthorised(BOOL newValue = TRUE) 
00548     { if (newValue) callStatus |= callAuthorised; else callStatus &= ~callAuthorised; }
00549   
00551   void SetCallAccepted(BOOL newValue = TRUE) 
00552     { if (newValue) callStatus |= callAccepted; else callStatus &= ~callAccepted; }
00553   
00555   void SetCallRinging(BOOL newValue = TRUE) 
00556     { if (newValue) callStatus |= callRinging; else callStatus &= ~callRinging; }
00557   
00559   void SetCallAnswered(BOOL newValue = TRUE) 
00560     { if (newValue) callStatus |= callAnswered; else callStatus &= ~callAnswered; }
00561 
00563   void SetCallTerminating(BOOL newValue = TRUE) 
00564     { if (newValue) callStatus |= callTerminating; else callStatus &= ~callTerminating; }
00565   
00567   BOOL IsCallHappening() { return callStatus > 0; }
00568   
00570   BOOL IsCallNewed() { return callStatus & callNewed; }
00571   
00573   BOOL IsCallSentRinging() { return callStatus & callSentRinging; }
00574   
00576   BOOL IsCallRegistered() { return callStatus & callRegistered; }
00577   
00579   BOOL IsCallAuthorised() { return callStatus & callAuthorised; }
00580   
00582   BOOL IsCallAccepted() { return callStatus & callAccepted; }
00583   
00585   BOOL IsCallRinging() { return callStatus & callRinging; }
00586   
00588   BOOL IsCallAnswered() { return callStatus & callAnswered; }
00589   
00591   void SendAnswerMessageToRemoteNode();
00592      
00595   void StartStatusCheckTimer(PINDEX msToWait = 10000 );
00596 
00597 #ifdef DOC_PLUS_PLUS
00598 
00604   void OnStatusCheck(PTimer &, INT);
00605 #else
00606   PDECLARE_NOTIFIER(PTimer, IAX2CallProcessor, OnStatusCheck);
00607 #endif
00608   
00610   void DoStatusCheck();
00611   
00614   void RemoteNodeIsRinging();
00615 
00619   void RingingWasAcked();
00620 
00625   void AnswerWasAcked();
00626 
00630   BOOL firstMediaFrame;
00631 
00634   BOOL answerCallNow;
00635 
00640   BOOL statusCheckOtherEnd;
00641 
00643   PTimer statusCheckTimer;
00644 
00647   PINDEX audioFrameDuration;
00648 
00650   PINDEX audioCompressedBytes;
00651 
00655   BOOL audioFramesNotStarted;
00656 
00659   void CheckForRemoteCapabilities(IAX2FullFrameProtocol *src);
00660   
00663   virtual void OnNoResponseTimeout();
00664   
00666   virtual void ProcessFullFrame(IAX2FullFrame & fullFrame);
00667   
00671   PString userName;
00672   
00676   PString password;
00677   
00679   PMutex transferMutex;
00680   
00682   BOOL doTransfer;
00683   
00685   PString transferCalledNumber;
00686   
00688   PString transferCalledContext;  
00689 };
00690 
00692 
00693 /* The comment below is magic for those who use emacs to edit this file. */
00694 /* With the comment below, the tab key does auto indent to 4 spaces.     */
00695 
00696 /*
00697  * Local Variables:
00698  * mode:c
00699  * c-file-style:linux
00700  * c-basic-offset:2
00701  * End:
00702  */
00703 
00704 
00705 #endif // CALLPROCESSOR_H

Generated on Fri Mar 7 06:33:08 2008 for OPAL by  doxygen 1.5.1