/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi * * 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., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * */ #ifndef SIP_HEADER_H /**Defined when has been included.*/ #define SIP_HEADER_H /**@file sofia-sip/sip_header.h * * SIP parser library prototypes. * * @author Pekka Pessi . * * @date Created: Tue Jun 13 02:58:26 2000 ppessi */ #ifndef SU_ALLOC_H #include #endif #ifndef SU_TAG_H #include #endif #ifndef SIP_H #include #endif #ifndef MSG_HEADER_H #include #endif #ifndef _STRING_H #include #endif SOFIA_BEGIN_DECLS /** Return a built-in SIP parser object. */ SOFIAPUBFUN msg_mclass_t const *sip_default_mclass(void); /** Release SIP parser object if it was cloned. */ SOFIAPUBFUN void sip_cloned_parser_destroy(void); SOFIAPUBFUN int sip_update_default_mclass(msg_mclass_t const *mclass); SOFIAPUBFUN msg_mclass_t *sip_extend_mclass(msg_mclass_t *input); /** Check that sip_t is a SIP header structure (not MIME or HTTP). @HIDE */ #define sip_is_sip(sip) ((sip) && (sip)->sip_ident == SIP_PROTOCOL_TAG) /** Initializer for a SIP header structure. @HIDE */ #define SIP_HDR_INIT(name) {{{ 0, 0, sip_##name##_class }}} /** Initialize a SIP header structure. @HIDE */ #define SIP_HEADER_INIT(h, sip_class, size) \ ((void)memset((h), 0, (size)), \ (void)(((sip_common_t *)(h))->h_class = (sip_class)), \ (h)) /** Serialize headers into the fragment chain. */ SOFIAPUBFUN int sip_serialize(msg_t *msg, sip_t *sip); /** Encode a SIP message. */ SOFIAPUBFUN issize_t sip_e(sip_t const *sip, int flags, char b[], isize_t size); /** Test if @a header is a pointer to a SIP header object. */ SOFIAPUBFUN int sip_is_header(sip_header_t const *header); /** Convert the header @a h to a string allocated from @a home. */ SOFIAPUBFUN char *sip_header_as_string(su_home_t *home, sip_header_t const *h); /** Add a duplicate of header object to a SIP message. */ SOFIAPUBFUN int sip_add_dup(msg_t *, sip_t *, sip_header_t const *); /** Add a duplicate of header object to the SIP message. */ SOFIAPUBFUN int sip_add_dup_as(msg_t *msg, sip_t *sip, msg_hclass_t *hc, sip_header_t const *o); /** Add duplicates of headers to the SIP message. */ SOFIAPUBFUN int sip_add_headers(msg_t *msg, sip_t *sip, void const *extra, va_list headers); /** Add duplicates of headers from taglist to the SIP message. */ SOFIAPUBFUN int sip_add_tl(msg_t *msg, sip_t *sip, tag_type_t tag, tag_value_t value, ...); /** Add duplicates of headers from taglist to the SIP message. */ SOFIAPUBFUN int sip_add_tagis(msg_t *, sip_t *, tagi_t const **inout_list); /** Parse a string as a header and add it to the SIP message. */ SOFIAPUBFUN int sip_add_make(msg_t *, sip_t *, msg_hclass_t *hc, char const *s); /** Convert headers from taglist as URL query. */ SOFIAPUBFUN char *sip_headers_as_url_query(su_home_t *home, tag_type_t tag, tag_value_t value, ...); /** Convert URL query to a tag list. */ SOFIAPUBFUN tagi_t *sip_url_query_as_taglist(su_home_t *home, char const *query, msg_mclass_t const *parser); /** Complete SIP message. */ SOFIAPUBFUN int sip_complete_message(msg_t *msg); /** Clear encoded data. @HIDE */ #define sip_fragment_clear(a) ((a)->h_data = NULL, (a)->h_len = 0) /* Use __attribute__ to allow argument checking for sip_header_format() */ #if !defined(__GNUC__) && !defined(__attribute__) #define __attribute__(x) #endif /** Make a SIP header with formatting provided. */ SOFIAPUBFUN sip_header_t *sip_header_format(su_home_t *home, msg_hclass_t *hc, char const *fmt, ...) __attribute__((__format__ (printf, 3, 4))); /** Return current time */ SOFIAPUBFUN sip_time_t sip_now(void); SOFIAPUBVAR char const sip_method_name_ack[]; SOFIAPUBVAR char const sip_method_name_bye[]; SOFIAPUBVAR char const sip_method_name_cancel[]; SOFIAPUBVAR char const sip_method_name_invite[]; SOFIAPUBVAR char const sip_method_name_options[]; SOFIAPUBVAR char const sip_method_name_register[]; SOFIAPUBVAR char const sip_method_name_info[]; SOFIAPUBVAR char const sip_method_name_prack[]; SOFIAPUBVAR char const sip_method_name_comet[]; SOFIAPUBVAR char const sip_method_name_message[]; SOFIAPUBVAR char const sip_method_name_subscribe[]; SOFIAPUBVAR char const sip_method_name_notify[]; SOFIAPUBVAR char const sip_method_name_refer[]; /** @internal UDP transport version string. */ SOFIAPUBVAR char const sip_transport_udp[]; /** @internal TCP transport version string. */ SOFIAPUBVAR char const sip_transport_tcp[]; /** @internal SCTP transport version string. */ SOFIAPUBVAR char const sip_transport_sctp[]; /** @internal TLS transport version string. */ SOFIAPUBVAR char const sip_transport_tls[]; /** @internal WS transport version string. */ SOFIAPUBVAR char const sip_transport_ws[]; /** @internal WSS transport version string. */ SOFIAPUBVAR char const sip_transport_wss[]; /** @internal SIP version string. */ SOFIAPUBVAR char const sip_version_2_0[]; #define SIP_VERSION_CURRENT sip_version_2_0 /** SIP parser version */ SOFIAPUBVAR char const sip_parser_version[]; /** Get SIP service name */ #define SIP_PORT(s) ((s) ? (s) : "5060") /** Get SIPS service name */ #define SIPS_PORT(s) ((s) ? (s) : "5061") /** Return string corresponding to the method. */ SOFIAPUBFUN char const *sip_method_name(sip_method_t method, char const *name); /** Return code corresponding to the method code */ SOFIAPUBFUN sip_method_t sip_method_code(char const *name); SOFIAPUBVAR char const * const sip_method_names[]; #define SIP_METHOD_NAME(method, name) \ ((method) == sip_method_unknown ? (name) : sip_method_name(method, name)) #define sip_header_make(h, c, s) \ ((sip_header_t *)msg_header_make((h), (c), (s))) #define sip_header_vformat(h, c, f, a) \ ((sip_header_t *)msg_header_vformat((h), (c), (f), (a))) SOFIA_END_DECLS #ifndef SIP_PROTOS_H #include #endif SOFIA_BEGIN_DECLS /** Create a request line object. */ SOFIAPUBFUN sip_request_t *sip_request_create(su_home_t *home, sip_method_t method, const char *name, url_string_t const *url, char const *version); /** Create a status line object. */ SOFIAPUBFUN sip_status_t *sip_status_create(su_home_t *home, unsigned status, char const *phrase, char const *version); /** Create a @CallID header object. */ SOFIAPUBFUN sip_call_id_t *sip_call_id_create(su_home_t *home, char const *domain); /** Create a @CSeq header object. */ SOFIAPUBFUN sip_cseq_t *sip_cseq_create(su_home_t *, uint32_t seq, unsigned method, char const *name); /** Create a @Identity header object. */ SOFIAPUBFUN sip_identity_t *sip_identity_create(su_home_t *, uint32_t seq, unsigned method, char const *name); /** Create a @Contact header object. */ SOFIAPUBFUN sip_contact_t * sip_contact_create(su_home_t *, url_string_t const *url, char const *param, /* char const *params, */ ...); /** Calculate expiration time of a @Contact header. */ SOFIAPUBFUN sip_time_t sip_contact_expires(sip_contact_t const *m, sip_expires_t const *ex, sip_date_t const *date, sip_time_t def, sip_time_t now); /** Create a @ContentLength header object. */ SOFIAPUBFUN sip_content_length_t *sip_content_length_create(su_home_t *, uint32_t n); /** Create an @Date header object. */ SOFIAPUBFUN sip_date_t *sip_date_create(su_home_t *, sip_time_t t); /** Create an @Expires header object. */ SOFIAPUBFUN sip_expires_t *sip_expires_create(su_home_t *, sip_time_t delta); /** Create a @Route header object. */ SOFIAPUBFUN sip_route_t *sip_route_create(su_home_t *home, url_t const *url, url_t const *maddr); /** Create a @RecordRoute header object. */ SOFIAPUBFUN sip_record_route_t *sip_record_route_create(su_home_t *, url_t const *rq_url, url_t const *m_url); /** Create a @From header object. */ SOFIAPUBFUN sip_from_t *sip_from_create(su_home_t *, url_string_t const *url); SOFIAPUBFUN int sip_from_tag(su_home_t *, sip_from_t *from, char const *tag); /** Create a @To header object. */ SOFIAPUBFUN sip_to_t *sip_to_create(su_home_t *, url_string_t const *url); SOFIAPUBFUN int sip_to_tag(su_home_t *, sip_to_t *to, char const *tag); /** Create a @Via object. */ SOFIAPUBFUN sip_via_t *sip_via_create(su_home_t *h, char const *host, char const *port, char const *transport, /* char const *params */ ...); /** Get transport protocol name. */ #if SU_HAVE_INLINE su_inline char const *sip_via_transport(sip_via_t const *v) { char const *tp = v->v_protocol; if (tp) { tp = strchr(tp, '/'); if (tp) { tp = strchr(tp + 1, '/'); if (tp) return tp + 1; } } return NULL; } #else char const *sip_via_transport(sip_via_t const *v); #endif SOFIAPUBFUN char const *sip_via_port(sip_via_t const *v, int *using_rport); SOFIAPUBFUN sip_payload_t *sip_payload_create(su_home_t *, void const *data, isize_t len); /**@ingroup sip_payload * * Initialize a SIP payload structure with pointer to data and its length. * * The SIP_PAYLOAD_INIT2() macro initializes a #sip_payload_t header * structure with a pointer to data and its length in octets. For * instance, * @code * sip_payload_t txt_payload = SIP_PAYLOAD_INIT2(txt, strlen(txt)); * @endcode * * The SIP_PAYLOAD_INIT2() macro can be used when creating a new payload * from heap is not required, for instance, when the resulting payload * structure is immediately copied. * * @HIDE */ #define SIP_PAYLOAD_INIT2(data, length) \ {{{ 0, 0, sip_payload_class, data, length }}, NULL, data, length } /** Create a SIP separator line structure. */ SOFIAPUBFUN sip_separator_t *sip_separator_create(su_home_t *home); /** Check that a required feature is supported. */ SOFIAPUBFUN sip_unsupported_t *sip_has_unsupported(su_home_t *, sip_supported_t const *support, sip_require_t const *require); SOFIAPUBFUN sip_unsupported_t *sip_has_unsupported2(su_home_t *, sip_supported_t const *support, sip_require_t const *by_require, sip_require_t const *require); SOFIAPUBFUN sip_unsupported_t * sip_has_unsupported_any(su_home_t *, sip_supported_t const *support, sip_require_t const *by_require, sip_proxy_require_t const *by_proxy_require, sip_require_t const *require, sip_require_t const *require2, sip_require_t const *require3); /** Check that a feature is supported. */ SOFIAPUBFUN int sip_has_supported(sip_supported_t const *support, char const *feature); /** Check that a feature is in the list. */ SOFIAPUBFUN int sip_has_feature(msg_list_t const *supported, char const *feature); /** Return true if the method is listed in @Allow header. */ SOFIAPUBFUN int sip_is_allowed(sip_allow_t const *allow, sip_method_t method, char const *name); /** Check if the well-known method is listed in @Allow header. @NEW_1_12_6. */ #define SIP_IS_ALLOWED(allow, method) \ (sip_method_unknown < (method) && (method) < 32 && \ (allow) && ((allow)->k_bitmap & (1 << (method))) != 0) /** * Bitmasks for header classifications. * * If parsing of a particular header fails, the error bits in #msg_t are * updated. The error bits can be obtained via msg_extract_errors() after * parsing. The header-specific bits are stored along with the * @ref msg_hclass_t "header class" in the #msg_href_t structure, found in * the parser tables of the #msg_mclass_t object. * * @sa NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(), * #msg_mclass_t, struct #msg_mclass_s, msg_mclass_clone(), * msg_mclass_insert_with_mask(), * #msg_href_t, struct #msg_href_s, msg_mclass_insert(). */ enum sip_bad_mask { /** Bit marking essential headers in a request message. * * @ref sip_request \"request line\"", @From, @To, @CSeq, @CallID, * @ContentLength, @Via */ sip_mask_request = (1 << 0), /** Bit marking essential headers in a response message. * * @ref sip_status \"status line\"", @From, @To, @CSeq, @CallID, * @ContentLength, @Via */ sip_mask_response = (1 << 1), /** Bit marking essential headers for User-Agent. * * @ContentType, @ContentDisposition, @ContentEncoding, @Supported, * @Contact, @Require, and @RecordRoute. */ sip_mask_ua = (1 << 2), /** Bit marking essential headers for proxy server. * * @Route, @MaxForwards, @ProxyRequire, @ProxyAuthorization, @Supported, * @Contact, and @RecordRoute. */ sip_mask_proxy = (1 << 3), /** Bit marking essential headers for registrar server. * * @MinExpires, @Authorization, @Path, @Supported, @Contact, @Require, and * @Expires. * */ sip_mask_registrar = (1 << 4), /** Bit marking essential headers for 100rel extension. * * @RAck and @RSeq. * * @sa @RFC3262. */ sip_mask_100rel = (1 << 5), /** Bit marking essential headers for SIP events. * * @Event, @Expires, and @SubscriptionState. * * @sa @RFC3265. */ sip_mask_events = (1 << 6), /** Bit marking essential headers for session timer extension. * * @SessionExpires, and @MinSE. * * @RFC4028 */ sip_mask_timer = (1 << 7), /** Bit marking essential headers for privacy extension. * * @Privacy. * * @sa @RFC3323 */ sip_mask_privacy = (1 << 8), /** Bit marking essential headers for caller preference extension. * * @RequestDisposition, @AcceptContact, and @RejectContact. * * @sa @RFC3841. */ sip_mask_pref = (1 << 9), /** Bit marking essential headers for PUBLISH servers and clients. * * @SIPETag, and @SIPIfMatch. * * @sa @RFC3903. */ sip_mask_publish = (1 << 10) /* NOTE: * When adding bits, please update nta_agent_create() and * NTATAG_BAD_RESP_MASK()/NTATAG_BAD_REQ_MASK() documentation. */ }; /* ------------------------------------------------------------------------- */ /* Here are @deprecated functions and names for compatibility */ /** Encode a SIP header field (name: contents CRLF). */ SOFIAPUBFUN issize_t sip_header_e(char[], isize_t, sip_header_t const *, int); /** Decode a SIP header string (name: contents CRLF?). */ SOFIAPUBFUN sip_header_t *sip_header_d(su_home_t *, msg_t const *, char const *); /** Encode contents of a SIP header field. */ SOFIAPUBFUN issize_t sip_header_field_e(char[], isize_t, sip_header_t const *, int); /** Decode the string containing header field */ SOFIAPUBFUN issize_t sip_header_field_d(su_home_t *, sip_header_t *, char *, isize_t); /** Calculate the size of a SIP header and associated memory areas. */ SOFIAPUBFUN isize_t sip_header_size(sip_header_t const *h); /** Duplicate (deep copy) a SIP header or whole list. */ SOFIAPUBFUN sip_header_t *sip_header_dup(su_home_t *, sip_header_t const *); /** Copy a SIP header or whole list. */ SOFIAPUBFUN sip_header_t *sip_header_copy(su_home_t *, sip_header_t const *o); /** Add an event to @AllowEvents header. */ SOFIAPUBFUN int sip_allow_events_add(su_home_t *, sip_allow_events_t *ae, char const *e); /** Add a parameter to a @Contact header object. */ SOFIAPUBFUN int sip_contact_add_param(su_home_t *, sip_contact_t *, char const *param); SOFIAPUBFUN int sip_to_add_param(su_home_t *, sip_to_t *, char const *); SOFIAPUBFUN int sip_from_add_param(su_home_t *, sip_from_t *, char const *); /** Add a parameter to a @Via header object. */ SOFIAPUBFUN int sip_via_add_param(su_home_t *, sip_via_t *, char const *); #define sip_from_make_url sip_from_create #define sip_to_make_url sip_to_create #define sip_params_find msg_params_find SOFIA_END_DECLS #endif