|
@@ -135,14 +135,17 @@ void async_aar_callback(int is_timeout, void *param, AAAMessage *aaa, long elaps
|
|
|
LM_DBG("Success, received code: [%i] from PCRF for AAR request\n", cdp_result);
|
|
|
|
|
|
LM_DBG("Auth session ID [%.*s]", aaa->sessionId->data.len, aaa->sessionId->data.s);
|
|
|
-
|
|
|
- str * passed_rx_session_id = shm_malloc(sizeof (struct _str));
|
|
|
- passed_rx_session_id->s = 0;
|
|
|
- passed_rx_session_id->len = 0;
|
|
|
- STR_SHM_DUP(*passed_rx_session_id, aaa->sessionId->data, "cb_passed_rx_session_id");
|
|
|
- LM_DBG("passed rx session id [%.*s]", passed_rx_session_id->len, passed_rx_session_id->s);
|
|
|
-
|
|
|
- dlgb.register_dlgcb_nodlg(&data->callid, &data->ftag, &data->ttag, DLGCB_TERMINATED | DLGCB_DESTROY | DLGCB_EXPIRED, callback_dialog_terminated, (void*) (passed_rx_session_id), free_dialog_data);
|
|
|
+
|
|
|
+ if(!data->aar_update) {
|
|
|
+ LM_DBG("This is an AAA response to an initial AAR");
|
|
|
+ str * passed_rx_session_id = shm_malloc(sizeof (struct _str));
|
|
|
+ passed_rx_session_id->s = 0;
|
|
|
+ passed_rx_session_id->len = 0;
|
|
|
+ STR_SHM_DUP(*passed_rx_session_id, aaa->sessionId->data, "cb_passed_rx_session_id");
|
|
|
+ LM_DBG("passed rx session id [%.*s]", passed_rx_session_id->len, passed_rx_session_id->s);
|
|
|
+
|
|
|
+ dlgb.register_dlgcb_nodlg(&data->callid, &data->ftag, &data->ttag, DLGCB_TERMINATED | DLGCB_DESTROY | DLGCB_EXPIRED | DLGCB_RESPONSE_WITHIN | DLGCB_CONFIRMED, callback_dialog, (void*) (passed_rx_session_id), free_dialog_data);
|
|
|
+ }
|
|
|
result = CSCF_RETURN_TRUE;
|
|
|
} else {
|
|
|
LM_DBG("Received negative reply from PCRF for AAR Request\n");
|
|
@@ -316,10 +319,33 @@ int rx_process_aaa(AAAMessage *aaa, unsigned int * rc) {
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+/** Helper function for adding media component AVPs - uses previously stored flow descriptions not SDP from messages*/
|
|
|
+int add_media_components_using_current_flow_description(AAAMessage* aar, rx_authsessiondata_t *p_session_data) {
|
|
|
+
|
|
|
+ flow_description_t *flow_description;
|
|
|
+
|
|
|
+ flow_description = p_session_data->first_current_flow_description;
|
|
|
+ if(!flow_description) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ while (flow_description) {
|
|
|
+ rx_add_media_component_description_avp(aar, flow_description->stream_num,
|
|
|
+ &flow_description->media, &flow_description->req_sdp_ip_addr,
|
|
|
+ &flow_description->req_sdp_port, &flow_description->rpl_sdp_ip_addr,
|
|
|
+ &flow_description->rpl_sdp_port, &flow_description->rpl_sdp_transport,
|
|
|
+ &flow_description->req_sdp_raw_stream,
|
|
|
+ &flow_description->rpl_sdp_raw_stream, flow_description->direction);
|
|
|
+
|
|
|
+ flow_description = flow_description->next;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
/** Helper function for adding media component AVPs for each SDP stream*/
|
|
|
int add_media_components(AAAMessage* aar, struct sip_msg *req,
|
|
|
- struct sip_msg *rpl, enum dialog_direction direction,
|
|
|
- uint16_t *ip_version) {
|
|
|
+ struct sip_msg *rpl, enum dialog_direction direction, AAASession* auth) {
|
|
|
int sdp_session_num;
|
|
|
int sdp_stream_num;
|
|
|
sdp_session_cell_t* req_sdp_session, *rpl_sdp_session;
|
|
@@ -359,13 +385,6 @@ int add_media_components(AAAMessage* aar, struct sip_msg *req,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- //we only populate ip if its not already populated
|
|
|
- if (direction == DLG_MOBILE_ORIGINATING) {
|
|
|
- *ip_version = req_sdp_session->pf;
|
|
|
- } else if (direction == DLG_MOBILE_TERMINATING) {
|
|
|
- *ip_version = rpl_sdp_session->pf;
|
|
|
- }
|
|
|
-
|
|
|
sdp_stream_num = 0;
|
|
|
for (;;) {
|
|
|
req_sdp_stream = get_sdp_stream(req, sdp_session_num,
|
|
@@ -383,7 +402,17 @@ int add_media_components(AAAMessage* aar, struct sip_msg *req,
|
|
|
int intportA = atoi(req_sdp_stream->port.s);
|
|
|
int intportB = atoi(rpl_sdp_stream->port.s);
|
|
|
if(intportA != 0 && intportB != 0){
|
|
|
- rx_add_media_component_description_avp(aar, sdp_stream_num + 1,
|
|
|
+
|
|
|
+ //add this to auth session data
|
|
|
+
|
|
|
+ add_flow_description((rx_authsessiondata_t*) auth->u.auth.generic_data, sdp_stream_num + 1,
|
|
|
+ &req_sdp_stream->media, &req_sdp_session->ip_addr,
|
|
|
+ &req_sdp_stream->port, &rpl_sdp_session->ip_addr,
|
|
|
+ &rpl_sdp_stream->port, &rpl_sdp_stream->transport,
|
|
|
+ &req_sdp_stream->raw_stream,
|
|
|
+ &rpl_sdp_stream->raw_stream, direction, 0 /*This is a new mcd, we are not setting it as active*/);
|
|
|
+
|
|
|
+ rx_add_media_component_description_avp(aar, sdp_stream_num + 1,
|
|
|
&req_sdp_stream->media, &req_sdp_session->ip_addr,
|
|
|
&req_sdp_stream->port, &rpl_sdp_session->ip_addr,
|
|
|
&rpl_sdp_stream->port, &rpl_sdp_stream->transport,
|
|
@@ -402,6 +431,171 @@ int add_media_components(AAAMessage* aar, struct sip_msg *req,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 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
|
|
|
+ */
|
|
|
+
|
|
|
+int rx_send_aar_update_no_video(AAASession* auth) {
|
|
|
+
|
|
|
+ AAAMessage* aar = 0;
|
|
|
+ int must_free_asserted_identity = 0;
|
|
|
+
|
|
|
+ str identifier;
|
|
|
+ int identifier_type;
|
|
|
+
|
|
|
+
|
|
|
+ AAA_AVP* avp = 0;
|
|
|
+ char x[4];
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ str ip;
|
|
|
+ uint16_t ip_version;
|
|
|
+
|
|
|
+ //we get ip and identifier for the auth session data
|
|
|
+ rx_authsessiondata_t* p_session_data = 0;
|
|
|
+ p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
|
|
|
+ identifier = p_session_data->identifier;
|
|
|
+ ip = p_session_data->ip;
|
|
|
+ ip_version = p_session_data->ip_version;
|
|
|
+
|
|
|
+ aar = cdpb.AAACreateRequest(IMS_Rx, IMS_AAR, Flag_Proxyable, auth);
|
|
|
+
|
|
|
+ LM_DBG("Sending AAR update to remove a video bearer\n");
|
|
|
+ show_callsessiondata(p_session_data);
|
|
|
+
|
|
|
+ if (!aar)
|
|
|
+ goto error;
|
|
|
+
|
|
|
+ /*Adding AVPs*/
|
|
|
+
|
|
|
+ LM_DBG("Adding auth app id AVP...\n");
|
|
|
+ /* Add Auth-Application-Id AVP */
|
|
|
+ if (!rx_add_auth_application_id_avp(aar, IMS_Rx))
|
|
|
+ goto error;
|
|
|
+ if (!rx_add_vendor_specific_application_id_group(aar, IMS_vendor_id_3GPP,
|
|
|
+ IMS_Rx))
|
|
|
+ goto error;
|
|
|
+
|
|
|
+ LM_DBG("Adding dest realm if not there already...\n");
|
|
|
+ /* Add Destination-Realm AVP, if not already there */
|
|
|
+ avp = cdpb.AAAFindMatchingAVP(aar, aar->avpList.head, AVP_Destination_Realm,
|
|
|
+ 0, AAA_FORWARD_SEARCH);
|
|
|
+ if (!avp) {
|
|
|
+ str realm = rx_dest_realm;
|
|
|
+ if (realm.len && !rx_add_destination_realm_avp(aar, realm))
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
+ LM_DBG("Adding AF App identifier...\n");
|
|
|
+ /* Add AF-Application-Identifier AVP */
|
|
|
+ str af_id = {0, 0};
|
|
|
+ af_id = IMS_Serv_AVP_val;
|
|
|
+ if (!rx_add_avp(aar, af_id.s, af_id.len, AVP_IMS_AF_Application_Identifier,
|
|
|
+ AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
|
|
|
+ __FUNCTION__))
|
|
|
+ goto error;
|
|
|
+
|
|
|
+ LM_DBG("Adding service info status...\n");
|
|
|
+ /* Add Service-Info-Status AVP, if prelimiary
|
|
|
+ * by default(when absent): final status is considered*/
|
|
|
+
|
|
|
+ set_4bytes(x,
|
|
|
+ AVP_EPC_Service_Info_Status_Preliminary_Service_Information);
|
|
|
+ if (!rx_add_avp(aar, x, 4, AVP_IMS_Service_Info_Status,
|
|
|
+ AAA_AVP_FLAG_MANDATORY, IMS_vendor_id_3GPP, AVP_DUPLICATE_DATA,
|
|
|
+ __FUNCTION__))
|
|
|
+ goto error;
|
|
|
+
|
|
|
+ /* Add Auth lifetime AVP */LM_DBG("auth_lifetime %u\n", rx_auth_expiry); //TODO check why this is 0 all the time
|
|
|
+ if (rx_auth_expiry) {
|
|
|
+ set_4bytes(x, rx_auth_expiry);
|
|
|
+ if (!rx_add_avp(aar, x, 4, AVP_Authorization_Lifetime,
|
|
|
+ AAA_AVP_FLAG_MANDATORY, 0, AVP_DUPLICATE_DATA, __FUNCTION__))
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
+ LM_DBG("Adding subscription id...\n");
|
|
|
+
|
|
|
+ if (strncasecmp(identifier.s,"tel:",4)==0) {
|
|
|
+ identifier_type = AVP_Subscription_Id_Type_E164; //
|
|
|
+ }else{
|
|
|
+ identifier_type = AVP_Subscription_Id_Type_SIP_URI; //default is END_USER_SIP_URI
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ rx_add_subscription_id_avp(aar, identifier, identifier_type);
|
|
|
+ if (must_free_asserted_identity) {
|
|
|
+ pkg_free(identifier.s);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ LM_DBG("Adding reservation priority...\n");
|
|
|
+ /* Add Reservation Priority AVP*/
|
|
|
+ set_4bytes(x, 0);
|
|
|
+ if (!rx_add_avp(aar, x, 4, AVP_ETSI_Reservation_Priority,
|
|
|
+ AAA_AVP_FLAG_VENDOR_SPECIFIC, IMS_vendor_id_ETSI,
|
|
|
+ AVP_DUPLICATE_DATA, __FUNCTION__))
|
|
|
+ goto error;
|
|
|
+
|
|
|
+ LM_DBG("Adding media component...\n");
|
|
|
+ //Note we add this AVP first as it gets the IP address which we need to create the auth session
|
|
|
+ //Could and maybe should have a separate method that retrieves the IP from SDP - TODO
|
|
|
+
|
|
|
+ /*---------- 2. Create and add Media-Component-Description AVP ----------*/
|
|
|
+
|
|
|
+ /*
|
|
|
+ * See 3GPP TS29214
|
|
|
+ *
|
|
|
+ * <Media-Component-Description> = {Media-Component-Number}
|
|
|
+ * [Media-Sub-Component]
|
|
|
+ * [AF-Application-Identifier]
|
|
|
+ * [Media-Type]
|
|
|
+ * [Max-Requested-Bandwidth-UL]
|
|
|
+ * [Max-Requested-Bandwidth-DL]
|
|
|
+ * [Flow-Status]
|
|
|
+ * [Reservation-Priority] (Not used yet)
|
|
|
+ * [RS-Bandwidth]
|
|
|
+ * [RR-Bandwidth]
|
|
|
+ * *[Codec-Data]
|
|
|
+ */
|
|
|
+
|
|
|
+ add_media_components_using_current_flow_description(aar, p_session_data);
|
|
|
+
|
|
|
+ LM_DBG("Adding framed ip address [%.*s]\n", ip.len, ip.s);
|
|
|
+ /* Add Framed IP address AVP*/
|
|
|
+ if (!rx_add_framed_ip_avp(&aar->avpList, ip, ip_version)) {
|
|
|
+ LM_ERR("Unable to add framed IP AVP\n");
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ LM_DBG("Unlocking AAA session...\n");
|
|
|
+
|
|
|
+ if (auth)
|
|
|
+ cdpb.AAASessionsUnlock(auth->hash);
|
|
|
+
|
|
|
+ LM_DBG("sending AAR to PCRF\n");
|
|
|
+ if (rx_forced_peer.len)
|
|
|
+ ret = cdpb.AAASendMessageToPeer(aar, &rx_forced_peer,
|
|
|
+ NULL, NULL);
|
|
|
+ else
|
|
|
+ ret = cdpb.AAASendMessage(aar, NULL,
|
|
|
+ NULL);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+
|
|
|
+error:
|
|
|
+ LM_ERR("unexpected error\n");
|
|
|
+ if (aar)
|
|
|
+ cdpb.AAAFreeMessage(&aar);
|
|
|
+ if (auth) {
|
|
|
+ cdpb.AAASessionsUnlock(auth->hash);
|
|
|
+ cdpb.AAADropAuthSession(auth);
|
|
|
+ auth = 0;
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* Sends the Authorization Authentication Request.
|
|
|
* @param req - SIP request
|
|
@@ -433,6 +627,7 @@ int rx_send_aar(struct sip_msg *req, struct sip_msg *res,
|
|
|
p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
|
|
|
identifier = p_session_data->identifier;
|
|
|
ip = p_session_data->ip;
|
|
|
+ ip_version = p_session_data->ip_version;
|
|
|
|
|
|
/* find direction for AAR (orig/term) */
|
|
|
//need this to add the media component details
|
|
@@ -543,7 +738,7 @@ int rx_send_aar(struct sip_msg *req, struct sip_msg *res,
|
|
|
* *[Codec-Data]
|
|
|
*/
|
|
|
|
|
|
- add_media_components(aar, req, res, dlg_direction, &ip_version);
|
|
|
+ add_media_components(aar, req, res, dlg_direction, auth);
|
|
|
|
|
|
LM_DBG("Adding framed ip address [%.*s]\n", ip.len, ip.s);
|
|
|
/* Add Framed IP address AVP*/
|
|
@@ -551,6 +746,9 @@ int rx_send_aar(struct sip_msg *req, struct sip_msg *res,
|
|
|
LM_ERR("Unable to add framed IP AVP\n");
|
|
|
goto error;
|
|
|
}
|
|
|
+
|
|
|
+ show_callsessiondata(p_session_data);
|
|
|
+
|
|
|
LM_DBG("Unlocking AAA session...\n");
|
|
|
|
|
|
if (auth)
|