Exemple #1
0
/**
 * Process a Push Profile Request and return the Answer for it.
 * @param ppr - the PPR Diameter request
 * @returns the PPA Diameter answer
 */
AAAMessage* Cx_PPA(AAAMessage * ppr)
{
	AAAMessage	*ppa_msg;
	str ppr_data;
	ims_subscription *imss;
	int i,j;
	r_public *pu;
	str ccf1,ccf2,ecf1,ecf2;

	ppa_msg	= cdpb.AAACreateResponse(ppr);
	if (!ppa_msg) return 0;	
	
	if((ppr_data=Cx_get_user_data(ppr)).len != 0){
		LOG(L_INFO,"INFO:"M_NAME":Cx_PPA(): Received a User_Data PPR!\n");
		imss=parse_user_data(ppr_data);
		print_user_data(L_ALERT,imss);
		
		for(i=0;i<imss->service_profiles_cnt;i++)
			for(j=0;j<imss->service_profiles[i].public_identities_cnt;j++){				
				pu = update_r_public(imss->service_profiles[i].public_identities[j].public_identity,
					0,&imss,0,0,0,0);
				if (!pu) continue;
				r_unlock(pu->hash);
			}			
	}
	else{
		if (Cx_get_charging_info(ppr,&ccf1,&ccf2,&ecf1,&ecf2)){
			LOG(L_INFO,"INFO:"M_NAME":Cx_PPA(): Received a Charging Info PPR - NOT IMPLEMENTED\n");
			//TODO find all r_public that should be updated and update
		}
	}	
	Cx_add_vendor_specific_appid(ppa_msg,IMS_vendor_id_3GPP,IMS_Cx,0 /*IMS_Cx*/);
	Cx_add_auth_session_state(ppa_msg,1);		
	
	Cx_add_result_code(ppa_msg,DIAMETER_SUCCESS);
	#ifdef WITH_IMS_PM
		ims_pm_diameter_answer(ppa_msg);
	#endif			
	return ppa_msg;
}
Exemple #2
0
void async_cdp_callback(int is_timeout, void *param, AAAMessage *saa, long elapsed_msecs) {
    struct cell *t = 0;
    int rc = -1, experimental_rc = -1;
    int result = CSCF_RETURN_TRUE;
    saved_transaction_t* data = 0;
    struct sip_msg* req;

    str xml_data = {0, 0}, ccf1 = {0, 0}, ccf2 = {0, 0}, ecf1 = {0, 0}, ecf2 = {0, 0};
    ims_subscription* s = 0;
    rerrno = R_FINE;

    if (!param) {
        LM_DBG("No transaction data this must have been called from usrloc cb impu deleted - just log result code and then exit");
        cxdx_get_result_code(saa, &rc);
        cxdx_get_experimental_result_code(saa, &experimental_rc);

        if (saa) cdpb.AAAFreeMessage(&saa);

        if (!rc && !experimental_rc) {
            LM_ERR("bad SAA result code\n");
            return;
        }
        switch (rc) {
            case -1:
                LM_DBG("Received Diameter error\n");
                return;

            case AAA_UNABLE_TO_COMPLY:
                LM_DBG("Unable to comply\n");
                return;

            case AAA_SUCCESS:
                LM_DBG("received AAA success\n");
                return;

            default:
                LM_ERR("Unknown error\n");
                return;
        }

    } else {
        LM_DBG("There is transaction data this must have been called from save or assign server unreg");
        data = (saved_transaction_t*) param;
        if (tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) {
            LM_ERR("t_continue: transaction not found and t is now pointing to %p and will be set to NULL\n", t);
            t = NULL;
            rerrno = R_SAR_FAILED;
            goto error_no_send;
        }

	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from);
	set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to);
	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from);
	set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to);
	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from);
	set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to);

        get_act_time();

        req = get_request_from_tx(t);
        if (!req) {
            LM_ERR("Failed to get SIP Request from Transaction\n");
            goto error_no_send;
        }
        
        if (is_timeout) {
        	update_stat(stat_sar_timeouts, 1);
            LM_ERR("Transaction timeout - did not get SAA\n");
            rerrno = R_SAR_FAILED;
            goto error;
        }
        if (!saa) {
            LM_ERR("Error sending message via CDP\n");
            rerrno = R_SAR_FAILED;
            goto error;
        }

        update_stat(sar_replies_received, 1);
        update_stat(sar_replies_response_time, elapsed_msecs);

        
        /* check and see that all the required headers are available and can be parsed */
        if (parse_message_for_register(req) < 0) {
            LM_ERR("Unable to parse register message correctly\n");
            rerrno = R_SAR_FAILED;
            goto error;
        }

        cxdx_get_result_code(saa, &rc);
        cxdx_get_experimental_result_code(saa, &experimental_rc);
        cxdx_get_charging_info(saa, &ccf1, &ccf2, &ecf1, &ecf2);

        if (!rc && !experimental_rc) {
            LM_ERR("bad SAA result code\n");
            rerrno = R_SAR_FAILED;
            goto error;
        }

        switch (rc) {
            case -1:
                LM_DBG("Received Diameter error\n");
                rerrno = R_SAR_FAILED;
                goto error;

            case AAA_UNABLE_TO_COMPLY:
                LM_DBG("Unable to comply\n");
                rerrno = R_SAR_FAILED;
                goto error;

            case AAA_SUCCESS:
                LM_DBG("received AAA success for SAR - SAA\n");
                break;

            default:
                LM_ERR("Unknown error\n");
                rerrno = R_SAR_FAILED;
                goto error;
        }
        //success
        //if this is from a save (not a server assign unreg) and expires is zero we don't update usrloc as this is a dereg and usrloc was updated previously
        if (data->sar_assignment_type != AVP_IMS_SAR_UNREGISTERED_USER && data->expires == 0) {
            LM_DBG("no need to update usrloc - already done for de-reg\n");
            result = CSCF_RETURN_TRUE;
            goto success;
        }

        xml_data = cxdx_get_user_data(saa);
        /*If there is XML user data we must be able to parse it*/
        if (xml_data.s && xml_data.len > 0) {
            LM_DBG("Parsing user data string from SAA\n");
            s = parse_user_data(xml_data);
            if (!s) {
                LM_ERR("Unable to parse user data XML string\n");
                rerrno = R_SAR_FAILED;
                goto error;
            }
            LM_DBG("Successfully parse user data XML setting ref to 1 (we are referencing it)\n");
            s->ref_count = 1; //no need to lock as nobody else will be referencing this piece of memory just yet
        } else {
            if (data->require_user_data) {
                LM_ERR("We require User data for this assignment/register and none was supplied\n");
                rerrno = R_SAR_FAILED;
                result = CSCF_RETURN_FALSE;
                goto done;
            }
        }

        if (data->sar_assignment_type == AVP_IMS_SAR_REGISTRATION || data->sar_assignment_type == AVP_IMS_SAR_RE_REGISTRATION) {
            if (s) {
                if (build_p_associated_uri(s) != 0) {
                    LM_ERR("Unable to build p_associated_uri\n");
                    rerrno = R_SAR_FAILED;
                    goto error;
                }
            }

        }

        if (s) {
            //here we update the contacts and also build the new contact header for the 200 OK reply
            if (update_contacts(req, data->domain, &data->public_identity, data->sar_assignment_type, &s, &ccf1, &ccf2, &ecf1, &ecf2, &data->contact_header) <= 0) {
                LM_ERR("Error processing REGISTER\n");
                rerrno = R_SAR_FAILED;
                goto error;
            }
        }
        
        if (data->contact_header) {
            LM_DBG("Updated contacts: %.*s\n", data->contact_header->data_len, data->contact_header->buf);
        } else {
            LM_DBG("Updated unreg contact\n");
        }
        
    }

success:
    update_stat(accepted_registrations, 1);

done:
    if (data->sar_assignment_type != AVP_IMS_SAR_UNREGISTERED_USER)
        reg_send_reply_transactional(req, data->contact_header, t);
    LM_DBG("DBG:SAR Async CDP callback: ... Done resuming transaction\n");

    create_return_code(result);

    //release our reference on subscription (s)
    if (s) 
        ul.unref_subscription(s);
    
    //free memory
    if (saa) cdpb.AAAFreeMessage(&saa);
    if (t) {
//        del_nonshm_lump_rpl(&req->reply_lump);
        tmb.unref_cell(t);
    }
    //free path vector pkg memory
//    reset_path_vector(req);

    tmb.t_continue(data->tindex, data->tlabel, data->act);
    free_saved_transaction_data(data);
    return;

error:
    create_return_code(-2);
    if (data->sar_assignment_type != AVP_IMS_SAR_UNREGISTERED_USER)
        reg_send_reply_transactional(req, data->contact_header, t);
		
error_no_send: //if we don't have the transaction then we can't send a transaction response
    update_stat(rejected_registrations, 1);
    //free memory
    if (saa) cdpb.AAAFreeMessage(&saa);
    if (t) {
//        del_nonshm_lump_rpl(&req->reply_lump);
        tmb.unref_cell(t);
    }
    tmb.t_continue(data->tindex, data->tlabel, data->act);
    free_saved_transaction_data(data);
    return;
}