/* The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) Copyright (C) 2001,2002,2003,2004 Aymeric MOIZARD jack@atosc.org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSIP_MESSAGE_H_ #define _OSIP_MESSAGE_H_ #include #include #include /** * @file osip_message.h * @brief oSIP SIP Message Accessor Routines * * This is the SIP accessor and parser related API. */ /** * @defgroup oSIP_MESSAGE oSIP message API * @ingroup osip2_parser * @{ */ #ifdef __cplusplus extern "C" { #endif /** * Structure for SIP Message (REQUEST and RESPONSE). * @var osip_message_t */ typedef struct osip_message osip_message_t; /** * Structure for SIP Message (REQUEST and RESPONSE). * @struct osip_message */ struct osip_message { char *sip_version; /**< SIP version (SIP request only) */ osip_uri_t *req_uri; /**< Request-Uri (SIP request only) */ char *sip_method; /**< METHOD (SIP request only) */ int status_code; /**< Status Code (SIP answer only) */ char *reason_phrase; /**< Reason Phrase (SIP answer only) */ osip_list_t accepts; /**< Accept headers */ osip_list_t accept_encodings; /**< Accept-Encoding headers */ osip_list_t accept_languages; /**< Accept-Language headers */ osip_list_t alert_infos; /**< Alert-Info headers */ osip_list_t allows; /**< Allows headers */ osip_list_t authentication_infos;/**< authentication_info headers */ osip_list_t authorizations; /**< Authorizations headers */ osip_call_id_t *call_id; /**< Call-ID header */ osip_list_t call_infos; /**< Call-Infos header */ osip_list_t contacts; /**< Contacts headers */ osip_list_t content_encodings; /**< Content-Encodings headers */ osip_content_length_t *content_length; /**< Content-Length header */ osip_content_type_t *content_type; /**< Content-Type header */ osip_cseq_t *cseq; /**< CSeq header */ osip_list_t error_infos; /**< Error-Info headers */ osip_from_t *from; /**< From header */ osip_mime_version_t *mime_version;/**< Mime-Version header */ osip_list_t proxy_authenticates; /**< Proxy-Authenticate headers */ osip_list_t proxy_authentication_infos; /**< P-Authentication-Info headers */ osip_list_t proxy_authorizations;/**< Proxy-authorization headers */ osip_list_t record_routes; /**< Record-Route headers */ osip_list_t routes; /**< Route headers */ osip_to_t *to; /**< To header */ osip_list_t vias; /**< Vias headers */ osip_list_t www_authenticates; /**< WWW-Authenticate headers */ osip_list_t headers; /**< Other headers */ osip_list_t bodies; /**< List of attachements */ /* 1: structure and buffer "message" are identical. 2: buffer "message" is not up to date with the structure info (call osip_message_to_str to update it). */ int message_property; /**@internal */ char *message; /**@internal */ size_t message_length; /**@internal */ void *application_data; /**can be used by upper layer*/ }; #ifndef SIP_MESSAGE_MAX_LENGTH /** * You can re-define your own maximum length for SIP message. */ #define SIP_MESSAGE_MAX_LENGTH 4000 #endif #ifndef BODY_MESSAGE_MAX_SIZE /** * You can define the maximum length for a body inside a SIP message. */ #define BODY_MESSAGE_MAX_SIZE 4000 #endif /** * Allocate a osip_message_t element. * @param sip The element to allocate. */ int osip_message_init (osip_message_t ** sip); /** * Free all resource in a osip_message_t element. * @param sip The element to free. */ void osip_message_free (osip_message_t * sip); /** * Parse a osip_message_t element. * @param sip The resulting element. * @param buf The buffer to parse. * @param length The length of the buffer to parse. */ int osip_message_parse (osip_message_t * sip, const char *buf, size_t length); /** * Parse a message/sipfrag part and store it in an osip_message_t element. * @param sip The resulting element. * @param buf The buffer to parse. * @param length The length of the buffer to parse. */ int osip_message_parse_sipfrag (osip_message_t * sip, const char *buf, size_t length); /** * Get a string representation of a osip_message_t element. * @param sip The element to work on. * @param dest new allocated buffer returned. * @param message_length The length of the returned buffer. */ int osip_message_to_str (osip_message_t * sip, char **dest, size_t * message_length); /** * Get a string representation of a message/sipfrag part * stored in an osip_message_t element. * @param sip The element to work on. * @param dest new allocated buffer returned. * @param message_length The length of the returned buffer. */ int osip_message_to_str_sipfrag (osip_message_t * sip, char **dest, size_t * message_length); /** * Clone a osip_message_t element. * @param sip The element to clone. * @param dest The new allocated element cloned. */ int osip_message_clone (const osip_message_t * sip, osip_message_t ** dest); /** * Set the reason phrase. This is entirely free in SIP. * @param sip The element to work on. * @param reason The reason phrase. */ void osip_message_set_reason_phrase (osip_message_t * sip, char *reason); /** * Get the reason phrase. This is entirely free in SIP. * @param sip The element to work on. */ char *osip_message_get_reason_phrase (const osip_message_t * sip); /** * Set the status code. This is entirely free in SIP. * @param sip The element to work on. * @param statuscode The status code. */ void osip_message_set_status_code (osip_message_t * sip, int statuscode); /** * Get the status code. * @param sip The element to work on. */ int osip_message_get_status_code (const osip_message_t * sip); /** * Set the method. You can set any string here. * @param sip The element to work on. * @param method The method name. */ void osip_message_set_method (osip_message_t * sip, char *method); /** * Get the method name. * @param sip The element to work on. */ char *osip_message_get_method (const osip_message_t * sip); /** * Set the SIP version used. (default is "SIP/2.0") * @param sip The element to work on. * @param version The version of SIP. */ void osip_message_set_version (osip_message_t * sip, char *version); /** * Get the SIP version. * @param sip The element to work on. */ char *osip_message_get_version (const osip_message_t * sip); /** * Set the Request-URI. * @param sip The element to work on. * @param uri The uri to set. */ void osip_message_set_uri (osip_message_t * sip, osip_uri_t * uri); /** * Get the Request-URI. * @param sip The element to work on. */ osip_uri_t *osip_message_get_uri (const osip_message_t * sip); /* * These are helpfull MACROs to test messages type. */ /** * Test if the message is a SIP RESPONSE * @param msg the SIP message. */ #define MSG_IS_RESPONSE(msg) ((msg)->status_code!=0) /** * Test if the message is a SIP REQUEST * @param msg the SIP message. */ #define MSG_IS_REQUEST(msg) ((msg)->status_code==0) /** * Test if the message is an INVITE REQUEST * @param msg the SIP message. */ #define MSG_IS_INVITE(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"INVITE")) /** * Test if the message is an ACK REQUEST * @param msg the SIP message. */ #define MSG_IS_ACK(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"ACK")) /** * Test if the message is a REGISTER REQUEST * @param msg the SIP message. */ #define MSG_IS_REGISTER(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"REGISTER")) /** * Test if the message is a BYE REQUEST * @param msg the SIP message. */ #define MSG_IS_BYE(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"BYE")) /** * Test if the message is an OPTIONS REQUEST * @param msg the SIP message. */ #define MSG_IS_OPTIONS(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"OPTIONS")) /** * Test if the message is an INFO REQUEST * @param msg the SIP message. */ #define MSG_IS_INFO(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"INFO")) /** * Test if the message is a CANCEL REQUEST * @param msg the SIP message. */ #define MSG_IS_CANCEL(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"CANCEL")) /** * Test if the message is a REFER REQUEST * @param msg the SIP message. */ #define MSG_IS_REFER(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"REFER")) /** * Test if the message is a NOTIFY REQUEST * @param msg the SIP message. */ #define MSG_IS_NOTIFY(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"NOTIFY")) /** * Test if the message is a SUBSCRIBE REQUEST * @def MSG_IS_SUBSCRIBE * @param msg the SIP message. */ #define MSG_IS_SUBSCRIBE(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"SUBSCRIBE")) /** * Test if the message is a MESSAGE REQUEST * @param msg the SIP message. */ #define MSG_IS_MESSAGE(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"MESSAGE")) /** * Test if the message is a PRACK REQUEST (!! PRACK IS NOT SUPPORTED by the fsm!!) * @param msg the SIP message. */ #define MSG_IS_PRACK(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"PRACK")) /** * Test if the message is an UPDATE REQUEST * @param msg the SIP message. */ #define MSG_IS_UPDATE(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"UPDATE")) /** * Test if the message is an UPDATE REQUEST * @param msg the SIP message. */ #define MSG_IS_PUBLISH(msg) (MSG_IS_REQUEST(msg) && \ 0==strcmp((msg)->sip_method,"PUBLISH")) /** * Test if the message is a response with status between 100 and 199 * @param msg the SIP message. */ #define MSG_IS_STATUS_1XX(msg) ((msg)->status_code >= 100 && \ (msg)->status_code < 200) /** * Test if the message is a response with status between 200 and 299 * @param msg the SIP message. */ #define MSG_IS_STATUS_2XX(msg) ((msg)->status_code >= 200 && \ (msg)->status_code < 300) /** * Test if the message is a response with status between 300 and 399 * @param msg the SIP message. */ #define MSG_IS_STATUS_3XX(msg) ((msg)->status_code >= 300 && \ (msg)->status_code < 400) /** * Test if the message is a response with status between 400 and 499 * @param msg the SIP message. */ #define MSG_IS_STATUS_4XX(msg) ((msg)->status_code >= 400 && \ (msg)->status_code < 500) /** * Test if the message is a response with status between 500 and 599 * @param msg the SIP message. */ #define MSG_IS_STATUS_5XX(msg) ((msg)->status_code >= 500 && \ (msg)->status_code < 600) /** * Test if the message is a response with status between 600 and 699 * @param msg the SIP message. */ #define MSG_IS_STATUS_6XX(msg) ((msg)->status_code >= 600 && \ (msg)->status_code < 700) /** * Test if the message is a response with a status set to the code value. * @param msg the SIP message. * @param code the status code. */ #define MSG_TEST_CODE(msg,code) (MSG_IS_RESPONSE(msg) && \ (code)==(msg)->status_code) /** * Test if the message is a response for a REQUEST of certain type * @param msg the SIP message. * @param requestname the method name to match. */ #define MSG_IS_RESPONSE_FOR(msg,requestname) (MSG_IS_RESPONSE(msg) && \ (msg)->cseq && \ 0==strcmp((msg)->cseq->method,(requestname))) /** * Allocate a generic parameter element. * @param GP The element to work on. */ #define osip_generic_param_init(GP) osip_uri_param_init(GP) /** * Free a generic parameter element. * @param GP The element to work on. */ #define osip_generic_param_free(GP) osip_uri_param_free(GP) /** * Set values of a generic parameter element. * @param GP The element to work on. * @param NAME The token name. * @param VALUE The token value. */ #define osip_generic_param_set(GP, NAME, VALUE) osip_uri_param_set(GP, NAME, VALUE) /** * Clone a generic parameter element. * @param GP The element to work on. * @param DEST The resulting new allocated buffer. */ #define osip_generic_param_clone(GP,DEST) osip_uri_param_clone(GP,DEST) #ifndef DOXYGEN /* * Free a list of a generic parameter element. * @param LIST The list of generic parameter element to free. */ #define osip_generic_param_freelist(LIST) osip_uri_param_freelist(LIST) #endif /** * Allocate and add a generic parameter element in a list. * @param LIST The list of generic parameter element to work on. * @param NAME The token name. * @param VALUE The token value. */ #define osip_generic_param_add(LIST,NAME,VALUE) osip_uri_param_add(LIST,NAME,VALUE) /** * Find in a generic parameter element in a list. * @param LIST The list of generic parameter element to work on. * @param NAME The name of the parameter element to find. * @param DEST A pointer on the element found. */ #define osip_generic_param_get_byname(LIST,NAME,DEST) osip_uri_param_get_byname(LIST,NAME,DEST) /** * Set the name of a generic parameter element. * @param generic_param The element to work on. * @param name the token name to set. */ void osip_generic_param_set_name (osip_generic_param_t * generic_param, char *name); /** * Get the name of a generic parameter element. * @param generic_param The element to work on. */ char *osip_generic_param_get_name (const osip_generic_param_t * generic_param); /** * Set the value of a generic parameter element. * @param generic_param The element to work on. * @param value the token name to set. */ void osip_generic_param_set_value (osip_generic_param_t * generic_param, char *value); /** * Get the value of a generic parameter element. * @param generic_param The element to work on. */ char *osip_generic_param_get_value (const osip_generic_param_t * generic_param); /** @} */ #ifdef __cplusplus } #endif #endif