Definition in file location.c.
#include <values.h>
#include "location.h"
#include "../../mem/shm_mem.h"
#include "mod.h"
#include "db.h"
#include "sip.h"
#include "cx.h"
#include "cx_avp.h"
#include "registration.h"
#include "../../action.h"
#include "../../route.h"
#include "../../parser/parse_uri.h"
Go to the source code of this file.
Functions | |
| int | I_LIR (struct sip_msg *msg, char *str1, char *str2) |
| Perform Location-Information-Request. | |
| int | I_LIA (struct sip_msg *msg, AAAMessage **lia, int originating) |
| Process a Location-Information-Answer. | |
| int | I_originating (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the message contains the orig parameter in the first Route header. | |
Variables | |
| tm_binds | tmb |
| Structure with pointers to tm funcs. | |
| cdp_binds | cdpb |
| Structure with pointers to cdp funcs. | |
| str | icscf_default_realm_str |
| fixed default realm | |
| int | route_on_term_user_unknown_n |
| script route number for Initial request processing after HSS says User Unknown | |
| int I_LIR | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Perform Location-Information-Request.
creates and send the user location query
| msg | - the SIP message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 89 of file location.c.
References cdp_binds::AAAFreeMessage, cdpb, cscf_get_asserted_identity(), cscf_get_public_identity_from_requri(), cscf_get_realm_from_ruri(), cscf_get_realm_from_uri(), cscf_reply_transactional(), CSCF_RETURN_BREAK, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, Cx_LIR(), I_LIA(), I_originating(), icscf_default_realm_str, M_NAME, MSG_400_NO_PUBLIC, and MSG_480_DIAMETER_ERROR.
00090 { 00091 int result=CSCF_RETURN_FALSE; 00092 str public_identity={0,0}; 00093 str realm={0,0}; 00094 AAAMessage *lia=0; 00095 int orig = 0; 00096 00097 00098 LOG(L_DBG,"DBG:"M_NAME":I_LIR: Starting ...\n"); 00099 /* check if we received what we should */ 00100 if (msg->first_line.type!=SIP_REQUEST) { 00101 LOG(L_ERR,"ERR:"M_NAME":I_LIR: The message is not a request\n"); 00102 goto done; 00103 } 00104 00105 /* check orig uri parameter in topmost Route */ 00106 if (I_originating(msg, str1, str2)==CSCF_RETURN_TRUE) { 00107 orig = 1; 00108 LOG(L_DBG,"DBG:"M_NAME":I_LIR: orig\n"); 00109 } 00110 00111 /* extract data from message */ 00112 if (orig) { 00113 public_identity = cscf_get_asserted_identity(msg); 00114 realm = cscf_get_realm_from_uri(public_identity); 00115 } else { 00116 realm = cscf_get_realm_from_ruri(msg); 00117 public_identity=cscf_get_public_identity_from_requri(msg); 00118 } 00119 if (!public_identity.len) { 00120 LOG(L_ERR,"ERR:"M_NAME":I_LIR: Public Identity not found, responding with 400\n"); 00121 cscf_reply_transactional(msg,400,MSG_400_NO_PUBLIC); 00122 result=CSCF_RETURN_BREAK; 00123 goto done; 00124 } 00125 if(!realm.len) realm = icscf_default_realm_str; 00126 00127 lia = Cx_LIR(msg,public_identity,realm); 00128 00129 if (public_identity.s && !orig) 00130 shm_free(public_identity.s); // shm_malloc in cscf_get_public_identity_from_requri 00131 00132 00133 if (!lia){ 00134 LOG(L_ERR,"ERR:"M_NAME":I_LIR: Error creating/sending LIR\n"); 00135 cscf_reply_transactional(msg,480,MSG_480_DIAMETER_ERROR); 00136 result=CSCF_RETURN_BREAK; 00137 goto done; 00138 } 00139 00140 result = I_LIA(msg, &lia, orig); 00141 00142 done: 00143 if (lia) cdpb.AAAFreeMessage(&lia); 00144 LOG(L_DBG,"DBG:"M_NAME":I_LIR: ... Done\n"); 00145 return result; 00146 }
| int I_LIA | ( | struct sip_msg * | msg, | |
| AAAMessage ** | lia, | |||
| int | originating | |||
| ) |
Process a Location-Information-Answer.
Called from the Cx_LIA handler when the LIA is received
| msg | - the original SIP message retrieved from the transaction | |
| lia | - the LIA diameter answer received from the HSS |
Definition at line 155 of file location.c.
References AAA_SUCCESS, AAA_UNABLE_TO_COMPLY, cdp_binds::AAAFreeMessage, add_scscf_list(), cdpb, cscf_get_call_id(), cscf_reply_transactional(), CSCF_RETURN_BREAK, CSCF_RETURN_TRUE, Cx_get_capabilities(), Cx_get_experimental_result_code(), Cx_get_result_code(), Cx_get_server_name(), I_get_capab_ordered(), M_NAME, MSG_403_UNABLE_TO_COMPLY, MSG_403_UNKOWN_EXPERIMENTAL_RC, MSG_403_UNKOWN_RC, MSG_480_DIAMETER_MISSING_AVP_LIA, MSG_480_DIAMETER_TIMEOUT_LIA, MSG_480_NOT_REGISTERED, MSG_500_ERROR_SAVING_LIST, MSG_600_EMPTY_LIST, MSG_604_USER_UNKNOWN, new_scscf_entry(), RC_IMS_DIAMETER_ERROR_IDENTITY_NOT_REGISTERED, RC_IMS_DIAMETER_ERROR_USER_UNKNOWN, RC_IMS_DIAMETER_UNREGISTERED_SERVICE, and route_on_term_user_unknown_n.
Referenced by I_LIR().
00156 { 00157 int rc=-1,experimental_rc=-1; 00158 str server_name; 00159 int *m_capab=0,m_capab_cnt=0; 00160 int *o_capab=0,o_capab_cnt=0; 00161 str *p_server_names=0; 00162 int p_server_names_cnt=0; 00163 scscf_entry *list=0; 00164 str call_id; 00165 int status_code=999; 00166 char *reason_phrase=0; 00167 00168 if (!*lia){ 00169 //TODO - add the warning code 99 in the reply 00170 cscf_reply_transactional(msg,480,MSG_480_DIAMETER_TIMEOUT_LIA); 00171 return CSCF_RETURN_BREAK; 00172 } 00173 00174 if (!Cx_get_result_code(*lia,&rc)&& 00175 !Cx_get_experimental_result_code(*lia,&experimental_rc)) 00176 { 00177 status_code = 480; 00178 reason_phrase = MSG_480_DIAMETER_MISSING_AVP_LIA; 00179 goto reply_final_response; 00180 } 00181 00182 switch(rc){ 00183 case -1: 00184 switch(experimental_rc){ 00185 00186 case RC_IMS_DIAMETER_ERROR_USER_UNKNOWN: 00187 if (!originating && route_on_term_user_unknown_n > -1) { 00188 if (*lia) cdpb.AAAFreeMessage(lia); 00189 if (run_actions(main_rt.rlist[route_on_term_user_unknown_n], msg)<0){ 00190 LOG(L_WARN,"ERR:"M_NAME":I_LIA: error while trying script\n"); 00191 } 00192 return CSCF_RETURN_BREAK; 00193 } else { 00194 status_code = 604; 00195 reason_phrase = MSG_604_USER_UNKNOWN; 00196 goto reply_final_response; 00197 } 00198 break; 00199 00200 case RC_IMS_DIAMETER_ERROR_IDENTITY_NOT_REGISTERED: 00201 status_code = 480; 00202 reason_phrase = MSG_480_NOT_REGISTERED; 00203 goto reply_final_response; 00204 00205 case RC_IMS_DIAMETER_UNREGISTERED_SERVICE: 00206 goto success; 00207 00208 default: 00209 status_code = 403; 00210 reason_phrase = MSG_403_UNKOWN_EXPERIMENTAL_RC; 00211 goto reply_final_response; 00212 } 00213 break; 00214 00215 case AAA_UNABLE_TO_COMPLY: 00216 status_code = 403; 00217 reason_phrase = MSG_403_UNABLE_TO_COMPLY; 00218 goto reply_final_response; 00219 00220 case AAA_SUCCESS: 00221 goto success; 00222 00223 default: 00224 status_code = 403; 00225 reason_phrase = MSG_403_UNKOWN_RC; 00226 goto reply_final_response; 00227 } 00228 00229 success: 00230 server_name = Cx_get_server_name(*lia); 00231 if (server_name.len){ 00232 list = new_scscf_entry(server_name,MAXINT, originating); 00233 }else{ 00234 Cx_get_capabilities(*lia,&m_capab,&m_capab_cnt,&o_capab,&o_capab_cnt,&p_server_names,&p_server_names_cnt); 00235 00236 list = I_get_capab_ordered(server_name,m_capab,m_capab_cnt,o_capab,o_capab_cnt,p_server_names,p_server_names_cnt,originating); 00237 if (m_capab) shm_free(m_capab); 00238 if (o_capab) shm_free(o_capab); 00239 if (p_server_names) shm_free(p_server_names); 00240 } 00241 00242 if (!list) { 00243 status_code = 600; 00244 reason_phrase = MSG_600_EMPTY_LIST; 00245 goto reply_final_response; 00246 } 00247 call_id = cscf_get_call_id(msg,0); 00248 if (!call_id.len||!add_scscf_list(call_id,list)){ 00249 status_code = 500; 00250 reason_phrase = MSG_500_ERROR_SAVING_LIST; 00251 goto reply_final_response; 00252 } 00253 //print_s_list(L_ERR); 00254 00255 return CSCF_RETURN_TRUE; 00256 00257 reply_final_response: 00258 if (*lia) cdpb.AAAFreeMessage(lia); 00259 cscf_reply_transactional(msg,status_code,reason_phrase); 00260 return CSCF_RETURN_BREAK; 00261 }
| int I_originating | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Finds if the message contains the orig parameter in the first Route header.
| msg | - the SIP message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 271 of file location.c.
References CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, if, and M_NAME.
Referenced by I_LIR().
00272 { 00273 //int ret=CSCF_RETURN_FALSE; 00274 struct hdr_field *h; 00275 str* uri; 00276 rr_t *r; 00277 00278 if (parse_headers(msg, HDR_ROUTE_F, 0)<0){ 00279 LOG(L_ERR,"ERR:"M_NAME":I_originating: error parsing headers\n"); 00280 return CSCF_RETURN_FALSE; 00281 } 00282 h = msg->route; 00283 if (!h){ 00284 LOG(L_DBG,"DBG:"M_NAME":I_originating: Header Route not found\n"); 00285 return CSCF_RETURN_FALSE; 00286 } 00287 if (parse_rr(h)<0){ 00288 LOG(L_ERR,"ERR:"M_NAME":I_originating: Error parsing as Route header\n"); 00289 return CSCF_RETURN_FALSE; 00290 } 00291 r = (rr_t*)h->parsed; 00292 00293 uri = &r->nameaddr.uri; 00294 struct sip_uri puri; 00295 if (parse_uri(uri->s, uri->len, &puri) < 0) { 00296 LOG(L_ERR, "DBG:"M_NAME":I_originating: Error while parsing the first route URI\n"); 00297 return -1; 00298 } 00299 if (puri.params.len < 4) return CSCF_RETURN_FALSE; 00300 //LOG(L_DBG,"DBG:"M_NAME":I_originating: uri params <%.*s>\n", puri.params.len, puri.params.s); 00301 // parse_uri does not support orig param... 00302 int c = 0; 00303 int state = 0; 00304 while (c < puri.params.len) { 00305 switch (puri.params.s[c]) { 00306 case 'o': if (state==0) state=1; 00307 break; 00308 case 'r': if (state==1) state=2; 00309 break; 00310 case 'i': if (state==2) state=3; 00311 break; 00312 case 'g': if (state==3) state=4; 00313 break; 00314 case ' ': 00315 case '\t': 00316 case '\r': 00317 case '\n': 00318 case ',': 00319 case ';': 00320 if (state==4) return CSCF_RETURN_TRUE; 00321 state=0; 00322 break; 00323 case '=': if (state==4) return CSCF_RETURN_TRUE; 00324 state=-1; 00325 break; 00326 default: state=-1; 00327 } 00328 c++; 00329 } 00330 00331 return state==4 ? CSCF_RETURN_TRUE : CSCF_RETURN_FALSE; 00332 }
fixed default realm
Definition at line 126 of file mod.c.
Referenced by fix_parameters(), and I_LIR().
script route number for Initial request processing after HSS says User Unknown
Definition at line 107 of file mod.c.
Referenced by I_LIA(), and icscf_mod_init().
1.5.2