Browse code

ims_charging: add support for Application-Provided-Called-Party-Address AVP

Henning Westerholt authored on 16/06/2020 19:49:17
Showing 8 changed files
... ...
@@ -87,7 +87,8 @@ out_of_memory:
87 87
 }
88 88
 
89 89
 ims_information_t * new_ims_information(event_type_t * event_type, time_stamps_t * time_stamps, str * user_session_id, str * outgoing_session_id, str * calling_party, 
90
-	str * called_party, str * icid, str * orig_ioi, str * term_ioi, int node_role, str *incoming_trunk_id, str *outgoing_trunk_id, str* pani) {
90
+	str * called_party, str * icid, str * orig_ioi, str * term_ioi, int node_role, str *incoming_trunk_id, str *outgoing_trunk_id, str* pani,
91
+	str * app_provided_party) {
91 92
 
92 93
     str_list_slot_t *sl = 0;
93 94
     ims_information_t *x = 0;
... ...
@@ -131,6 +132,10 @@ ims_information_t * new_ims_information(event_type_t * event_type, time_stamps_t
131 132
 	str_dup_ptr(x->access_network_info, *pani, pkg);
132 133
     }
133 134
 
135
+    if (app_provided_party && app_provided_party->s && (app_provided_party->len > 0)) {
136
+	str_dup_ptr(x->app_provided_party, *app_provided_party, pkg);
137
+    }
138
+
134 139
     //WL_FREE_ALL(&(x->called_asserted_identity),str_list_t,pkg);
135 140
     //str_free_ptr(x->requested_party_address,pkg);
136 141
 
... ...
@@ -256,6 +261,7 @@ void ims_information_free(ims_information_t *x) {
256 261
     str_free_ptr(x->incoming_trunk_id, pkg);
257 262
     str_free_ptr(x->outgoing_trunk_id, pkg);
258 263
     str_free_ptr(x->access_network_info, pkg);
264
+    str_free_ptr(x->app_provided_party, pkg);
259 265
 
260 266
     time_stamps_free(x->time_stamps);
261 267
 
... ...
@@ -273,6 +273,7 @@ typedef struct {
273 273
     str_list_t called_asserted_identity;
274 274
     str *requested_party_address;
275 275
     str *access_network_info;
276
+    str *app_provided_party;
276 277
 
277 278
     time_stamps_t *time_stamps;
278 279
 
... ...
@@ -407,7 +408,8 @@ ims_information_t * new_ims_information(event_type_t * event_type,
407 408
         int node_role,
408 409
 	str *incoming_trunk_id,
409 410
 	str *outgoing_trunk_id,
410
-        str *pani);
411
+        str *pani,
412
+        str * app_provided_party);
411 413
 
412 414
 void event_type_free(event_type_t *x);
413 415
 void time_stamps_free(time_stamps_t *x);
... ...
@@ -176,6 +176,15 @@ int Ro_write_ims_information_avps(AAA_AVP_LIST * avp_list, ims_information_t* x)
176 176
         if (!cdp_avp->epcapp.add_Cause_Code(&aList2, *(x->cause_code)))
177 177
             goto error;
178 178
 
179
+    if (x->app_provided_party) {
180
+        if (!cdp_avp->epcapp.add_Application_Provided_Called_Party_Address(&aList, *(x->app_provided_party),0))
181
+            goto error;
182
+        if (!cdp_avp->epcapp.add_Application_Server_Information(&aList2, &aList, 0))
183
+            goto error;
184
+        cdp_avp->cdp->AAAFreeAVPList(&aList);
185
+        aList.head = aList.tail = 0;
186
+    }
187
+
179 188
     if (!cdp_avp->epcapp.add_IMS_Information(avp_list, &aList2, AVP_FREE_DATA))//TODO check why not DONT FREE DATA
180 189
         goto error;
181 190
 
... ...
@@ -794,6 +794,29 @@ modparam("ims_charging", "custom_user_avp", "$avp(from_user)")
794 794
       </example>
795 795
     </section>
796 796
 
797
+    <section>
798
+      <title><varname>app_provided_party_avp</varname> (avp string)</title>
799
+
800
+      <para>When this parameter is set and the contents of the AVP is not
801
+      empty, an Application-Provided-Called Party-Address AVP will be
802
+      addedd to charging related requests. This is required for special
803
+      cases e.g. related to roaming for some diameter server.</para>
804
+
805
+      <para><emphasis> Default value: if not set, the
806
+      Application-Provided-Called-Party-Address AVP will be not set.</emphasis></para>
807
+
808
+      <example>
809
+        <title><varname>app_provided_party_avp</varname>parameter
810
+        usage</title>
811
+
812
+        <programlisting format="linespecific">
813
+...
814
+modparam("ims_charging", "app_provided_party_avp", "$avp(app_user)")
815
+...
816
+        </programlisting>
817
+      </example>
818
+    </section>
819
+
797 820
     <section>
798 821
       <title><varname>vendor_specific_chargeinfo</varname> (int)</title>
799 822
 
... ...
@@ -66,7 +66,9 @@ client_ro_cfg cfg = { str_init(""),
66 66
 };
67 67
 
68 68
 static str custom_user_spec = {NULL, 0};
69
+static str app_provided_party_spec = {NULL, 0};
69 70
 pv_spec_t custom_user_avp;
71
+pv_spec_t app_provided_party_avp;
70 72
 
71 73
 extern struct ims_charging_counters_h ims_charging_cnts_h;
72 74
 struct cdp_binds cdpb;
... ...
@@ -138,6 +140,7 @@ static param_export_t params[] = {
138 140
 		{ "vendor_specific_chargeinfo",		INT_PARAM,	&vendor_specific_chargeinfo		}, /* VSI for extra charing info in Ro */
139 141
 		{ "vendor_specific_id",		INT_PARAM,			&vendor_specific_id		}, /* VSI for extra charing info in Ro */
140 142
 		{ "custom_user_avp",		PARAM_STR,			&custom_user_spec},
143
+		{ "app_provided_party_avp",	PARAM_STR,			&app_provided_party_spec},
141 144
 		{ 0, 0, 0 }
142 145
 };
143 146
 
... ...
@@ -188,7 +191,19 @@ int fix_parameters() {
188 191
 		}
189 192
 	}
190 193
 
194
+	if (app_provided_party_spec.s) {
195
+		if (pv_parse_spec(&app_provided_party_spec, &app_provided_party_avp) == 0
196
+				&& (app_provided_party_avp.type != PVT_AVP)) {
197
+			LM_ERR("malformed or non AVP app_provided_party "
198
+					"AVP definition in '%.*s'\n",
199
+					app_provided_party_spec.len,
200
+					app_provided_party_spec.s);
201
+			return -1;
202
+		}
203
+	}
204
+
191 205
 	init_custom_user(custom_user_spec.s ? &custom_user_avp : 0);
206
+	init_app_provided_party(app_provided_party_spec.s ? &app_provided_party_avp : 0);
192 207
 
193 208
 	return 1;
194 209
 }
... ...
@@ -35,6 +35,7 @@
35 35
 #include "ims_charging_stats.h"
36 36
 
37 37
 static pv_spec_t *custom_user_avp;		/*!< AVP for custom_user setting */
38
+static pv_spec_t *app_provided_party_avp;	/*!< AVP for app_provided_party setting */
38 39
 
39 40
 extern struct tm_binds tmb;
40 41
 extern struct cdp_binds cdpb;
... ...
@@ -77,6 +78,11 @@ void init_custom_user(pv_spec_t *custom_user_avp_p)
77 78
     custom_user_avp = custom_user_avp_p;
78 79
 }
79 80
 
81
+void init_app_provided_party(pv_spec_t *app_provided_party_avp_p)
82
+{
83
+    app_provided_party_avp = app_provided_party_avp_p;
84
+}
85
+
80 86
 /*!
81 87
  * \brief Return the custom_user for a record route
82 88
  * \param req SIP message
... ...
@@ -99,6 +105,29 @@ static int get_custom_user(struct sip_msg *req, str *custom_user) {
99 105
 	return -1;
100 106
 }
101 107
 
108
+/*!
109
+ * \brief Return the Application-Provided-Called-Party-Address
110
+ * \param req SIP message
111
+ * \param address to be returned
112
+ * \return <0 for failure
113
+ */
114
+static int get_app_provided_party(struct sip_msg *req, str *address) {
115
+	pv_value_t pv_val;
116
+
117
+	if (app_provided_party_avp) {
118
+		if ((pv_get_spec_value(req, app_provided_party_avp, &pv_val) == 0)
119
+				&& (pv_val.flags & PV_VAL_STR) && (pv_val.rs.len > 0)) {
120
+			address->s = pv_val.rs.s;
121
+			address->len = pv_val.rs.len;
122
+			return 0;
123
+		}
124
+		LM_DBG("invalid AVP value, no Application-Provided-Called-Party-Address\n");
125
+	}
126
+
127
+	return -1;
128
+}
129
+
130
+
102 131
 void credit_control_session_callback(int event, void* session) {
103 132
     switch (event) {
104 133
         case AUTH_EV_SESSION_DROP:
... ...
@@ -447,7 +476,8 @@ Ro_CCR_t * dlg_create_ro_session(struct sip_msg * req, struct sip_msg * reply, A
447 476
     str user_name/* ={0,0}*/, sip_method = {0, 0}, event = {0, 0};
448 477
     uint32_t expires = 0;
449 478
     str callid = {0, 0}, to_uri = {0, 0}, from_uri = {0, 0},
450
-    icid = {0, 0}, orig_ioi = {0, 0}, term_ioi = {0, 0};
479
+    icid = {0, 0}, orig_ioi = {0, 0}, term_ioi = {0, 0},
480
+    app_provided_party = {0, 0};
451 481
 
452 482
     event_type_t * event_type = 0;
453 483
     ims_information_t * ims_info = 0;
... ...
@@ -478,8 +508,12 @@ Ro_CCR_t * dlg_create_ro_session(struct sip_msg * req, struct sip_msg * reply, A
478 508
     if (!(time_stamps = new_time_stamps(&req_timestamp, NULL, &reply_timestamp, NULL)))
479 509
         goto error;
480 510
 
511
+    if (get_app_provided_party(req, &app_provided_party) == -1) {
512
+        LM_DBG("no valid Application-Provided-Called-Party-Address AVP provided\n");
513
+    }
514
+
481 515
     if (!(ims_info = new_ims_information(event_type, time_stamps, &callid, &callid, &asserted_identity, &called_asserted_identity, &icid,
482
-            &orig_ioi, &term_ioi, dir, incoming_trunk_id, outgoing_trunk_id, pani)))
516
+            &orig_ioi, &term_ioi, dir, incoming_trunk_id, outgoing_trunk_id, pani, &app_provided_party)))
483 517
         goto error;
484 518
     LM_DBG("created IMS information\n");
485 519
     event_type = 0;
... ...
@@ -586,7 +620,8 @@ void send_ccr_interim(struct ro_session* ro_session, unsigned int used, unsigned
586 620
         goto error;
587 621
 
588 622
     if (!(ims_info = new_ims_information(event_type, time_stamps, &ro_session->callid, &ro_session->callid, &ro_session->asserted_identity,
589
-            &ro_session->called_asserted_identity, 0, 0, 0, ro_session->direction, &ro_session->incoming_trunk_id, &ro_session->outgoing_trunk_id, &ro_session->pani)))
623
+            &ro_session->called_asserted_identity, 0, 0, 0, ro_session->direction, &ro_session->incoming_trunk_id, &ro_session->outgoing_trunk_id,
624
+            &ro_session->pani, &ro_session->app_provided_party)))
590 625
         goto error;
591 626
 
592 627
     LM_DBG("created IMS information\n");
... ...
@@ -859,7 +894,8 @@ void send_ccr_stop_with_param(struct ro_session *ro_session, unsigned int code,
859 894
         goto error0;
860 895
 
861 896
     if (!(ims_info = new_ims_information(event_type, time_stamps, &ro_session->callid, &ro_session->callid, &ro_session->asserted_identity,
862
-            &ro_session->called_asserted_identity, 0, 0, 0, ro_session->direction, &ro_session->incoming_trunk_id, &ro_session->outgoing_trunk_id, &ro_session->pani)))
897
+            &ro_session->called_asserted_identity, 0, 0, 0, ro_session->direction, &ro_session->incoming_trunk_id, &ro_session->outgoing_trunk_id,
898
+            &ro_session->pani, &ro_session->app_provided_party)))
863 899
         goto error0;
864 900
 
865 901
     event_type = 0;
... ...
@@ -28,5 +28,6 @@ void send_ccr_stop_with_param(struct ro_session *ro_session, unsigned int code,
28 28
 int get_direction_as_int(str* direction);
29 29
 
30 30
 void init_custom_user(pv_spec_t *custom_user_avp);
31
+void init_app_provided_party(pv_spec_t *app_provided_party_avp_p);
31 32
 
32 33
 #endif /* CLIENT_RF_IMS_RO_H */
... ...
@@ -58,6 +58,7 @@ struct ro_session {
58 58
     str incoming_trunk_id;
59 59
     str outgoing_trunk_id;
60 60
     str pani;
61
+    str app_provided_party;
61 62
     unsigned int hop_by_hop;
62 63
     struct ro_tl ro_tl;
63 64
     unsigned int reserved_secs;