sip.h File Reference


Detailed Description

IMS Service Control - SIP Operations.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

Definition in file sip.h.

#include "../../data_lump_rpl.h"
#include "../../parser/contact/parse_contact.h"
#include "../../parser/parse_uri.h"
#include "../../parser/parse_from.h"
#include "../../parser/parse_content.h"
#include "../../parser/parse_disposition.h"
#include "../../db/db.h"
#include "../tm/tm_load.h"
#include "mark.h"

Go to the source code of this file.

Functions

int str2cmp (str x, str y)
 Compare 2 strings.
int str2icmp (str x, str y)
 Compare 2 strings case insensitive.
int isc_is_initial_request (struct sip_msg *msg)
 Check if the message is an initial request for a dialog.
int isc_is_register (struct sip_msg *msg)
 Check if the message is a REGISTER request.
int isc_get_originating_user (struct sip_msg *msg, isc_mark *mark, str *uri)
 Get the public identity from P-Asserted-Identity, or From if asserted not found.
int isc_is_registered (str *uri)
 Find if user is registered or not => TRUE/FALSE.
int isc_get_terminating_type (str *uri)
 Get terminating type for a user.
int isc_get_terminating_user (struct sip_msg *msg, isc_mark *mark, str *uri)
 Get public identity from Request-URI for terminating.
int isc_get_expires (struct sip_msg *msg)
 Get the expires header value from a message.
int cscf_get_transaction (struct sip_msg *msg, unsigned int *hash, unsigned int *label)
 Returns the tm transaction identifiers.
sip_msg * cscf_get_request_from_reply (struct sip_msg *reply)
 Returns the corresponding request for a reply, using tm transactions.
int cscf_get_expires_hdr (struct sip_msg *msg)
 Returns the expires value from the Expires header in the message.
int cscf_get_max_expires (struct sip_msg *msg)
 Returns the expires value from the message.
contact_body_t * cscf_parse_contacts (struct sip_msg *msg)
 Parses all the contact headers.
str cscf_get_public_identity (struct sip_msg *msg)
 Returns the Public Identity extracted from the To header.
int cscf_get_first_p_associated_uri (struct sip_msg *msg, str *public_id)
 Returns the first entry of the P-Associated-URI header.
str cscf_get_access_network_info (struct sip_msg *msg, struct hdr_field **h)
 Return the P-Access-Network-Info header.
str cscf_get_visited_network_id (struct sip_msg *msg, struct hdr_field **h)
 Return the P-Visited-Network-ID header.
str cscf_get_charging_vector (struct sip_msg *msg, struct hdr_field **h)
 Return the P-Charging-Vector header.
str cscf_get_call_id (struct sip_msg *msg, struct hdr_field **hr)
 Looks for the Call-ID header.
int cscf_get_cseq (struct sip_msg *msg, struct hdr_field **hr)
 Looks for the Call-ID header.


Function Documentation

int str2cmp ( str  x,
str  y 
)

Compare 2 strings.

Parameters:
x - first string
y - second string
Returns:
0 if equal, -1 or 1 else

Definition at line 80 of file sip.c.

00080                           {
00081     if (x.len < y.len) return -1;
00082     if (x.len > y.len) return +1;
00083     return strncmp(x.s, y.s, x.len);
00084 }

int str2icmp ( str  x,
str  y 
)

Compare 2 strings case insensitive.

Parameters:
x - first string
y - second string
Returns:
0 if equal, -1 or 1 else

Definition at line 92 of file sip.c.

Referenced by isc_check_session_desc(), and isc_check_spt().

00092                            {
00093     if (x.len < y.len) return -1;
00094     if (x.len > y.len) return +1;
00095     return strncasecmp(x.s, y.s, x.len);
00096 }

int isc_is_initial_request ( struct sip_msg *  msg  ) 

Check if the message is an initial request for a dialog.

Definition at line 110 of file sip.c.

References ack_s, bye_s, notify_s, prack_s, and update_s.

Referenced by ISC_from_AS(), ISC_is_session_continued(), and ISC_match_filter().

00111 {
00112     if (msg->first_line.type != SIP_REQUEST ) return 0;
00113     if (strncasecmp(msg->first_line.u.request.method.s,bye_s.s,bye_s.len)==0) return 0;
00114     if (strncasecmp(msg->first_line.u.request.method.s,ack_s.s,ack_s.len)==0) return 0;
00115     if (strncasecmp(msg->first_line.u.request.method.s,prack_s.s,prack_s.len)==0) return 0;
00116     if (strncasecmp(msg->first_line.u.request.method.s,update_s.s,update_s.len)==0) return 0;
00117     if (strncasecmp(msg->first_line.u.request.method.s,notify_s.s,notify_s.len)==0) return 0;
00118     return 1;
00119 }

int isc_is_register ( struct sip_msg *  msg  ) 

Check if the message is a REGISTER request.

Parameters:
msg - the message to check
Returns:
1 if initial, 0 if not

Definition at line 128 of file sip.c.

References register_s.

Referenced by ISC_match_filter_reg().

00129 {
00130     if (msg->first_line.type != SIP_REQUEST ) return 0;
00131     if (strncasecmp(msg->first_line.u.request.method.s,register_s.s,register_s.len)==0) return 1;           
00132     return 0;
00133 }

int isc_get_originating_user ( struct sip_msg *  msg,
isc_mark mark,
str *  uri 
)

Get the public identity from P-Asserted-Identity, or From if asserted not found.

Parameters:
msg - the SIP message
uri - uri to fill into
Returns:
1 if found, 0 if not

Definition at line 211 of file sip.c.

References _isc_mark::aor, cscf_get_asserted_identity(), isc_strip_uri(), and M_NAME.

Referenced by ISC_match_filter(), and ISC_match_filter_reg().

00212 {
00213     struct to_body * from;
00214     if (mark && mark->aor.len){
00215         *uri = mark->aor;
00216         return 1;
00217     }
00218     *uri = cscf_get_asserted_identity(msg);
00219     if (!uri->len) {        
00220         /* Fallback to From header */
00221         if ( parse_from_header( msg ) == -1 ) {
00222             LOG(L_ERR,"ERROR:"M_NAME":isc_get_originating_user: unable to extract URI from FROM header\n" );
00223             return 0;
00224         }
00225         if (!msg->from) return 0;
00226         from = (struct to_body*) msg->from->parsed;
00227         *uri = from->uri;
00228         isc_strip_uri(uri);
00229     }
00230     DBG("DEBUG:"M_NAME":isc_get_originating_user: From %.*s\n", uri->len,uri->s );
00231     return 1;
00232 }

int isc_is_registered ( str *  uri  ) 

Find if user is registered or not => TRUE/FALSE.

This uses the S-CSCF registrar to get the state.

Parameters:
uri - uri of the user to check
Returns:
the reg_state

Definition at line 240 of file sip.c.

References scscf_binds::get_r_public, _r_public::hash, isc_scscfb, scscf_binds::r_unlock, and _r_public::reg_state.

Referenced by isc_get_terminating_type(), and ISC_match_filter().

00241 {
00242     int result = 0;
00243     r_public *p;
00244     
00245     p = isc_scscfb.get_r_public(*uri);
00246     
00247     if (p) {
00248         result = p->reg_state;
00249         isc_scscfb.r_unlock(p->hash);
00250     }   
00251     return result;
00252 }

int isc_get_terminating_type ( str *  uri  )  [inline]

Get terminating type for a user.

This uses the S-CSCF registrar to get the state.

Parameters:
uri - uri of the user to check
Returns:
IFC_TERMINATING_SESSION if the user is registered or else IFC_TERMINATING_UNREGISTERED

Definition at line 260 of file sip.c.

References IFC_TERMINATING_SESSION, IFC_TERMINATING_UNREGISTERED, and isc_is_registered().

00261 {
00262     if (isc_is_registered(uri)) return IFC_TERMINATING_SESSION;
00263         else return IFC_TERMINATING_UNREGISTERED;
00264 }

int isc_get_terminating_user ( struct sip_msg *  msg,
isc_mark mark,
str *  uri 
)

Get public identity from Request-URI for terminating.

returns in uri the freshly pkg allocated uri - don't forget to free

