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   
00155   void SendDtmf(const PString & dtmfs);
00156 
00160   void SendText(const PString & text);
00161 
00168   virtual PBoolean SetUpConnection();
00169 
00172   PBoolean Matches(IAX2Frame *frame) { return remote == (frame->GetRemoteInfo()); }
00173   
00176   virtual void PrintOn(ostream & strm) const;
00177   
00180   void ReportStatistics();  
00181 
00183   PBoolean MatchingLocalCallNumber(PINDEX compare) { return (compare == remote.SourceCallNumber()); }  
00184   
00186   unsigned short GetSelectedCodec() { return (unsigned short) selectedCodec; }
00187   
00192   void AcceptIncomingCall();
00193 
00204   virtual PBoolean SetAlerting(
00205          const PString & calleeName,   
00206          PBoolean withMedia                
00207          ) ;
00208 
00212   void Hangup(PString messageToSend);
00213 
00216   PBoolean IsCallTerminating() { return callStatus & callTerminating; }
00217   
00219   void SendHold();
00220 
00222   void SendHoldRelease();
00223   
00230   void SetUserName(PString & inUserName) { userName = inUserName; };
00231   
00233   PString GetUserName() const;
00234   
00241   void SetPassword(PString & inPassword) { password = inPassword; };
00242   
00244   PString GetPassword() const { return password; };
00245   
00248   void SendTransfer(
00249     const PString & calledNumber,
00250     const PString & calledContext = PString::Empty());  
00251 
00254   void StartStatusCheckTimer(PINDEX msToWait = 10000 );
00256   
00263   virtual PBoolean IncomingMessageOutOfOrder(IAX2FullFrame *ff);
00264 
00268   void SendAnswerMessageToRemoteNode();
00269 
00270  protected:
00271   
00273   IAX2Connection * con;
00274 
00279   PBoolean RemoteSelectedCodecOk();
00280  
00284   void CheckForHangupMessages();
00285  
00287   void ProcessNetworkFrame(IAX2Frame * src);
00288   
00291   void ProcessNetworkFrame(IAX2MiniFrame * src);
00292   
00295   void ProcessNetworkFrame(IAX2FullFrame * src);
00296   
00299   void ProcessNetworkFrame(IAX2FullFrameDtmf * src);
00300   
00303   void ProcessNetworkFrame(IAX2FullFrameVoice * src);
00304   
00307   void ProcessNetworkFrame(IAX2FullFrameVideo * src);
00308   
00311   void ProcessNetworkFrame(IAX2FullFrameSessionControl * src);
00312   
00315   void ProcessNetworkFrame(IAX2FullFrameNull * src);
00316   
00322   virtual PBoolean ProcessNetworkFrame(IAX2FullFrameProtocol * src);
00323   
00326   void ProcessNetworkFrame(IAX2FullFrameText * src);
00327   
00330   void ProcessNetworkFrame(IAX2FullFrameImage * src);
00331   
00334   void ProcessNetworkFrame(IAX2FullFrameHtml * src);
00335   
00338   void ProcessNetworkFrame(IAX2FullFrameCng * src);
00339   
00342   virtual void ProcessLists();
00343     
00345   void ConnectToRemoteNode(PString & destination);
00346   
00348   void SendDtmfMessage(char message);
00349   
00351   void SendTextMessage(PString & message);
00352 
00355   void SendSoundMessage(PBYTEArray *sound);
00356   
00358   void SendTransferMessage();
00359   
00361   void SendQuelchMessage();
00362   
00364   void SendUnQuelchMessage();
00365   
00367   void IncAudioFramesSent()   { ++audioFramesSent; }
00368   
00370   void IncAudioFramesRcvd()   { ++audioFramesRcvd; }
00371   
00373   void IncVideoFramesSent()   { ++videoFramesSent; }
00374   
00376   void IncVideoFramesRcvd()   { ++videoFramesRcvd; }
00377   
00380   void RemoteNodeHasAnswered();
00381   
00385   void CallStopSounds();
00386   
00389   void ReceivedHookFlash();
00390   
00393   void RemoteNodeIsBusy();
00394   
00397   void ProcessIncomingAudioFrame(IAX2Frame *newFrame);
00398   
00401   void ProcessIncomingVideoFrame(IAX2Frame *newFrame);
00402   
00405   void ProcessIaxCmdNew(IAX2FullFrameProtocol *src);
00406   
00409   void ProcessIaxCmdAck(IAX2FullFrameProtocol *src);
00410   
00413   void ProcessIaxCmdHangup(IAX2FullFrameProtocol *src);
00414   
00417   void ProcessIaxCmdReject(IAX2FullFrameProtocol *src);
00418   
00421   void ProcessIaxCmdAccept(IAX2FullFrameProtocol *src);
00422   
00425   void ProcessIaxCmdAuthReq(IAX2FullFrameProtocol *src);
00426   
00429   void ProcessIaxCmdAuthRep(IAX2FullFrameProtocol *src);
00430   
00433   void ProcessIaxCmdInval(IAX2FullFrameProtocol *src);
00434   
00437   void ProcessIaxCmdDpReq(IAX2FullFrameProtocol *src);
00438   
00441   void ProcessIaxCmdDpRep(IAX2FullFrameProtocol *src);
00442   
00445   void ProcessIaxCmdDial(IAX2FullFrameProtocol *src);
00446   
00449   void ProcessIaxCmdTxreq(IAX2FullFrameProtocol *src);
00450   
00453   void ProcessIaxCmdTxcnt(IAX2FullFrameProtocol *src);
00454   
00457   void ProcessIaxCmdTxacc(IAX2FullFrameProtocol *src);
00458   
00461   void ProcessIaxCmdTxready(IAX2FullFrameProtocol *src);
00462   
00465   void ProcessIaxCmdTxrel(IAX2FullFrameProtocol *src);
00466   
00469   void ProcessIaxCmdTxrej(IAX2FullFrameProtocol *src);
00470   
00473   void ProcessIaxCmdQuelch(IAX2FullFrameProtocol *src);
00474   
00477   void ProcessIaxCmdUnquelch(IAX2FullFrameProtocol *src);
00478   
00481   void ProcessIaxCmdPage(IAX2FullFrameProtocol *src);
00482   
00485   void ProcessIaxCmdMwi(IAX2FullFrameProtocol *src);
00486   
00489   void ProcessIaxCmdUnsupport(IAX2FullFrameProtocol *src);
00490   
00493   void ProcessIaxCmdTransfer(IAX2FullFrameProtocol *src);
00494   
00497   void ProcessIaxCmdProvision(IAX2FullFrameProtocol *src);
00498   
00501   void ProcessIaxCmdFwDownl(IAX2FullFrameProtocol *src);
00502   
00505   void ProcessIaxCmdFwData(IAX2FullFrameProtocol *src);
00506   
00508   PAtomicInteger audioFramesSent;
00509   
00511   PAtomicInteger audioFramesRcvd;
00512   
00514   PAtomicInteger videoFramesSent;
00515   
00517   PAtomicInteger videoFramesRcvd;
00518   
00520   SafeString remotePhoneNumber;
00521   
00523   SafeStrings callList;
00524   
00528   SafeString dtmfText;
00529 
00532   SafeStrings textList;
00533 
00535   SafeStrings dtmfNetworkList;
00536 
00538   SafeStrings hangList;
00539   
00541   PBoolean holdCall;
00542   
00544   PBoolean holdReleaseCall;
00545   
00548   IAX2SoundList   soundWaitingForTransmission;
00549   
00555   enum SoundBufferState {
00556     BufferToSmall, 
00557     Normal, 
00558     BufferToBig 
00559   };
00560   
00562   SoundBufferState soundBufferState;
00563   
00566   PINDEX lastFullFrameTimeStamp;
00567     
00569   PBoolean audioCanFlow;
00570 
00573   unsigned int selectedCodec;
00574   
00576   enum CallStatus {
00577     callNewed      =  1 << 0,   
00578     callSentRinging = 1 << 1,   
00579     callRegistered =  1 << 2,   
00580     callAuthorised =  1 << 3,   
00581     callAccepted   =  1 << 4,   
00582     callRinging    =  1 << 5,   
00583     callAnswered   =  1 << 6,   
00584     callTerminating = 1 << 7    
00585   };
00586   
00588   unsigned short callStatus;
00589   
00591   void SetCallSentRinging(PBoolean newValue = PTrue) 
00592     { if (newValue) callStatus |= callSentRinging; else callStatus &= ~callSentRinging; }
00593   
00595   void SetCallNewed(PBoolean newValue = PTrue) 
00596     { if (newValue) callStatus |= callNewed; else callStatus &= ~callNewed; }
00597   
00599   void SetCallRegistered(PBoolean newValue = PTrue) 
00600     { if (newValue) callStatus |= callRegistered; else callStatus &= ~callRegistered; }
00601   
00603   void SetCallAuthorised(PBoolean newValue = PTrue) 
00604     { if (newValue) callStatus |= callAuthorised; else callStatus &= ~callAuthorised; }
00605   
00607   void SetCallAccepted(PBoolean newValue = PTrue) 
00608     { if (newValue) callStatus |= callAccepted; else callStatus &= ~callAccepted; }
00609   
00611   void SetCallRinging(PBoolean newValue = PTrue) 
00612     { if (newValue) callStatus |= callRinging; else callStatus &= ~callRinging; }
00613   
00615   void SetCallAnswered(PBoolean newValue = PTrue) 
00616     { if (newValue) callStatus |= callAnswered; else callStatus &= ~callAnswered; }
00617 
00619   void SetCallTerminating(PBoolean newValue = PTrue) 
00620     { if (newValue) callStatus |= callTerminating; else callStatus &= ~callTerminating; }
00621   
00623   PBoolean IsCallHappening() { return callStatus > 0; }
00624   
00627   PBoolean IsCallNewed() { return callStatus & callNewed; }
00628   
00631   PBoolean IsCallSentRinging() { return callStatus & callSentRinging; }
00632   
00634   PBoolean IsCallRegistered() { return callStatus & callRegistered; }
00635   
00637   PBoolean IsCallAuthorised() { return callStatus & callAuthorised; }
00638   
00640   PBoolean IsCallAccepted() { return callStatus & callAccepted; }
00641   
00643   PBoolean IsCallRinging() { return callStatus & callRinging; }
00644   
00646   PBoolean IsCallAnswered() { return callStatus & callAnswered; }
00647        
00648 #ifdef DOC_PLUS_PLUS
00649 
00655   void OnStatusCheck(PTimer &, INT);
00656 #else
00657   PDECLARE_NOTIFIER(PTimer, IAX2CallProcessor, OnStatusCheck);
00658 #endif
00659   
00661   void DoStatusCheck();
00662   
00665   void RemoteNodeIsRinging();
00666 
00670   void RingingWasAcked();
00671 
00676   void AnswerWasAcked();
00677 
00681   PBoolean firstMediaFrame;
00682 
00685   PBoolean answerCallNow;
00686 
00691   PBoolean statusCheckOtherEnd;
00692 
00694   PTimer statusCheckTimer;
00695 
00698   PINDEX audioFrameDuration;
00699 
00701   PINDEX audioCompressedBytes;
00702 
00706   PBoolean audioFramesNotStarted;
00707 
00710   void CheckForRemoteCapabilities(IAX2FullFrameProtocol *src);
00711   
00714   virtual void OnNoResponseTimeout();
00715   
00717   virtual void ProcessFullFrame(IAX2FullFrame & fullFrame);
00718   
00722   PString userName;
00723   
00727   PString password;
00728   
00730   PMutex transferMutex;
00731   
00733   PBoolean doTransfer;
00734   
00736   PString transferCalledNumber;
00737   
00739   PString transferCalledContext;    
00740 };
00741 
00743 
00744 /* The comment below is magic for those who use emacs to edit this file. */
00745 /* With the comment below, the tab key does auto indent to 4 spaces.     */
00746 
00747 /*
00748  * Local Variables:
00749  * mode:c
00750  * c-basic-offset:2
00751  * End:
00752  */
00753 
00754 
00755 #endif // CALLPROCESSOR_H

Generated on Mon Sep 15 11:48:42 2008 for OPAL by  doxygen 1.5.1