ADD-A-HEADER 4.72 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2
Description of Adding a SIP Header to Sofia SIP
===============================================
Pekka Pessi's avatar
Pekka Pessi committed
3

4
by Pekka Pessi (2002-08-16, updated 2006-10-03)
5

6 7 8 9 10
There are three ways to extend the Sofia SIP parser, including a standard
header in sip_t structure, including a standard header in extra headers or
putting the extension headers into a separate library.

Probalem with extending #sip_t is that it breaks binary compatibility.
Pekka Pessi's avatar
Pekka Pessi committed
11 12 13 14 15 16

In the text below, we use "Example" header as our example with following
ABNF:

   sip-example = "Example" COLON 1*DIGIT

Pekka Pessi's avatar
Pekka Pessi committed
17

18 19
IF YOUR HEADER IS A STANDARD ONE
--------------------------------
Pekka Pessi's avatar
Pekka Pessi committed
20 21

  * In <sip.h>, add:
Pekka Pessi's avatar
Pekka Pessi committed
22

23
  - Add typedef to the header structure.
Pekka Pessi's avatar
Pekka Pessi committed
24

25
    The typedefs to ordinary headers are in more or less alphabetic
Pekka Pessi's avatar
Pekka Pessi committed
26 27 28 29 30 31 32 33
    order after typedef of sip_unknown_t. You should add a typedef line
    like this:

     typedef struct sip_example_s sip_example_t;
	
    Note that the typedefs are documented together with the
    implementation in the .c file.

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
  - Add field to the sip_t structure (struct sip_s)
    - Remember to add a comment containing the header name
      after field for benefit of the AWK script autmatically generating
      boilerplate functions and macros:
      sip_example_t *sip_example; /**< Example */
    - The AWK script msg_parser.awk automatically creates the default
      prototypes and tags for the newly created header when the entry in
      sip_t structure is formatted like to the example above. 
      It will complain about mismatches between header name and field name.

  * Add the actual header structure:

    The header structure would look like below. The first field MUST be a
    sip_common_t structure, second field MUST be a pointer to next header
    with same name. As a convention, if there can be only one header field
    of this kind, the type of the "next" pointer is sip_error_t.

    The fields representing the header value are located after the mandatory
    fields, usually in the order they are present in the header contents. In
    this case, the Example header consist of a 32-bit integer:

       /**@ingroup sip_example
        * @brief Structure for Example header.
        */
       struct sip_example_s {
         sip_common_t   ex_common[1];	    /**< Common fragment info. */
         sip_error_t   *ex_next;	    /**< Link to next (dummy). */
         unsigned long  ex_value;	    /**< Value of example. */
       };

  * Write parsing tests for your new headers in torture_sip.c:

    Add all relevant parsing/processing cases you can think of
    at the end of function sip_header_test() or add a testing
    function of your own.

  * Add implementation in a suitable ".c" file
    - For an simple example, see implementation of Date header in sip_basic.c
    - Add a documentation group with @defgroup
    - Document the typedef
    - Add header class structure
    - Add parsing and printing functions:
      + sip_example_d(), sip_example_e()
    - Add functions used when copying the header structure:
      + sip_example_dup_xtra(), sip_example_dup_one()

  * If you added a .c file, add to the Makefile.am
    - remember to run autogen.sh unless you have given --enable-maintainer-mode 
      to configure script
Pekka Pessi's avatar
Pekka Pessi committed
83

84
  * Run "make check" after you are ready 
Pekka Pessi's avatar
Pekka Pessi committed
85

86 87 88 89 90 91 92 93 94 95 96 97 98
  * Run "make check" after you are ready. Really.


IF YOUR HEADERS ARE NON-STANDARD
--------------------------------

    - There is an example package sofia-sip-2543.tar.gz, available from
      sofia-sip.sourceforge.net

      See the extension package for 1) 

    - Create a header template for your header just like 
      sofia-sip/rfc2543.h.in (found in <sofia-sip/rfc2543.h> package), 
Pekka Pessi's avatar
Pekka Pessi committed
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
      e.g, sip_example.h.in:

---8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<---
/**@file sip_example.h.in
 *
 * Template for <sip_example.h>.
 */

#ifndef SIP_EXAMPLE_H 
/** Defined when <sip_example.h> has been included. */
#define SIP_EXAMPLE_H 

/**@file sip_example.h 
*
 * @brief Example header.
 *
 * #AUTO#
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>.
 *
 * @date Created: Fri May 27 18:40:38 EEST 2005 ppessi
 */

#ifndef SIP_H
123 124 125 126
#include <sofia-sip/sip.h>
#endif
#ifndef SIP_HEADER_H
#include <sofia-sip/sip_header.h>
Pekka Pessi's avatar
Pekka Pessi committed
127 128
#endif

129 130
/**@ingroup sip_example
 * @brief Structure for @b Example header.
Pekka Pessi's avatar
Pekka Pessi committed
131
 */
132
struct sip_example_s
Pekka Pessi's avatar
Pekka Pessi committed
133
{
134 135 136
  sip_common_t   ex_common[1];    /**< Common fragment info */
  sip_error_t   *ex_next;	  /**< Link to next (dummy). */
  uint32_t       ex_value;	  /**< Value of Example */
Pekka Pessi's avatar
Pekka Pessi committed
137 138
};

139
typedef struct sip_example_s sip_example_t;
Pekka Pessi's avatar
Pekka Pessi committed
140 141 142

struct sip_example_dummy_structure {
  /* === Headers start here */
143
  sip_example_t *sip_example;                            /**< Example */
Pekka Pessi's avatar
Pekka Pessi committed
144 145 146 147 148 149 150
  /* === Headers end here */
};


#endif /** !defined(SIP_EXAMPLE_H) */
--->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---

Pekka Pessi's avatar
Pekka Pessi committed
151 152