sip2

所属分类:IP电话/视频会议
开发工具:Visual C++
文件大小:349KB
下载次数:97
上传日期:2005-03-30 15:36:06
上 传 者percival
说明:  一个简单的SIP协议栈,但基本的功能已经实现。是osip的第二选择
(a simple SIP protocol stack, but the basic function has been achieved. Osip is the second choice)

文件列表:
sip2 (0, 2004-01-15)
sip2\.cvsignore (27, 2002-09-30)
sip2\CVS (0, 2004-01-15)
sip2\CVS\Entries (195, 2002-10-21)
sip2\CVS\Repository (19, 2002-09-26)
sip2\CVS\Root (42, 2002-09-26)
sip2\emacs.el (26900, 2002-09-22)
sip2\sip2.sln (887, 2002-10-03)
sip2\sip2.vcproj (9991, 2002-10-13)
sip2\sipstack (0, 2004-01-15)
sip2\sipstack\.cvsignore (158, 2002-10-21)
sip2\sipstack\ChangeLog (1168, 2002-10-28)
sip2\sipstack\convertStringToInt.cxx (3928, 2002-10-21)
sip2\sipstack\CVS (0, 2004-01-15)
sip2\sipstack\CVS\Entries (4677, 2002-10-28)
sip2\sipstack\CVS\Repository (28, 2002-09-26)
sip2\sipstack\CVS\Root (42, 2002-09-26)
sip2\sipstack\DataParameter.cxx (3875, 2002-10-21)
sip2\sipstack\DataParameter.hxx (3491, 2002-10-21)
sip2\sipstack\Dialog.cxx (9560, 2002-10-21)
sip2\sipstack\Dialog.hxx (4912, 2002-10-21)
sip2\sipstack\doc (0, 2004-01-15)
sip2\sipstack\doc\.cvsignore (38, 2002-10-21)
sip2\sipstack\doc\ClassDiag.vsd (112128, 2002-09-26)
sip2\sipstack\doc\CVS (0, 2004-01-15)
sip2\sipstack\doc\CVS\Entries (415, 2002-10-28)
sip2\sipstack\doc\CVS\Repository (32, 2002-09-26)
sip2\sipstack\doc\CVS\Root (42, 2002-09-26)
sip2\sipstack\doc\design-overview.xml (8109, 2002-10-28)
sip2\sipstack\doc\design.css (1355, 2002-09-29)
sip2\sipstack\doc\fsm-dot.awk (773, 2002-09-23)
sip2\sipstack\doc\htmlcss.xsl (1027, 2002-09-29)
sip2\sipstack\doc\Makefile (1298, 2002-10-21)
sip2\sipstack\doc\srv-inv-fsm.dot (3150, 2002-09-23)
sip2\sipstack\doc\srv-inv-tree.dot (4132, 2002-09-23)
sip2\sipstack\Executive.cxx (3818, 2002-10-21)
sip2\sipstack\Executive.hxx (3180, 2002-10-21)
sip2\sipstack\ExistsParameter.cxx (3000, 2002-10-21)
sip2\sipstack\ExistsParameter.hxx (3037, 2002-10-21)
sip2\sipstack\FloatParameter.cxx (3301, 2002-10-21)
... ...

