📄 sip_basic.c
字号:
* msg_param_t af_duration; // Duration parameter * } sip_retry_after_t; * @endcode *//**@ingroup sip_retry_after * @brief Structure for @b Retry-After header. */static msg_xtra_f sip_retry_after_dup_xtra;static msg_dup_f sip_retry_after_dup_one;static msg_update_f sip_retry_after_update;msg_hclass_t sip_retry_after_class[] = SIP_HEADER_CLASS(retry_after, "Retry-After", "", af_params, single, retry_after);int sip_retry_after_d(su_home_t *home, sip_header_t *h, char *s, int slen){ sip_retry_after_t *af = h->sh_retry_after; if ((msg_delta_d((char const **)&s, &af->af_delta) < 0) || (*s == '(' && msg_comment_d(&s, &af->af_comment) == -1) || (*s == ';' && msg_params_d(home, &s, &af->af_params) == -1) || (*s != '\0')) { if (af->af_params) su_free(home, (void *)af->af_params), af->af_params = NULL; return -1; } if (af->af_params) msg_header_update_params(h->sh_common, 0); return 0;}int sip_retry_after_e(char b[], int bsiz, sip_header_t const *h, int f){ sip_retry_after_t const *af = h->sh_retry_after; int const compact = MSG_IS_COMPACT(f); char *b0 = b, *end = b + bsiz; b += snprintf(b, bsiz, "%lu", af->af_delta); if (af->af_comment) { if (!compact) MSG_CHAR_E(b, end, ' '); MSG_CHAR_E(b, end, '('); MSG_STRING_E(b, end, af->af_comment); MSG_CHAR_E(b, end, ')'); if (!compact && af->af_params && af->af_params[0]) MSG_CHAR_E(b, end, ' '); } if (af->af_params) MSG_PARAMS_E(b, end, af->af_params, f); MSG_TERM_E(b, end); return b - b0;}int sip_retry_after_dup_xtra(sip_header_t const *h, int offset){ int rv = offset; sip_retry_after_t const *af = h->sh_retry_after; MSG_PARAMS_SIZE(rv, af->af_params); rv += MSG_STRING_SIZE(af->af_comment); return rv;}char *sip_retry_after_dup_one(sip_header_t *dst, sip_header_t const *src, char *b, int xtra){ sip_retry_after_t *af = dst->sh_retry_after; sip_retry_after_t const *o = src->sh_retry_after; char *end = b + xtra; b = msg_params_dup(&af->af_params, o->af_params, b, xtra); MSG_STRING_DUP(b, af->af_comment, o->af_comment); af->af_delta = o->af_delta; assert(b <= end); return b;}static int sip_retry_after_update(msg_common_t *h, char const *name, int namelen, char const *value){ sip_retry_after_t *af = (sip_retry_after_t *)h; if (name == NULL) { af->af_duration = NULL; } else if (namelen == strlen("duration") && !strncasecmp(name, "duration", namelen)) { af->af_duration = value; } return 0;}/* ====================================================================== *//** * Parse a Route/Record-Route header * * The function sip_route_d() parses a Route or a Record-Route header. * * @retval 0 when successful, * @retval -1 upon an error. */int sip_any_route_d(su_home_t *home, sip_header_t *h, char *s, int slen){ sip_header_t **hh = &h->sh_succ, *h0 = h; sip_route_t *r = h->sh_route; assert(h); /* Loop through comma-separated list of route headers.. */ for (;*s;) { /* Ignore empty entries (comma-whitespace) */ if (*s == ',') { *s++ = '\0'; skip_lws(&s); continue; } if (!h) { if (!(h = sip_header_alloc(home, h0->sh_class, 0))) break; *hh = h; h->sh_prev = hh; hh = &h->sh_succ; r = r->r_next = h->sh_route; } r = h->sh_route; if (sip_name_addr_d(home, &s, &r->r_display, r->r_url, &r->r_params, NULL) < 0) return -1; if (*s != '\0' && *s != ',') return -1; h = NULL; } if (h) /* Empty list is an error */ return -1; return 0;}int sip_any_route_e(char b[], int bsiz, sip_header_t const *h, int flags){ sip_route_t const *r = h->sh_route; return sip_name_addr_e(b, bsiz, flags, r->r_display, 1, r->r_url, r->r_params, NULL);}int sip_any_route_dup_xtra(sip_header_t const *h, int offset){ int rv = offset; sip_route_t const *r = h->sh_route; MSG_PARAMS_SIZE(rv, r->r_params); rv += MSG_STRING_SIZE(r->r_display); rv += url_xtra(r->r_url); return rv;}char *sip_any_route_dup_one(sip_header_t *dst, sip_header_t const *src, char *b, int xtra){ sip_route_t *r = dst->sh_route; sip_route_t const *o = src->sh_route; char *end = b + xtra; b = msg_params_dup(&r->r_params, o->r_params, b, xtra); MSG_STRING_DUP(b, r->r_display, o->r_display); URL_DUP(b, end, r->r_url, o->r_url); assert(b <= end); return b;}#define sip_any_route_update NULL/** Create a route. * * The function sip_any_route_create() creates a route or record-route entry * from two URLs; first one provides the URL, second maddr parameter and * port. * * @param home memory home * @param rq_url route URL * @param maddr optional route address and port * */staticsip_route_t *sip_any_route_create(su_home_t *home, msg_hclass_t *hc, url_t const *rq_url, url_t const *maddr){ sip_header_t *h; sip_route_t *rr; url_t url[1]; int xtra, n, n_url, n_params, n_addr; char *b, *param; *url = *rq_url; if (maddr) { url->url_port = maddr->url_port; url->url_params = NULL; } n_url = url_xtra(url); n_params = maddr && maddr->url_params ? strlen(maddr->url_params) : 0; if (maddr && (!maddr->url_params || !url_param(maddr->url_params, "maddr", NULL, 0))) n_addr = (n_params != 0) + strlen("maddr=") + strlen(maddr->url_host); else n_addr = 0; xtra = n_url + n_params + n_addr + (n_params || n_addr); h = sip_header_alloc(home, hc, xtra); if ((rr = h->sh_record_route)) { b = sip_header_data(h); n = url_dup(b, n_url, rr->r_url, url); assert(n == n_url); if (n_params || n_addr) { param = b + n_url; if (n_params) { rr->r_url->url_params = strcpy(param, maddr->url_params); param += n_params; } if (n_addr) { if (n_params) *param++ = ';'; strcpy(param, "maddr="), param += strlen("maddr="); strcpy(param, maddr->url_host), param += strlen(maddr->url_host); } assert(b + xtra == param + 1); } } return rr;}/* ====================================================================== *//**@SIP_HEADER sip_route Route Header * * The Route headers is used to store the route set of a transaction. * The Route header is defined in [S10.38] as follows: * * @code * Route = "Route" HCOLON route-param *(COMMA route-param) * route-param = name-addr *( SEMI rr-param ) * @endcode * *//**@ingroup sip_route * @typedef typedef struct sip_route_s sip_route_t; * * The structure #sip_route_t contains representation of SIP @b Route header. * * The #sip_route_t is defined as follows: * @code * typedef struct sip_route_s { * sip_common_t r_common[1]; // Common fragment info * sip_route_t *r_next; // Link to next Route * char const *r_display; // Display name * url_t r_url[1]; // Route URL * msg_param_t const *r_params; // List of route parameters * } sip_route_t; * @endcode */msg_hclass_t sip_route_class[] = SIP_HEADER_CLASS(route, "Route", "", r_params, append, any_route);int sip_route_d(su_home_t *home, sip_header_t *h, char *s, int slen){ return sip_any_route_d(home, h, s, slen);}int sip_route_e(char b[], int bsiz, sip_header_t const *h, int flags){ assert(sip_is_route(h)); return sip_any_route_e(b, bsiz, h, flags);}/**@ingroup sip_route * @brief Create a @b Route header object. * * The function sip_route_create() creates a route entry from two URLs; * first one provides the URL, second maddr parameter and port. * * @param home memory home * @param url route URL * @param maddr optional route address and port * * @return * The function sip_route_create() returns a pointer to newly created * @b Route header object when successful, or NULL upon an error. */sip_route_t *sip_route_create(su_home_t *home, url_t const *url, url_t const *maddr){ return sip_any_route_create(home, sip_route_class, url, maddr); }/* ====================================================================== *//**@SIP_HEADER sip_record_route Record-Route Header * * The Record-Route headers are used to establish a route for transactions * belonging to a session. The Record-Route header is defined in [S10.34] * as follows: * * @code * Record-Route = "Record-Route" HCOLON rec-route *(COMMA rec-route) * rec-route = name-addr *( SEMI rr-param ) * rr-param = generic-param * @endcode * *//**@ingroup sip_record_route * @typedef typedef struct sip_record_route_s sip_record_route_t; * * The structure #sip_record_route_t contains representation of SIP * @b Record-Route header. * * The #sip_record_route_t is defined as follows: * @code * typedef struct sip_record_route_s { * sip_common_t r_common[1]; // Common fragment info * sip_route_t *r_next; // Link to next Record-Route * char const *r_display; // Display name * url_t r_url[1]; // Route URL * msg_param_t const *r_params; // List of route parameters * } sip_record_route_t; * @endcode */msg_hclass_t sip_record_route_class[] = SIP_HEADER_CLASS(record_route, "Record-Route", "", r_params, prepend, any_route);int sip_record_route_d(su_home_t *home, sip_header_t *h, char *s, int slen){ return sip_any_route_d(home, h, s, slen);}int sip_record_route_e(char b[], int bsiz, sip_header_t const *h, int flags){ assert(sip_is_record_route(h)); return sip_any_route_e(b, bsiz, h, flags);}/** @ingroup sip_record_route * * Create a record-route. * * The function sip_record_route_create() creates a record-route entry * from two URLs; first one provides the URL, second maddr parameter and * port. * * @param home memory home * @param rq_url route URL * @param maddr optional route address and port * * @return * The function sip_record_route_create() returns a pointer to newly * created Record-Route header object when successful or NULL upon an * error. */sip_record_route_t *sip_record_route_create(su_home_t *home, url_t const *rq_url, url_t const *maddr){ return sip_any_route_create(home, sip_record_route_class, rq_url, maddr);}/* ====================================================================== *//**@SIP_HEADER sip_to To Header * * The To header field specifies the "logical" recipient of the * request. It is defined in [S10.43] as follows: * * @code * To = ( "To" / "t" ) HCOLON ( name-addr * / addr-spec ) *( SEMI to-param ) * to-param = tag-param / generic-param * @endcode * *//**@ingroup sip_to * @typedef typedef struct sip_addr_s sip_to_t; * * The structure sip_to_t contains representation of @b To header. * * The sip_to_t is defined as follows: * @code * typedef struct { * sip_common_t a_common[1]; // Common fragment info * sip_unknown_t *a_next; // Link to next (dummy) * char const *a_display; // Display name * url_t a_url[1]; // URL * msg_param_t const *a_params; // List of to-params * char const *a_comment; // Comment * char const *a_tag; // Tag parameter * } sip_to_t; * @endcode * */msg_hclass_t sip_to_class[] = SIP_HEADER_CLASS(to, "To", "t", a_params, single, addr);int sip_to_d(su_home_t *home, sip_header_t *h, char *s, int slen){ return sip_addr_d(home, h, s, slen);}int sip_to_e(char b[], int bsiz, sip_header_t const *h, int flags){ assert(sip_is_to(h)); return sip_addr_e(b, bsiz, h, flags);}/**@ingroup sip_to * * Create a @b To header object with URL. * * The function sip_to_create() creates a To header object with * the given URL. * * @param home memory home * @param url URL (string or pointer to url_t) * * @return * The function sip_to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -