/* * OpenBTS provides an open source alternative to legacy telco protocols and * traditionally complex, proprietary hardware systems. * * Copyright 2008 Free Software Foundation, Inc. * Copyright 2010 Kestrel Signal Processing, Inc. * Copyright 2011, 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero General * Public License version 3. See the COPYING and NOTICE files in the main * directory for licensing information. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. */ #ifndef SIPENGINE_H #define SIPENGINE_H #include #include #include #include #include #include #include #include using namespace std; namespace SIP { class SIPInterface; enum SIPState { NullState, Timeout, Starting, Proceeding, Ringing, Busy, Connecting, Active, MODClearing, MTDClearing, Cleared, Fail, MessageSubmit }; const char* SIPStateString(SIPState s); std::ostream& operator<<(std::ostream& os, SIPState s); class SIPEngine { public: enum Method { SIPRegister =0, SIPUnregister=1 }; private: /**@name General SIP tags and ids. */ //@{ std::string mRemoteUsername; std::string mRemoteDomain; std::string mMyTag; std::string mCallID; std::string mViaBranch; std::string mSIPUsername; ///< our SIP username unsigned mCSeq; /**@name Pre-formed headers. These point into mINVITE. */ //@{ osip_from_t* mMyToFromHeader; ///< To/From header for us osip_from_t* mRemoteToFromHeader; ///< To/From header for the remote party osip_call_id_t *mCallIDHeader; ///< the call ID header for this transaction //@} //@} /**@name SIP UDP parameters */ //@{ unsigned mSIPPort; ///< our local SIP port std::string mSIPIP; ///< our SIP IP address as seen by the proxy std::string mProxyIP; ///< IP address of the SIP proxy unsigned mProxyPort; ///< UDP port number of the SIP proxy struct ::sockaddr_in mProxyAddr; ///< the ready-to-use UDP address //@} /**@name Saved SIP messages. */ //@{ osip_message_t * mINVITE; ///< the INVITE message for this transaction osip_message_t * mLastResponse; ///< the last response received for this transaction osip_message_t * mBYE; ///< the BYE message for this transaction //@} /**@name RTP state and parameters. */ //@{ short mRTPPort; unsigned mCodec; RtpSession * mSession; ///< RTP media session unsigned int mTxTime; ///< RTP transmission timestamp in 8 kHz samples unsigned int mRxTime; ///< RTP receive timestamp in 8 kHz samples //@} SIPState mState; ///< current SIP call state /**@name RFC-2833 DTMF state. */ //@{ char mDTMF; ///< current DTMF digit, \0 if none unsigned mDTMFDuration; ///< duration of DTMF event so far unsigned mDTMFStartTime; ///< start time of the DTMF key event //@} public: /** Default constructor. Initialize the object. @param proxy : */ SIPEngine(const char* proxy, const char* IMSI=NULL); /** Destroy held message copies. */ ~SIPEngine(); const std::string& callID() const { return mCallID; } const std::string& proxyIP() const { return mProxyIP; } unsigned proxyPort() const { return mProxyPort; } /** Return the current SIP call state. */ SIPState state() const { return mState; } /** Set the user to IMSI and generate a call ID; for mobile-originated transactions. */ void user( const char * IMSI ); /** Set the use to IMSI and set the other SIP call parameters; for network-originated transactions. */ void user( const char * wCallID, const char * IMSI , const char *origID, const char *origHost); /**@name Messages for SIP registration. */ //@{ /** Send sip register and look at return msg. Can throw SIPTimeout(). @return True on success. */ bool Register(Method wMethod=SIPRegister, string *RAND = NULL, const char *IMSI = NULL, const char *SRES = NULL); /** Send sip unregister and look at return msg. Can throw SIPTimeout(). @return True on success. */ bool unregister() { return (Register(SIPUnregister)); }; //@} /**@name Messages associated with MOC procedure. */ //@{ /** Send an invite message. @param calledUser SIP userid or E.164 address. @param calledDomain SIP user's domain. @param rtpPort UDP port to use for speech (will use this and next port) @param codec Code for codec to be used. @return New SIP call state. */ SIPState MOCSendINVITE(const char * calledUser, const char * calledDomain, short rtpPort, unsigned codec); SIPState MOCResendINVITE(); SIPState MOCWaitForOK(); SIPState MOCSendACK(); //@} /**@name Messages associated with MOSMS procedure. */ //@{ /** Send an instant message. @param calledUsername SIP userid or E.164 address. @param calledDomain SIP user's domain. @param messageText MESSAGE payload as a C string. @return New SIP call state. */ SIPState MOSMSSendMESSAGE(const char * calledUsername, const char * calledDomain, const char *messageText, const char *contentType); SIPState MOSMSWaitForSubmit(); SIPState MTSMSSendOK(); //@} /**@name Messages associated with MTC procedure. */ //@{ SIPState MTCSendTrying(); SIPState MTCSendRinging(); SIPState MTCSendOK(short rtpPort, unsigned codec); SIPState MTCWaitForACK(); SIPState MTCCheckForCancel(); //@} /**@name Messages associated with MTSMS procedure. */ //@{ SIPState MTCSendOK(); //@} /**@name Messages for MOD procedure. */ //@{ SIPState MODSendBYE(); SIPState MODResendBYE(); SIPState MODWaitForOK(); //@} /**@name Messages for MTD procedure. */ //@{ SIPState MTDCheckBYE(); SIPState MTDSendOK(); //@} /** Set up to start sending RFC2833 DTMF event frames in the RTP stream. */ bool startDTMF(char key); /** Send a DTMF end frame and turn off the DTMF events. */ void stopDTMF(); /** Send a vocoder frame over RTP. */ void txFrame(unsigned char* frame); /** Receive a vocoder frame over RTP. @param The vocoder frame @return new RTP timestamp */ int rxFrame(unsigned char* frame); void MOCInitRTP(); void MTCInitRTP(); /** In-call Signalling */ //@{ /** Send a SIP INFO message, usually for DTMF. Most parameters taken from current SIPEngine state. This call blocks for the response. @param wInfo The DTMF signalling code. @return Success/Fail flag. */ bool sendINFOAndWaitForOK(unsigned wInfo); //@} /** Save a copy of an INVITE or MESSAGE message in the engine. */ void saveINVITE(const osip_message_t *INVITE, bool mine); /** Save a copy of a response message in the engine. */ void saveResponse(osip_message_t *respsonse); /** Save a copy of a BYE message in the engine. */ void saveBYE(const osip_message_t *BYE, bool mine); private: /** Initialize the RTP session. @param msg A SIP INVITE or 200 OK wth RTP parameters */ void InitRTP(const osip_message_t * msg ); }; }; #endif // SIPENGINE_H // vim: ts=4 sw=4