September 23, 2002 head/vocal/sip2/sipstack/README SipMessage design goals: - efficient parsing - reasonable interface for the application writer - reasonably easy path to adding new headers, methods, parameter names SipMessage design. There are two APIs to SipMessage; one from the transport layer 'up' and one from the application layer 'down'. The transport layers pulls the raw message text off the wire, parses the text just enough to segment it onto headers and sets the text of the headers into the SipMessage generically. This minimal header parse phase is called "pre-parsing". The pre-parse phase needs to identify the header for generic storage into the SipMessage. In addition, the pre-parse phase needs to know if unescaped commas are delimiters in the header text to be parsed. However, the pre-parse phase does not require static typing of the header or whether the header can appear multiple times in the message. The pre-parse phase allows unknown headers. The application requests a specific header by static type. If the header does not exists, an empty header of the appropriate type is created. If the header has not already been parsed, a parser is created and associated with the header. The parser is not invoked until the application requests a sub-part of the header. This permits headers to be moved from one message to another without parsing within the header. The parser is statically typed to provide a specific interface to the application. The specifics of how to parse a message of a given type is implemented by the parser type. The static header types are available to the application through global variables named after the headers; e.g. CallId, CSeq, From, Via. The interface from each parser is a set of accessors. Each accessor may return a reference, allowing the application to set the corresponding value directly, or it may return a const reference, indicating a read only value. Most parsers also present an interface to a generic parameter accessor. This generic parameter accessors allows the application to get or set proprietary parameters. The application retrieves unknown headers by the string name of the unknown header. Interface Examples: SipMessage *msg; msg->get(From).getAddressOfRecord(); Data& aor = msg->get(From)->host(); msg->get(From).host() = "vovida.org"; msg->exists(Warning); msg->exists("Proprietary-Header"); // true if present msg->get("Proprietary-Header"); // returns ParserContainer& for (Vias::iterator i = msg->get(Vias).begin(); i != msg->get(Vias).end(); i++) { Data& host = i->host(); int& port = i->port(); } Implementation: There is a fixed set of headers. Each header is assigned an enum value. There is a type associated with each enum value and a distinctly named global variable of header type. The enum value is used to store and retrieve the headers at runtime. The header type is used to retrieve the parsed and statically typed headers at compile time. A SipMessage contains an array of pointers to HeaderFieldValueList. This array is indexed by the header enums. The pre-parse phase consists of: 0. determine the boundaries of the header string 1. determine the boundaries of the header name string 2. look up the enum value for the header name 3. look up the comma tokenizing property of the header enum 4. determine the boundaries of each header in the header string 5. for each header in the header string, add the header string boundaries by enum to the message -- the message stores the header string boundaries in the as indexed by the header enum While processing headers the pre-parse will allocate chunks of memory to hold the header strings. Each of these buffers is passed opaquely to the message for deletion when the message is deleted. After pre-parsing the message header array contains one HeaderFieldValueList for each header encountered in the pre-parse. Each HeaderFieldValueList contains a list of HeaderFieldValue. The application requests the contents of a header through a type safe interface; the returned object is either a particular parser type or a particular parser container. A parser container is returned if and only if the header is specified to permit multiple values. If the header specifies multiple values, the returned value is iterable. Each iteration provides access to a header value. In addition, there is an interface on the returned value to determine the number of header values. The returned value in the single header value case, and within the iteration over the multi header value case provides access to the components of the header value specfic to the type of header. For example, CSeq provides getMethod() and sequence. For sequence, the sequence value is an integer returned by reference and may be directly modified. Adding a new header: Assume the new header name New-Header Symbols.hxx 1. Add New_Header to the static symbol declarations. Symbols.chxx 1. Add New_Header = "New-Header" to the static symbol definitions. HeaderTypes.hxx 1. Add New_Header to the Headers::Type enum. Add this entry anywhere before UNKNOWN. Headers are output in the same order they appear in the Headers::Type enum. 2. Determine if the header allows multiple values. Use the MultiHeader template if the new header allows multiple values, use the Header template if the new header does not allow multiple values. 3. Determine the parser type for the header. This may be StringComponent for unstructured headers, may be another existing parser type (see ParserCategories.hxx), or may require a new parser type. 4. Add the declaration of the header type and the header type global variable to HeaderTypes.hxx e.g.: class Header { public: typedef StringComponent Type; Header() { Headers::CommaTokenizing[Headers::New_Header] = Type::isCommaTokenizing; HeaderStrings[Headers::New_Header] = Symbols::New_Header; } }; extern Header Content_Disposition; 5. Add the mapping from the four character hash to the header enum. This is error prone. The hash value is platform dependent. HeaderTypesSetup.cxx 1. Add a line to the hash id generator. HeaderTypes.cxx 1. Add the definition of the new header type global variable. Be sure to use the same template type as in the declaration. e.g. Header Vocal2:: New_Header>; ParserCategories.hxx (if the new header requires a new parser) 1. Declare the new parser category as publicly inheriting from ParserCategory. 2. Determine if commas can be used to include multiple header values in a single line. 3. Declare virtual ParserCategory* clone(HeaderFieldValue*) const; 4. Declare virtual void parse(); 5. Declare private members as required to store the parsed header value. 6. Declare public methods as required to access the parsed header value. 7. Typedef the container for the parser. Not required if the header value is never used in a header that allows multiple values. e.g. typedef ParserContainer NewComponents; ParserCategories.cxx (if the new header requires a new parser) 1. Define clone(), parse() 2. Define accessors. Each accessor must call checkParsed() before processing any data. (* It would be nice if getHeaderType(const char *headerName, int len) was defined my configure/make. The supported.hxx would be replaced with a configuration file headers.hdr that specified the SIP header name, the C++ parser category, and whether the header allows multiple values. This file could be compiled into the various declarations and definitions. It is even possible to allow the user to specify additional headers in the code; have the automatically generated types go into the enum HeaderTypesBase, and have HeaderTypes inherit; HeaderTypes::Types could continue where the inherited enum leaves off. *)

近期下载者

相关文件


收藏者