示例#1
0
static void resume_on_termination_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs) {
    Ro_CCA_t *ro_cca_data = NULL;

    if (is_timeout) {
        counter_inc(ims_charging_cnts_h.ccr_timeouts);
        LM_ERR("Transaction timeout - did not get CCA\n");
        goto error;
    }

    counter_inc(ims_charging_cnts_h.ccr_replies_received);
    counter_add(ims_charging_cnts_h.ccr_response_time, elapsed_msecs);

    if (!cca) {
        LM_ERR("Error in termination CCR.\n");
        counter_inc(ims_charging_cnts_h.failed_final_ccrs); 
        return;
    }

    ro_cca_data = Ro_parse_CCA_avps(cca);

    if (ro_cca_data == NULL) {
        LM_DBG("Could not parse CCA message response.\n");
        counter_inc(ims_charging_cnts_h.failed_final_ccrs); 
        return;
    }

    if (ro_cca_data->resultcode != 2001) {
        LM_ERR("Got bad CCA result code for STOP record - [%d]\n", ro_cca_data->resultcode);
        goto error;
    } else {
        LM_DBG("Valid CCA response for STOP record\n");
    }

    counter_inc(ims_charging_cnts_h.successful_final_ccrs);
    Ro_free_CCA(ro_cca_data);
    if (!is_timeout && cca) {
        cdpb.AAAFreeMessage(&cca);
    }
    return;

error:
    counter_inc(ims_charging_cnts_h.failed_final_ccrs);      
    Ro_free_CCA(ro_cca_data);
    if (!is_timeout && cca) {
        cdpb.AAAFreeMessage(&cca);
    }
}
示例#2
0
static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs) {
    Ro_CCA_t *ro_cca_data = NULL;
    struct cell *t = NULL;
    struct session_setup_data *ssd = (struct session_setup_data *) param;
    int error_code = RO_RETURN_ERROR;

    if (is_timeout) {
        counter_inc(ims_charging_cnts_h.ccr_timeouts);
        LM_ERR("Transaction timeout - did not get CCA\n");
        error_code = RO_RETURN_ERROR;
        goto error0;
    }

    counter_inc(ims_charging_cnts_h.ccr_replies_received);
    counter_add(ims_charging_cnts_h.ccr_response_time, elapsed_msecs);

    if (!cca) {
        LM_ERR("Error reserving credit for CCA.\n");
        error_code = RO_RETURN_ERROR;
        goto error0;
    }

    if (!ssd) {
        LM_ERR("Session lookup data is NULL.\n");
        error_code = RO_RETURN_ERROR;
        goto error0;
    }

    // we make sure the transaction exists
    if (tmb.t_lookup_ident(&t, ssd->tindex, ssd->tlabel) < 0) {
        LM_ERR("t_continue: transaction not found\n");
        error_code = RO_RETURN_ERROR;
        goto error0;
    }

    // we bring the list of AVPs of the transaction to the current context
    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);

    ro_cca_data = Ro_parse_CCA_avps(cca);

    if (!ro_cca_data) {
        LM_ERR("Could not parse CCA message response.\n");
        error_code = RO_RETURN_ERROR;
	create_cca_result_code(0);
        goto error0;
    }
    create_cca_result_code((int)ro_cca_data->resultcode);
    if (ro_cca_data->resultcode != 2001) {
        LM_ERR("Got bad CCA result code - reservation failed");
        error_code = RO_RETURN_FALSE;
        goto error1;
    }

    LM_DBG("Valid CCA response with time chunk of [%i] and validity [%i]\n",
            ro_cca_data->mscc->granted_service_unit->cc_time,
            ro_cca_data->mscc->validity_time);

    if (ro_cca_data->mscc->granted_service_unit->cc_time <= 0) {
        LM_DBG("got zero GSU.... reservation failed");
        error_code = RO_RETURN_FALSE;
        goto error1;
    }

    ssd->ro_session->last_event_timestamp = get_current_time_micro();
    ssd->ro_session->event_type = pending;
    ssd->ro_session->reserved_secs = ro_cca_data->mscc->granted_service_unit->cc_time;
    ssd->ro_session->valid_for = ro_cca_data->mscc->validity_time;
    ssd->ro_session->is_final_allocation = 0;

    if (ro_cca_data->mscc->final_unit_action && (ro_cca_data->mscc->final_unit_action->action == 0))
        ssd->ro_session->is_final_allocation = 1;

    Ro_free_CCA(ro_cca_data);

    LM_DBG("Freeing CCA message\n");
    cdpb.AAAFreeMessage(&cca);

    link_ro_session(ssd->ro_session, 0); 

    if (ro_db_mode == DB_MODE_REALTIME) {
        ssd->ro_session->flags |= RO_SESSION_FLAG_NEW;
        if (update_ro_dbinfo(ssd->ro_session) != 0) {
            LM_ERR("Failed to update ro_session in database... continuing\n");
        };
    }

    unref_ro_session(ssd->ro_session, 1); /* release our reference */

    create_cca_return_code(RO_RETURN_TRUE);

    if (t)
        tmb.unref_cell(t);

    tmb.t_continue(ssd->tindex, ssd->tlabel, ssd->action);
    shm_free(ssd);

    counter_inc(ims_charging_cnts_h.successful_initial_ccrs);

    return;

error1:
    Ro_free_CCA(ro_cca_data);

error0:
    LM_DBG("Trying to reserve credit on initial INVITE failed on cdp callback\n");
//    counter_add(ims_charging_cnts_h.active_ro_sessions, -1); /*we bumped active on the original initial ccr sent */
    counter_inc(ims_charging_cnts_h.failed_initial_ccrs);      /* drop by one as theoretically this is failed initial ccr */
    create_cca_return_code(error_code);

    if (!is_timeout && cca) {
        cdpb.AAAFreeMessage(&cca);
    }

    if (t)
        tmb.unref_cell(t);

    tmb.t_continue(ssd->tindex, ssd->tlabel, ssd->action);
    shm_free(ssd);
}
示例#3
0
static void resume_on_interim_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs) {
    struct interim_ccr *i_req = (struct interim_ccr *) param;
    Ro_CCA_t * ro_cca_data = NULL;

    if (is_timeout) {
        counter_inc(ims_charging_cnts_h.ccr_timeouts);
        LM_ERR("Transaction timeout - did not get CCA\n");
        goto error;
    }

    counter_add(ims_charging_cnts_h.ccr_response_time, elapsed_msecs);
    counter_inc(ims_charging_cnts_h.ccr_replies_received);

    if (!i_req) {
        LM_ERR("This is so wrong: ro session is NULL\n");
        goto error;
    }

    if (cca == NULL) {
        LM_ERR("Error reserving credit for CCA.\n");
        goto error;
    }

    ro_cca_data = Ro_parse_CCA_avps(cca);

    if (ro_cca_data == NULL) {
        LM_ERR("Could not parse CCA message response.\n");
        goto error;
    }

    if (ro_cca_data->resultcode != 2001) {
        LM_ERR("Got bad CCA result code [%d] - reservation failed", ro_cca_data->resultcode);
        goto error;
    } else {
        LM_DBG("Valid CCA response with time chunk of [%i] and validity [%i].\n", ro_cca_data->mscc->granted_service_unit->cc_time, ro_cca_data->mscc->validity_time);
    }

    i_req->new_credit = ro_cca_data->mscc->granted_service_unit->cc_time;
    i_req->credit_valid_for = ro_cca_data->mscc->validity_time;
    i_req->is_final_allocation = 0;

    if (ro_cca_data->mscc->final_unit_action && (ro_cca_data->mscc->final_unit_action->action == 0))
        i_req->is_final_allocation = 1;

    Ro_free_CCA(ro_cca_data);
    cdpb.AAAFreeMessage(&cca);

    counter_inc(ims_charging_cnts_h.successful_interim_ccrs);
    goto success;

error:
    counter_inc(ims_charging_cnts_h.failed_interim_ccr);  
    if (ro_cca_data)
        Ro_free_CCA(ro_cca_data);

    if (!is_timeout && cca) {
        cdpb.AAAFreeMessage(&cca);
    }

    if (i_req) {
        i_req->credit_valid_for = 0;
        i_req->new_credit = 0;
    }

success:
    resume_ro_session_ontimeout(i_req);
}
示例#4
0
Ro_CCA_t *Ro_parse_CCA_avps(AAAMessage *cca) {
    if (!cca)
        return 0;

    Ro_CCA_t *ro_cca_data = 0;
    mem_new(ro_cca_data, sizeof (Ro_CCR_t), pkg);
    multiple_services_credit_control_t *mscc = 0;
    mem_new(mscc, sizeof (multiple_services_credit_control_t), pkg);
    granted_services_unit_t *gsu = 0;
    mem_new(gsu, sizeof (granted_services_unit_t), pkg);
    final_unit_indication_t *fui = 0;
    mem_new(fui, sizeof (final_unit_indication_t), pkg);
    mscc->granted_service_unit = gsu;
    mscc->final_unit_action = fui;

    mscc->final_unit_action->action = -1;
	mscc->final_unit_action->redirect_server = 0;

    AAA_AVP_LIST* avp_list = &cca->avpList;
    AAA_AVP_LIST mscc_avp_list;
    AAA_AVP_LIST* mscc_avp_list_ptr;

    AAA_AVP *avp = avp_list->head;
    unsigned int x;
    while (avp != NULL) {
        switch (avp->code) {
            case AVP_CC_Request_Type:
                x = get_4bytes(avp->data.s);
                ro_cca_data->cc_request_type = x;
                break;
            case AVP_CC_Request_Number:
                x = get_4bytes(avp->data.s);
                ro_cca_data->cc_request_number = x;
                break;
            case AVP_Multiple_Services_Credit_Control:
                mscc_avp_list = cdp_avp->cdp->AAAUngroupAVPS(avp->data);
                mscc_avp_list_ptr = &mscc_avp_list;
                AAA_AVP *mscc_avp = mscc_avp_list_ptr->head;
                while (mscc_avp != NULL) {
                    LM_DBG("MSCC AVP code is [%i] and data length is [%i]", mscc_avp->code, mscc_avp->data.len);
                    switch (mscc_avp->code) {
                            AAA_AVP_LIST y;
                            AAA_AVP *z;
                        case AVP_Granted_Service_Unit:
                            y = cdp_avp->cdp->AAAUngroupAVPS(mscc_avp->data);
                            z = y.head;
                            while (z) {
                                switch (z->code) {
                                    case AVP_CC_Time:
                                        mscc->granted_service_unit->cc_time = get_4bytes(z->data.s);
                                        break;
                                    default:
                                        LM_ERR("Unsupported Granted Service Unit with code:[%d]\n", z->code);
                                }
                                z = z->next;
                            }
                            cdp_avp->cdp->AAAFreeAVPList(&y);
                            break;
                        case AVP_Validity_Time:
                            mscc->validity_time = get_4bytes(mscc_avp->data.s);
                            break;
						case AVP_Result_Code:
							mscc->resultcode = get_4bytes(mscc_avp->data.s);
							break;
                        case AVP_Final_Unit_Indication:
                            y = cdp_avp->cdp->AAAUngroupAVPS(mscc_avp->data);
                            z = y.head;
                            while (z) {
                                switch (z->code) {
                                    case AVP_Final_Unit_Action:
                                        mscc->final_unit_action->action = get_4bytes(z->data.s);
                                        break;
									case AVP_Redirect_Server:
										LM_DBG("Received redirect server\n");
										redirect_server_t* redirect_server_info = 0;
										mem_new(redirect_server_info, sizeof (redirect_server_t), pkg);
										mscc->final_unit_action->redirect_server = redirect_server_info;
										
										AAA_AVP_LIST yy;
										AAA_AVP *zz;
										yy = cdp_avp->cdp->AAAUngroupAVPS(z->data);
										zz = yy.head;
										while (zz) {
											switch (zz->code) {
												case AVP_Redirect_Address_Type:
													LM_DBG("Received redirect address type\n");
													mscc->final_unit_action->redirect_server->address_type = get_4bytes(zz->data.s);
													break;
												case AVP_Redirect_Server_Address:
													LM_DBG("Received redirect server address of [%.*s]\n", zz->data.len, zz->data.s);
													str_dup_ptr(redirect_server_info->server_address, zz->data, pkg);
													break;	
												default:
													LM_ERR("Unsupported Redirect Server AVP with code:[%d]\n", zz->code);
											}
											zz = zz->next;
											cdp_avp->cdp->AAAFreeAVPList(&yy);
										}
										break;		
                                    default:
                                        LM_ERR("Unsupported Final Unit Indication AVP.\n");
                                }
                                z = z->next;
                            }
                            cdp_avp->cdp->AAAFreeAVPList(&y);
                    }
                    mscc_avp = mscc_avp->next;
                }
                cdp_avp->cdp->AAAFreeAVPList(mscc_avp_list_ptr);
                break;
            case AVP_Result_Code:
                x = get_4bytes(avp->data.s);
                ro_cca_data->resultcode = x;
                break;
        }
        avp = avp->next;
    }
    ro_cca_data->mscc = mscc;
    return ro_cca_data;

out_of_memory:
    LM_ERR("out of pkg memory\n");
    Ro_free_CCA(ro_cca_data);
    return 0;
}