summaryrefslogtreecommitdiffstats
path: root/src/parser/sip_body.h
blob: 42ecd6faf2e5e1641c0bfc9e1adafc869f4710e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*
    Copyright (C) 2005-2009  Michel de Boer <michel@twinklephone.com>

    This program 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.

    This program 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, see <https://www.gnu.org/licenses/>.
*/

// SIP bodies
#ifndef _H_SIP_BODY
#define _H_SIP_BODY

#include <commoncpp/config.h>
#include <string>
#include <libxml/tree.h>

#include "media_type.h"

//@{
/** @name Utilies for XML body parsing */
/**
 * Check the tag name of an XML node.
 * @param node [in] (xmlNode *) The XML node to check.
 * @param tag [in] (const char *) The tag name.
 * @param namespace [in] (const char *) The namespace of the tag.
 * @return true if the node has the tag name within the name space.
 */
#define IS_XML_TAG(node, tag, namespace)\
				((node)->type == XML_ELEMENT_NODE &&\
				(node)->ns &&\
				xmlStrEqual((node)->ns->href, BAD_CAST (namespace)) &&\
				xmlStrEqual((node)->name, BAD_CAST (tag)))
				
/**
 * Check the attribute name of an XML attribute.
 */
#define IS_XML_ATTR(attr, attr_name, namespace)\
				 ((attr)->type == XML_ATTRIBUTE_NODE &&\
				 (attr)->ns &&\
				 xmlStrEqual((attr)->ns->href, BAD_CAST (namespace)) &&\
				 xmlStrEqual((attr)->name, BAD_CAST (attr_name)))
//@}

class t_sip_message;

using namespace std;

/** Body type. */
enum t_body_type {
	BODY_OPAQUE,		/**< Opaque body. */
	BODY_SDP,		/**< SDP */
	BODY_SIPFRAG,		/**< message/sipfrag RFC 3420 */
	BODY_DTMF_RELAY,	/**< DTMF relay as defined by Cisco */
	BODY_SIMPLE_MSG_SUM,	/**< Simple message summary RFC 3842 */
	BODY_PLAIN_TEXT,	/**< Plain text for messaging */
	BODY_HTML_TEXT,		/**< HTML text for messaging */
	BODY_PIDF_XML,		/**< pidf+xml RFC 3863 */
	BODY_IM_ISCOMPOSING_XML	/**< im-iscomposing+xml RFC 3994 */
};

/** Abstract base class for SIP bodies. */
class t_sip_body {
public:
	/**
	 * Indicates if the body content is invalid.
	 * This will be set by the body parser.
	 */
	bool 	invalid;

	/** Constructor. */
	t_sip_body();
	
	virtual ~t_sip_body() {}

	/**
	 * Encode the body.
	 * @return Text encoded body.
	 */
	virtual string encode(void) const = 0;

	/**
	 * Create a copy of the body.
	 * @return Copy of the body.
	 */
	virtual t_sip_body *copy(void) const = 0;

	/** 
	 * Get type of body.
	 * @return body type.
	 */
	virtual t_body_type get_type(void) const = 0;
	
	/**
	 * Get content type for this type of body.
	 * @return Content type.
	 */
	virtual t_media get_media(void) const = 0;
	
	/**
	 * Check if all local IP address are correctly filled in. This
	 * check is an integrity check to help debugging the auto IP
	 * discover feature.
	 */
	virtual bool local_ip_check(void) const;
	
	/**
	 * Return the size of the encoded body. This method encodes the body
	 * to calculate the size. When a more efficient algorithm is available
	 * a sub class may override this method.
	 * @return The size of the encoded body in bytes.
	 */
	virtual size_t get_encoded_size(void) const;
};

/** Abstract base class for XML formatted bodies. */
class t_sip_body_xml : public t_sip_body {
protected:
	xmlDoc		*xml_doc;	/**< XML document */
	
	/**
	 * Create an empty XML document.
	 * Override this method to create the specific XML document.
	 * @param xml_version [in] The XML version of the document.
	 * @param charset [in] The character set of the document.
	 */
	virtual void create_xml_doc(const string &xml_version = "1.0", const string &charset = "UTF-8");
	
	/** Remove the XML document */
	virtual void clear_xml_doc(void);
	
	/** 
	 * Copy the XML document from this body to another body.
	 * @param to_body [in] The body to copy the XML body to.
	 */
	virtual void copy_xml_doc(t_sip_body_xml *to_body) const;
	
public:
	/** Constructor */
	t_sip_body_xml();
	
	/** Destructor */
	virtual ~t_sip_body_xml();
	
	virtual string encode(void) const;
	
	/**
	 * Parse a text representation of the body.
	 * The result is stored in @ref xml_doc
	 * @param s [in] Text to parse.
	 * @return True if parsing and state extracting succeeded, false otherwise.
	 * @pre xml_doc == NULL
	 * @post If parsing succeeds then xml_doc != NULL
	 */
	virtual bool parse(const string &s);
};


/**
 * This body can contain any type of body. The contents are
 * unparsed and thus opaque.
 */
class t_sip_body_opaque : public t_sip_body {
public:
	string	opaque; /**< The body contents. */

	/** Construct body with empty content. */
	t_sip_body_opaque();

	/**
	 * Construct a body with opaque content.
	 * @param s [in] The content.
	 */
	t_sip_body_opaque(string s);
	
	string encode(void) const;
	t_sip_body *copy(void) const;
	t_body_type get_type(void) const;
	t_media get_media(void) const;
	virtual size_t get_encoded_size(void) const;
};

// RFC 3420
// sipfrag body
class t_sip_body_sipfrag : public t_sip_body {
public:
	t_sip_message	*sipfrag;

	t_sip_body_sipfrag(t_sip_message *m);
	~t_sip_body_sipfrag();
	string encode(void) const;
	t_sip_body *copy(void) const;
	t_body_type get_type(void) const;
	t_media get_media(void) const;
};

// application/dtmf-relay body
class t_sip_body_dtmf_relay : public t_sip_body {
public:
	char	signal;
	uint16	duration; // ms
	
	t_sip_body_dtmf_relay();
	t_sip_body_dtmf_relay(char _signal, uint16 _duration);
	string encode(void) const;
	t_sip_body *copy(void) const;
	t_body_type get_type(void) const;
	t_media get_media(void) const;
	bool parse(const string &s);
};

/** Plain text body. */
class t_sip_body_plain_text : public t_sip_body {
public:
	string	text;	/**< The text */
	
	/** Construct a body with empty text. */
	t_sip_body_plain_text();
	
	/**
	 * Constructor.
	 * @param _text [in] The body text.
	 */
	t_sip_body_plain_text(const string &_text);
	
	string encode(void) const;
	t_sip_body *copy(void) const;
	t_body_type get_type(void) const;
	t_media get_media(void) const;
	virtual size_t get_encoded_size(void) const;
};

/** Html text body. */
class t_sip_body_html_text : public t_sip_body {
public:
	string	text;	/**< The text */
	
	/**
	 * Constructor.
	 * @param _text [in] The body text.
	 */
	t_sip_body_html_text(const string &_text);
	
	string encode(void) const;
	t_sip_body *copy(void) const;
	t_body_type get_type(void) const;
	t_media get_media(void) const;
	virtual size_t get_encoded_size(void) const;
};

#endif