📄 sip_feature.c
字号:
* @code * Unsupported = "Unsupported" HCOLON [option-tag *(COMMA option-tag)] * @endcode * * * The parsed Unsupported header is stored in #sip_unsupported_t structure. *//**@ingroup sip_unsupported * @typedef struct msg_list_s sip_unsupported_t; * * The structure #sip_unsupported_t contains representation of an * @Unsupported header. * * The #sip_unsupported_t is defined as follows: * @code * typedef struct msg_list_s * { * 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 items * } sip_unsupported_t; * @endcode */msg_hclass_t sip_unsupported_class[] = SIP_HEADER_CLASS_LIST(unsupported, "Unsupported", "", list);issize_t sip_unsupported_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen){ sip_unsupported_t *k = (sip_unsupported_t *)h; return msg_commalist_d(home, &s, &k->k_items, msg_token_scan);}issize_t sip_unsupported_e(char b[], isize_t bsiz, sip_header_t const *h, int f){ assert(sip_is_unsupported(h)); return msg_list_e(b, bsiz, h, f);}/** Check if required feature is not supported. * * @retval NULL if all the required features are supported * @retval pointer to a @Unsupported header or * #SIP_NONE if @a home is NULL */sip_unsupported_t *sip_has_unsupported(su_home_t *home, sip_supported_t const *support, sip_require_t const *require){ return sip_has_unsupported_any(home, support, NULL, NULL, require, NULL, NULL);}/** Check if required feature is not supported. * * @retval NULL if all the required features are supported * @retval pointer to a @Unsupported header or * #SIP_NONE if @a home is NULL */sip_unsupported_t *sip_has_unsupported2(su_home_t *home, sip_supported_t const *support, sip_require_t const *support_by_require, sip_require_t const *require){ return sip_has_unsupported_any(home, support, support_by_require, NULL, require, NULL, NULL);}/** Check if required features are not supported. * * The supported features can be listed in @Supported, @Require or * @ProxyRequire headers (in @a supported, @a by_require, or @a * by_proxy_require parameters, respectively) * * @param home (optional) home pointer for allocating @Unsupported header * @param supported @Supported features (may be NULL) [IN] * @param by_require supported features listed by * @Require (may be NULL) [IN] * @param by_proxy_require supported features listed * by @ProxyRequire (may be NULL) [IN] * * @param require list of required features (may be NULL) [IN] * @param require2 2nd list of required features (may be NULL) [IN] * @param require3 3rd list of required features (may be NULL) [IN] * * @retval NULL if all the required features are supported * @retval pointer to a @Unsupported header or * #SIP_NONE if @a home is NULL */sip_unsupported_t *sip_has_unsupported_any(su_home_t *home, sip_supported_t const *supported, 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){ size_t i, j; sip_unsupported_t *unsupported = NULL; msg_param_t const empty[1] = { NULL }; msg_param_t const *slist = empty; msg_param_t const *rlist = empty; msg_param_t const *prlist = empty; if (require2 == NULL) require2 = require3, require3 = NULL; if (require == NULL) require = require2, require2 = NULL; if (require && require->k_items) { if (supported && supported->k_items) slist = supported->k_items; if (by_require && by_require->k_items) rlist = by_require->k_items; if (by_proxy_require && by_proxy_require->k_items) prlist = by_proxy_require->k_items; for (i = 0; require->k_items && require->k_items[i];) { msg_param_t feature = require->k_items[i++]; for (j = 0; slist[j]; j++) if (strcasecmp(feature, slist[j]) == 0) { feature = NULL; break; } if (feature) for (j = 0; rlist[j]; j++) if (strcasecmp(feature, rlist[j]) == 0) { feature = NULL; break; } if (feature) for (j = 0; prlist[j]; j++) if (strcasecmp(feature, prlist[j]) == 0) { feature = NULL; break; } if (feature) { if (home) { if (unsupported == NULL) unsupported = sip_unsupported_make(home, feature); else msg_params_add(home, (msg_param_t **)&unsupported->k_items, feature); } else { return (sip_unsupported_t *)SIP_NONE; } } if (require->k_items[i] == NULL && require2 && require2->k_items) { i = 0, require = require2, require2 = require3, require3 = NULL; } } } return unsupported;}int sip_has_feature(msg_list_t const *supported, char const *feature){ size_t i; if (!feature || !feature[0]) return 1; /* Empty feature is always supported */ for (; supported; supported = supported->k_next) if (supported->k_items) for (i = 0; supported->k_items[i]; i++) if (strcasecmp(feature, supported->k_items[i]) == 0) return 1; return 0;}/** Check that a feature is supported. */int sip_has_supported(sip_supported_t const *supported, char const *feature){ return sip_has_feature(supported, feature);}/* ====================================================================== *//**@SIP_HEADER sip_path Path Header * * The Path header field is a SIP extension header field (@RFC3327) with * syntax very similar to the @RecordRoute header field. It is used in * conjunction with SIP REGISTER requests and with 200 class messages in * response to REGISTER (REGISTER responses). * * @code * Path = "Path" HCOLON path-value *(COMMA path-value) * path-value = name-addr *( SEMI rr-param ) * @endcode * * * The parsed Path header is stored in #sip_path_t structure. *//**@ingroup sip_path * @typedef typedef struct sip_route_s sip_path_t; * * The structure #sip_path_t contains representation of SIP @Path header. * * The #sip_path_t is defined as follows: * @code * typedef struct sip_route_s { * sip_common_t r_common[1]; // Common fragment info * sip_path_t *r_next; // Link to next @Path * char const *r_display; // Display name * url_t r_url[1]; // @Path URL * msg_param_t const *r_params; // List of parameters * } sip_path_t; * @endcode */msg_hclass_t sip_path_class[] =SIP_HEADER_CLASS(path, "Path", "", r_params, prepend, any_route);issize_t sip_path_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen){ return sip_any_route_d(home, h, s, slen);}issize_t sip_path_e(char b[], isize_t bsiz, sip_header_t const *h, int flags){ assert(sip_is_path(h)); return sip_any_route_e(b, bsiz, h, flags);}/* ====================================================================== *//**@SIP_HEADER sip_service_route Service-Route Header * * The "Service-Route" is a SIP extension header field (@RFC3608), which can * contain a route vector that will direct requests through a specific * sequence of proxies. A registrar may use a Service-Route header field to * inform a UA of a service route that, if used by the UA, will provide * services from a proxy or set of proxies associated with that registrar. * The Service-Route header field may be included by a registrar in the * response to a REGISTER request. The syntax for the Service-Route header * field is: * * @code * Service-Route = "Service-Route" HCOLON sr-value *(COMMA sr-value) * sr-value = name-addr *( SEMI rr-param ) * @endcode * * The parsed Service-Route header is stored in #sip_service_route_t structure. * * @sa @RFC3608, @Path, @Route, @RecordRoute *//**@ingroup sip_service_route * @typedef typedef struct sip_route_s sip_service_route_t; * * The structure #sip_service_route_t contains representation of SIP * @ServiceRoute header. * * The #sip_service_route_t is defined as follows: * @code * typedef struct sip_route_s { * sip_common_t r_common[1]; // Common fragment info * sip_service_route_t*r_next; // Link to next @ServiceRoute * char const *r_display; // Display name * url_t r_url[1]; // Service-Route URL * msg_param_t const *r_params; // List of parameters * } sip_service_route_t; * @endcode */msg_hclass_t sip_service_route_class[] =SIP_HEADER_CLASS(service_route, "Service-Route", "", r_params, append, any_route);issize_t sip_service_route_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen){ return sip_any_route_d(home, h, s, slen);}issize_t sip_service_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flags){ assert(sip_is_service_route(h)); return sip_any_route_e(b, bsiz, h, flags);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -