1 /*
2   The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3   Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com
4 
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9 
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14 
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #ifndef _OSIP_MESSAGE_H_
21 #define _OSIP_MESSAGE_H_
22 
23 #include <osipparser2/osip_const.h>
24 #include <osipparser2/osip_headers.h>
25 #include <osipparser2/osip_body.h>
26 
27 /**
28  * @file osip_message.h
29  * @brief oSIP SIP Message Accessor Routines
30  *
31  * This is the SIP accessor and parser related API.
32  */
33 
34 /**
35  * @defgroup oSIP_MESSAGE oSIP message API
36  * @ingroup osip2_parser
37  * @{
38  */
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /**
45  * Structure for SIP Message (REQUEST and RESPONSE).
46  * @var osip_message_t
47  */
48 typedef struct osip_message osip_message_t;
49 
50 /**
51  * Structure for SIP Message (REQUEST and RESPONSE).
52  * @struct osip_message
53  */
54 struct osip_message {
55   char *sip_version;   /**< SIP version (SIP request only) */
56   osip_uri_t *req_uri; /**< Request-Uri (SIP request only) */
57   char *sip_method;    /**< METHOD (SIP request only) */
58 
59   int status_code;     /**< Status Code (SIP answer only) */
60   char *reason_phrase; /**< Reason Phrase (SIP answer only) */
61 
62 #ifndef MINISIZE
63   osip_list_t accepts;              /**< Accept headers */
64   osip_list_t accept_encodings;     /**< Accept-Encoding headers */
65   osip_list_t accept_languages;     /**< Accept-Language headers */
66   osip_list_t alert_infos;          /**< Alert-Info headers */
67   osip_list_t allows;               /**< Allows headers */
68   osip_list_t authentication_infos; /**< authentication_info headers */
69 #endif
70   osip_list_t authorizations; /**< Authorizations headers */
71   osip_call_id_t *call_id;    /**< Call-ID header */
72   osip_list_t call_infos;     /**< Call-Infos header */
73   osip_list_t contacts;       /**< Contacts headers */
74 #ifndef MINISIZE
75   osip_list_t content_encodings; /**< Content-Encodings headers */
76 #endif
77   osip_content_length_t *content_length; /**< Content-Length header */
78   osip_content_type_t *content_type;     /**< Content-Type header */
79   osip_cseq_t *cseq;                     /**< CSeq header */
80 #ifndef MINISIZE
81   osip_list_t error_infos; /**< Error-Info headers */
82 #endif
83   osip_from_t *from;                 /**< From header */
84   osip_mime_version_t *mime_version; /**< Mime-Version header */
85   osip_list_t proxy_authenticates;   /**< Proxy-Authenticate headers */
86 #ifndef MINISIZE
87   osip_list_t proxy_authentication_infos; /**< P-Authentication-Info headers */
88 #endif
89   osip_list_t proxy_authorizations; /**< Proxy-authorization headers */
90   osip_list_t record_routes;        /**< Record-Route headers */
91   osip_list_t routes;               /**< Route headers */
92   osip_to_t *to;                    /**< To header */
93   osip_list_t vias;                 /**< Vias headers */
94   osip_list_t www_authenticates;    /**< WWW-Authenticate headers */
95 
96   osip_list_t headers; /**< Other headers */
97 
98   osip_list_t bodies; /**< List of attachements */
99 
100   /*
101      1: structure and buffer "message" are identical.
102      2: buffer "message" is not up to date with the structure info (call osip_message_to_str to update it).
103    */
104   int message_property;  /**< internal value */
105   char *message;         /**< internal value */
106   size_t message_length; /**< internal value */
107 
108   void *application_data; /**< can be used by upper layer*/
109 };
110 
111 #ifndef SIP_MESSAGE_MAX_LENGTH
112 /**
113  * You can re-define your own maximum length for SIP message.
114  */
115 #define SIP_MESSAGE_MAX_LENGTH 8000
116 #endif
117 
118 #ifndef BODY_MESSAGE_MAX_SIZE
119 /**
120  * You can define the maximum length for a body inside a SIP message.
121  */
122 #define BODY_MESSAGE_MAX_SIZE 4000
123 #endif
124 
125 /**
126  * Allocate a osip_message_t element.
127  * @param sip The element to allocate.
128  */
129 int osip_message_init(osip_message_t **sip);
130 /**
131  * Free all resource in a osip_message_t element.
132  * @param sip The element to free.
133  */
134 void osip_message_free(osip_message_t *sip);
135 /**
136  * Parse a osip_message_t element.
137  * @param sip The resulting element.
138  * @param buf The buffer to parse.
139  * @param length The length of the buffer to parse.
140  */
141 int osip_message_parse(osip_message_t *sip, const char *buf, size_t length);
142 /**
143  * Parse a message/sipfrag part and store it in an osip_message_t element.
144  * @param sip The resulting element.
145  * @param buf The buffer to parse.
146  * @param length The length of the buffer to parse.
147  */
148 int osip_message_parse_sipfrag(osip_message_t *sip, const char *buf, size_t length);
149 /**
150  * Get a string representation of a osip_message_t element.
151  * NOTE: You need to release the sip buffer returned by this API when you
152  * are done with the buffer. ie: osip_free(dest)
153  * @param sip The element to work on.
154  * @param dest new allocated buffer returned.
155  * @param message_length The length of the returned buffer.
156  */
157 int osip_message_to_str(osip_message_t *sip, char **dest, size_t *message_length);
158 /**
159  * Get a string representation of a message/sipfrag part
160  * stored in an osip_message_t element.
161  * NOTE: You need to release the sip buffer returned by this API when you
162  * are done with the buffer. ie: osip_free(dest)
163  * @param sip The element to work on.
164  * @param dest new allocated buffer returned.
165  * @param message_length The length of the returned buffer.
166  */
167 int osip_message_to_str_sipfrag(osip_message_t *sip, char **dest, size_t *message_length);
168 /**
169  * Clone a osip_message_t element.
170  * @param sip The element to clone.
171  * @param dest The new allocated element cloned.
172  */
173 int osip_message_clone(const osip_message_t *sip, osip_message_t **dest);
174 
175 /**
176  * Set the reason phrase. This is entirely free in SIP.
177  * @param sip The element to work on.
178  * @param reason The reason phrase.
179  */
180 void osip_message_set_reason_phrase(osip_message_t *sip, char *reason);
181 /**
182  * Get the reason phrase. This is entirely free in SIP.
183  * @param sip The element to work on.
184  */
185 char *osip_message_get_reason_phrase(const osip_message_t *sip);
186 /**
187  * Set the status code. This is entirely free in SIP.
188  * @param sip The element to work on.
189  * @param statuscode The status code.
190  */
191 void osip_message_set_status_code(osip_message_t *sip, int statuscode);
192 /**
193  * Get the status code.
194  * @param sip The element to work on.
195  */
196 int osip_message_get_status_code(const osip_message_t *sip);
197 /**
198  * Set the method. You can set any string here.
199  * @param sip The element to work on.
200  * @param method The method name.
201  */
202 void osip_message_set_method(osip_message_t *sip, char *method);
203 /**
204  * Get the method name.
205  * @param sip The element to work on.
206  */
207 char *osip_message_get_method(const osip_message_t *sip);
208 /**
209  * Set the SIP version used. (default is "SIP/2.0")
210  * @param sip The element to work on.
211  * @param version The version of SIP.
212  */
213 void osip_message_set_version(osip_message_t *sip, char *version);
214 /**
215  * Get the SIP version.
216  * @param sip The element to work on.
217  */
218 char *osip_message_get_version(const osip_message_t *sip);
219 /**
220  * Set the Request-URI.
221  * @param sip The element to work on.
222  * @param uri The uri to set.
223  */
224 void osip_message_set_uri(osip_message_t *sip, osip_uri_t *uri);
225 /**
226  * Get the Request-URI.
227  * @param sip The element to work on.
228  */
229 osip_uri_t *osip_message_get_uri(const osip_message_t *sip);
230 
231 /*
232  *  These are helpfull MACROs to test messages type.
233  */
234 /**
235  * Test if the message is a SIP RESPONSE
236  * @param msg the SIP message.
237  */
238 #define MSG_IS_RESPONSE(msg) ((msg)->status_code != 0)
239 /**
240  * Test if the message is a SIP REQUEST
241  * @param msg the SIP message.
242  */
243 #define MSG_IS_REQUEST(msg) ((msg)->status_code == 0)
244 
245 /**
246  * Test if the message is an INVITE REQUEST
247  * @param msg the SIP message.
248  */
249 #define MSG_IS_INVITE(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "INVITE"))
250 /**
251  * Test if the message is an ACK REQUEST
252  * @param msg the SIP message.
253  */
254 #define MSG_IS_ACK(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "ACK"))
255 /**
256  * Test if the message is a REGISTER REQUEST
257  * @param msg the SIP message.
258  */
259 #define MSG_IS_REGISTER(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "REGISTER"))
260 /**
261  * Test if the message is a BYE REQUEST
262  * @param msg the SIP message.
263  */
264 #define MSG_IS_BYE(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "BYE"))
265 /**
266  * Test if the message is an OPTIONS REQUEST
267  * @param msg the SIP message.
268  */
269 #define MSG_IS_OPTIONS(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "OPTIONS"))
270 /**
271  * Test if the message is an INFO REQUEST
272  * @param msg the SIP message.
273  */
274 #define MSG_IS_INFO(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "INFO"))
275 /**
276  * Test if the message is a CANCEL REQUEST
277  * @param msg the SIP message.
278  */
279 #define MSG_IS_CANCEL(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "CANCEL"))
280 /**
281  * Test if the message is a REFER REQUEST
282  * @param msg the SIP message.
283  */
284 #define MSG_IS_REFER(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "REFER"))
285 /**
286  * Test if the message is a NOTIFY REQUEST
287  * @param msg the SIP message.
288  */
289 #define MSG_IS_NOTIFY(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "NOTIFY"))
290 /**
291  * Test if the message is a SUBSCRIBE REQUEST
292  * @def MSG_IS_SUBSCRIBE
293  * @param msg the SIP message.
294  */
295 #define MSG_IS_SUBSCRIBE(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "SUBSCRIBE"))
296 /**
297  * Test if the message is a MESSAGE REQUEST
298  * @param msg the SIP message.
299  */
300 #define MSG_IS_MESSAGE(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "MESSAGE"))
301 /**
302  * Test if the message is a PRACK REQUEST  (!! PRACK IS NOT SUPPORTED by the fsm!!)
303  * @param msg the SIP message.
304  */
305 #define MSG_IS_PRACK(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "PRACK"))
306 
307 /**
308  * Test if the message is an UPDATE REQUEST
309  * @param msg the SIP message.
310  */
311 #define MSG_IS_UPDATE(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "UPDATE"))
312 
313 /**
314  * Test if the message is an UPDATE REQUEST
315  * @param msg the SIP message.
316  */
317 #define MSG_IS_PUBLISH(msg) (MSG_IS_REQUEST(msg) && 0 == strcmp((msg)->sip_method, "PUBLISH"))
318 
319 /**
320  * Test if the message is a response with status between 100 and 199
321  * @param msg the SIP message.
322  */
323 #define MSG_IS_STATUS_1XX(msg) ((msg)->status_code >= 100 && (msg)->status_code < 200)
324 /**
325  * Test if the message is a response with status between 200 and 299
326  * @param msg the SIP message.
327  */
328 #define MSG_IS_STATUS_2XX(msg) ((msg)->status_code >= 200 && (msg)->status_code < 300)
329 /**
330  * Test if the message is a response with status between 300 and 399
331  * @param msg the SIP message.
332  */
333 #define MSG_IS_STATUS_3XX(msg) ((msg)->status_code >= 300 && (msg)->status_code < 400)
334 /**
335  * Test if the message is a response with status between 400 and 499
336  * @param msg the SIP message.
337  */
338 #define MSG_IS_STATUS_4XX(msg) ((msg)->status_code >= 400 && (msg)->status_code < 500)
339 /**
340  * Test if the message is a response with status between 500 and 599
341  * @param msg the SIP message.
342  */
343 #define MSG_IS_STATUS_5XX(msg) ((msg)->status_code >= 500 && (msg)->status_code < 600)
344 /**
345  * Test if the message is a response with status between 600 and 699
346  * @param msg the SIP message.
347  */
348 #define MSG_IS_STATUS_6XX(msg) ((msg)->status_code >= 600 && (msg)->status_code < 700)
349 /**
350  * Test if the message is a response with a status set to the code value.
351  * @param msg the SIP message.
352  * @param code the status code.
353  */
354 #define MSG_TEST_CODE(msg, code) (MSG_IS_RESPONSE(msg) && (code) == (msg)->status_code)
355 /**
356  * Test if the message is a response for a REQUEST of certain type
357  * @param msg the SIP message.
358  * @param requestname the method name to match.
359  */
360 #define MSG_IS_RESPONSE_FOR(msg, requestname) (MSG_IS_RESPONSE(msg) && 0 == strcmp((msg)->cseq->method, (requestname)))
361 
362 /**
363  * Allocate a generic parameter element.
364  * @param GP The element to work on.
365  */
366 #define osip_generic_param_init(GP) osip_uri_param_init(GP)
367 /**
368  * Free a generic parameter element.
369  * @param GP The element to work on.
370  */
371 #define osip_generic_param_free(GP) osip_uri_param_free(GP)
372 /**
373  * Set values of a generic parameter element.
374  * @param GP The element to work on.
375  * @param NAME The token name.
376  * @param VALUE The token value.
377  */
378 #define osip_generic_param_set(GP, NAME, VALUE) osip_uri_param_set(GP, NAME, VALUE)
379 /**
380  * Clone a generic parameter element.
381  * @param GP The element to work on.
382  * @param DEST The resulting new allocated buffer.
383  */
384 #define osip_generic_param_clone osip_uri_param_clone
385 #ifndef DOXYGEN
386 /*
387  * Free a list of a generic parameter element.
388  * @param LIST The list of generic parameter element to free.
389  */
390 #define osip_generic_param_freelist(LIST) osip_uri_param_freelist(LIST)
391 #endif
392 /**
393  * Allocate and add a generic parameter element in a list.
394  * @param LIST The list of generic parameter element to work on.
395  * @param NAME The token name.
396  * @param VALUE The token value.
397  */
398 #define osip_generic_param_add(LIST, NAME, VALUE) osip_uri_param_add(LIST, NAME, VALUE)
399 /**
400  * Find in a generic parameter element in a list.
401  * @param LIST The list of generic parameter element to work on.
402  * @param NAME The name of the parameter element to find.
403  * @param DEST A pointer on the element found.
404  */
405 #define osip_generic_param_get_byname(LIST, NAME, DEST) osip_uri_param_get_byname(LIST, NAME, DEST)
406 
407 /**
408  * Set the name of a generic parameter element.
409  * @param generic_param The element to work on.
410  * @param name the token name to set.
411  */
412 void osip_generic_param_set_name(osip_generic_param_t *generic_param, char *name);
413 /**
414  * Get the name of a generic parameter element.
415  * @param generic_param The element to work on.
416  */
417 char *osip_generic_param_get_name(const osip_generic_param_t *generic_param);
418 /**
419  * Set the value of a generic parameter element.
420  * @param generic_param The element to work on.
421  * @param value the token name to set.
422  */
423 void osip_generic_param_set_value(osip_generic_param_t *generic_param, char *value);
424 /**
425  * Get the value of a generic parameter element.
426  * @param generic_param The element to work on.
427  */
428 char *osip_generic_param_get_value(const osip_generic_param_t *generic_param);
429 
430 /**
431  * Get the a known header from a list of known header.
432  * @param header_list The element to work on.
433  * @param pos The index of the element to get.
434  * @param dest A pointer on the header found.
435  */
436 int osip_message_get_knownheaderlist(osip_list_t *header_list, int pos, void **dest);
437 
438 /** @} */
439 
440 #ifdef __cplusplus
441 }
442 #endif
443 #endif
444