Parameters:
msg - the SIP message
uri - uri to fill into
Returns:
IMS_USER_REGISTERED if found, else IMS_USER_NOT_REGISTERED

Definition at line 300 of file sip.c.

References _isc_mark::aor, cscf_get_public_identity_from_requri(), IMS_USER_NOT_REGISTERED, and IMS_USER_REGISTERED.

Referenced by ISC_match_filter().

00301 {
00302     if (mark && mark->aor.len){
00303         *uri = mark->aor;
00304         return 1;
00305     }   
00306     *uri = cscf_get_public_identity_from_requri(msg);
00307     if (!uri->len) return IMS_USER_NOT_REGISTERED;
00308     /*if ( isc_get_terminating_type( uri ) == IFC_TERMINATING_UNREGISTERED )
00309         DBG("DBG:"M_NAME":isc_get_terminating_type: To UNREGISTERED %.*s\n", uri->len,uri->s);
00310     else
00311         DBG("DBG:"M_NAME":isc_get_terminating_type: To REGISTERED %.*s\n", uri->len,uri->s);    */
00312     return IMS_USER_REGISTERED;
00313 }

int isc_get_expires ( struct sip_msg *  msg  ) 

Get the expires header value from a message.

Parameters:
msg - the SIP message
Returns:
the expires value or -1 if not found

Definition at line 321 of file sip.c.

Referenced by isc_checker_find().

00322 {   
00323     if (msg->expires) {
00324         if (parse_expires(msg->expires) < 0) {
00325             LOG(L_INFO, "INFO:ifc:ifc_get_expires:Error while parsing Expires header\n");
00326             return -1;
00327         }
00328          return ((exp_body_t*) msg->expires->parsed)->val;
00329     } else {
00330         return -1;
00331     }
00332 }

int cscf_get_transaction ( struct sip_msg *  msg,
unsigned int *  hash,
unsigned int *  label 
)

Returns the tm transaction identifiers.

If no transaction, then creates one

Parameters:
msg - the SIP message
hash - where to write the hash
label - where to write the label
Returns:
1 on success and creation of a new transaction, 0 if transaction existed, -1 if failure

Definition at line 344 of file sip.c.

00345 {
00346     
00347     if (isc_tmb.t_get_trans_ident(msg,hash,label)<0){   
00348         LOG(L_DBG,"DBG:"M_NAME":cscf_get_transaction: SIP message without transaction. OK - first request\n");
00349         if (isc_tmb.t_newtran(msg)<0) 
00350             LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Failed creating SIP transaction\n");
00351         if (isc_tmb.t_get_trans_ident(msg,hash,label)<0){   
00352             LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: SIP message still without transaction\n");
00353             return -1;
00354         }else {
00355             LOG(L_DBG,"DBG:"M_NAME":cscf_get_transaction: New SIP message transaction %u %u\n",
00356                 *hash,*label);
00357             return 1;
00358         }                       
00359     }else {
00360         LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Transaction %u %u exists."
00361         "Retransmission?\n",*hash,*label);
00362         return 0;
00363     }
00364 }

struct sip_msg* cscf_get_request_from_reply ( struct sip_msg *  reply  )  [read]

Returns the corresponding request for a reply, using tm transactions.

Parameters:
reply - the reply to find request for
Returns:
the transactional request

Definition at line 372 of file sip.c.

00373 {
00374     struct cell *t;
00375     t = isc_tmb.t_gett();
00376     if (!t || t==(void*) -1){
00377         LOG(L_ERR,"ERR:"M_NAME":cscf_get_request_from_reply: Reply without transaction\n");
00378         return 0;
00379     }
00380     return t->uas.request;
00381 }

int cscf_get_expires_hdr ( struct sip_msg *  msg  ) 

Returns the expires value from the Expires header in the message.

It searches into the Expires header and if not found returns -1

Parameters:
msg - the SIP message, if available
Returns:
the value of the expire or -1 if not found

Definition at line 389 of file sip.c.

