sip_mime.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. /*
  2. * This file is part of the Sofia-SIP package
  3. *
  4. * Copyright (C) 2005 Nokia Corporation.
  5. *
  6. * Contact: Pekka Pessi <pekka.pessi@nokia.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 2.1 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21. * 02110-1301 USA
  22. *
  23. */
  24. /**@CFILE sip_mime.c
  25. *
  26. * MIME-related SIP headers
  27. *
  28. * @author Pekka Pessi <Pekka.Pessi@nokia.com>.
  29. *
  30. * @date Created: Tue Jun 13 02:57:51 2000 ppessi
  31. */
  32. #include "config.h"
  33. /* Avoid casting sip_t to msg_pub_t and sip_header_t to msg_header_t */
  34. #define MSG_PUB_T struct sip_s
  35. #define MSG_HDR_T union sip_header_u
  36. #include "sofia-sip/sip_parser.h"
  37. #include "sofia-sip/msg_mime_protos.h"
  38. #include <stdio.h>
  39. #include <stddef.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <limits.h>
  43. #include <assert.h>
  44. /* ====================================================================== */
  45. /**@SIP_HEADER sip_accept Accept Header
  46. *
  47. * The @b Accept request-header field can be used to specify certain media
  48. * types which are acceptable for the response. Its syntax is defined in
  49. * [H14.1, S10.6] as follows:
  50. *
  51. * @code
  52. * Accept = "Accept" HCOLON
  53. * [ accept-range *(COMMA accept-range) ]
  54. * accept-range = media-range *(SEMI accept-param)
  55. * media-range = ( "*" "/" "*"
  56. * / ( m-type SLASH "*" )
  57. * / ( m-type SLASH m-subtype )
  58. * ) *( SEMI m-parameter )
  59. * accept-param = ("q" EQUAL qvalue) / generic-param
  60. * qvalue = ( "0" [ "." 0*3DIGIT ] )
  61. * / ( "1" [ "." 0*3("0") ] )
  62. * generic-param = token [ EQUAL gen-value ]
  63. * gen-value = token / host / quoted-string
  64. * @endcode
  65. *
  66. *
  67. * The parsed Accept header is stored in #sip_accept_t structure.
  68. */
  69. /**@ingroup sip_accept
  70. * @typedef typedef struct sip_accept_s sip_accept_t;
  71. *
  72. * The structure #sip_accept_t contains representation of SIP
  73. * @Accept header.
  74. *
  75. * The #sip_accept_t is defined as follows:
  76. * @code
  77. * typedef struct sip_accept_s {
  78. * sip_common_t ac_common[1]; // Common fragment info
  79. * sip_accept_t *ac_next; // Pointer to next @Acceptheader
  80. * char const *ac_type; // Pointer to type/subtype
  81. * char const *ac_subtype; // Points after first slash in type
  82. * msg_param_t const *ac_params; // List of parameters
  83. * char const *ac_q; // Value of q parameter
  84. * } sip_accept_t;
  85. * @endcode
  86. */
  87. #define sip_accept_dup_xtra msg_accept_dup_xtra
  88. #define sip_accept_dup_one msg_accept_dup_one
  89. #define sip_accept_update msg_accept_update
  90. msg_hclass_t sip_accept_class[] =
  91. SIP_HEADER_CLASS(accept, "Accept", "", ac_params, apndlist, accept);
  92. issize_t sip_accept_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  93. {
  94. return msg_accept_d(home, h, s, slen);
  95. }
  96. issize_t sip_accept_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  97. {
  98. return msg_accept_e(b, bsiz, h, flags);
  99. }
  100. #if SIP_HAVE_ACCEPT_DISPOSITION
  101. /* ====================================================================== */
  102. /**@SIP_HEADER sip_accept_disposition Accept-Disposition Header
  103. *
  104. * The Accept-Disposition header field is used to indicate what content
  105. * disposition types are acceptable to a client or server. Its syntax is
  106. * defined in draft-lennox-sip-reg-payload-01.txt section 3.2 as follows:
  107. *
  108. * @code
  109. * Accept-Disposition = "Accept-Disposition" ":"
  110. * #( (disposition-type | "*") *( ";" generic-param ) )
  111. * @endcode
  112. *
  113. *
  114. * The parsed Accept-Disposition header
  115. * is stored in #sip_accept_disposition_t structure.
  116. */
  117. msg_hclass_t sip_accept_disposition_class[] =
  118. SIP_HEADER_CLASS(accept_disposition, "Accept-Disposition", "",
  119. ad_params, apndlist, accept_disposition);
  120. issize_t sip_accept_disposition_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  121. {
  122. sip_accept_disposition_t *ad;
  123. assert(h);
  124. for(;;) {
  125. ad = (sip_accept_disposition_t *)h;
  126. /* Ignore empty entries (comma-whitespace) */
  127. while (*s == ',')
  128. s += span_lws(s + 1) + 1;
  129. /* "Accept:" #(type/subtyp ; *(parameters))) */
  130. if (/* Parse protocol */
  131. sip_version_d(&s, &ad->ad_type) == -1 ||
  132. (ad->ad_subtype = strchr(ad->ad_type, '/')) == NULL ||
  133. (*s == ';' && msg_params_d(home, &s, &ad->ad_params) == -1))
  134. return -1;
  135. if (ad->ad_subtype) ad->ad_subtype++;
  136. msg_parse_next_field_without_recursion();
  137. }
  138. }
  139. issize_t sip_accept_disposition_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  140. {
  141. char *b0 = b, *end = b + bsiz;
  142. sip_accept_disposition_t const *ad = h->sh_accept_disposition;
  143. MSG_STRING_E(b, end, ad->ad_type);
  144. MSG_PARAMS_E(b, end, ad->ad_params, flags);
  145. MSG_TERM_E(b, end);
  146. return b - b0;
  147. }
  148. #endif
  149. /* ====================================================================== */
  150. /**@SIP_HEADER sip_accept_encoding Accept-Encoding Header
  151. *
  152. * The Accept-Encoding header is similar to Accept, but restricts the
  153. * content-codings that are acceptable in the response. Its syntax is
  154. * defined in [H14.3, S10.7] as follows:
  155. *
  156. * @code
  157. * Accept-Encoding = "Accept-Encoding" HCOLON
  158. * [ encoding *(COMMA encoding) ]
  159. * encoding = codings *(SEMI accept-param)
  160. * codings = content-coding / "*"
  161. * content-coding = token
  162. * @endcode
  163. *
  164. *
  165. * The parsed Accept-Encoding header
  166. * is stored in #sip_accept_encoding_t structure.
  167. */
  168. /**@ingroup sip_accept_encoding
  169. * @typedef typedef struct msg_accept_any_s sip_accept_encoding_t;
  170. *
  171. * The structure #sip_accept_encoding_t contains representation of SIP
  172. * @AcceptEncoding header.
  173. *
  174. * The #sip_accept_encoding_t is defined as follows:
  175. * @code
  176. * typedef struct {
  177. * msg_common_t aa_common[1]; // Common fragment info
  178. * sip_accept_encoding_t *aa_next; // Pointer to next @AcceptEncoding header
  179. * char const *aa_value; // Encoding token
  180. * msg_param_t const *aa_params; // List of parameters
  181. * char const *aa_q; // Value of q parameter
  182. * } sip_accept_encoding_t;
  183. * @endcode
  184. */
  185. #define sip_accept_encoding_dup_xtra msg_accept_any_dup_xtra
  186. #define sip_accept_encoding_dup_one msg_accept_any_dup_one
  187. #define sip_accept_encoding_update msg_accept_any_update
  188. msg_hclass_t sip_accept_encoding_class[] =
  189. SIP_HEADER_CLASS(accept_encoding, "Accept-Encoding", "",
  190. aa_params, apndlist, accept_encoding);
  191. issize_t sip_accept_encoding_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  192. {
  193. issize_t retval = msg_accept_encoding_d(home, h, s, slen);
  194. if (retval == -2) {
  195. /* Empty Accept-Encoding list is not an error */
  196. sip_accept_encoding_t *aa = (sip_accept_encoding_t *)h;
  197. aa->aa_value = "";
  198. retval = 0;
  199. }
  200. return retval;
  201. }
  202. issize_t sip_accept_encoding_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  203. {
  204. return msg_accept_encoding_e(b, bsiz, h, f);
  205. }
  206. /* ====================================================================== */
  207. /**@SIP_HEADER sip_accept_language Accept-Language Header
  208. *
  209. * The Accept-Language header can be used to allow the client to indicate to
  210. * the server in which language it would prefer to receive reason phrases,
  211. * session descriptions or status responses carried as message bodies. Its
  212. * syntax is defined in [H14.4, S10.8] as follows:
  213. *
  214. * @code
  215. * Accept-Language = "Accept-Language" HCOLON
  216. * [ language *(COMMA language) ]
  217. * language = language-range *(SEMI accept-param)
  218. * language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) / "*" )
  219. * @endcode
  220. *
  221. *
  222. * The parsed Accept-Language header
  223. * is stored in #sip_accept_language_t structure.
  224. */
  225. /**@ingroup sip_accept_language
  226. * @typedef typedef struct msg_accept_any_s sip_accept_language_t;
  227. *
  228. * The structure #sip_accept_language_t contains representation of SIP
  229. * @AcceptLanguage header.
  230. *
  231. * The #sip_accept_language_t is defined as follows:
  232. * @code
  233. * typedef struct {
  234. * msg_common_t aa_common[1]; // Common fragment info
  235. * sip_accept_language_t *aa_next; // Pointer to next <language>
  236. * char const *aa_value; // Language-range
  237. * msg_param_t const *aa_params; // List of accept-parameters
  238. * char const *aa_q; // Value of q parameter
  239. * } sip_accept_language_t;
  240. * @endcode
  241. */
  242. #define sip_accept_language_dup_xtra msg_accept_any_dup_xtra
  243. #define sip_accept_language_dup_one msg_accept_any_dup_one
  244. #define sip_accept_language_update msg_accept_any_update
  245. msg_hclass_t sip_accept_language_class[] =
  246. SIP_HEADER_CLASS(accept_language, "Accept-Language", "",
  247. aa_params, apndlist, accept_language);
  248. issize_t sip_accept_language_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  249. {
  250. int retval = msg_accept_language_d(home, h, s, slen);
  251. if (retval == -2) {
  252. /* Empty Accept-Language list is not an error */
  253. ((sip_accept_language_t *)h)->aa_value = "";
  254. retval = 0;
  255. }
  256. return retval;
  257. }
  258. issize_t sip_accept_language_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  259. {
  260. return msg_accept_language_e(b, bsiz, h, f);
  261. }
  262. /* ====================================================================== */
  263. /**@SIP_HEADER sip_content_disposition Content-Disposition Header
  264. *
  265. * The Content-Disposition header field describes how the message body or,
  266. * in the case of multipart messages, a message body part is to be
  267. * interpreted by the UAC or UAS. Its syntax is defined in @RFC3261
  268. * as follows:
  269. *
  270. * @code
  271. * Content-Disposition = "Content-Disposition" HCOLON
  272. * disp-type *( SEMI disp-param )
  273. * disp-type = "render" / "session" / "icon" / "alert"
  274. * / disp-extension-token
  275. * disp-param = handling-param / generic-param
  276. * handling-param = "handling" EQUAL
  277. * ( "optional" / "required"
  278. * / other-handling )
  279. * other-handling = token
  280. * disp-extension-token = token
  281. * @endcode
  282. *
  283. * The Content-Disposition header was extended by
  284. * draft-lennox-sip-reg-payload-01.txt section 3.1 as follows:
  285. *
  286. * @code
  287. * Content-Disposition = "Content-Disposition" ":"
  288. * disposition-type *( ";" disposition-param )
  289. * disposition-type = "script" | "sip-cgi" | token
  290. * disposition-param = action-param
  291. * | modification-date-param
  292. * | generic-param
  293. * action-param = "action" "=" action-value
  294. * action-value = "store" | "remove" | token
  295. * modification-date-param = "modification-date" "=" quoted-date-time
  296. * quoted-date-time = <"> SIP-date <">
  297. * @endcode
  298. *
  299. * The parsed Content-Disposition header
  300. * is stored in #sip_content_disposition_t structure.
  301. */
  302. /**@ingroup sip_content_disposition
  303. * @typedef struct msg_content_disposition_s sip_content_disposition_t;
  304. *
  305. * The structure #sip_content_disposition_t contains representation of an
  306. * @ContentDisposition header.
  307. *
  308. * The #sip_content_disposition_t is defined as follows:
  309. * @code
  310. * typedef struct msg_content_disposition_s
  311. * {
  312. * msg_common_t cd_common[1]; // Common fragment info
  313. * msg_error_t *cd_next; // Link to next (dummy)
  314. * char const *cd_type; // Disposition type
  315. * msg_param_t const *cd_params; // List of parameters
  316. * char const *cd_handling; // Value of @b handling parameter
  317. * unsigned cd_required:1; // True if handling=required
  318. * unsigned cd_optional:1; // True if handling=optional
  319. * } sip_content_disposition_t;
  320. * @endcode
  321. */
  322. static msg_xtra_f sip_content_disposition_dup_xtra;
  323. static msg_dup_f sip_content_disposition_dup_one;
  324. #define sip_content_disposition_update msg_content_disposition_update
  325. msg_hclass_t sip_content_disposition_class[] =
  326. SIP_HEADER_CLASS(content_disposition, "Content-Disposition", "", cd_params,
  327. single, content_disposition);
  328. issize_t sip_content_disposition_d(su_home_t *home, sip_header_t *h,
  329. char *s, isize_t slen)
  330. {
  331. return msg_content_disposition_d(home, h, s, slen);
  332. }
  333. issize_t sip_content_disposition_e(char b[], isize_t bsiz,
  334. sip_header_t const *h, int f)
  335. {
  336. return msg_content_disposition_e(b, bsiz, h, f);
  337. }
  338. static
  339. isize_t sip_content_disposition_dup_xtra(sip_header_t const *h, isize_t offset)
  340. {
  341. return msg_content_disposition_dup_xtra(h, offset);
  342. }
  343. /** Duplicate one #sip_content_disposition_t object */
  344. static
  345. char *sip_content_disposition_dup_one(sip_header_t *dst,
  346. sip_header_t const *src,
  347. char *b, isize_t xtra)
  348. {
  349. return msg_content_disposition_dup_one(dst, src, b, xtra);
  350. }
  351. /* ====================================================================== */
  352. /**@SIP_HEADER sip_content_encoding Content-Encoding Header
  353. *
  354. * The Content-Encoding header indicates what additional content codings
  355. * have been applied to the entity-body. Its syntax is defined in @RFC3261
  356. * as follows:
  357. *
  358. * @code
  359. * Content-Encoding = ( "Content-Encoding" / "e" ) HCOLON
  360. * content-coding *(COMMA content-coding)
  361. * content-coding = token
  362. * @endcode
  363. *
  364. * The parsed Content-Encoding header
  365. * is stored in #sip_content_encoding_t structure.
  366. */
  367. /**@ingroup sip_content_encoding
  368. * @typedef struct msg_list_s sip_content_encoding_t;
  369. *
  370. * The structure #sip_content_encoding_t contains representation of an
  371. * @ContentEncoding header.
  372. *
  373. * The #sip_content_encoding_t is defined as follows:
  374. * @code
  375. * typedef struct msg_list_s
  376. * {
  377. * msg_common_t k_common[1]; // Common fragment info
  378. * msg_list_t *k_next; // Link to next header
  379. * msg_param_t *k_items; // List of items
  380. * } sip_content_encoding_t;
  381. * @endcode
  382. */
  383. msg_hclass_t sip_content_encoding_class[] =
  384. SIP_HEADER_CLASS_LIST(content_encoding, "Content-Encoding", "e", list);
  385. issize_t sip_content_encoding_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  386. {
  387. return msg_list_d(home, h, s, slen);
  388. }
  389. issize_t sip_content_encoding_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  390. {
  391. return msg_list_e(b, bsiz, h, f);
  392. }
  393. /* ====================================================================== */
  394. /**@SIP_HEADER sip_content_language Content-Language Header
  395. *
  396. * The Content-Language header @RFC2616 section 14.12 describes the natural language(s) of
  397. * the intended audience for the enclosed entity. Note that this might not
  398. * be equivalent to all the languages used within the entity-body. Its
  399. * syntax is defined in @RFC3261 as follows:
  400. *
  401. * @code
  402. * Content-Language = "Content-Language" HCOLON
  403. * language-tag *(COMMA language-tag)
  404. * language-tag = primary-tag *( "-" subtag )
  405. * primary-tag = 1*8ALPHA
  406. * subtag = 1*8ALPHA
  407. * @endcode
  408. *
  409. * The parsed Content-Language header
  410. * is stored in #sip_content_language_t structure.
  411. */
  412. /**@ingroup sip_content_language
  413. * @typedef typedef struct msg_content_language_s sip_content_language_t;
  414. *
  415. * The structure #sip_content_language_t contains representation of
  416. * @ContentLanguage header.
  417. *
  418. * The #sip_content_language_t is defined as follows:
  419. * @code
  420. * typedef struct {
  421. * msg_common_t k_common[1]; // Common fragment info
  422. * msg_content_language_t *k_next; // (Content-Encoding header)
  423. * msg_param_t *k_items; // List of languages
  424. * } sip_content_language_t;
  425. * @endcode
  426. */
  427. msg_hclass_t sip_content_language_class[] =
  428. SIP_HEADER_CLASS_LIST(content_language, "Content-Language", "", list);
  429. issize_t sip_content_language_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  430. {
  431. return msg_list_d(home, h, s, slen);
  432. }
  433. issize_t sip_content_language_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  434. {
  435. return msg_list_e(b, bsiz, h, f);
  436. }
  437. /* ====================================================================== */
  438. /**@SIP_HEADER sip_content_type Content-Type Header
  439. *
  440. * The Content-Type header indicates the media type of the message-body sent
  441. * to the recipient. Its syntax is defined in [H3.7, S] as
  442. * follows:
  443. *
  444. * @code
  445. * Content-Type = ( "Content-Type" / "c" ) HCOLON media-type
  446. * media-type = m-type SLASH m-subtype *(SEMI m-parameter)
  447. * m-type = discrete-type / composite-type
  448. * discrete-type = "text" / "image" / "audio" / "video"
  449. * / "application" / extension-token
  450. * composite-type = "message" / "multipart" / extension-token
  451. * extension-token = ietf-token / x-token
  452. * ietf-token = token
  453. * x-token = "x-" token
  454. * m-subtype = extension-token / iana-token
  455. * iana-token = token
  456. * m-parameter = m-attribute EQUAL m-value
  457. * m-attribute = token
  458. * m-value = token / quoted-string
  459. * @endcode
  460. *
  461. * The parsed Content-Type header is stored in #sip_content_type_t structure.
  462. */
  463. /**@ingroup sip_content_type
  464. * @typedef typedef struct sip_content_type_s sip_content_type_t;
  465. *
  466. * The structure #sip_content_type_t contains representation of SIP
  467. * @ContentType header.
  468. *
  469. * The #sip_content_type_t is defined as follows:
  470. * @code
  471. * typedef struct sip_content_type_s {
  472. * sip_common_t c_common[1]; // Common fragment info
  473. * sip_unknown_t *c_next; // Dummy link to next
  474. * char const *c_type; // Pointer to type/subtype
  475. * char const *c_subtype; // Points after first slash in type
  476. * msg_param_t const *c_params; // List of parameters
  477. * } sip_content_type_t;
  478. * @endcode
  479. *
  480. * The whitespace in the @a c_type is always removed when parsing.
  481. */
  482. static msg_xtra_f sip_content_type_dup_xtra;
  483. static msg_dup_f sip_content_type_dup_one;
  484. #define sip_content_type_update NULL
  485. msg_hclass_t sip_content_type_class[] =
  486. SIP_HEADER_CLASS(content_type, "Content-Type", "c", c_params,
  487. single, content_type);
  488. issize_t sip_content_type_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  489. {
  490. return msg_content_type_d(home, (msg_header_t *)h, s, slen);
  491. }
  492. issize_t sip_content_type_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  493. {
  494. return msg_content_type_e(b, bsiz, (msg_header_t const *)h, flags);
  495. }
  496. static
  497. isize_t sip_content_type_dup_xtra(sip_header_t const *h, isize_t offset)
  498. {
  499. return msg_content_type_dup_xtra((msg_header_t *)h, offset);
  500. }
  501. /** Duplicate one #sip_content_type_t object */
  502. static
  503. char *sip_content_type_dup_one(sip_header_t *dst, sip_header_t const *src,
  504. char *b, isize_t xtra)
  505. {
  506. return msg_content_type_dup_one((msg_header_t *)dst,
  507. (msg_header_t const *)src,
  508. b, xtra);
  509. }
  510. /* ====================================================================== */
  511. /**@SIP_HEADER sip_mime_version MIME-Version Header
  512. *
  513. * MIME-Version header indicates what version of the MIME protocol was used
  514. * to construct the message. Its syntax is defined in [H19.4.1, S10.28]
  515. * as follows:
  516. *
  517. * @code
  518. * MIME-Version = "MIME-Version" HCOLON 1*DIGIT "." 1*DIGIT
  519. * @endcode
  520. *
  521. * The parsed MIME-Version header is stored in #sip_mime_version_t structure.
  522. */
  523. /**@ingroup sip_mime_version
  524. * @typedef struct msg_generic_s sip_mime_version_t;
  525. *
  526. * The structure #sip_mime_version_t contains representation of an
  527. * @MIMEVersion header.
  528. *
  529. * The #sip_mime_version_t is defined as follows:
  530. * @code
  531. * typedef struct msg_generic_s
  532. * {
  533. * msg_common_t g_common[1]; // Common fragment info
  534. * msg_generic_t *g_next; // Link to next header
  535. * char const *g_string; // Header value
  536. * } sip_mime_version_t;
  537. * @endcode
  538. */
  539. msg_hclass_t sip_mime_version_class[] =
  540. SIP_HEADER_CLASS_G(mime_version, "MIME-Version", "", single);
  541. issize_t sip_mime_version_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  542. {
  543. return sip_generic_d(home, h, s, slen);
  544. }
  545. issize_t sip_mime_version_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  546. {
  547. return sip_generic_e(b, bsiz, h, f);
  548. }
  549. /* ====================================================================== */
  550. /**@SIP_HEADER sip_warning Warning Header
  551. *
  552. * The Warning response-header field is used to carry additional information
  553. * about the status of a response. Its syntax is defined in @RFC3261 as
  554. * follows:
  555. *
  556. * @code
  557. * Warning = "Warning" HCOLON warning-value *(COMMA warning-value)
  558. * warning-value = warn-code SP warn-agent SP warn-text
  559. * warn-code = 3DIGIT
  560. * warn-agent = hostport / pseudonym
  561. * ; the name or pseudonym of the server adding
  562. * ; the Warning header, for use in debugging
  563. * warn-text = quoted-string
  564. * pseudonym = token
  565. * @endcode
  566. *
  567. * The parsed Warning header is stored in #sip_warning_t structure.
  568. */
  569. /**@ingroup sip_warning
  570. * @typedef struct msg_warning_s sip_warning_t;
  571. *
  572. * The structure #sip_warning_t contains representation of an
  573. * @Warning header.
  574. *
  575. * The #sip_warning_t is defined as follows:
  576. * @code
  577. * typedef struct msg_warning_s
  578. * {
  579. * msg_common_t w_common[1]; // Common fragment info
  580. * msg_warning_t *w_next; // Link to next @Warning header
  581. * unsigned w_code; // Warning code
  582. * char const *w_host; // Hostname or pseudonym
  583. * char const *w_port; // Port number
  584. * char const *w_text; // Warning text
  585. * } sip_warning_t;
  586. * @endcode
  587. */
  588. #define sip_warning_dup_xtra msg_warning_dup_xtra
  589. #define sip_warning_dup_one msg_warning_dup_one
  590. #define sip_warning_update NULL
  591. msg_hclass_t sip_warning_class[] =
  592. SIP_HEADER_CLASS(warning, "Warning", "", w_common, append, warning);
  593. issize_t sip_warning_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  594. {
  595. return msg_warning_d(home, h, s, slen);
  596. }
  597. issize_t sip_warning_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  598. {
  599. return msg_warning_e(b, bsiz, h, f);
  600. }