📄 readme
字号:
$Id: README,v 1.9 1999/09/01 18:35:45 luan Exp $SIP READMEVersion 0.1.1September 1, 1999COPYRIGHTThis library is free software; you can redistribute it and/or modifyit under the terms of the GNU Lesser General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, or (at your option) any later version.This library is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with this library; if not; write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA.Copyright 1999 Vovida Networks, Inc. All Rights Reserved. Running the test parser applicationTo run the test application one should build it. Run make.After that open new window and start the SIPTest program without any arguments.SIPTest(one should see '0' being print on the window)Now that the server side of the application is run.In another window one can run the client side the following way:SIPTest <UDP|TCP> <host> <file>Where TCP or UDP - used protocol host - host name or IPv4 addres of the server side. file - one of files with test requests. There are three files: req1.sip, req2.sip and resp1.sip.One can run many client applications in diffrent sessions with TCPand UDP protocols. Server listens on port 5060 and can receive manyrequests from different clients simultaneously. SIPParserSIP messages parser is defined and implemented in the namespace 'msip'.This parser allows one to parse messages, check their syntax with diagnoseby exception mechanism, build new messages, and copy and modify existedones.1. MsgParser ClassThe main class is called MsgParser. It can be used for all possibleoperations and incapsulates all information of request or response.Isolated use of the header classes is possible as well. MsgParser class hasmethods to access any item of data as a string variable.2. ParsingTo parse the messages use: void decode(const std::mstring & str, std::string::size_type, bool checkSyntaxFlag=true) This method parses the message and may generate the exceptionMpSyntaxError. SIP messages do not have a special mark of the end ofmessages, so that one must know the total length of each message. Asmessage buffer can contain more than one message, one should have amechanism of determination the length of the each message. To determinationthe lenght and checking whether the message is ready to parse, thefollowing method should be used: std::string::size_type findMessageEnd(const std::mstring & str);It returns the total length of one message. Besides, this method must becalled before parse, because it determines the length of the content of themessage and saves it into internal class variable. After processing themessage, independently on whether it was success or not, one should removethe processed part of message to be prepared to continue receiving thefollowing ones, because the buffer may contain a whole message and somepiece of next one.The genegal algorithm of waiting for messages and parsing ones is: std::mstring buf; std::string::size_type len; msip::MsgParser p; while( !end_of_life_cycle() ) { //Add buf += get_the_next_piece_of_message(); len = p.findMessageEnd(buf); if(len != std::string::npos) { try { p.decode(buf, len); //The message has been parsed . . . . . . //Process the message, make necessary responses, etc... } catch(msip::MpSyntaxError & err) { std::string err_text = err.what(); . . . . . . //Send a "Bad request" message } //Erase the processed part of buf //to be ready to parse the next message buf.erase(0, len); } }3. AccessThe class SIPParser is a container of headers, a start line and the messagecontent. The message content is a usual a STL-string and it is not processedby parser. All other items - the start line and the message headers areobject of the base class Mp0ParsItem. There is an abstract class and it hasaccess methods to its data. First of all, each item has the followingthree methods: virtual void decode(const std::mstring & str, bool checkSyntaxFlag=true); virtual std::mstring encode(bool checkSyntaxFlag=true) const; virtual void checkSyntax() const;These methods allow one to parse (decode), to build (encode) and to checksyntax of the current items. If checkSyntaxFlag=true, checking syntax willbe done automatically after parsing or before building. chkSyntax() methodallows one to do this at any time. These methods can generate the exceptionMpSyntaxError. The methods decode and encode allow to have an access tothe whole content of items. For example: msip::MpHostPort hostPort; hostPort.decode("sip.pubserver.com"); //To assign a new host-port value std::mstring hp_str = hostPort.encode(); //To get the host-port valueAlso operators '<<' and '>>' are overloaded for convinience. The exampleabove can be rewritten: msip::MpHostPort hostPort; hostPort << "sip.pubserver.com:5060"; std::mstring hp_str; hostPort >> hp_str;Any item may have a string values and other nested items. Concrete parametersor items depend on SIP-header itself. To access to the values one can usethe following method: virtual std::mstring & val(const char * name);For example: msip::MpFrom from; std::mstring disp_name = from.val(msip::mpnDispName); //To get a display name from.val(msip::mpnDispName) = "John Smith"; //To assign a new display nameItems can incapsulate other nested items, for example, MpFrom item containsMpUrl and MpParm items and values mpnDispName and mpnComment. MpUrl itselfcontains MpUserInfo, MpHostPort, MpUrlParm and MpUrlHdr items. These itemsdo not have any nested items. To access the nested items one can use thefollowing operator: virtual Mp0ParsItem & operator [] (const char * name);For example: msip::MpFrom from; std::mstring host = from[msip::mpiUrl][msip::mpiHostPort].val(msip::mpnHost); //To get host-name from[msip::mpiUrl][msip::mpiHostPort].val(msip::mpnHost) = "sip.pubserver.com";//To assign new host-nameAll the access methods can generate the exception MpAccessError. It canmean that the method had an invalid name of item or value. For thedescription of all possible items see section 3.2. 3.1 Access to the Start LineThe start line of SIP messages is a parser item. To obtain an access to thestart line use the method of MsgParser class: MpStartLine & startLine();For example: msip::MsgParser p; p.stl() << "INVITE sip:vovida_robot@sip.pubserver.com:5060 SIP/2.0"; //To assign a whole line //To assign values: p.startLinestl().val(msip::mpnMsgType) = "INVITE"; p.startLinestl()[msip::mpiUrl][mpiHostPort].val(mpnHost) = "sip.pubserver.com"; p.startLinestl()[msip::mpiUrl][mpiHostPort].val(mpnPort) = "5060"; p.startLinestl()[msip::mpiUrl][mpiUserInfo].val(mpnUser) = "vovida_robot"; 3.2 Access to the HeadersAll the headers are Mp0ParsItem objects, so that the access to its data isthe same. To obtain an access to the headers by their name, use thefollowing method of MsgParser class: MpHeader & header(const char * name, unsigned index=0);For example: msip::MsgParser p; p.header(hdrnVia) << "SIP/2.0/UDP mera.ru:5060"; If the header does not exist, it will be added automatically. One SIPmessages may contain several headers with the same name, for example: SIP/2.0 180 Ringing Via: SIP/2.0/UDP csvax.cs.caltech.edu;branch=8348;maddr=239.128.16.254;ttl=16 Via: SIP/2.0/UDP north.east.isi.edu From: Mark Handley <sip:mjh@isi.edu> To: Eve Schooler <sip:schooler@caltech.edu> ;tag=9883472 Call-ID: 2963313058@north.east.isi.edu CSeq: 1 INVITEIn this case, to obtain an access to the second, third and so on Viaheaders one can use the hdr() method in the following way: p.header(hdrnVia, 0) << "SIP/2.0/UDP csvax.cs.caltech.edu;branch=8348;maddr=239.128.16.254;ttl=16"; p.header(hdrnVia, 1) << "SIP/2.0/UDP north.east.isi.edu"; p.header(hdrnVia, 2) << "SIP/2.0/UDP sip:vovida_robot@sip.pubserver.com:5060"; 3.3 Adding new headersSIP proxy server must add the Via header before the first existing Via. Todo it the MsgParser has a special function: MpHeader & insertHeader(const char * name, unsigned index=0);Where index is number of the header before which one wishes to insert a newheader. To insert a header before the first one (number 0), use thefollowing call: p.insertHeader(hdrnVia, 0);To insert to the end of header list one can use any big number, for example: p.insertHeader(hdrnVia, 10000);Note, that headers can be of single or multiple type. The message maycontain only one of each single headers, for example: From, To, CSeq. Butseveral multiple headers, of the same type are possible in the message.For example: Via, Allow, Accept-Language and so on. Besides, every multipleheader may be written as a list: Accept-Language: da, en-gb;q=0.8, en;q=0.7In this case, if the header type is muiltiple, the parser will separate thelist into detached headers: Accept-Language: da Accept-Language: en-gb;q=0.8 Accept-Language: en;q=0.7Thus, one can address the content of these headers with the same way: p.header(hdrnAcceptLanguage, 0) p.header(hdrnAcceptLanguage, 1) p.header(hdrnAcceptLanguage, 2)The content of Via headers can be rather long, unlike the Accept-Languageheader. Every type of header has a special flag, which detemines whetherit needs to unite separate headers to one list or not. All headers with ashort content will be united.For example:The source message: INVITE sip:watson@boston.bell-tel.com SIP/2.0 Via: SIP/2.0/UDP kton.bell-tel.com, SIP/2.0/UDP north.east.isi.edu From: A. Bell <sip:a.g.bell@bell-tel.com> To: T. Watson <sip:watson@bell-tel.com> Call-ID: 3298420296@kton.bell-tel.com CSeq: 1 INVITE Accept-Language: da, en-gb;q=0.8 Accept-Language: en;q=0.7 Content-Length: 0The message after decode / encode INVITE sip:watson@boston.bell-tel.com SIP/2.0 Via: SIP/2.0/UDP kton.bell-tel.com ViaL SIP/2.0/UDP north.east.isi.edu From: A. Bell <sip:a.g.bell@bell-tel.com> To: T. Watson <sip:watson@bell-tel.com> Call-ID: 3298420296@kton.bell-tel.com CSeq: 1 INVITE Accept-Language: da, en-gb;q=0.8, en;q=0.7 Content-Length: 0If one tries to add two or more single headers, then the exceptionMpAccessError will be generated. 3.4 Access to the Message ContentThe parser supports SIP+ multiple payloads as well as single ones(SIP/2.0). The content of the messages itself is not inerpreted by theparser. It is an ASCII string which may be used by other classes.The following methods allow to have access to message content: unsigned countContents() const;Returns the total number of content parts. MpContentType & contentType(unsigned index=0);Get or set the content type by index. If the message does not have a partof such index it will be added automatically. For example:msg.contentType(0) << "application/sdp";msg.contentType(1) << "application/GR-317"; const std::mstring & getContent(unsigned index=0) const;Get the content of part number 'index'. void setContent(const std::string & content, unsigned index=0);Set the content of part number 'index'. void removeContent(unsigned index=0);Remove the content of part number 'index'.If a message has a single content, one can use it without index. To setthe type of the single content one should use the method 'contentType'instead of using the method 'header'. The parser has an array of contentparts and if it is a single content then the parser uses the first item ofthe array and makes the headers 'Content-Type' and 'Content-Length'automatically. When the parser has more than one part of the content itsets the header 'Content-Type: application/multipart' automatically. Thus,no need to take care about the headers 'Content-Type' and 'Content-Length'.Example: MsgParser p; p.contentType(0) << "application/sdp" p.setContent( "v=0\r\n" "o=bell 53655765 2353687637 IN IP4 128.3.4.5\r\n" "s=Mr. Watson, come here.\r\n"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -