Browse code

ims_qos: fix compilation warning

Atanas Bakalov authored on 31/05/2022 10:52:38
Showing 1 changed files
... ...
@@ -53,6 +53,7 @@
53 53
 #include "../cdp_avp/cdp_avp_mod.h"
54 54
 
55 55
 #include "../../modules/ims_dialog/dlg_load.h"
56
+#include "../../modules/ims_dialog/dlg_hash.h"
56 57
 #include "../../modules/tm/tm_load.h"
57 58
 #include "../ims_usrloc_pcscf/usrloc.h"
58 59
 #include "rx_authdata.h"
Browse code

rx_aar: unreference dialog in case of aar update (#3104)

- release the dialog reference even for aar updates as the dialog was
already referenced when issuing the aar request

Co-authored-by: Atanas Bakalov <atanas@wgtwo.com>

Atanas Bakalov authored on 30/05/2022 08:46:38 • GitHub committed on 30/05/2022 08:46:38
Showing 1 changed files
... ...
@@ -180,6 +180,8 @@ void async_aar_callback(int is_timeout, void *param, AAAMessage *aaa, long elaps
180 180
             STR_SHM_DUP(*passed_rx_session_id, aaa->sessionId->data, "cb_passed_rx_session_id");
181 181
             LM_DBG("passed rx session id [%.*s]", passed_rx_session_id->len, passed_rx_session_id->s);
182 182
             dlgb.register_dlgcb_nodlg( data->dlg, DLGCB_TERMINATED | DLGCB_DESTROY | DLGCB_EXPIRED | DLGCB_RESPONSE_WITHIN | DLGCB_CONFIRMED | DLGCB_FAILED, callback_dialog, (void*) (passed_rx_session_id), free_dialog_data);
183
+        } else {
184
+            unref_dlg(data->dlg, 1);
183 185
         }
184 186
         result = CSCF_RETURN_TRUE;
185 187
     } else {
Browse code

ims_qos: Added new parameters for AAR,AVP517

- Added new parameters: af_signaling_ip6, component_media_type,
flow_protocol, omit_flow_ports, rs_default_bandwidth,
rr_default_bandwidth. Check doc for details.

Aleksandar Yosifov authored on 25/03/2022 15:18:10 • Daniel-Constantin Mierla committed on 01/04/2022 11:54:38
Showing 1 changed files
... ...
@@ -78,6 +78,9 @@ extern struct ims_qos_counters_h ims_qos_cnts_h;
78 78
 extern int authorize_video_flow;
79 79
 
80 80
 extern str af_signaling_ip;
81
+extern str af_signaling_ip6;
82
+extern str component_media_type;
83
+extern str flow_protocol;
81 84
 
82 85
 str IMS_Serv_AVP_val = {"IMS Services", 12};
83 86
 str IMS_Em_Serv_AVP_val = {"Emergency IMS Call", 18};
... ...
@@ -952,10 +955,10 @@ int rx_send_aar_register(struct sip_msg *msg, AAASession* auth, saved_transactio
952 955
     AAA_AVP* avp = 0;
953 956
     char x[4];
954 957
     str identifier;
955
-    str media;
956 958
 
957 959
     str ip;
958 960
     uint16_t ip_version;
961
+    str via_host;
959 962
 
960 963
     //we get ip and identifier for the auth session data
961 964
     rx_authsessiondata_t* p_session_data = 0;
... ...
@@ -998,8 +1001,6 @@ int rx_send_aar_register(struct sip_msg *msg, AAASession* auth, saved_transactio
998 1001
 
999 1002
     /* Create flow description for AF-Signaling */
1000 1003
     //add this to auth session data
1001
-    media.s = "control";
1002
-    media.len = strlen("control");
1003 1004
     str raw_stream;
1004 1005
     raw_stream.s = 0;
1005 1006
     raw_stream.len = 0;
... ...
@@ -1014,16 +1015,26 @@ int rx_send_aar_register(struct sip_msg *msg, AAASession* auth, saved_transactio
1014 1015
     port_to.len = snprintf(c_port_to, 10, "%u", saved_t_data->recv_port);
1015 1016
     port_to.s = c_port_to;
1016 1017
 
1017
-    str protocol;
1018
-    protocol.s = "IP";
1019
-    protocol.len = strlen("IP");
1018
+    via_host.len = saved_t_data->via_host.len;
1019
+    via_host.s = saved_t_data->via_host.s;
1020
+
1021
+    if (ip_version == AF_INET6 && via_host.len && via_host.s[0]=='[') {
1022
+        /* skip over [ ] */
1023
+        if (via_host.s[via_host.len - 1]!=']') {
1024
+            LM_ERR("Invalid IPv6 format %.*s\n", via_host.len, via_host.s);
1025
+                goto error;
1026
+        }
1027
+
1028
+        via_host.s++;
1029
+        via_host.len -= 2;
1030
+    }
1020 1031
 
1021 1032
     //rx_add_media_component_description_avp_register(aar);
1022 1033
     /* Add media component description avp for register*/
1023 1034
     rx_add_media_component_description_avp(aar, 1,
1024
-               &media, &saved_t_data->via_host,
1025
-               &port_from, &af_signaling_ip,
1026
-               &port_to, &protocol,
1035
+               &component_media_type, &via_host,
1036
+               &port_from, ip_version == AF_INET ? &af_signaling_ip : &af_signaling_ip6,
1037
+               &port_to, &flow_protocol,
1027 1038
                &raw_stream,
1028 1039
                &raw_stream, DLG_MOBILE_REGISTER, AVP_EPC_Flow_Usage_AF_Signaling);
1029 1040
 
Browse code

ims_qos: typos in comments

Daniel-Constantin Mierla authored on 24/02/2021 18:09:35
Showing 1 changed files
... ...
@@ -328,7 +328,8 @@ void async_aar_reg_callback(int is_timeout, void *param, AAAMessage *aaa, long e
328 328
         }
329 329
 
330 330
         //at this point we have the contact
331
-        /*set the contact state to say we have succesfully done ARR for register and that we dont need to do it again
331
+        /*set the contact state to say we have successfully done ARR for register
332
+         * and that we dont need to do it again
332 333
          * for the duration of the registration.
333 334
          * */
334 335
         if (ul.update_rx_regsession(domain_t, &local_data->auth_session_id, pcontact) != 0) {
Browse code

Fix typo on ims_qos module: Consecutives 'the'

Jorge Vallecillo authored on 02/10/2020 02:44:27 • Henning Westerholt committed on 02/10/2020 13:48:22
Showing 1 changed files
... ...
@@ -276,7 +276,7 @@ void async_aar_reg_callback(int is_timeout, void *param, AAAMessage *aaa, long e
276 276
     if (cdp_result >= 2000 && cdp_result < 3000) {
277 277
         counter_inc(ims_qos_cnts_h.successful_registration_aars);
278 278
         if (is_rereg) {
279
-            LM_DBG("this is a re-registration, therefore we don't need to do anything except know that the the subscription was successful\n");
279
+            LM_DBG("this is a re-registration, therefore we don't need to do anything except know that the subscription was successful\n");
280 280
             result = CSCF_RETURN_TRUE;
281 281
             create_return_code(result);
282 282
             goto done;
Browse code

ims_qos: extend get_pcontact with the new parameter.

Aleksandar Yosifov authored on 03/08/2020 11:52:29 • Henning Westerholt committed on 12/08/2020 18:44:08
Showing 1 changed files
... ...
@@ -321,7 +321,7 @@ void async_aar_reg_callback(int is_timeout, void *param, AAAMessage *aaa, long e
321 321
         contact_info.via_prot = local_data->via_proto;
322 322
         contact_info.reg_state = PCONTACT_ANY;
323 323
 
324
-        if (ul.get_pcontact(domain_t, &contact_info, &pcontact) != 0) {
324
+        if (ul.get_pcontact(domain_t, &contact_info, &pcontact, 0) != 0) {
325 325
             LM_ERR("Shouldn't get here, can't find contact....\n");
326 326
             ul.unlock_udomain(domain_t, &local_data->via_host, local_data->via_port, local_data->via_proto);
327 327
             goto error;
Browse code

ims_qos: bugfix for Rx register dialog callback

- bugfix for Rx register dialog callback
- In some scenarios like parallel forking several INVITE with identical
CALLID and FROMTAG sent to PCSCF which inserts dialogues for each INVITE.
- When 200OK is received in PCSCF the dialog callback must be registered
for the respective dialog. Currently sometimes the wrong dialog is selected
by searching with CALLID FROMTAG and TOTAG thus leading to problem
no STR is sent at BYE.
- Fix is to pickup the right dialog before suspending the transaction during
AAR/AAA processing and reuse this saved dialog.

Peter Friedrich authored on 30/03/2020 17:02:29 • Henning Westerholt committed on 30/03/2020 17:02:29
Showing 1 changed files
... ...
@@ -176,8 +176,7 @@ void async_aar_callback(int is_timeout, void *param, AAAMessage *aaa, long elaps
176 176
             passed_rx_session_id->len = 0;
177 177
             STR_SHM_DUP(*passed_rx_session_id, aaa->sessionId->data, "cb_passed_rx_session_id");
178 178
             LM_DBG("passed rx session id [%.*s]", passed_rx_session_id->len, passed_rx_session_id->s);
179
-
180
-            dlgb.register_dlgcb_nodlg(&data->callid, &data->ftag, &data->ttag, DLGCB_TERMINATED | DLGCB_DESTROY | DLGCB_EXPIRED | DLGCB_RESPONSE_WITHIN | DLGCB_CONFIRMED | DLGCB_FAILED, callback_dialog, (void*) (passed_rx_session_id), free_dialog_data);
179
+            dlgb.register_dlgcb_nodlg( data->dlg, DLGCB_TERMINATED | DLGCB_DESTROY | DLGCB_EXPIRED | DLGCB_RESPONSE_WITHIN | DLGCB_CONFIRMED | DLGCB_FAILED, callback_dialog, (void*) (passed_rx_session_id), free_dialog_data);
181 180
         }
182 181
         result = CSCF_RETURN_TRUE;
183 182
     } else {
Browse code

ims_qos: use extern in header files not to redeclare variables

Daniel-Constantin Mierla authored on 04/03/2020 07:28:30
Showing 1 changed files
... ...
@@ -71,7 +71,7 @@
71 71
 #define macro_name(_rc)	#_rc
72 72
 
73 73
 //extern struct tm_binds tmb;
74
-usrloc_api_t ul;
74
+extern usrloc_api_t ul;
75 75
 
76 76
 extern struct ims_qos_counters_h ims_qos_cnts_h;
77 77
 
Browse code

ims_qos: Rename module interface file #82

Victor Seva authored on 13/02/2017 14:35:55
Showing 1 changed files
... ...
@@ -62,7 +62,7 @@
62 62
 
63 63
 #include "../../lib/ims/ims_getters.h"
64 64
 
65
-#include "mod.h"
65
+#include "ims_qos_mod.h"
66 66
 
67 67
 #include "../../lib/ims/useful_defs.h"
68 68
 #include "ims_qos_stats.h"
Browse code

ims_qos: Safety check on length of ports

Carsten Bock authored on 02/02/2017 07:22:05
Showing 1 changed files
... ...
@@ -1004,14 +1004,14 @@ int rx_send_aar_register(struct sip_msg *msg, AAASession* auth, saved_transactio
1004 1004
     raw_stream.s = 0;
1005 1005
     raw_stream.len = 0;
1006 1006
 
1007
-    char c_port_from[5];
1007
+    char c_port_from[10];
1008 1008
     str port_from;
1009
-    port_from.len = sprintf(c_port_from, "%u", saved_t_data->via_port);
1009
+    port_from.len = snprintf(c_port_from, 10, "%u", saved_t_data->via_port);
1010 1010
     port_from.s = c_port_from;
1011 1011
 
1012
-    char c_port_to[5];
1012
+    char c_port_to[10];
1013 1013
     str port_to;
1014
-    port_to.len = sprintf(c_port_to, "%u", saved_t_data->recv_port);
1014
+    port_to.len = snprintf(c_port_to, 10, "%u", saved_t_data->recv_port);
1015 1015
     port_to.s = c_port_to;
1016 1016
 
1017 1017
     str protocol;
Browse code

cdp_avp: Rename module interface file #82

Victor Seva authored on 05/01/2017 12:03:55
Showing 1 changed files
... ...
@@ -50,7 +50,7 @@
50 50
 
51 51
 #include "../../core/mem/shm_mem.h"
52 52
 #include "../../core/parser/sdp/sdp.h"
53
-#include "../cdp_avp/mod_export.h"
53
+#include "../cdp_avp/cdp_avp_mod.h"
54 54
 
55 55
 #include "../../modules/ims_dialog/dlg_load.h"
56 56
 #include "../../modules/tm/tm_load.h"
Browse code

core, lib, modules: updated include paths for header files

Daniel-Constantin Mierla authored on 07/12/2016 11:07:22
Showing 1 changed files
... ...
@@ -48,8 +48,8 @@
48 48
  *  2011-02-02  initial version (jason.penton)
49 49
  */
50 50
 
51
-#include "../../mem/shm_mem.h"
52
-#include "../../parser/sdp/sdp.h"
51
+#include "../../core/mem/shm_mem.h"
52
+#include "../../core/parser/sdp/sdp.h"
53 53
 #include "../cdp_avp/mod_export.h"
54 54
 
55 55
 #include "../../modules/ims_dialog/dlg_load.h"
Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,1124 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com
5
+ * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com
6
+ *
7
+ * The initial version of this code was written by Dragos Vingarzan
8
+ * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
9
+ * Fruanhofer Institute. It was and still is maintained in a separate
10
+ * branch of the original SER. We are therefore migrating it to
11
+ * Kamailio/SR and look forward to maintaining it from here on out.
12
+ * 2011/2012 Smile Communications, Pty. Ltd.
13
+ * ported/maintained/improved by
14
+ * Jason Penton (jason(dot)penton(at)smilecoms.com and
15
+ * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
16
+ * effort to add full IMS support to Kamailio/SR using a new and
17
+ * improved architecture
18
+ *
19
+ * NB: Alot of this code was originally part of OpenIMSCore,
20
+ * FhG Fokus.
21
+ * Copyright (C) 2004-2006 FhG Fokus
22
+ * Thanks for great work! This is an effort to
23
+ * break apart the various CSCF functions into logically separate
24
+ * components. We hope this will drive wider use. We also feel
25
+ * that in this way the architecture is more complete and thereby easier
26
+ * to manage in the Kamailio/SR environment
27
+ *
28
+ * This file is part of Kamailio, a free SIP server.
29
+ *
30
+ * Kamailio is free software; you can redistribute it and/or modify
31
+ * it under the terms of the GNU General Public License as published by
32
+ * the Free Software Foundation; either version 2 of the License, or
33
+ * (at your option) any later version
34
+ *
35
+ * Kamailio is distributed in the hope that it will be useful,
36
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38
+ * GNU General Public License for more details.
39
+ *
40
+ * You should have received a copy of the GNU General Public License
41
+ * along with this program; if not, write to the Free Software
42
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
43
+ *
44
+ *
45
+ *
46
+ * History:
47
+ * --------
48
+ *  2011-02-02  initial version (jason.penton)
49
+ */
50
+
51
+#include "../../mem/shm_mem.h"
52
+#include "../../parser/sdp/sdp.h"
53
+#include "../cdp_avp/mod_export.h"
54
+
55
+#include "../../modules/ims_dialog/dlg_load.h"
56
+#include "../../modules/tm/tm_load.h"
57
+#include "../ims_usrloc_pcscf/usrloc.h"
58
+#include "rx_authdata.h"
59
+
60
+#include "rx_aar.h"
61
+#include "rx_avp.h"
62
+
63
+#include "../../lib/ims/ims_getters.h"
64
+
65
+#include "mod.h"
66
+
67
+#include "../../lib/ims/useful_defs.h"
68
+#include "ims_qos_stats.h"
69
+
70
+
71
+#define macro_name(_rc)	#_rc
72
+
73
+//extern struct tm_binds tmb;
74
+usrloc_api_t ul;
75
+
76
+extern struct ims_qos_counters_h ims_qos_cnts_h;
77
+
78
+extern int authorize_video_flow;
79
+
80
+extern str af_signaling_ip;
81
+
82
+str IMS_Serv_AVP_val = {"IMS Services", 12};
83
+str IMS_Em_Serv_AVP_val = {"Emergency IMS Call", 18};
84
+str IMS_Reg_AVP_val = {"IMS Registration", 16};
85
+
86
+static void free_dialog_data(void *data) {
87
+    str *rx_session_id = (str*) data;
88
+    if (rx_session_id) {
89
+        if (rx_session_id->s) {
90
+            shm_free(rx_session_id->s);
91
+            rx_session_id->s = 0;
92
+        }
93
+        shm_free(rx_session_id);
94
+        rx_session_id = 0;
95
+    }
96
+
97
+}
98
+
99
+void async_aar_callback(int is_timeout, void *param, AAAMessage *aaa, long elapsed_msecs) {
100
+    struct cell *t = 0;
101
+    unsigned int cdp_result;
102
+    int result = CSCF_RETURN_ERROR;
103
+    rx_authsessiondata_t* p_session_data = 0;
104
+    AAASession *auth = 0;
105
+
106
+    LM_DBG("Received AAR callback\n");
107
+    saved_transaction_t* data = (saved_transaction_t*) param;
108
+
109
+    LM_DBG("received AAA answer");
110
+
111
+    if (tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) {
112
+        LM_ERR("t_continue: transaction not found\n");
113
+        goto error;
114
+    } else {
115
+        LM_DBG("t_continue: transaction found\n");
116
+    }
117
+    //we have T, lets restore our state (esp. for AVPs)
118
+    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from);
119
+    set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to);
120
+    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from);
121
+    set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to);
122
+    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from);
123
+    set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to);
124
+
125
+    if (is_timeout != 0) {
126
+        LM_ERR("Error timeout when sending AAR message via CDP\n");
127
+        counter_inc(ims_qos_cnts_h.media_aar_timeouts);
128
+        goto error;
129
+    }
130
+    if (!aaa) {
131
+        LM_ERR("Error sending message via CDP\n");
132
+        goto error;
133
+    }
134
+
135
+    counter_inc(ims_qos_cnts_h.media_aars);
136
+    counter_add(ims_qos_cnts_h.media_aar_response_time, elapsed_msecs);
137
+    counter_inc(ims_qos_cnts_h.media_aar_replies_received);
138
+
139
+    /* Process the response to AAR, retrieving result code and associated Rx session ID */
140
+    if (rx_process_aaa(aaa, &cdp_result) < 0) {
141
+        LM_ERR("Failed to process AAA from PCRF\n"); //puri.host.len, puri.host.s);
142
+        goto error;
143
+    }
144
+
145
+    if (cdp_result >= 2000 && cdp_result < 3000) {
146
+        LM_DBG("Success, received code: [%i] from PCRF for AAR request\n", cdp_result);
147
+        counter_inc(ims_qos_cnts_h.successful_media_aars);
148
+
149
+        LM_DBG("Auth session ID [%.*s]", aaa->sessionId->data.len, aaa->sessionId->data.s);
150
+
151
+	if(!data->aar_update) {
152
+            LM_DBG("This is an AAA response to an initial AAR");
153
+            //need to set Rx auth data to say this session has been successfully opened
154
+            //This is used elsewhere to prevent acting on termination events when the session has not been opened
155
+            //getting auth session
156
+            auth = cdpb.AAAGetAuthSession(aaa->sessionId->data);
157
+            if (!auth) {
158
+                LM_DBG("Could not get Auth Session for session id: [%.*s]\n", aaa->sessionId->data.len, aaa->sessionId->data.s);
159
+                goto error;
160
+            }
161
+            //getting session data
162
+            p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
163
+            if (!p_session_data) {
164
+                LM_DBG("Could not get session data on Auth Session for session id: [%.*s]\n", aaa->sessionId->data.len, aaa->sessionId->data.s);
165
+                if (auth) cdpb.AAASessionsUnlock(auth->hash);
166
+                goto error;
167
+            }
168
+            p_session_data->session_has_been_opened = 1;
169
+            counter_inc(ims_qos_cnts_h.active_media_rx_sessions);
170
+			counter_inc(ims_qos_cnts_h.media_rx_sessions);
171
+
172
+            if (auth) cdpb.AAASessionsUnlock(auth->hash);
173
+
174
+            str * passed_rx_session_id = shm_malloc(sizeof (struct _str));
175
+            passed_rx_session_id->s = 0;
176
+            passed_rx_session_id->len = 0;
177
+            STR_SHM_DUP(*passed_rx_session_id, aaa->sessionId->data, "cb_passed_rx_session_id");
178
+            LM_DBG("passed rx session id [%.*s]", passed_rx_session_id->len, passed_rx_session_id->s);
179
+
180
+            dlgb.register_dlgcb_nodlg(&data->callid, &data->ftag, &data->ttag, DLGCB_TERMINATED | DLGCB_DESTROY | DLGCB_EXPIRED | DLGCB_RESPONSE_WITHIN | DLGCB_CONFIRMED | DLGCB_FAILED, callback_dialog, (void*) (passed_rx_session_id), free_dialog_data);
181
+        }
182
+        result = CSCF_RETURN_TRUE;
183
+    } else {
184
+        LM_DBG("Received negative reply from PCRF for AAR Request\n");
185
+        counter_inc(ims_qos_cnts_h.failed_media_aars);
186
+        //we don't free rx_authdata_p here - it is free-ed when the CDP session expires
187
+        goto error; // if its not a success then that means i want to reject this call!
188
+    }
189
+
190
+    //set success response code AVP
191
+    create_return_code(result);
192
+    goto done;
193
+
194
+out_of_memory:
195
+    error :
196
+            //set failure response code
197
+            create_return_code(result);
198
+
199
+done:
200
+    if (t) tmb.unref_cell(t);
201
+    //free memory
202
+    if (aaa)
203
+        cdpb.AAAFreeMessage(&aaa);
204
+
205
+    tmb.t_continue(data->tindex, data->tlabel, data->act);
206
+    free_saved_transaction_global_data(data);
207
+}
208
+
209
+void async_aar_reg_callback(int is_timeout, void *param, AAAMessage *aaa, long elapsed_msecs) {
210
+    struct cell *t = 0;
211
+    pcontact_t* pcontact;
212
+    unsigned int cdp_result;
213
+    struct pcontact_info ci;
214
+    udomain_t* domain_t;
215
+    int finalReply = 0;
216
+    AAASession *auth = 0;
217
+    rx_authsessiondata_t* p_session_data = 0;
218
+    int result = CSCF_RETURN_ERROR;
219
+    pcontact_info_t contact_info;
220
+
221
+    LM_DBG("Received AAR callback\n");
222
+    saved_transaction_local_t* local_data = (saved_transaction_local_t*) param;
223
+    saved_transaction_t* data = local_data->global_data;
224
+    domain_t = data->domain;
225
+
226
+    int is_rereg = local_data->is_rereg;
227
+
228
+    //before we do anything else, lets decrement the reference counter on replies
229
+    lock_get(data->lock);
230
+    data->answers_not_received--;
231
+    if (data->answers_not_received <= 0) {
232
+        finalReply = 1;
233
+    }
234
+    if (data->ignore_replies) { //there was obv. a subsequent error AFTER we had sent one/more AAR's - so we can ignore these replies and just free memory
235
+        free_saved_transaction_data(local_data);
236
+        if (finalReply) {
237
+            free_saved_transaction_global_data(data);
238
+        }
239
+        return;
240
+    }
241
+    lock_release(data->lock);
242
+
243
+    LM_DBG("received answer and we are waiting for [%d] answers so far failures flag is [%d]\n", data->answers_not_received, data->failed);
244
+
245
+    if (tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) {
246
+        LM_ERR("t_continue: transaction not found\n");
247
+        goto error;
248
+    }
249
+    //we have T, lets restore our state (esp. for AVPs)
250
+    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from);
251
+    set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to);
252
+    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from);
253
+    set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to);
254
+    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from);
255
+    set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to);
256
+
257
+    if (is_timeout != 0) {
258
+        LM_ERR("Error timeout when sending AAR message via CDP\n");
259
+        counter_inc(ims_qos_cnts_h.registration_aar_timeouts);
260
+        goto error;
261
+    }
262
+    if (!aaa) {
263
+        LM_ERR("Error sending message via CDP\n");
264
+        goto error;
265
+    }
266
+
267
+    counter_inc(ims_qos_cnts_h.registration_aars);
268
+    counter_add(ims_qos_cnts_h.registration_aar_response_time, elapsed_msecs);
269
+    counter_inc(ims_qos_cnts_h.registration_aar_replies_received);
270
+
271
+    /* Process the response to AAR, retrieving result code and associated Rx session ID */
272
+    if (rx_process_aaa(aaa, &cdp_result) < 0) {
273
+        LM_ERR("Failed to process AAA from PCRF\n"); //puri.host.len, puri.host.s);
274
+        goto error;
275
+    }
276
+
277
+    if (cdp_result >= 2000 && cdp_result < 3000) {
278
+        counter_inc(ims_qos_cnts_h.successful_registration_aars);
279
+        if (is_rereg) {
280
+            LM_DBG("this is a re-registration, therefore we don't need to do anything except know that the the subscription was successful\n");
281
+            result = CSCF_RETURN_TRUE;
282
+            create_return_code(result);
283
+            goto done;
284
+        }
285
+        //need to set Rx auth data to say this session has been successfully opened
286
+        //This is used elsewhere to prevent acting on termination events when the session has not been opened
287
+        //getting auth session
288
+        auth = cdpb.AAAGetAuthSession(aaa->sessionId->data);
289
+        if (!auth) {
290
+            LM_DBG("Could not get Auth Session for session id: [%.*s]\n", aaa->sessionId->data.len, aaa->sessionId->data.s);
291
+            goto error;
292
+        }
293
+        //getting session data
294
+        p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
295
+        if (!p_session_data) {
296
+            LM_DBG("Could not get session data on Auth Session for session id: [%.*s]\n", aaa->sessionId->data.len, aaa->sessionId->data.s);
297
+            if (auth) cdpb.AAASessionsUnlock(auth->hash);
298
+            goto error;
299
+        }
300
+        p_session_data->session_has_been_opened = 1;
301
+        counter_inc(ims_qos_cnts_h.active_registration_rx_sessions);
302
+
303
+        if (auth) cdpb.AAASessionsUnlock(auth->hash);
304
+
305
+
306
+        LM_DBG("Success, received code: [%i] from PCRF for AAR request (contact: [%.*s]), (auth session id: %.*s)\n",
307
+                cdp_result, local_data->contact.len, local_data->contact.s,
308
+                local_data->auth_session_id.len, local_data->auth_session_id.s);
309
+        LM_DBG("Registering for Usrloc callbacks on DELETE\n");
310
+
311
+        ul.lock_udomain(domain_t, &local_data->via_host, local_data->via_port, local_data->via_proto);
312
+		memset(&contact_info, 0, sizeof(struct pcontact_info));
313
+        contact_info.received_host = local_data->recv_host;
314
+        contact_info.received_port = local_data->recv_port;
315
+        contact_info.received_proto = local_data->recv_proto;
316
+        contact_info.searchflag = (1 << SEARCH_RECEIVED);
317
+
318
+
319
+        contact_info.aor = local_data->contact;
320
+        contact_info.via_host = local_data->via_host;
321
+        contact_info.via_port = local_data->via_port;
322
+        contact_info.via_prot = local_data->via_proto;
323
+        contact_info.reg_state = PCONTACT_ANY;
324
+
325
+        if (ul.get_pcontact(domain_t, &contact_info, &pcontact) != 0) {
326
+            LM_ERR("Shouldn't get here, can't find contact....\n");
327
+            ul.unlock_udomain(domain_t, &local_data->via_host, local_data->via_port, local_data->via_proto);
328
+            goto error;
329
+        }
330
+
331
+        //at this point we have the contact
332
+        /*set the contact state to say we have succesfully done ARR for register and that we dont need to do it again
333
+         * for the duration of the registration.
334
+         * */
335
+        if (ul.update_rx_regsession(domain_t, &local_data->auth_session_id, pcontact) != 0) {
336
+            LM_ERR("unable to update pcontact......\n");
337
+            ul.unlock_udomain(domain_t, &local_data->via_host, local_data->via_port, local_data->via_proto);
338
+            goto error;
339
+        }
340
+        memset(&ci, 0, sizeof (struct pcontact_info));
341
+        ci.reg_state = PCONTACT_REG_PENDING_AAR;
342
+        ci.num_service_routes = 0;
343
+        ci.num_public_ids = 0;
344
+        LM_DBG("impu: [%.*s] updating status to PCONTACT_REG_PENDING\n", pcontact->aor.len, pcontact->aor.s);
345
+        ul.update_pcontact(domain_t, &ci, pcontact);
346
+        //register for callbacks on contact
347
+        ul.register_ulcb(pcontact, PCSCF_CONTACT_DELETE | PCSCF_CONTACT_EXPIRE,
348
+                callback_pcscf_contact_cb, NULL);
349
+        ul.unlock_udomain(domain_t, &local_data->via_host, local_data->via_port, local_data->via_proto);
350
+        result = CSCF_RETURN_TRUE;
351
+    } else {
352
+        LM_DBG("Received negative reply from PCRF for AAR Request\n");
353
+        counter_inc(ims_qos_cnts_h.failed_registration_aars);
354
+        result = CSCF_RETURN_FALSE;
355
+        goto error;
356
+    }
357
+
358
+    //set success response code AVP
359
+    create_return_code(result);
360
+    goto done;
361
+
362
+error:
363
+    //set failure response code
364
+    create_return_code(result);
365
+
366
+done:
367
+    if (t) tmb.unref_cell(t);
368
+    //free memory
369
+    if (aaa)
370
+        cdpb.AAAFreeMessage(&aaa);
371
+
372
+    if (finalReply) {
373
+        tmb.t_continue(data->tindex, data->tlabel, data->act);
374
+        free_saved_transaction_global_data(data);
375
+    }
376
+    free_saved_transaction_data(local_data);
377
+}
378
+
379
+/* handle an AAA response to an AAR for resource reservation for a successful registration or initiated/updated dialog
380
+ * @param aaa - the diameter reply
381
+ * @return -  1 if result code found and processing ok, -1 if error
382
+ */
383
+int rx_process_aaa(AAAMessage *aaa, unsigned int * rc) {
384
+    int ret = 1;
385
+
386
+    ret = rx_get_result_code(aaa, rc);
387
+
388
+    if (ret == 0) {
389
+        LM_DBG("AAA message without result code\n");
390
+        return ret;
391
+    }
392
+
393
+    return ret;
394
+}
395
+
396
+/** Helper function for adding media component AVPs - uses previously stored flow descriptions not SDP from messages*/
397
+int add_media_components_using_current_flow_description(AAAMessage* aar, rx_authsessiondata_t *p_session_data) {
398
+
399
+    flow_description_t *flow_description;
400
+    int add_flow = 1;
401
+
402
+    flow_description = p_session_data->first_current_flow_description;
403
+    if(!flow_description) {
404
+        return -1;
405
+    }
406
+    while (flow_description) {
407
+
408
+	if(!authorize_video_flow) {
409
+            if (strncmp(flow_description->media.s, "video", 5) == 0) {
410
+                add_flow = 0;
411
+            }
412
+        }
413
+
414
+	if(add_flow) {
415
+            rx_add_media_component_description_avp(aar, flow_description->stream_num,
416
+                    &flow_description->media, &flow_description->req_sdp_ip_addr,
417
+                    &flow_description->req_sdp_port, &flow_description->rpl_sdp_ip_addr,
418
+                    &flow_description->rpl_sdp_port, &flow_description->rpl_sdp_transport,
419
+                    &flow_description->req_sdp_raw_stream,
420
+                    &flow_description->rpl_sdp_raw_stream, flow_description->direction, AVP_EPC_Flow_Usage_No_Information);
421
+        }
422
+
423
+        flow_description = flow_description->next;
424
+        add_flow = 1;
425
+    }
426
+    return 0;
427
+}
428
+
429
+
430
+
431
+/** Helper function for adding media component AVPs for each SDP stream*/
432
+int add_media_components(AAAMessage* aar, struct sip_msg *req,
433
+        struct sip_msg *rpl, enum dialog_direction direction, AAASession* auth) {
434
+    int sdp_session_num;
435
+    int sdp_stream_num;
436
+    sdp_session_cell_t* req_sdp_session, *rpl_sdp_session;
437
+    sdp_stream_cell_t* req_sdp_stream, *rpl_sdp_stream;
438
+    int add_flow = 1;
439
+	str ttag = {0, 0};
440
+	str ftag = {0, 0};
441
+	int request_originated_from_callee = 0;  
442
+	str ipA, ipB, portA, portB;
443
+	
444
+	rx_authsessiondata_t* p_session_data = 0;
445
+    p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
446
+	
447
+	if (!req || !rpl) {
448
+			goto error;
449
+    }
450
+
451
+    if (parse_sdp(req) < 0) {
452
+        LM_ERR("Unable to parse req SDP\n");
453
+        goto error;
454
+    }
455
+
456
+    if (parse_sdp(rpl) < 0) {
457
+        LM_ERR("Unable to parse res SDP\n");
458
+        goto error;
459
+    }
460
+
461
+    sdp_session_num = 0;
462
+
463
+    //Loop through req sessions and streams and get corresponding rpl sessions and streams and populate avps
464
+    for (;;) {
465
+        //we only cater for one session at the moment: TDOD: extend
466
+        if (sdp_session_num > 0) {
467
+            break;
468
+        }
469
+
470
+        req_sdp_session = get_sdp_session(req, sdp_session_num);
471
+        rpl_sdp_session = get_sdp_session(rpl, sdp_session_num);
472
+        if (!req_sdp_session || !rpl_sdp_session) {
473
+            if (!req_sdp_session)
474
+                LM_ERR("Missing SDP session information from req\n");
475
+
476
+            if (!rpl_sdp_session)
477
+                LM_ERR("Missing SDP session information from rpl\n");
478
+
479
+			goto error;
480
+        }
481
+
482
+        sdp_stream_num = 0;
483
+        for (;;) {
484
+            req_sdp_stream = get_sdp_stream(req, sdp_session_num,
485
+                    sdp_stream_num);
486
+            rpl_sdp_stream = get_sdp_stream(rpl, sdp_session_num,
487
+                    sdp_stream_num);
488
+            if (!req_sdp_stream || !rpl_sdp_stream) {
489
+                //LM_ERR("Missing SDP stream information\n");
490
+                break;
491
+            }
492
+            //is this a stream to add to AAR.
493
+            if (req_sdp_stream->is_rtp) {
494
+
495
+                //check if the src or dst port is 0 and if so then don't add to rx
496
+                int intportA = atoi(req_sdp_stream->port.s);
497
+                int intportB = atoi(rpl_sdp_stream->port.s);
498
+		if(intportA != 0 && intportB != 0){
499
+			if(!authorize_video_flow) {
500
+                        if (strncmp(req_sdp_stream->media.s, "video", 5) == 0) {
501
+                            add_flow = 0;
502
+                        }
503
+                    }
504
+
505
+			if(add_flow) {
506
+
507
+					
508
+						if (cscf_get_to_tag(rpl, &ttag) && cscf_get_from_tag(rpl, &ftag)) {
509
+								LM_DBG("Original ftag [%.*s] ttag [%.*s].  Current ftag [%.*s] ttag [%.*s]\n", 
510
+										p_session_data->ftag.len, p_session_data->ftag.s, p_session_data->ttag.len, p_session_data->ttag.s,
511
+										ftag.len, ftag.s, ttag.len, ttag.s);
512
+							if (!(strncmp(p_session_data->ttag.s, ttag.s, p_session_data->ttag.len) == 0 && strncmp(p_session_data->ftag.s, ftag.s, p_session_data->ftag.len) == 0)) {
513
+								LM_DBG("ftag and ttag of this response do not match initial response so this request came from callee\n");
514
+								request_originated_from_callee = 1;
515
+							}
516
+						} else {
517
+							LM_ERR("Couldn't retrieve ftag so assume this request originated from caller\n");
518
+						}
519
+					
520
+						if (request_originated_from_callee) {
521
+							LM_DBG("Request originated from callee so IPs are reversed\n");	
522
+							ipA = rpl_sdp_session->ip_addr;
523
+							portA = rpl_sdp_stream->port;
524
+							
525
+							ipB = req_sdp_session->ip_addr;
526
+							portB = req_sdp_stream->port;
527
+						} else {
528
+							ipA = req_sdp_session->ip_addr;
529
+							portA = req_sdp_stream->port;
530
+							
531
+							
532
+							ipB = rpl_sdp_session->ip_addr;
533
+							portB = rpl_sdp_stream->port;
534
+						}
535
+						
536
+
537
+						if (ipA.len <= 0) {
538
+								LM_DBG("Request SDP connection IP could not be retrieved, so we use SDP 1st stream IP\n");
539
+								if (request_originated_from_callee) {
540
+									LM_DBG("Request originated from callee so IPs are reversed\n");	
541
+									ipA = rpl_sdp_stream->ip_addr;
542
+									portA = rpl_sdp_stream->port;
543
+								} else {
544
+									ipA = req_sdp_stream->ip_addr;
545
+									portA = req_sdp_stream->port;
546
+								}
547
+								
548
+								
549
+								if (ipA.len <= 0) {
550
+										LM_ERR("Requested SDP IP information could not be retrieved\n");
551
+										goto error;
552
+								}
553
+						}
554
+
555
+						if (ipB.len <= 0) {
556
+								LM_DBG("Reply SDP connection IP could not be retrieved, so we use SDP 1st stream IP\n");
557
+								if (request_originated_from_callee) {
558
+									LM_DBG("Request originated from callee so IPs are reversed\n");	
559
+									ipB = req_sdp_stream->ip_addr;
560
+									portB = req_sdp_stream->port;
561
+								} else {
562
+									ipB = rpl_sdp_stream->ip_addr;
563
+									portB = rpl_sdp_stream->port;
564
+								}
565
+								
566
+								
567
+								if (ipB.len <= 0) {
568
+										LM_ERR("Request SDP IP information could not be retrieved\n");
569
+										goto error;
570
+								}
571
+						}
572
+
573
+						//add this to auth session data
574
+                        add_flow_description((rx_authsessiondata_t*) auth->u.auth.generic_data, sdp_stream_num + 1,
575
+                                &req_sdp_stream->media, &ipA,
576
+                                &portA, &ipB,
577
+                                &portB, &rpl_sdp_stream->transport,
578
+                                &req_sdp_stream->raw_stream,
579
+                                &rpl_sdp_stream->raw_stream, direction, 0 /*This is a new mcd, we are not setting it as active*/);
580
+
581
+                        rx_add_media_component_description_avp(aar, sdp_stream_num + 1,
582
+                                &req_sdp_stream->media, &ipA,
583
+                                &portA, &ipB,
584
+                                &portB, &rpl_sdp_stream->transport,
585
+                                &req_sdp_stream->raw_stream,
586
+                                &rpl_sdp_stream->raw_stream, direction, AVP_EPC_Flow_Usage_No_Information);
587
+                    }
588
+                    add_flow = 1;
589
+                }
590
+            }
591
+            sdp_stream_num++;
592
+        }
593
+        sdp_session_num++;
594
+    }
595
+
596
+    free_sdp((sdp_info_t**) (void*) &req->body);
597
+    free_sdp((sdp_info_t**) (void*) &rpl->body);
598
+
599
+	return 1;
600
+
601
+	error:
602
+
603
+    return 0;
604
+}
605
+
606
+/**
607
+ * Sends the Authorization Authentication Request - specifically this is an asynchronous AAR sent if another update adding video has failed so we need to remove video
608
+ */
609
+
610
+int rx_send_aar_update_no_video(AAASession* auth) {
611
+
612
+    AAAMessage* aar = 0;
613
+
614
+    str identifier;
615
+    int identifier_type;
616
+
617
+
618
+    AAA_AVP* avp = 0;
619
+    char x[4];
620
+    int ret = 0;
621
+
622
+    str recv_ip;
623
+    uint16_t ip_version;
624
+
625
+    //we get ip and identifier for the auth session data
626
+    rx_authsessiondata_t* p_session_data = 0;
627
+    p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
628
+    identifier = p_session_data->identifier;
629
+    identifier_type = p_session_data->identifier_type;
630
+    recv_ip = p_session_data->ip;
631
+    ip_version = p_session_data->ip_version;
632
+
633
+    aar = cdpb.AAACreateRequest(IMS_Rx, IMS_AAR, Flag_Proxyable, auth);
634
+
635
+    LM_DBG("Sending AAR update to remove a video bearer\n");
636
+    show_callsessiondata(p_session_data);
637
+
638
+    if (!aar)
639
+        goto error;
640
+
641
+    /*Adding AVPs*/
642
+
643
+    LM_DBG("Adding auth app id AVP...\n");
644
+    /* Add Auth-Application-Id AVP */
645
+    if (!rx_add_auth_application_id_avp(aar, IMS_Rx))
646
+        goto error;
647
+    if (!rx_add_vendor_specific_application_id_group(aar, IMS_vendor_id_3GPP,
648
+            IMS_Rx))
649
+        goto error;
650
+
651
+    LM_DBG("Adding dest realm if not there already...\n");
652
+    /* Add Destination-Realm AVP, if not already there */
653
+    avp = cdpb.AAAFindMatchingAVP(aar, aar->avpList.head, AVP_Destination_Realm,
654
+            0, AAA_FORWARD_SEARCH);
655
+    if (!avp) {
656
+        str realm = rx_dest_realm;
657
+        if (realm.len && !rx_add_destination_realm_avp(aar, realm))
658
+            goto error;
659
+    }
660
+
661
+    LM_DBG("Adding AF App identifier...\n");
662
+    /* Add AF-Application-Identifier AVP */
663
+    str af_id = {0, 0};
664
+    af_id = IMS_Serv_AVP_val;
665
+    if (!rx_add_avp(aar, af_id.s, af_id.len, AVP_IMS_AF_Application_Identifier,
666
+            AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
667
+            __FUNCTION__))
668
+        goto error;
669
+
670
+    LM_DBG("Adding service info status...\n");
671
+    /* Add Service-Info-Status AVP, if prelimiary
672
+     * by default(when absent): final status is considered*/
673
+
674
+    set_4bytes(x,
675
+            AVP_EPC_Service_Info_Status_Preliminary_Service_Information);
676
+    if (!rx_add_avp(aar, x, 4, AVP_IMS_Service_Info_Status,
677
+            AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
678
+            __FUNCTION__))
679
+        goto error;
680
+
681
+    /* Add Auth lifetime AVP */LM_DBG("auth_lifetime %u\n", rx_auth_expiry); //TODO check why this is 0 all the time
682
+    if (rx_auth_expiry) {
683
+        set_4bytes(x, rx_auth_expiry);
684
+        if (!rx_add_avp(aar, x, 4, AVP_Authorization_Lifetime,
685
+                AAA_AVP_FLAG_MANDATORY, 0, AVP_DUPLICATE_DATA, __FUNCTION__))
686
+            goto error;
687
+    }
688
+
689
+    LM_DBG("Adding subscription id...\n");
690
+
691
+    rx_add_subscription_id_avp(aar, identifier, identifier_type);
692
+
693
+
694
+    LM_DBG("Adding reservation priority...\n");
695
+    /* Add Reservation Priority AVP*/
696
+    set_4bytes(x, 0);
697
+    if (!rx_add_avp(aar, x, 4, AVP_ETSI_Reservation_Priority,
698
+            AAA_AVP_FLAG_VENDOR_SPECIFIC, IMS_vendor_id_ETSI,
699
+            AVP_DUPLICATE_DATA, __FUNCTION__))
700
+        goto error;
701
+
702
+    LM_DBG("Adding media component...\n");
703
+    //Note we add this AVP first as it gets the IP address which we need to create the auth session
704
+    //Could and maybe should have a separate method that retrieves the IP from SDP - TODO
705
+
706