SIP utility functions
#include <sofia-sip/sip.h>
#include <sofia-sip/string0.h>
#include <sofia-sip/msg_header.h>
Go to the source code of this file.
Data Structures | |
union | sip_pref |
Possible values for SIP media tags. More... | |
struct | sip_pref::sp_literal |
Literal (tag="foo"). More... | |
struct | sip_pref::sp_string |
String (tag="<foo>"). More... | |
struct | sip_pref::sp_range |
Numeric value or range (tag="#=1"; tag="#<=3"; tag="#>=-2"; tag="#1:6"). More... | |
Defines | |
#define | SIP_STRLOG(prefix, s) |
Add optional prefix and string to argument list if s is non-NULL. | |
Enumerations | |
enum | sp_type |
Type of the SIP media tag. | |
Functions | |
sip_contact_t * | sip_contact_create_from_via_with_transport (su_home_t *home, sip_via_t const *v, char const *user, char const *transport) |
Convert a Via header to Contact header. | |
sip_contact_t * | sip_contact_create_from_via (su_home_t *, sip_via_t const *, char const *user) |
Convert a Via header to Contact header. | |
char * | sip_contact_string_from_via (su_home_t *home, sip_via_t const *v, char const *user, char const *transport) |
Convert a Via header to Contact URL string. | |
int | sip_transport_has_tls (char const *transport_name) |
Check if tranport name refers to TLS. | |
int | sip_response_terminates_dialog (int response_code, sip_method_t method, int *return_graceful_terminate) |
Checks if the response with given response code terminates dialog or dialog usage. | |
int | sip_sanity_check (sip_t const *sip) |
Perform sanity check on a SIP message. | |
unsigned | sip_q_value (char const *q) |
Calculate Q value. | |
url_t * | sip_url_dup (su_home_t *sh, url_t const *o) |
Duplicate a url or make a url out of string. | |
int | sip_addr_match (sip_addr_t const *a, sip_addr_t const *b) |
Compare two SIP addresses ( From or To headers). | |
int | sip_route_is_loose (sip_route_t const *r) |
Check if route header has lr param. | |
sip_route_t * | sip_route_remove (msg_t *msg, sip_t *sip) |
Get first route header and remove it from its fragment chain. | |
sip_route_t * | sip_route_pop (msg_t *msg, sip_t *sip) |
Get last route header and remove it from its fragment chain. | |
sip_route_t * | sip_route_follow (msg_t *msg, sip_t *sip) |
Get first route header and rewrite the RequestURI. | |
sip_route_t * | sip_route_reverse (su_home_t *, sip_route_t const *) |
Reverse a Route header. | |
sip_route_t * | sip_route_fixdup (su_home_t *, sip_route_t const *) |
Fix and duplicate a Route header. | |
sip_route_t * | sip_route_fix (sip_route_t *route) |
Fix Route header. | |
sip_route_t * | sip_route_fixdup_as (su_home_t *, msg_hclass_t *, sip_route_t const *) |
Fix and duplicate a route header (Route, Record-Route, Path, Service-Route). | |
sip_route_t * | sip_route_reverse_as (su_home_t *, msg_hclass_t *, sip_route_t const *) |
Reverse a route header (Route, Record-Route, Path, Service-Route). | |
sip_via_t * | sip_via_remove (msg_t *msg, sip_t *sip) |
Get first via header and remove it from its fragment chain. | |
int | sip_prefs_matching (char const *pvalue, char const *nvalue, int *return_parse_error) |
Check callerprefs. | |
int | sip_is_callerpref (char const *param) |
Check if the parameter is a valid feature tag. | |
int | sip_prefs_parse (union sip_pref *sp, char const **in_out_s, int *return_negation) |
Parse a single preference. | |
int | sip_prefs_match (union sip_pref const *, union sip_pref const *) |
Match preferences. | |
int | sip_contact_is_immune (sip_contact_t const *m) |
Check if Contact is immune to callerprefs. | |
sip_contact_t * | sip_contact_immunize (su_home_t *home, sip_contact_t const *m) |
Immunize Contact to callerprefs. | |
int | sip_contact_reject (sip_contact_t const *m, sip_reject_contact_t const *rc) |
Check if Contact is rejected by Reject-Contact. | |
int | sip_contact_accept (sip_contact_t const *m, sip_accept_contact_t const *cp, unsigned *return_S, unsigned *return_N, int *return_error) |
Check if Contact matches by Accept-Contact. | |
int | sip_contact_score (sip_contact_t const *m, sip_accept_contact_t const *ac, sip_reject_contact_t const *rc) |
Calculate score for contact. | |
int | sip_aor_strip (url_t *url) |
Remove extra parameters from an AOR URL. | |
sip_security_client_t const * | sip_security_client_select (sip_security_client_t const *client, sip_security_server_t const *server) |
Select best mechanism from Security-Client header. |
int sip_addr_match | ( | sip_addr_t const * | a, | |
sip_addr_t const * | b | |||
) |
int sip_aor_strip | ( | url_t * | url | ) |
Remove extra parameters from an AOR URL.
The extra parameters listed in the RFC 3261 table 1 include port number, method, maddr, ttl, transport, lr and headers.
0 | when successful | |
-1 | upon an error |
int sip_contact_accept | ( | sip_contact_t const * | m, | |
sip_accept_contact_t const * | cp, | |||
unsigned * | return_S, | |||
unsigned * | return_N, | |||
int * | return_error | |||
) |
Check if Contact matches by Accept-Contact.
Matching Accept-Contact and Contact headers is done as explained in RFC 3841 section 7.2.4. The caller score can be calculated from the returned S and N values.
m | pointer to Contact header structure | |
cp | pointer to Accept-Contact header structure | |
return_N | return-value parameter for number of feature tags in Accept-Contact | |
return_S | return-value parameter for number of matching feature tags | |
return_error | return-value parameter for parsing error |
if (sip_contact_accept(contact, accept_contact, &S, &N, &error)) { if (N == 0) score == 1.0; else score = (double)S / (double)N; if (accept_contact->cp_explicit) { if (accept_contact->cp_require) goto drop; else score = 0.0; } } else if (!error) { score = 0.0; }
1 | if Contact matches |
return_N contains number of feature tags in Accept-Contact
0 | if Contact does not match |
sip_contact_t* sip_contact_create_from_via | ( | su_home_t * | home, | |
sip_via_t const * | v, | |||
char const * | user | |||
) |
Convert a Via header to Contact header.
The Contact URI will contain the port number if needed. If transport protocol name starts with "TLS", "SIPS:" URI schema is used. Transport parameter is included in the URI unless the transport protocol is UDP.
home | memory home | |
v | Via header field structure (with <sent-protocol> and <sent-by> parameters) | |
user | username for Contact URI (may be NULL) |
contact | header structure | |
NULL | upon an error |
sip_contact_t* sip_contact_create_from_via_with_transport | ( | su_home_t * | home, | |
sip_via_t const * | v, | |||
char const * | user, | |||
char const * | transport | |||
) |
Convert a Via header to Contact header.
The Contact URI will contain the port number and transport parameters if needed. If transport protocol name starts with "TLS", "SIPS:" URI schema is used.
home | memory home | |
v | Via header field structure (with <sent-by> parameter containing host and port) | |
user | username for Contact URI (may be NULL) | |
transport | transport name for Contact URI (may be NULL) |
contact | header structure | |
NULL | upon an error |
sip_contact_t* sip_contact_immunize | ( | su_home_t * | home, | |
sip_contact_t const * | m | |||
) |
Immunize Contact to callerprefs.
Make a copy of Contact header m and remove all parameters which affect caller preferences.
home | home object used when allocating copy | |
m | pointer to Contact header structure to immunize |
pointer | to immunized copy if successful | |
NULL | upon an error |
int sip_contact_is_immune | ( | sip_contact_t const * | m | ) |
Check if Contact is immune to callerprefs.
int sip_contact_reject | ( | sip_contact_t const * | m, | |
sip_reject_contact_t const * | reject | |||
) |
Check if Contact is rejected by Reject-Contact.
m | pointer to Contact header | |
reject | pointer to Reject-Contact header |
1 | when rejecting | |
0 | when Contact does not match with Reject-Contact |
int sip_contact_score | ( | sip_contact_t const * | m, | |
sip_accept_contact_t const * | ac, | |||
sip_reject_contact_t const * | rc | |||
) |
Calculate score for contact.
The caller preference score is an integer in range of 0 to 1000.
-1 | if the contact is rejected | |
1000 | if contact is immune to caller preferences | |
0..1000 | reflecting RFC 3841 score in 0.000 - 1.000. |
char* sip_contact_string_from_via | ( | su_home_t * | home, | |
sip_via_t const * | v, | |||
char const * | user, | |||
char const * | transport | |||
) |
Convert a Via header to Contact URL string.
The Contact URI will contain the port number and transport parameters if needed. If transport protocol name starts with "TLS", "SIPS:" URI schema is used.
The contact URI string returned will always have angle brackets ("<" and ">") around it.
home | memory home | |
v | Via header field structure (with <sent-by> parameter containing host and port) | |
user | username for Contact URI (may be NULL) | |
transport | transport name for Contact URI (may be NULL) |
string | containing Contact URI with angle brackets | |
NULL | upon an error |
int sip_is_callerpref | ( | char const * | param | ) |
Check if the parameter is a valid feature tag.
A feature tag is a parameter starting with a single plus, or a well-known feature tag listed in RFC 3841: "audio", "automata", "application", "class", "control", "duplex", "data", "description", "events", "isfocus", "language", "mobility", "methods", "priority", "schemes", "type", or "video". However, well-known feature tag can not start with plus. So, "+alarm" or "audio" is a feature tag, "alarm", "++alarm", or "+audio" are not.
1 | if string is a feature tag parameter | |
0 | otherwise |
int sip_prefs_matching | ( | char const * | pvalue, | |
char const * | nvalue, | |||
int * | return_parse_error | |||
) |
Check callerprefs.
Check callerprefs.
Check if the given feature values match with each other.
pvalue | first feature parameter | |
nvalue | second feature parameter | |
return_parse_error | return-value parameter for error (may be NULL) |
1 | if given feature parameters match | |
0 | if there is no match or a parse or type error occurred. |
unsigned sip_q_value | ( | char const * | q | ) |
Calculate Q value.
Convert q-value string q to numeric value in range (0..1000). Q values are used, for instance, to describe relative priorities of registered contacts.
q | q-value string ("1" | "." 1,3DIGIT) |
int sip_response_terminates_dialog | ( | int | response_code, | |
sip_method_t | method, | |||
int * | return_graceful_terminate_usage | |||
) |
Checks if the response with given response code terminates dialog or dialog usage.
1 if the response terminates the dialog usage.
0 if the response does not terminate dialog or dialog usage.
The *return_graceful_terminate_usage is set to 1, if application should gracefully terminate its dialog usage. It is set to 0, if no graceful terminate is required. If it is up to application policy to decide whether to gracefully terminate or not, the *return_graceful_terminate_usage is left unmodified.
The dialog itself should not be destroyed unless this was the last usage. The effects of a 481 on a dialog and its usages are the most ambiguous of any final response. There are implementations that have chosen the meaning recommended here, and others that destroy the entire dialog without regard to the number of outstanding usages. Going forward with this clarification will allow those deployed implementations that assumed only the usage was destroyed to work with a wider number of implementations. Those that made the other choice will continue to function as they do now, suffering at most the same extra messages needed for a peer to discover that that other usages have gone away that they currently do. However, the necessary clarification to RFC 3261 needs to make it very clear that the ability to terminate usages independently from the overall dialog using a 481 is not justification for designing new applications that count on multiple usages in a dialog.
Asterisk (v 1.2.7.1) does response with 484 if a client does send a refer with a Refer-To header to an unknown number. This is therefore not fundamentally wrong and the dialog should not be destroyed!
If the response contains a Retry-After header field value, the user is indicating willingness to communicate later and the request can be retried after the indicated interval. This usage, and any other usages sharing the dialog are unaffected. If the response does not contain a Retry-After header field value, the UA may decide to retry after an interval of its choosing or attempt to gracefully terminate the usage. Whether or not to terminate other usages depends on the application. If the UA receives a 600 (or unrecognized 6xx) in response to an attempt to gracefully terminate this usage, it can treat this usage as terminated. If this is the last usage sharing the dialog, the dialog is also terminated.
int sip_sanity_check | ( | sip_t const * | sip | ) |
Perform sanity check on a SIP message.
Check that the SIP message has all the mandatory fields.
sip | SIP message to be checked |
sip_security_client_t const* sip_security_client_select | ( | sip_security_client_t const * | client, | |
sip_security_server_t const * | server | |||
) |
Select best mechanism from Security-Client header.