00389                                               {
00390     exp_body_t *exp;
00391     int expires;
00392     if (!msg) return -1;
00393     /*first search in Expires header */         
00394     if (parse_headers(msg,HDR_EXPIRES_F,0)!=0) {
00395         LOG(L_ERR,"ERR:"M_NAME":cscf_get_expires_hdr: Error parsing until header EXPIRES: \n");
00396         return -1;
00397     }
00398     if (msg->expires){
00399         if (!msg->expires->parsed) {
00400                 parse_expires(msg->expires);
00401         }
00402         if (msg->expires->parsed) {
00403                 exp = (exp_body_t*) msg->expires->parsed;
00404                 if (exp->valid) {
00405                         expires = exp->val;
00406                         LOG(L_DBG,"DBG:"M_NAME":cscf_get_expires_hdr: <%d> \n",expires);
00407                         return expires;
00408                 }
00409         }
00410     }
00411     
00412     return -1;
00413 }

int cscf_get_max_expires ( struct sip_msg *  msg  ) 

Returns the expires value from the message.

First it searches into the Expires header and if not found it also looks into the expires parameter in the contact header

Parameters:
msg - the SIP message
Returns:
the value of the expire or the default 3600 if none found

Definition at line 421 of file sip.c.

00422 {
00423     unsigned int exp;
00424     int max_expires = -1;
00425     struct hdr_field *h;
00426     contact_t *c;
00427     /*first search in Expires header */
00428     max_expires = cscf_get_expires_hdr(msg);
00429     
00430     cscf_parse_contacts(msg);
00431     for(h=msg->contact;h;h=h->next){
00432         if (h->type==HDR_CONTACT_T && h->parsed) {
00433             for(c=((contact_body_t *) h->parsed)->contacts;c;c=c->next){
00434                 if(c->expires){
00435                     if (!str2int(&(c->expires->body), (unsigned int*)&exp) && (int)exp>max_expires) max_expires = exp;
00436                 }
00437             }
00438         }   
00439     }
00440     LOG(L_DBG,"DBG:"M_NAME":cscf_get_max_expires: <%d> \n",max_expires);
00441     return max_expires;
00442 }

contact_body_t* cscf_parse_contacts ( struct sip_msg *  msg  ) 

Parses all the contact headers.

Parameters:
msg - the SIP message
Returns:
the first contact_body

Definition at line 449 of file sip.c.

00450 {
00451     struct hdr_field* ptr;
00452     if (!msg) return 0;
00453     
00454     if (parse_headers(msg, HDR_EOH_F, 0)<0){
00455         LOG(L_ERR,"ERR:"M_NAME":cscf_parse_contacts: Error parsing headers \n");
00456         return 0;
00457     }
00458     if (msg->contact) {
00459         ptr = msg->contact;
00460         while(ptr) {
00461             if (ptr->type == HDR_CONTACT_T) {
00462                 if (msg->contact->parsed==0){                   
00463                     if (parse_contact(ptr)<0){
00464                         LOG(L_ERR,"ERR:"M_NAME":cscf_parse_contacts: error parsing contacts [%.*s]\n",
00465                             ptr->body.len,ptr->body.s); 
00466                     }
00467                 }
00468             }
00469             ptr = ptr->next;
00470         }
00471     }
00472     if (!msg->contact) return 0;
00473     return msg->contact->parsed;
00474 }

str cscf_get_public_identity ( struct sip_msg *  msg  ) 

Returns the Public Identity extracted from the To header.

Parameters:
msg - the SIP message
Returns:
the str containing the public id, no mem dup

Definition at line 523 of file sip.c.

00524 {
00525     str pu={0,0};
00526     struct to_body *to;
00527     
00528     if (parse_headers(msg,HDR_TO_F,0)!=0) {
00529         LOG(L_ERR,"ERR:"M_NAME":cscf_get_public_identity: Error parsing until header To: \n");
00530         return pu;
00531     }
00532     
00533     if ( get_to(msg) == NULL ) {
00534         to = (struct to_body*) pkg_malloc(sizeof(struct to_body));
00535         parse_to( msg->to->body.s, msg->to->body.s + msg->to->body.len, to );
00536         msg->to->parsed = to;
00537     }
00538         else to=(struct to_body *) msg->to->parsed;
00539     
00540     pu = to->uri;
00541     
00542     LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity: <%.*s> \n",
00543         pu.len,pu.s);
00544     return pu;
00545 }

