Skip to content

Commit

Permalink
modules/ims_charging: add support for final_unit_indication and redir…
Browse files Browse the repository at this point in the history
…ect fn'ality in CCA
  • Loading branch information
jaybeepee committed Sep 28, 2016
1 parent 3f9969d commit 46f1888
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 3 deletions.
14 changes: 12 additions & 2 deletions modules/ims_charging/Ro_data.c
Expand Up @@ -296,10 +296,20 @@ void Ro_free_CCR(Ro_CCR_t *x) {
}

void Ro_free_CCA(Ro_CCA_t *x) {
if (!x) return;
str *p_str;
if (!x) return;

if (x->mscc->final_unit_action) {
mem_free(x->mscc->final_unit_action, pkg);
if (x->mscc->final_unit_action->redirect_server) {
if (x->mscc->final_unit_action->redirect_server->server_address) {
p_str = x->mscc->final_unit_action->redirect_server->server_address;
if (p_str->len > 0 && p_str->s)
mem_free(p_str->s, pkg);
mem_free(p_str, pkg);
}
}
mem_free(x->mscc->final_unit_action, pkg);

}
mem_free(x->mscc->granted_service_unit, pkg);
mem_free(x->mscc, pkg);
Expand Down
7 changes: 7 additions & 0 deletions modules/ims_charging/Ro_data.h
Expand Up @@ -362,14 +362,21 @@ typedef struct {
uint32_t cc_output_octets;
} granted_services_unit_t;

typedef struct {
uint32_t address_type;
str* server_address;
} redirect_server_t;

typedef struct {
uint32_t action;
redirect_server_t *redirect_server;
} final_unit_indication_t;

typedef struct {
granted_services_unit_t *granted_service_unit;
uint32_t validity_time;
final_unit_indication_t *final_unit_action;
uint32_t resultcode;
} multiple_services_credit_control_t;

typedef struct {
Expand Down
31 changes: 31 additions & 0 deletions modules/ims_charging/ccr.c
Expand Up @@ -277,6 +277,7 @@ Ro_CCA_t *Ro_parse_CCA_avps(AAAMessage *cca) {
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;
Expand Down Expand Up @@ -321,6 +322,9 @@ Ro_CCA_t *Ro_parse_CCA_avps(AAAMessage *cca) {
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;
Expand All @@ -329,6 +333,33 @@ Ro_CCA_t *Ro_parse_CCA_avps(AAAMessage *cca) {
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");
}
Expand Down
71 changes: 70 additions & 1 deletion modules/ims_charging/ims_ro.c
Expand Up @@ -64,6 +64,7 @@ extern int video_rating_group;

static int create_cca_return_code(int result);
static int create_cca_result_code(int result);
static int create_cca_fui_avps(int action, str* redirecturi);
static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs);
static void resume_on_interim_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs);
static void resume_on_termination_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs);
Expand Down Expand Up @@ -1246,6 +1247,8 @@ static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca,
struct cell *t = NULL;
struct session_setup_data *ssd = (struct session_setup_data *) param;
int error_code = RO_RETURN_ERROR;
str *redirecturi = 0;
int fui_action = 0;

if (is_timeout) {
counter_inc(ims_charging_cnts_h.ccr_timeouts);
Expand Down Expand Up @@ -1289,7 +1292,7 @@ static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca,
if (!ro_cca_data) {
LM_ERR("Could not parse CCA message response.\n");
error_code = RO_RETURN_ERROR;
create_cca_result_code(0);
create_cca_result_code(0);
goto error0;
}

Expand All @@ -1302,6 +1305,40 @@ static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca,
goto error1;
}

if (ro_cca_data->mscc->final_unit_action) {
fui_action = ro_cca_data->mscc->final_unit_action->action;

if (fui_action == AVP_Final_Unit_Action_Redirect) {
if (ro_cca_data->mscc->final_unit_action->redirect_server) {
LM_DBG("FUI with action: [%d]", ro_cca_data->mscc->final_unit_action->action);

if (ro_cca_data->mscc->final_unit_action->action == AVP_Final_Unit_Action_Redirect) {
LM_DBG("Have REDIRECT action with address type of [%d]\n", ro_cca_data->mscc->final_unit_action->redirect_server->address_type);
if (ro_cca_data->mscc->final_unit_action->redirect_server->address_type == AVP_Redirect_Address_Type_SIP_URI) {
LM_DBG("SIP URI for redirect is [%.*s] with len of %d\n",
ro_cca_data->mscc->final_unit_action->redirect_server->server_address->len, ro_cca_data->mscc->final_unit_action->redirect_server->server_address->s,
ro_cca_data->mscc->final_unit_action->redirect_server->server_address->len);
redirecturi = ro_cca_data->mscc->final_unit_action->redirect_server->server_address;
} else {
LM_DBG("we don't cater for any redirect action which is not a SIP URI... ignoring [%d]\n", ro_cca_data->mscc->final_unit_action->redirect_server->address_type);
}
} else {
LM_DBG("ignoring final unit action which is not REDIRECT - [%d]\n", fui_action);
}
}
}
}

/* create the AVPs cca_redirect_uri and cca_fui_action for export to cfg file */
create_cca_fui_avps(fui_action, redirecturi);

/* check result code at mscc level */
if (ro_cca_data->mscc->resultcode != 2001) {
LM_DBG("CCA failure at MSCC level with resultcode [%d]\n", ro_cca_data->mscc->resultcode);
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);
Expand Down Expand Up @@ -1451,8 +1488,40 @@ static int create_cca_result_code(int result) {
return 1;
}

static int create_cca_fui_avps(int action, str* redirecturi) {
int_str action_avp_val, action_avp_name, redirecturi_avp_val, redirecturi_avp_name;
action_avp_name.s.s = RO_AVP_CCA_FUI_ACTION;
action_avp_name.s.len = RO_AVP_CCA_FUI_ACTION_LENGTH;
redirecturi_avp_name.s.s = RO_AVP_CCA_FUI_REDIRECT_URI;
redirecturi_avp_name.s.len = RO_AVP_CCA_FUI_REDIRECT_URI_LENGTH;
char buf[10];
int rc;

action_avp_val.n = action;
action_avp_val.s.len = snprintf(buf, 10, "%i", action);
action_avp_val.s.s = buf;

rc = add_avp(AVP_NAME_STR|AVP_VAL_STR, action_avp_name, action_avp_val);

if (rc < 0)
LM_ERR("Couldn't create ["RO_AVP_CCA_FUI_ACTION"] AVP\n");
else
LM_DBG("Created AVP ["RO_AVP_CCA_FUI_ACTION"] successfully: value=[%d]\n", action);

if (redirecturi && redirecturi->len >0 && redirecturi->s) {
redirecturi_avp_val.s.len = redirecturi->len;
redirecturi_avp_val.s.s = redirecturi->s;

rc = add_avp(AVP_NAME_STR|AVP_VAL_STR, redirecturi_avp_name, redirecturi_avp_val);

if (rc < 0)
LM_ERR("Couldn't create ["RO_AVP_CCA_FUI_REDIRECT_URI"] AVP\n");
else
LM_DBG("Created AVP ["RO_AVP_CCA_FUI_REDIRECT_URI"] successfully: value=[%.*s]\n", redirecturi->len, redirecturi->s);
}

return 1;
}

static int get_mac_avp_value(struct sip_msg *msg, str *value) {
str mac_avp_name_str = str_init(RO_MAC_AVP_NAME);
Expand Down
6 changes: 6 additions & 0 deletions modules/ims_charging/mod.h
Expand Up @@ -48,6 +48,12 @@
#define RO_AVP_CCA_RESULT_CODE "cca_result_code"
#define RO_AVP_CCA_RESULT_CODE_LENGTH 15

#define RO_AVP_CCA_FUI_ACTION "cca_fui_action"
#define RO_AVP_CCA_FUI_ACTION_LENGTH 14

#define RO_AVP_CCA_FUI_REDIRECT_URI "cca_redirect_uri"
#define RO_AVP_CCA_FUI_REDIRECT_URI_LENGTH 16

#define RO_MAC_AVP_NAME "$avp(ro_mac_value)"

#define DB_DEFAULT_UPDATE_PERIOD 60
Expand Down

0 comments on commit 46f1888

Please sign in to comment.