Commit f6859481 authored by Pekka Pessi's avatar Pekka Pessi
Browse files

sip: added RFC 3261 headers Reply-To and Alert-Info.

The headers are accessed with accessor functions sip_reply_to() and
sip_alert_info() from a sip_t structure.

Added also @NEW_1_12_7 Doxygen macro.

darcs-hash:20070523174933-65a35-16cff7cda896afe18193377e78a8358174d6a8c7.gz
parent 540903e9
......@@ -49,4 +49,7 @@ ALIASES = \
"VERSION_1_12_6=<a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.6.txt\">1.12.6</a>" \
"NEW_1_12_6=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.6.txt\">1.12.6</a>" \
"EXP_1_12_6=@since Experimental in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.6.txt\">1.12.6</a>, available if --enable-experimental configuration option is given" \
"VERSION_1_12_7=<a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>" \
"NEW_1_12_7=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>" \
"EXP_1_12_7=@since Experimental in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>, available if --enable-experimental configuration option is given" \
......@@ -202,6 +202,163 @@ issize_t sip_error_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
NULL, 1, ei->ei_url, ei->ei_params, NULL);
}
/* ====================================================================== */
/**@SIP_HEADER sip_alert_info Alert-Info Header
*
* When present in an INVITE request, the Alert-Info header field
* specifies an alternative ring tone to the UAS. When present in a 180
* (Ringing) response, the Alert-Info header field specifies an
* alternative ringback tone to the UAC. A typical usage is for a proxy
* to insert this header field to provide a distinctive ring feature.
*
* @code
* Alert-Info = "Alert-Info" HCOLON alert-param *(COMMA alert-param)
* alert-param = LAQUOT absoluteURI RAQUOT *(SEMI generic-param)
* @endcode
*
* The parsed Alert-Info header is stored in #sip_alert_info_t structure.
*
* @NEW_1_12_7
*/
/**@ingroup sip_alert_info
* @typedef struct sip_alert_info_s sip_alert_info_t;
*
* The structure #sip_alert_info_t contains representation of an
* @AlertInfo header.
*
* The #sip_alert_info_t is defined as follows:
* @code
* struct sip_alert_info_s
* {
* sip_common_t ai_common[1]; // Common fragment info
* sip_alert_info_t *ai_next; // Link to next @AlertInfo
* url_t ai_url[1]; // URI to alert info
* msg_param_t const *ai_params; // List of optional parameters
* };
* @endcode
*
* @NEW_1_12_7
*/
msg_hclass_t sip_alert_info_class[] =
SIP_HEADER_CLASS(alert_info, "Alert-Info", "",
ai_params, append, info);
issize_t sip_alert_info_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
return sip_info_d(home, h, s, slen);
}
issize_t sip_alert_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
{
sip_alert_info_t *ai = (sip_alert_info_t *)h;
return sip_name_addr_e(b, bsiz, f, NULL, 1, ai->ai_url, ai->ai_params, NULL);
}
/* ====================================================================== */
/**@SIP_HEADER sip_reply_to Reply-To Header
*
* The @b Reply-To header field contains a logical return URI that may be
* different from the @From header field. For example, the URI MAY be used to
* return missed calls or unestablished sessions. If the user wished to
* remain anonymous, the header field SHOULD either be omitted from the
* request or populated in such a way that does not reveal any private
* information. Its syntax is defined in @RFC3261 as follows:
*
* @code
* Reply-To = "Reply-To" HCOLON rplyto-spec
* rplyto-spec = ( name-addr / addr-spec )
* *( SEMI rplyto-param )
* rplyto-param = generic-param
* @endcode
*
* The parsed Reply-To header is stored in #sip_reply_to_t structure.
*/
/**@ingroup sip_reply_to
* @typedef struct msg_list_s sip_reply_to_t;
*
* The structure #sip_reply_to_t contains representation of SIP
* @ReplyTo header.
*
* The #sip_reply_to_t is defined as follows:
* @code
* struct sip_reply_to_s
* {
* sip_common_t rplyto_common[1]; // Common fragment info
* sip_error_t *rplyto_next; // Dummy link to next header
* char const *rplyto_display; // Display name
* url_t rplyto_url[1]; // Return URI
* msg_param_t const *rplyto_params; // List of optional parameters
* };
* @endcode
*/
static isize_t sip_reply_to_dup_xtra(sip_header_t const *h, isize_t offset);
static char *sip_reply_to_dup_one(sip_header_t *dst,
sip_header_t const *src,
char *b,
isize_t xtra);
#define sip_reply_to_update NULL
msg_hclass_t sip_reply_to_class[] =
SIP_HEADER_CLASS(reply_to, "Reply-To", "", rplyto_params, single, reply_to);
issize_t sip_reply_to_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_reply_to_t *rplyto = (sip_reply_to_t *)h;
return sip_name_addr_d(home,
&s,
&rplyto->rplyto_display,
rplyto->rplyto_url,
&rplyto->rplyto_params,
NULL);
}
issize_t sip_reply_to_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_reply_to_t *rplyto = (sip_reply_to_t *)h;
return sip_name_addr_e(b, bsiz,
flags,
rplyto->rplyto_display,
MSG_IS_CANONIC(flags), rplyto->rplyto_url,
rplyto->rplyto_params,
NULL);
}
static isize_t sip_reply_to_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_reply_to_t const *rplyto = (sip_reply_to_t const *)h;
MSG_PARAMS_SIZE(offset, rplyto->rplyto_params);
offset += MSG_STRING_SIZE(rplyto->rplyto_display);
offset += url_xtra(rplyto->rplyto_url);
return offset;
}
/**@internal Duplicate one sip_reply_to_t object. */
static char *sip_reply_to_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_reply_to_t *rplyto = (sip_reply_to_t *)dst;
sip_reply_to_t const *o = (sip_reply_to_t *)src;
char *end = b + xtra;
b = msg_params_dup(&rplyto->rplyto_params, o->rplyto_params, b, xtra);
MSG_STRING_DUP(b, rplyto->rplyto_display, o->rplyto_display);
URL_DUP(b, end, rplyto->rplyto_url, o->rplyto_url);
assert(b <= end);
return b;
}
/* ====================================================================== */
......@@ -231,7 +388,7 @@ issize_t sip_error_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
* msg_common_t k_common[1]; // Common fragment info
* msg_list_t *k_next; // Link to next header
* msg_param_t *k_items; // List of call ids
* } sip_allow_events_t;
* } sip_in_reply_to_t;
* @endcode
*/
......@@ -249,7 +406,6 @@ issize_t sip_in_reply_to_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
return msg_list_e(b, bsiz, h, f);
}
/* ====================================================================== */
/**@SIP_HEADER sip_organization Organization Header
......
......@@ -9,6 +9,8 @@
#### EXTRA HEADER LIST STARTS HERE ####
refer_sub @NEW_1_12_5 /**< Refer-Sub header */
alert_info @NEW_1_12_7 /**< Alert-Info header */
reply_to @NEW_1_12_7 /**< Reply-To header */
#### EXPERIMENTAL HEADER LIST STARTS HERE ####
......
......@@ -66,6 +66,33 @@ struct sip_refer_sub_s
msg_param_t const *rs_params; /**< List of extension parameters */
};
typedef struct sip_alert_info_s sip_alert_info_t;
/**@ingroup sip_alert_info
* @brief Structure for @AlertInfo header.
*/
struct sip_alert_info_s
{
sip_common_t ai_common[1]; /**< Common fragment info */
sip_alert_info_t *ai_next; /**< Link to next @AlertInfo */
url_t ai_url[1]; /**< URI to alert info */
msg_param_t const *ai_params; /**< List of optional parameters */
};
typedef struct sip_reply_to_s sip_reply_to_t;
/**@ingroup sip_reply_to
* @brief Structure for @ReplyTo header.
*/
struct sip_reply_to_s
{
sip_common_t rplyto_common[1]; /**< Common fragment info */
sip_error_t *rplyto_next; /**< Dummy link to next header */
char const *rplyto_display; /**< Display name */
url_t rplyto_url[1]; /**< Return URI */
msg_param_t const *rplyto_params; /**< List of optional parameters */
};
typedef struct sip_suppress_body_if_match_s sip_suppress_body_if_match_t;
/**@ingroup sip_suppress_body_if_match
......@@ -91,6 +118,8 @@ struct sip_suppress_notify_if_match_s
};
/** Defined as 1 if the @ref sip_#xxxxxx# "#xxxxxxx_xxxxxxx#" is supported */
#define SIP_HAVE_#XXXXXX# 1
SOFIA_END_DECLS
......
......@@ -694,6 +694,40 @@ int test_basic(void)
su_free(home, ci0);
}
{
sip_alert_info_t *ai, *ai0;
TEST_1(ai = sip_alert_info_make(home, "<http://www.nokia.com/ringtone.mp3>;x-format=mp3"));
TEST_1(ai0 = sip_alert_info_dup(home, ai));
TEST(msg_header_remove_param(ai->ai_common, "x-format"), 1);
TEST(msg_header_remove_param(ai0->ai_common, "x-format"), 1);
su_free(home, ai);
su_free(home, ai0);
}
{
sip_reply_to_t *rplyto, *rplyto0;
TEST_1(rplyto = sip_reply_to_make(home, "sip:joe@bar"));
TEST_1(msg_header_add_param(home, (msg_common_t *)rplyto, "x-extra=extra") == 0);
while (rplyto->rplyto_params && rplyto->rplyto_params[0])
msg_header_remove_param(rplyto->rplyto_common, rplyto->rplyto_params[0]);
su_free(home, rplyto);
TEST_1(!sip_reply_to_make(home, (void *)"sip:joe@[baa"));
TEST_1(rplyto = sip_reply_to_make(home, (void *)"sip:joe@bar"));
su_free(home, rplyto);
TEST_1(rplyto = sip_reply_to_make(home, (void *)"Joe <sip:joe@bar;user=ip>;x-extra=extra"));
TEST_1(rplyto0 = sip_reply_to_dup(home, rplyto));
su_free(home, rplyto);
su_free(home, rplyto0);
}
su_home_check(home);
su_home_zap(home);
......@@ -891,6 +925,8 @@ static int test_encoding(void)
"Warning: 399 presence.bar:5060 \"Unimplemented filter\"\r\n"
"RSeq: 421414\r\n"
"Refer-To: <sip:hsdf@cdwf.xcfw.com?Subject=test&Organization=Bar>\r\n"
"Alert-Info: <http://alert.example.org/test.mp3>\r\n"
"Reply-To: Bob <sip:bob@example.com>\r\n"
"WWW-Authenticate: Digest realm=\"foo\"\r\n"
"Proxy-Authenticate: Digest realm=\"foo\"\r\n"
"Security-Server: tls;q=0.2\r\n"
......@@ -1555,6 +1591,10 @@ static int parser_test(void)
TEST_SIZE(sip_error_info_class->hc_params,
offsetof(sip_error_info_t, ei_params));
TEST_SIZE(sip_alert_info_class->hc_params,
offsetof(sip_alert_info_t, ai_params));
TEST_SIZE(sip_reply_to_class->hc_params,
offsetof(sip_reply_to_t, rplyto_params));
TEST_SIZE(sip_warning_class->hc_params, 0);
TEST_SIZE(sip_mime_version_class->hc_params, 0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment