Browse code

modules/ims_qos: Rx_AAR new params that let you set sub-id and sub-id-type This allows users to specify sub-id and sub-id-type when calling Rx_AAR If passed as empty then default is used This helps with some PCRFs

Richard Good authored on 17/12/2014 08:55:15
Showing 5 changed files
... ...
@@ -277,7 +277,7 @@ route[REG_AAR_REPLY]
277 277
 
278 278
     <section>
279 279
       <title><function moreinfo="none">Rx_AAR(route_block,
280
-      direction)</function></title>
280
+      direction, subscription_id, subscription_id_type)</function></title>
281 281
 
282 282
       <para>Perform a AAR on Diameter RX interface to request resource
283 283
       authorisation from a Diameter server (typically a PCRF). For more
... ...
@@ -287,14 +287,27 @@ route[REG_AAR_REPLY]
287 287
 
288 288
       <itemizedlist>
289 289
         <listitem>
290
-          <para>Route block to resume after async UAR Diameter reply.</para>
290
+          <para><emphasis>Route block</emphasis> to resume after async UAR Diameter reply.</para>
291 291
         </listitem>
292 292
 
293 293
         <listitem>
294
-          <para><emphasis>direction</emphasis>the direction of this message -
294
+          <para><emphasis>direction</emphasis> of this message -
295 295
           orig, term, etc.</para>
296 296
         </listitem>
297
-      </itemizedlist>
297
+	
298
+	<listitem>
299
+          <para><emphasis>subscription_id</emphasis> to hard code subscription ID for AAR.
300
+	  Used for some broken PCRFs.  Leave blank to use default</para>
301
+        </listitem>
302
+	
303
+	<listitem>
304
+          <para><emphasis>subscription_id_type</emphasis> to hard code subscription ID type
305
+	  for AAR. Only applicable if subscription_id is set. Set to -1 to use default.
306
+	  This is as per RFC 4006: 
307
+	  END_USER_E164 0, END_USER_IMSI 1, END_USER_SIP_URI 2, END_USER_NAI 3,
308
+	  END_USER_PRIVATE 4</para>
309
+	</listitem>
310
+	</itemizedlist>
298 311
 
299 312
       <para>This function can be used from REQUEST_ROUTE or
300 313
       ONREPLY_ROUTE.</para>
... ...
@@ -307,7 +320,7 @@ route[REG_AAR_REPLY]
307 307
 
308 308
         <programlisting format="linespecific">
309 309
 ...
310
-if(Rx_AAR("ORIG_SESSION_AAR_REPLY","orig")==0){
310
+if(Rx_AAR("ORIG_SESSION_AAR_REPLY","orig","",-1)==0){
311 311
     exit;
312 312
 }
313 313
 ...
... ...
@@ -114,11 +114,11 @@ str rx_dest_realm = str_init("ims.smilecoms.com");
114 114
 str rx_forced_peer = str_init("");
115 115
 
116 116
 /* commands wrappers and fixups */
117
-static int w_rx_aar(struct sip_msg *msg, char *route, char* direction, char *bar);
117
+static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *id, int id_type);
118 118
 static int w_rx_aar_register(struct sip_msg *msg, char *route, char* str1, char *bar);
119 119
 
120 120
 static cmd_export_t cmds[] = {
121
-    { "Rx_AAR", (cmd_function) w_rx_aar, 2, fixup_aar, 0, REQUEST_ROUTE | ONREPLY_ROUTE},
121
+    { "Rx_AAR", (cmd_function) w_rx_aar, 4, fixup_aar, 0, REQUEST_ROUTE | ONREPLY_ROUTE},
122 122
     { "Rx_AAR_Register", (cmd_function) w_rx_aar_register, 2, fixup_aar_register, 0, REQUEST_ROUTE},
123 123
     { 0, 0, 0, 0, 0, 0}
124 124
 };
... ...
@@ -522,7 +522,7 @@ void callback_pcscf_contact_cb(struct pcontact *c, int type, void *param) {
522 522
 /* Wrapper to send AAR from config file - this only allows for AAR for calls - not register, which uses r_rx_aar_register
523 523
  * return: 1 - success, <=0 failure. 2 - message not a AAR generating message (ie proceed without PCC if you wish)
524 524
  */
525
-static int w_rx_aar(struct sip_msg *msg, char *route, char* str1, char* bar) {
525
+static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int id_type) {
526 526
 
527 527
     int ret = CSCF_RETURN_ERROR;
528 528
     int result = CSCF_RETURN_ERROR;
... ...
@@ -537,18 +537,25 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* str1, char* bar) {
537 537
     
538 538
     str route_name;
539 539
     str identifier, ip;
540
+    int identifier_type;
540 541
     int ip_version = 0;
541 542
     int must_free_asserted_identity = 0;
542 543
     sdp_session_cell_t* sdp_session;
544
+    str s_id;
543 545
 
544 546
     cfg_action_t* cfg_action = 0;
545 547
     saved_transaction_t* saved_t_data = 0; //data specific to each contact's AAR async call
546
-    char* direction = str1;
548
+    char* direction = dir;
547 549
     if (fixup_get_svalue(msg, (gparam_t*) route, &route_name) != 0) {
548 550
         LM_ERR("no async route block for assign_server_unreg\n");
549 551
         return result;
550 552
     }
551 553
     
554
+    if (get_str_fparam(&s_id, msg, (fparam_t*) c_id) < 0) {
555
+	LM_ERR("failed to get s__id\n");
556
+	return result;
557
+    }
558
+    
552 559
     LM_DBG("Looking for route block [%.*s]\n", route_name.len, route_name.s);
553 560
     int ri = route_get(&main_rt, route_name.s);
554 561
     if (ri < 0) {
... ...
@@ -684,30 +691,53 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* str1, char* bar) {
684 684
 	//get ip and subscription_id and store them in the call session data
685 685
 	
686 686
 	//SUBSCRIPTION-ID
687
+	
688
+	//if subscription-id and identifier_type is passed from config file we use them - if not we use default behaviour of
689
+	
687 690
 	//if its mo we use p_asserted_identity in request - if that not there we use from_uri
688 691
 	//if its mt we use p_asserted_identity in reply - if that not there we use to_uri
692
+	if(s_id.len > 0 && id_type > -1) {
693
+	    identifier.s = s_id.s;
694
+	    identifier.len = s_id.len;
695
+	    identifier_type = id_type;
696
+	    LM_DBG("Passed in subscription_id [%.*s] and subscription_id_type [%d]\n", identifier.len, identifier.s, identifier_type);
697
+	} else {
698
+	    if (dlg_direction == DLG_MOBILE_ORIGINATING) {
699
+		LM_DBG("originating direction\n");
700
+		if ((identifier = cscf_get_asserted_identity(t->uas.request, 1)).len == 0) {
701
+		    LM_DBG("No P-Asserted-Identity hdr found in request. Using From hdr in req");
702
+
703
+		    if (!cscf_get_from_uri(t->uas.request, &identifier)) {
704
+			    LM_ERR("Error assigning P-Asserted-Identity using From hdr in req");
705
+			    goto error;
706
+		    }
707
+		} else {
708
+		    must_free_asserted_identity = 1;
709
+		}
710
+	    } else {
711
+		LM_DBG("terminating direction\n");
712
+		if ((identifier = cscf_get_asserted_identity(msg, 0)).len == 0) {
713
+		    LM_DBG("No P-Asserted-Identity hdr found in response. Using To hdr in resp");
714
+		    identifier = cscf_get_public_identity(msg); //get public identity from to header
715
+		}
716
+	    }
717
+	    if (strncasecmp(identifier.s,"tel:",4)==0) {
718
+		identifier_type = AVP_Subscription_Id_Type_E164; //
719
+	    }else{
720
+		identifier_type = AVP_Subscription_Id_Type_SIP_URI; //default is END_USER_SIP_URI
721
+	    }
722
+	}
689 723
 	//IP 
690 724
 	//if its mo we use request SDP
691 725
 	//if its mt we use reply SDP
692 726
 	if (dlg_direction == DLG_MOBILE_ORIGINATING) {
693 727
 	    LM_DBG("originating direction\n");
694
-	    if ((identifier = cscf_get_asserted_identity(t->uas.request, 1)).len == 0) {
695
-		LM_DBG("No P-Asserted-Identity hdr found in request. Using From hdr in req");
696
-
697
-		if (!cscf_get_from_uri(t->uas.request, &identifier)) {
698
-			LM_ERR("Error assigning P-Asserted-Identity using From hdr in req");
699
-			goto error;
700
-		}
701
-	    } else {
702
-		must_free_asserted_identity = 1;
703
-	    }
704
-	    
705 728
 	    //get ip from request sdp (we use first SDP session)
706 729
 	    if (parse_sdp(t->uas.request) < 0) {
707 730
 		LM_ERR("Unable to parse req SDP\n");
708 731
 		goto error;
709 732
 	    }
710
-	    
733
+
711 734
 	    sdp_session = get_sdp_session(t->uas.request, 0);
712 735
 	    if (!sdp_session) {
713 736
 		    LM_ERR("Missing SDP session information from req\n");
... ...
@@ -716,20 +746,15 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* str1, char* bar) {
716 716
 	    ip = sdp_session->ip_addr;
717 717
 	    ip_version = sdp_session->pf;
718 718
 	    free_sdp((sdp_info_t**) (void*) &t->uas.request->body);
719
-	    
719
+
720 720
 	} else {
721 721
 	    LM_DBG("terminating direction\n");
722
-	    if ((identifier = cscf_get_asserted_identity(msg, 0)).len == 0) {
723
-		LM_DBG("No P-Asserted-Identity hdr found in response. Using To hdr in resp");
724
-		identifier = cscf_get_public_identity(msg); //get public identity from to header
725
-	    }
726
-	    
727 722
 	    //get ip from reply sdp (we use first SDP session)
728 723
 	    if (parse_sdp(msg) < 0) {
729 724
 		LM_ERR("Unable to parse req SDP\n");
730 725
 		goto error;
731 726
 	    }
732
-	    
727
+
733 728
 	    sdp_session = get_sdp_session(msg, 0);
734 729
 	    if (!sdp_session) {
735 730
 		    LM_ERR("Missing SDP session information from reply\n");
... ...
@@ -738,10 +763,9 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* str1, char* bar) {
738 738
 	    ip = sdp_session->ip_addr;
739 739
 	    ip_version = sdp_session->pf;
740 740
 	    free_sdp((sdp_info_t**) (void*) &msg->body);
741
-	    
742 741
 	}
743
-
744
-        int ret = create_new_callsessiondata(&callid, &ftag, &ttag, &identifier, &ip, ip_version, &rx_authdata_p);
742
+	
743
+        int ret = create_new_callsessiondata(&callid, &ftag, &ttag, &identifier, identifier_type, &ip, ip_version, &rx_authdata_p);
745 744
         if (!ret) {
746 745
             LM_DBG("Unable to create new media session data parcel\n");
747 746
             goto error;
... ...
@@ -1171,6 +1195,9 @@ static int fixup_aar_register(void** param, int param_no) {
1171 1171
 }
1172 1172
 
1173 1173
 static int fixup_aar(void** param, int param_no) {
1174
+    str s;
1175
+    unsigned int num;
1176
+    
1174 1177
     if (strlen((char*) *param) <= 0) {
1175 1178
         LM_ERR("empty parameter %d not allowed\n", param_no);
1176 1179
         return -1;
... ...
@@ -1180,6 +1207,19 @@ static int fixup_aar(void** param, int param_no) {
1180 1180
         if (fixup_spve_null(param, param_no) < 0)
1181 1181
             return -1;
1182 1182
         return 0;
1183
+    } else if (param_no == 3) {
1184
+	return fixup_var_str_12(param, param_no);
1185
+    } else if (param_no == 4) {
1186
+	/*convert to int */
1187
+	s.s = (char*)*param;
1188
+	s.len = strlen(s.s);
1189
+	if (str2int(&s, &num)==0) {
1190
+		pkg_free(*param);
1191
+		*param = (void*)(unsigned long)num;
1192
+		return 0;
1193
+	}
1194
+	LM_ERR("Bad reservation units: <%s>n", (char*)(*param));
1195
+	return E_CFG;
1183 1196
     }
1184 1197
 
1185 1198
     return 0;
... ...
@@ -480,7 +480,6 @@ int add_media_components(AAAMessage* aar, struct sip_msg *req,
480 480
 int rx_send_aar_update_no_video(AAASession* auth) {
481 481
 
482 482
     AAAMessage* aar = 0;
483
-    int must_free_asserted_identity = 0;
484 483
     
485 484
     str identifier;
486 485
     int identifier_type;
... ...
@@ -497,6 +496,7 @@ int rx_send_aar_update_no_video(AAASession* auth) {
497 497
     rx_authsessiondata_t* p_session_data = 0;
498 498
     p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
499 499
     identifier = p_session_data->identifier;
500
+    identifier_type = p_session_data->identifier_type;
500 501
     ip = p_session_data->ip;
501 502
     ip_version = p_session_data->ip_version;
502 503
     
... ...
@@ -558,17 +558,7 @@ int rx_send_aar_update_no_video(AAASession* auth) {
558 558
 
559 559
     LM_DBG("Adding subscription id...\n");
560 560
 
561
-    if (strncasecmp(identifier.s,"tel:",4)==0) {
562
-	identifier_type = AVP_Subscription_Id_Type_E164; //
563
-    }else{
564
-	identifier_type = AVP_Subscription_Id_Type_SIP_URI; //default is END_USER_SIP_URI
565
-    }
566
-    
567
-    
568 561
     rx_add_subscription_id_avp(aar, identifier, identifier_type);
569
-    if (must_free_asserted_identity) {
570
-            pkg_free(identifier.s);
571
-    }
572 562
 
573 563
 
574 564
     LM_DBG("Adding reservation priority...\n");
... ...
@@ -651,7 +641,6 @@ int rx_send_aar(struct sip_msg *req, struct sip_msg *res,
651 651
         AAASession* auth, char* direction, saved_transaction_t* saved_t_data) {
652 652
 
653 653
     AAAMessage* aar = 0;
654
-    int must_free_asserted_identity = 0;
655 654
     
656 655
     str identifier;
657 656
     int identifier_type;
... ...
@@ -668,6 +657,7 @@ int rx_send_aar(struct sip_msg *req, struct sip_msg *res,
668 668
     rx_authsessiondata_t* p_session_data = 0;
669 669
     p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
670 670
     identifier = p_session_data->identifier;
671
+    identifier_type = p_session_data->identifier_type;
671 672
     ip = p_session_data->ip;
672 673
     ip_version = p_session_data->ip_version;
673 674
     
... ...
@@ -737,17 +727,7 @@ int rx_send_aar(struct sip_msg *req, struct sip_msg *res,
737 737
 
738 738
     LM_DBG("Adding subscription id...\n");
739 739
 
740
-    if (strncasecmp(identifier.s,"tel:",4)==0) {
741
-	identifier_type = AVP_Subscription_Id_Type_E164; //
742
-    }else{
743
-	identifier_type = AVP_Subscription_Id_Type_SIP_URI; //default is END_USER_SIP_URI
744
-    }
745
-    
746
-    
747 740
     rx_add_subscription_id_avp(aar, identifier, identifier_type);
748
-    if (must_free_asserted_identity) {
749
-            pkg_free(identifier.s);
750
-    }
751 741
 
752 742
 
753 743
     LM_DBG("Adding reservation priority...\n");
... ...
@@ -113,7 +113,7 @@ int create_new_regsessiondata(str* domain, str* aor, str *ip, int ip_version, in
113 113
 	return 1;
114 114
 }
115 115
 
116
-int create_new_callsessiondata(str* callid, str* ftag, str* ttag, str* identifier, str* ip, int ip_version, rx_authsessiondata_t** session_data) {
116
+int create_new_callsessiondata(str* callid, str* ftag, str* ttag, str* identifier, int identifier_type, str* ip, int ip_version, rx_authsessiondata_t** session_data) {
117 117
 
118 118
 	int len = callid->len + ftag->len + ttag->len + identifier->len + ip->len + sizeof(rx_authsessiondata_t);
119 119
 	rx_authsessiondata_t* call_session_data = shm_malloc(len);
... ...
@@ -128,6 +128,7 @@ int create_new_callsessiondata(str* callid, str* ftag, str* ttag, str* identifie
128 128
 	call_session_data->first_current_flow_description=0;
129 129
 	call_session_data->first_new_flow_description=0;
130 130
 	call_session_data->ip_version = ip_version;
131
+	call_session_data->identifier_type = identifier_type;
131 132
 	
132 133
 	char *p = (char*)(call_session_data + 1);
133 134
 
... ...
@@ -80,6 +80,7 @@ typedef struct rx_authsessiondata {
80 80
     str ftag;
81 81
     str ttag;
82 82
     str identifier;
83
+    int identifier_type;
83 84
     str ip;
84 85
     int recv_port;
85 86
     int ip_version;
... ...
@@ -94,7 +95,7 @@ typedef struct rx_authsessiondata {
94 94
 } rx_authsessiondata_t;
95 95
 
96 96
 int create_new_regsessiondata(str* domain, str* aor,  str *ip, int ip_version, int recv_port, rx_authsessiondata_t** session_data);
97
-int create_new_callsessiondata(str* callid, str* ftag, str* ttag, str* identifier, str *ip, int ip_version, rx_authsessiondata_t** session_data);
97
+int create_new_callsessiondata(str* callid, str* ftag, str* ttag, str* identifier, int identifier_type, str *ip, int ip_version, rx_authsessiondata_t** session_data);
98 98
 void free_callsessiondata(rx_authsessiondata_t* session_data);
99 99
 
100 100
 int add_flow_description(rx_authsessiondata_t* session_data, int stream_num, str *media, str *req_sdp_ip_addr, str *req_sdp_port,