cx.c

Go to the documentation of this file.
00001 /*
00002  * $Id: cx.c 452 2007-09-26 16:16:48Z vingarzan $
00003  *  
00004  * Copyright (C) 2004-2006 FhG Fokus
00005  *
00006  * This file is part of Open IMS Core - an open source IMS CSCFs & HSS
00007  * implementation
00008  *
00009  * Open IMS Core is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * For a license to use the Open IMS Core software under conditions
00015  * other than those described here, or to purchase support for this
00016  * software, please contact Fraunhofer FOKUS by e-mail at the following
00017  * addresses:
00018  *     info@open-ims.org
00019  *
00020  * Open IMS Core is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  * 
00025  * It has to be noted that this Open Source IMS Core System is not 
00026  * intended to become or act as a product in a commercial context! Its 
00027  * sole purpose is to provide an IMS core reference implementation for 
00028  * IMS technology testing and IMS application prototyping for research 
00029  * purposes, typically performed in IMS test-beds.
00030  * 
00031  * Users of the Open Source IMS Core System have to be aware that IMS
00032  * technology may be subject of patents and licence terms, as being 
00033  * specified within the various IMS-related IETF, ITU-T, ETSI, and 3GPP
00034  * standards. Thus all Open IMS Core users have to take notice of this 
00035  * fact and have to agree to check out carefully before installing, 
00036  * using and extending the Open Source IMS Core System, if related 
00037  * patents and licences may become applicable to the intended usage 
00038  * context.  
00039  *
00040  * You should have received a copy of the GNU General Public License
00041  * along with this program; if not, write to the Free Software
00042  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00043  * 
00044  */
00045  
00056 #include "cx.h"
00057 
00058 #include "../tm/tm_load.h"
00059 #include "cx_avp.h"
00060 #include "sip.h"
00061 #include "registrar_storage.h"
00062 #include "registrar_parser.h"
00063 #include "registration.h"
00064 #include "ims_pm_scscf.h"
00065 
00066 extern struct tm_binds tmb;         
00067 extern struct cdp_binds cdpb;       
00069 extern str scscf_forced_hss_peer_str;       
00071 extern int r_hash_size;             
00072 extern r_hash_slot *registrar;      
00081 int CxAnswerHandler(AAAMessage *response, AAATransaction *t)
00082 {
00083     #ifdef WITH_IMS_PM
00084         ims_pm_diameter_answer(response);
00085     #endif      
00086     switch(response->commandCode){
00087         default:
00088             LOG(L_ERR,"ERR:"M_NAME":CxAnswerHandler: Unkown Command Code %d\n",
00089                 response->commandCode);
00090     }
00091     return 1;
00092 }
00093 
00101 int CxFailureHandler(AAATransaction *t,int reason)
00102 {
00103     LOG(L_INFO,"INF:"M_NAME":AAAFailureHandler:  SIP transaction %u %u Reason %d\n",
00104         t->hash,t->label,reason);
00105     switch(t->command_code){
00106         default:
00107         LOG(L_ERR,"ERR:"M_NAME":CxFailureHandler: Unkown Command Code %d\n",
00108             t->command_code);
00109     }
00110     return 0;
00111 }
00112 
00119 AAAMessage* CxRequestHandler(AAAMessage *request,void *param)
00120 {
00121     if (is_req(request)){       
00122         LOG(L_INFO,"INFO:"M_NAME":CxRequestHandler(): We have received a request\n");
00123         #ifdef WITH_IMS_PM
00124             ims_pm_diameter_request(request);
00125         #endif      
00126         switch(request->applicationId){
00127             case IMS_Cx:
00128                 switch(request->commandCode){               
00129                     case IMS_RTR:
00130                         LOG(L_INFO,"INFO:"M_NAME":CxRequestHandler():- Received an IMS_RTR \n");
00131                         return Cx_RTA(request);
00132                         break;
00133                     case IMS_PPR:
00134                         LOG(L_INFO,"INFO:"M_NAME":CxRequestHandler(): - Received an IMS_PPR \n");
00135                         return Cx_PPA(request);
00136                         break;
00137                     default :
00138                         LOG(L_ERR,"ERR:"M_NAME":CxRequestHandler(): - Received unknown request for Cx command %d\n",request->commandCode);
00139                         break;  
00140                 }
00141                 break;
00142             default:
00143                 LOG(L_ERR,"ERR:"M_NAME":CxRequestHandler(): - Received unknown request for app %d command %d\n",
00144                     request->applicationId,
00145                     request->commandCode);
00146                 break;              
00147         }                   
00148     }
00149     return 0;       
00150 }
00151 
00152 
00153 static str s_empty={0,0};
00154 extern str auth_scheme_types[];
00155 
00169 AAAMessage *Cx_MAR(struct sip_msg *msg, str public_identity, str private_identity,
00170                     unsigned int count,str algorithm,str authorization,str server_name,str realm)
00171 {
00172     AAAMessage *mar=0,*maa=0;
00173     AAASessionId sessId={0,0};
00174     AAATransaction *trans=0;
00175     unsigned int hash=0,label=0;    
00176     
00177     sessId = cdpb.AAACreateSession();
00178     trans=cdpb.AAACreateTransaction(IMS_Cx,IMS_MAR);
00179 
00180     mar = cdpb.AAACreateRequest(IMS_Cx,IMS_MAR,Flag_Proxyable,&sessId);
00181     if (!mar) goto error;
00182 
00183     if (!Cx_add_destination_realm(mar,realm)) goto error;
00184         
00185     if (!Cx_add_vendor_specific_appid(mar,IMS_vendor_id_3GPP,IMS_Cx,0 /*IMS_Cx*/)) goto error;
00186     if (!Cx_add_auth_session_state(mar,1)) goto error;      
00187         
00188     if (!Cx_add_public_identity(mar,public_identity)) goto error;
00189     if (!Cx_add_user_name(mar,private_identity)) goto error;
00190     if (!Cx_add_sip_number_auth_items(mar, count)) goto error;
00191     if (algorithm.len==auth_scheme_types[AUTH_HTTP_DIGEST_MD5].len &&
00192         strncasecmp(algorithm.s,auth_scheme_types[AUTH_HTTP_DIGEST_MD5].s,algorithm.len)==0) {
00193         if (!Cx_add_sip_auth_data_item_request(mar, algorithm, authorization, private_identity, realm, 
00194             msg->first_line.u.request.method, server_name)) goto error;
00195     }else{
00196         if (!Cx_add_sip_auth_data_item_request(mar, algorithm, authorization, private_identity, realm, 
00197             msg->first_line.u.request.method, s_empty)) goto error;     
00198     }
00199     if (!Cx_add_server_name(mar,server_name)) goto error;
00200     //TODO - add the realm also - and don't add when sending if added here 
00201         
00202     if (tmb.t_get_trans_ident(msg,&hash,&label)<0){ 
00203         LOG(L_ERR,"INF:"M_NAME":Cx_MAR: SIP message without transaction... very strange\n");
00204         return 0;
00205     }
00206 
00207     trans->hash=hash;
00208     trans->label=label;
00209     trans->application_id=mar->applicationId;
00210     trans->command_code=mar->commandCode;
00211     
00212     #ifdef WITH_IMS_PM
00213         ims_pm_diameter_request(mar);
00214     #endif              
00215     if (scscf_forced_hss_peer_str.len)
00216         maa = cdpb.AAASendRecvMessageToPeer(mar,&scscf_forced_hss_peer_str);
00217     else 
00218         maa = cdpb.AAASendRecvMessage(mar);
00219     #ifdef WITH_IMS_PM
00220         ims_pm_diameter_answer(maa);
00221     #endif          
00222     
00223     cdpb.AAADropSession(&sessId);
00224     cdpb.AAADropTransaction(trans);
00225     
00226     return maa;
00227     
00228 error:
00229     //free stuff
00230     if (trans) cdpb.AAADropTransaction(trans);
00231     if (sessId.s) cdpb.AAADropSession(&sessId);
00232     if (mar) cdpb.AAAFreeMessage(&mar);
00233     return 0;   
00234 }
00235 
00236 
00248 AAAMessage *Cx_SAR(struct sip_msg *msg, str public_identity, str private_identity,
00249                     str server_name,str realm,int assignment_type, int data_available)
00250 {
00251     AAAMessage *sar=0,*saa=0;
00252     AAASessionId sessId={0,0};
00253     AAATransaction *trans=0;
00254 //  struct cell* t;
00255     unsigned int hash=0,label=0;    
00256     
00257     sessId = cdpb.AAACreateSession();
00258     trans=cdpb.AAACreateTransaction(IMS_Cx,IMS_SAR);
00259 
00260     sar = cdpb.AAACreateRequest(IMS_Cx,IMS_SAR,Flag_Proxyable,&sessId);
00261     if (!sar) goto error;
00262 
00263     if (!Cx_add_destination_realm(sar,realm)) goto error;
00264         
00265     if (!Cx_add_vendor_specific_appid(sar,IMS_vendor_id_3GPP,IMS_Cx,0 /*IMS_Cx*/)) goto error;
00266     if (!Cx_add_auth_session_state(sar,1)) goto error;      
00267         
00268     if (!Cx_add_public_identity(sar,public_identity)) goto error;
00269     if (!Cx_add_server_name(sar,server_name)) goto error;
00270     if (private_identity.len)
00271         if (!Cx_add_user_name(sar,private_identity)) goto error;
00272     if (!Cx_add_server_assignment_type(sar,assignment_type)) goto error;
00273     if (!Cx_add_userdata_available(sar,data_available)) goto error;
00274     
00275     if (msg&&tmb.t_get_trans_ident(msg,&hash,&label)<0){    
00276         // it's ok cause we can call this async with a message
00277         //LOG(L_ERR,"INF:"M_NAME":Cx_MAR: SIP message without transaction... very strange\n");
00278         //return 0;
00279     }
00280 
00281     trans->hash=hash;
00282     trans->label=label;
00283     trans->application_id=sar->applicationId;
00284     trans->command_code=sar->commandCode;
00285     
00286     #ifdef WITH_IMS_PM
00287         ims_pm_diameter_request(sar);
00288     #endif              
00289     if (scscf_forced_hss_peer_str.len)
00290         saa = cdpb.AAASendRecvMessageToPeer(sar,&scscf_forced_hss_peer_str);
00291     else 
00292         saa = cdpb.AAASendRecvMessage(sar);
00293     #ifdef WITH_IMS_PM
00294         ims_pm_diameter_answer(saa);
00295     #endif              
00296     
00297     cdpb.AAADropSession(&sessId);
00298     cdpb.AAADropTransaction(trans);
00299     
00300     return saa;
00301     
00302 error:
00303     //free stuff
00304     if (trans) cdpb.AAADropTransaction(trans);
00305     if (sessId.s)   cdpb.AAADropSession(&sessId);
00306     if (sar) cdpb.AAAFreeMessage(&sar);
00307     return 0;   
00308 }
00309 
00315 AAAMessage* Cx_RTA(AAAMessage * rtr)
00316 {   
00317     AAAMessage  *rta_msg;
00318     AAA_AVP* avp;
00319     str public_id;
00320     str private_id;
00321     
00322     rta_msg = cdpb.AAACreateResponse(rtr);//session ID?
00323     if (!rta_msg) return 0;
00324 
00325     avp = Cx_get_next_public_identity(rtr,0,AVP_IMS_Public_Identity,IMS_vendor_id_3GPP,__FUNCTION__);   
00326     if(avp==0){
00327         private_id=Cx_get_user_name(rtr);   
00328         r_private_expire(private_id);            
00329     }else{
00330         public_id=avp->data;
00331         r_public_expire(public_id);
00332         while(cdpb.AAAGetNextAVP(avp) && (avp=Cx_get_next_public_identity(rtr,cdpb.AAAGetNextAVP(avp),AVP_IMS_Public_Identity,IMS_vendor_id_3GPP,__FUNCTION__))!=0){
00333             public_id=avp->data;
00334             r_public_expire(public_id);
00335         }       
00336     }
00337     Cx_add_vendor_specific_appid(rta_msg,IMS_vendor_id_3GPP,IMS_Cx,0 /*IMS_Cx*/);
00338     Cx_add_auth_session_state(rta_msg,1);       
00339 
00340     /* send an RTA back to the HSS */
00341     Cx_add_result_code(rta_msg,DIAMETER_SUCCESS);
00342     #ifdef WITH_IMS_PM
00343         ims_pm_diameter_answer(rta_msg);
00344     #endif      
00345     
00346     return rta_msg;
00347 }
00348 
00349 
00355 AAAMessage* Cx_PPA(AAAMessage * ppr)
00356 {
00357     AAAMessage  *ppa_msg;
00358     str ppr_data;
00359     ims_subscription *imss;
00360     int i,j;
00361     r_public *pu;
00362     str ccf1,ccf2,ecf1,ecf2;
00363 
00364     ppa_msg = cdpb.AAACreateResponse(ppr);
00365     if (!ppa_msg) return 0; 
00366     
00367     if((ppr_data=Cx_get_user_data(ppr)).len != 0){
00368         LOG(L_INFO,"INFO:"M_NAME":Cx_PPA(): Received a User_Data PPR!\n");
00369         imss=parse_user_data(ppr_data);
00370         print_user_data(L_ALERT,imss);
00371         
00372         for(i=0;i<imss->service_profiles_cnt;i++)
00373             for(j=0;j<imss->service_profiles[i].public_identities_cnt;j++){             
00374                 pu = update_r_public(imss->service_profiles[i].public_identities[j].public_identity,
00375                     0,&imss,0,0,0,0);
00376                 if (!pu) continue;
00377                 r_unlock(pu->hash);
00378             }           
00379     }
00380     else{
00381         if (Cx_get_charging_info(ppr,&ccf1,&ccf2,&ecf1,&ecf2)){
00382             LOG(L_INFO,"INFO:"M_NAME":Cx_PPA(): Received a Charging Info PPR - NOT IMPLEMENTED\n");
00383             //TODO find all r_public that should be updated and update
00384         }
00385     }   
00386     Cx_add_vendor_specific_appid(ppa_msg,IMS_vendor_id_3GPP,IMS_Cx,0 /*IMS_Cx*/);
00387     Cx_add_auth_session_state(ppa_msg,1);       
00388     
00389     Cx_add_result_code(ppa_msg,DIAMETER_SUCCESS);
00390     #ifdef WITH_IMS_PM
00391         ims_pm_diameter_answer(ppa_msg);
00392     #endif          
00393     return ppa_msg;
00394 }
00395 

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