int cscf_get_first_p_associated_uri ( struct sip_msg *  msg,
str *  public_id 
)

Returns the first entry of the P-Associated-URI header.

Parameters:
msg - the SIP message to look into
public_id - the public identity to be filled with the result
Returns:
1 on success or 0 on failure

Definition at line 482 of file sip.c.

00483 {
00484     struct hdr_field *h;
00485     rr_t *r;
00486     public_id->s=0;public_id->len=0;
00487     
00488     if (!msg) return 0;
00489     if (parse_headers(msg, HDR_EOH_F, 0)<0){
00490         LOG(L_ERR,"ERR:"M_NAME":cscf_get_p_associated_uri: error parsing headers\n");
00491         return 0;
00492     }
00493     h = msg->headers;
00494     while(h){
00495         if (h->name.len==16 && strncasecmp(h->name.s,"P-Associated-URI",16)==0)
00496             break;
00497         h = h->next;
00498     }
00499     if (!h){
00500         LOG(L_DBG,"DBG:"M_NAME":cscf_get_p_associated_uri: Header P-Associated-URI not found\n");
00501         return 0;
00502     }
00503     if (parse_rr(h)<0){
00504         LOG(L_ERR,"ERR:"M_NAME":cscf_get_p_associated_uri: Error parsing as Route header\n");
00505         return 0;
00506     }
00507     r = (rr_t*)h->parsed;
00508     h->type = HDR_ROUTE_T;
00509     
00510     if (r) {
00511         *public_id=r->nameaddr.uri;
00512         return 1;
00513     }
00514     else
00515         return 0;
00516 }

str cscf_get_access_network_info ( struct sip_msg *  msg,
struct hdr_field **  h 
)

Return the P-Access-Network-Info header.

Parameters:
msg - the SIP message
h - ptr to the header found
Returns:
the str with the header's body

Definition at line 555 of file sip.c.

00556 {
00557     str ani={0,0};
00558     struct hdr_field *hdr;
00559     
00560     *h=0;
00561     if (parse_headers(msg,HDR_EOH_F,0)!=0) {
00562         LOG(L_DBG,"DBG:"M_NAME":cscf_get_access_network_info: Error parsing until header EOH: \n");
00563         return ani;
00564     }
00565     hdr = msg->headers;
00566     while(hdr){
00567         if (hdr->name.len==cscf_p_access_network_info.len &&
00568             strncasecmp(hdr->name.s,cscf_p_access_network_info.s,hdr->name.len)==0)
00569         {
00570             *h = hdr;
00571             ani = hdr->body;
00572             goto done;
00573         }                 
00574         hdr = hdr->next;
00575     }
00576     LOG(L_DBG,"DBG:"M_NAME":cscf_get_access_network_info: P-Access-Network-Info header not found \n");
00577     
00578 done:
00579     LOG(L_DBG,"DBG:"M_NAME":cscf_get_access_network_info: <%.*s> \n",
00580         ani.len,ani.s);
00581     return ani;
00582 }

str cscf_get_visited_network_id ( struct sip_msg *  msg,
struct hdr_field **  h 
)

Return the P-Visited-Network-ID header.

Parameters:
msg - the SIP message
Returns:
the str with the header's body

Definition at line 592 of file sip.c.

00593 {
00594     str vnid={0,0};
00595     struct hdr_field *hdr;
00596     
00597     *h=0;
00598     if (parse_headers(msg,HDR_EOH_F,0)!=0) {
00599         LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity: Error parsing until header EOH: \n");
00600         return vnid;
00601     }
00602     hdr = msg->headers;
00603     while(hdr){
00604         if (hdr->name.len==cscf_p_visited_network_id.len &&
00605             strncasecmp(hdr->name.s,cscf_p_visited_network_id.s,hdr->name.len)==0)
00606         {
00607             *h = hdr;
00608             vnid = hdr->body;
00609             goto done;
00610         }
00611         hdr = hdr->next;
00612     }
00613     LOG(L_DBG,"DBG:"M_NAME":cscf_get_visited_network_id: P-Visited-Network-ID header not found \n");
00614 
00615 done:
00616     LOG(L_DBG,"DBG:"M_NAME":cscf_get_visited_network_id: <%.*s> \n",
00617         vnid.len,vnid.s);
00618     return vnid;
00619 }

str cscf_get_charging_vector ( struct sip_msg *  msg,
struct hdr_field **  h 
)

Return the P-Charging-Vector header.

Parameters:
msg - the SIP message
Returns:
the str with the header's body

Definition at line 629 of file sip.c.

References cscf_p_charging_vector, and M_NAME.

Referenced by isc_third_party_reg().

00630 {
00631     str cv={0,0};
00632     struct hdr_field *hdr;
00633     
00634     *h=0;
00635     if (parse_headers(msg,HDR_EOH_F,0)!=0) {
00636         LOG(L_DBG,"DBG:"M_NAME":cscf_get_charging_vector: Error parsing until header EOH: \n");
00637         return cv;
00638     }
00639     hdr = msg->headers;
00640     while(hdr){
00641         if (hdr->name.len==cscf_p_charging_vector.len &&
00642             strncasecmp(hdr->name.s,cscf_p_charging_vector.s,hdr->name.len)==0)
00643         {
00644             *h = hdr;
00645             cv = hdr->body;
00646             goto done;
00647         }
00648         hdr = hdr->next;
00649     }
00650     LOG(L_DBG,"DBG:"M_NAME":cscf_get_charging_vector: P-Charging-Vector header not found \n");
00651 
00652 done:
00653     LOG(L_DBG,"DBG:"M_NAME":cscf_get_charging_vector: <%.*s> \n",
00654         cv.len,cv.s);
00655     return cv;
00656 }

str cscf_get_call_id ( struct sip_msg *  msg,
struct hdr_field **  hr 
)

Looks for the Call-ID header.

Parameters:
msg - the sip message
hr - ptr to return the found hdr_field
Returns:
the callid value

Definition at line 664 of file sip.c.

00665 {
00666     struct hdr_field *h;
00667     str call_id={0,0};
00668     if (hr) *hr = 0;    
00669     if (!msg) return call_id;
00670     if (parse_headers(msg, HDR_CALLID_F, 0)<0){
00671         LOG(L_ERR,"ERR:"M_NAME":cscf_get_call_id: error parsing headers\n");
00672         return call_id;
00673     }
00674     h = msg->callid;
00675     if (!h){
00676         LOG(L_ERR,"ERR:"M_NAME":cscf_get_call_id: Header Call-ID not found\n");
00677         return call_id;
00678     }
00679     if (hr) *hr = h;
00680     call_id = h->body;  
00681     return call_id;
00682 }

int cscf_get_cseq ( struct sip_msg *  msg,
struct hdr_field **  hr 
)

Looks for the Call-ID header.

Parameters:
msg - the sip message
hr - ptr to return the found hdr_field
Returns:
the callid value

Definition at line 691 of file sip.c.

00692 {
00693     struct hdr_field *h;
00694     struct cseq_body *cseq;
00695     int nr = 0,i;
00696     
00697     if (hr) *hr = 0;    
00698     if (!msg) return 0;
00699     if (parse_headers(msg, HDR_CSEQ_F, 0)<0){
00700         LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: error parsing headers\n");
00701         return 0;
00702     }
00703     h = msg->cseq;
00704     if (!h){
00705         LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
00706         return 0;
00707     }
00708     if (hr) *hr = h;
00709     if (!h->parsed){
00710         cseq = pkg_malloc(sizeof(struct cseq_body));
00711         if (!cseq){
00712             LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
00713             return 0;
00714         }
00715         parse_cseq(h->body.s,h->body.s+h->body.len,cseq);
00716         h->parsed = cseq;
00717     }else
00718         cseq = (struct cseq_body*) h->parsed;       
00719     for(i=0;i<cseq->number.len;i++)
00720         nr = (nr*10)+(cseq->number.s[i]-'0');
00721     return nr;
00722 }


Generated on Thu Oct 23 04:14:42 2008 for Open IMS Core CSCFs by  doxygen 1.5.2