# 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