/* * $Id: AmSession.h,v 1.20.2.5 2005/08/31 13:54:29 rco Exp $ * * Copyright (C) 2002-2003 Fhg Fokus * * This file is part of sems, a free SIP media server. * * sems is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * info@iptel.org * * sems is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _AmSession_h_ #define _AmSession_h_ #include "AmRtpStream.h" #include "AmThread.h" //#include "AmRequest.h" #include "AmEventQueue.h" #include "AmRtpAudio.h" #include "AmDtmfDetector.h" #include "AmSipRequest.h" #include "AmSipDialog.h" #include "AmSipEvent.h" #include "AmApi.h" #include #include #include #include using std::string; using std::vector; using std::queue; using std::map; using std::pair; class AmSessionFactory; //class AmDialogState; class AmDtmfEvent; /** * Signaling plugins must inherite from this class. */ class AmSessionEventHandler { public: AmSession* s; bool destroy; AmSessionEventHandler(AmSession* s) : destroy(true),s(s) {} /* * All the methods return true if event processing * should stopped after calling them. */ virtual bool process(AmEvent*); virtual bool onSipEvent(AmSipEvent*); virtual bool onSipRequest(const AmSipRequest&); virtual bool onSipReply(const AmSipReply&); virtual bool onSendRequest(const string& method, const string& content_type, const string& body, string& hdrs); virtual bool onSendReply(const AmSipRequest& req, unsigned int code, const string& reason, const string& content_type, const string& body, string& hdrs); }; /** * The session class. * It implements the behavior. * The session is identified by Call-ID, From-Tag and To-Tag. */ class AmSession : public AmThread, public AmEventQueue, public AmEventHandler, public AmSipDialogEventHandler // public AmDialogState { AmMutex audio_mut; AmAudio* input; AmAudio* output; SdpPayload payload; bool first_negotiation; AmDtmfDetector m_dtmfDetector; AmDtmfEventQueue m_dtmfEventQueue; AmDtmfHandler m_dtmfHandler; AmEventQueue m_dtmfOutputQueue; bool m_dtmfDetectionEnabled; vector ev_handlers; /** @see AmThread::run() */ void run(); /** @see AmThread::on_stop() */ void on_stop(); AmCondition sess_stopped; AmCondition detached; friend class AmSessionScheduler; friend class AmSessionSchedulerThread; friend class AmSessionContainer; friend class AmSessionFactory; // this is the call group - by default local tag string callgroup; protected: AmSdp sdp; AmRtpAudio rtp_str; public: AmSipDialog dlg; struct Exception { int code; string reason; Exception(int c, string r) : code(c), reason(r) {} }; // struct SessionTimerException : Exception { // unsigned int minSE; // SessionTimerException(unsigned int min_SE) // : Exception(422, "Session Interval Too Small"), // minSE(min_SE) { } // string getErrorHeaders() const; // }; /** * Session constructor. */ AmSession(); virtual ~AmSession(); /** * @see AmEventHandler */ void process(AmEvent*); void addHandler(AmSessionEventHandler*); /** * Set the call group for this call. * * Note: this must be set before inserting * the session to the scheduler! */ void setCallgroup(const string& cg); /** * Accept the INVITE proposal * thus setting up audio stream */ int acceptAudio(const AmSipRequest& req); /** * Lock and unlock audio input & output * (inclusive RTP stream) */ void lockAudio(); void unlockAudio(); /** * Audio input & output get methods. * Note: audio must be locked. */ AmAudio* getInput() { return input; } AmAudio* getOutput(){ return output;} /** * Audio input & output set methods. * Note: audio will be locked by the methods. */ void setInput(AmAudio* in); void setOutput(AmAudio* out); void setInOut(AmAudio* in, AmAudio* out); /** * Clears input & ouput (no need to lock) */ void clearAudio(); /** setter for rtp_str->mute */ void setMute(bool mute) { rtp_str.mute = mute; } /** Gets the Session's call ID */ const string& getCallID() const; /** Gets the Session's remote tag */ const string& getRemoteTag()const ; /** Gets the Session's local tag */ const string& getLocalTag() const; void setLocalTag(const string& tag); // AmSipDialog& getDialog() { return dlg; } /** Gets the current RTP payload */ const SdpPayload* getPayload(); /** Gets the port number of the remote part of the session */ int getRPort(); /** handle SDP negotiation: only for INVITEs & re-INVITEs */ virtual void negotiate(const AmSipRequest& request); void sendUpdate(); void sendReinvite(); /** * Destroy the session. * It causes the session to be erased from the active session list * and added to the dead session list. * @see AmSessionContainer */ void destroy(); /** * Signals the session it should stop. * This will cause the session to be able * to exit the main loop. */ void setStopped() { sess_stopped.set(true); } /** * Has the session already been stopped ? */ bool getStopped() { return sess_stopped.get(); } /** * Creates a new Id which can be used within sessions. */ static string getNewId(); /** * Entry point for DTMF events */ void postDtmfEvent(AmDtmfEvent *); void processDtmfEvents(); bool isDtmfDetectionEnabled() { return m_dtmfDetectionEnabled; } void setDtmfDetectionEnabled(bool e) { m_dtmfDetectionEnabled = e; } void putDtmfAudio(const unsigned char *buf, int size, int user_ts); void onDtmf(int event, int duration); /** * onStart will be called before everything else. */ virtual void onStart(){} /** * onBeforeCallAccept will be called on incoming * request before the call gets definitely established. * * Throw AmSession::Exception if you want to * signal any error. */ virtual void onBeforeCallAccept(const AmSipRequest& req){} /** * onSessionStart will be called after call setup. * * Throw AmSession::Exception if you want to * signal any error. * * Warning: * The session ends with this method. * Sems will NOT send any BYE on his own. */ virtual void onSessionStart(const AmSipRequest& req){} /** * @see AmDialogState */ void onBye(const AmSipRequest& req); /** * Entry point for SIP events */ virtual void onSipEvent(AmSipEvent* sip_ev); virtual void onSipRequest(const AmSipRequest& req); virtual void onSipReply(const AmSipReply& reply); /* only called by AmSipDialog */ virtual void onSendRequest(const string& method, const string& content_type, const string& body, string& hdrs); virtual void onSendReply(const AmSipRequest& req, unsigned int code, const string& reason, const string& content_type, const string& body, string& hdrs); }; #endif // Local Variables: // mode:C++ // End: