📄 sipconcepts.h
字号:
/********************************************************************* $Id: SIPConcepts.h,v 1.2 1999/08/31 02:22:05 cullen Exp $ ********************************************************************* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. In addition to the terms and conditions set forth in the GNU Lesser General Public License, as a condition of using this library you are required to grant to all users of this library or any implementation utilizing or derived from this library a reciprocal, no cost, worldwide, perpetual, non-exclusive, non-transferable, unrestricted license to your claims of all patents and patent applications throughout the world that are infringed by the library or any implementation utilizing or derived from this library. In the event you redistribute this library or any implementation utilizing or derived from this library, you must prominently display the foregoing terms and conditions with the library or the implementation utilizing or derived from this library. In the event of a conflict of terms between the foregoing license grant and the terms set forth in the GNU Lesser General Public License, the foregoing terms and conditions shall be deemed to govern. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not; write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. Copyright 1999 Vovida Networks, Inc. All Rights Reserved. ********************************************************************* $Log: SIPConcepts.h,v $ Revision 1.2 1999/08/31 02:22:05 cullen updated header **********************************************************************/namespace msip{ /* This is a brief description of SIP middle level implementation. The implementation is used by the High-Level of SIP such as EndPoint, Proxy, MGCPGateway, etc. The main class is called Agent and it must be quite "transparent", i.e. do not have any restrictions of using the SIP stack. It must allow to use all the possibilities of SIP. The class Message will be improved and it must have some functions of making the most frequently used headers (such as From, To, Via, Contact) for convinience and some methods as checkViaLoop, addVia and so on. The middle level of SIP stack consists of the following entities: 1. Receiver 2. Message processor (Parser and Builder) 3. Transmitter These entities are classes which are rather weakly connected to each other according to general OOD concepts. The receiver (class msip::MsgReceiver) listens TCP and UDP ports, creates an incoming queue of messages and calls the parser to make necessary structures and obtain access to parts of them. The message processor parses the incoming messages and returns them as ready-to-use objects (class Message). The transmitter just transmits the messages via UDP or TCP without any checking and retransmitting. The realiability via UDP will be attained in the Hi-Level API (EndPoint, Proxy, etc...). All these components are integrated into the class Agent. The specification of SIP says the following: "If TCP is used, request and responses within a single SIP transaction are carried over the same TCP connection (see Section 10). Several SIP requests from the same client to the same server MAY use the same TCP connection or MAY use a new connection for each request." Thus, when we send a message we can use two methods: 1. Open connection, then send one or more messages, then close connection. 2. Just send one message without keepeng the connection opened. In the last case method 1 will be used locally. For UDP opening connections may mean whether "connect" (it can be used via UDP as well as via TCP) or whether nothing (if we use the "sendto" function). There are two overloaded metods "send" of the class Agent. The Agent must support two possible methods of using - Asynchronous (event driven) and Syncronous (multi-thread) 1. Asynchronous (event driven) We have a common loop of event processing, and the state-machine of all the events. Someting like that: while(not_exit()) { sip_agent.addToFdSet(&fds); usr_agent.addToFdSet(&fds); select(&fds...) if(sip_agent.process(&fds)) { //... Incoming events processing //... State-machine switch } if(usr_agent.process(&fds)) { //... Outgoing events registrantion, // Message creation, State-machine switch //... Sending the messages with possible retransmittions // With a state-machine using } } This piece of code will be possible implemented into the high-level API such as EndPoint, Proxy, Gateway 2. Syncronous (multi-thread) We create a thread which will have a loop such as in point 1. We will have a special class Dispatcher which will keep information about current SIP calls. This thread will add new messages into the Dispatcher and the Dispatcher will whether create a new thread if the call (From, To, CallID and CSeq) does not exist or wheter add the message into the existing queue of the call. The Dispatcher will take care about transactions, retransmittions and so on. It will have a very simple state-machine and all the logic of work will be implemented into the threads which the Dispatcher will create. These threads will take the messages into its private queues, process the messages and send responses. The Dispatcher will have a special functions of creation and control calls by the user events (offhook, call initiation, onhook, etc). The middle level of SIP stack does not have this functionality but must allow to use both of these approaches. */ ///Send via TCP or UDP protocols. enum SendVia { viaUDP, viaTCP }; ///Transmitter class class Transmitter { private: //... Data members public: /// Create connection bool connect(SendVia via, const std::string & addr, int port=0); /// Close connection bool close(); /// Send a message via connection bool send(const Message& msg); }; ///The middle level of SIP stack - SIP Agent. class Agent { private: //... Data Members public: /**@name Setup functions */ //@{ /// Listening ports setup. Create a MsgReceiver object bool listen(int udp_port=5060, int tcp_port=5060); //@} /**@name Listening and Process functions */ //@{ ///Adds descriptors to fd_set void addToFdSet(fd_set* fds) const; /// Process incoming messages. Returns true if there is something to do. void process(fd_set* fds); /// True if the Incoming queue is empty bool empty() const; /// Receive a message ProcessResult receive(Message* msg, mh323::IPAddress* addr_from); //@} /**@name Transmitting functions */ //@{ /** Create a connection via TCP or UDP. Using UDP may mean that there is nothing to do. It may be used for the unify only. When the TCP is used the transmiter creates a real connection. After we creates the connection we will be abble to send messages via this connection. The pointer to the Transmitter is used as a descriptor (or identifier of this connection). There several forms of call are possible: transmitter = connect(viaTCP, "remote_host", 5060); transmitter = connect(viaTCP, "195.67.176.77", 6061); transmitter = connect(viaTCP, "remote_host:5060"); When the port is indicated as a parameter it will be used (The parameter has a higher priority)*/ Transmitter* connect(SendVia via, const std::string & addr, int port=0) const; /** Send a message via the opened connection */ bool send(const Message& msg, Transmitter *transmitter) const; /** Send a message as a local transaction (connect, send, close) */ bool send(const Message& msg, SendVia via, const std::string & addr, int port=0) const; /** Close existed connection */ bool close(Transmitter *transmitter) const; //@} }; class Call { }; class Dispacther { }; /* The EndPoint class is an example of High-Level API working asynchronously. The EndPoint class is intended to applications such as SIP UserAgent and/or ServerAgent. It has a simple interface and a powerful state machine inside it. A general idea of using the EndPoint class is: 1. We create a derived class which contains all necessary data and overrides the virtuals. 2. When UserAgent wants to make a call it must create an object of the class Message and then call the method "call". 3. Into the common loop we must call the method "process" periodically. 4. When the transaction is finihed the method onConnect will be called. It must open RTP channels (create RtpSession) and prepare exchanging of data 5. onDataExchange will be called periodically according to activity of file descriptors (fd_set). 6. When the user application wants to finish the call it must call the method "bye". 7. When the call is finished the method "onBye" will be called. This method will be called whether when the user calls the method "bue" or whether the remote agent sends the BYE request. The method "onBye" must close the RTP/RTCP channels and delete the RtpSession object The ServerAgent side does the same except point 2. It is just waiting a new calls. In the implementation of the pure-C interface we will have to create the Call-Back functions according to these virual overrides. */ class EndPoint { private: //... Data Members public: /**@name Listening and Process functions */ //@{ ///Adds descriptors to fd_set void addToFdSet(fd_set* fds) const; /// Process incoming messages. Returns true if there is something to do. void process(fd_set* fds); /// Return true if the call is finished. bool endOfLoop(); //@} /// Create a call according to Message content. bool call(const Message& msg); /// Finish the call and send the remote agent a BYE request bool bye(); /** The method onConnect will be called when the SIP transaction is finished. Generally this method must open RTP channels (create RtpSession) */ virtual bool onConnect() = 0; /** The method is called when the call is finished. It must close RTP channels (delete RtpSession) */ virtual void onBye() = 0; /** The method will be called periodically when to exchange data via RTP*/ virtual bool onDataExchange() = 0;//!!!!!not quite clear yet// /** A "virtual" constructor. When the server side receives // an INVITE request this method will be called to create// a new object EndPoint */// virtual EndPoint* clone() = 0; };}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -