Thanks for working on exporting to kemi from various ims related module!
However, the functions exported to the native kamailio.cfg cannot be directly exported to kemi. It has to be split in one where the parameters must be converted to str*
and int
, which then calls the function that can be exported to kemi. For example, next is the current w_ro_ccr_stop()
:
static int w_ro_ccr_stop(struct sip_msg *msg, char* c_direction, char* _code, char* _reason) {
struct ro_session* ro_session;
struct ro_session_entry *ro_session_entry;
unsigned int h_entry;
str s_code, s_reason;
unsigned int code;
int dir = 0; /*any side*/
LM_DBG("Inside Ro_CCR_Stop with direction [%s]\n", c_direction);
if (strlen(c_direction) == 4) {
if (c_direction[0] == 'O' || c_direction[0] == 'o') {
dir = RO_ORIG_DIRECTION;
} else {
dir = RO_TERM_DIRECTION;
}
} else {
LM_ERR("Unknown direction [%s] to terminate\n", c_direction);
return RO_RETURN_FALSE;
}
struct dlg_cell* dlg = dlgb.get_dlg(msg);
if (!dlg) {
LM_ERR("Unable to find dialog to send CCR STOP record\n");
return RO_RETURN_ERROR;
}
if (get_str_fparam(&s_code, msg, (fparam_t*) _code) < 0) {
LM_ERR("failed to get code\n");
dlgb.release_dlg(dlg);
return RO_RETURN_ERROR;
}
LM_DBG("Code is [%.*s]\n", s_code.len, s_code.s);
if (get_str_fparam(&s_reason, msg, (fparam_t*) _reason) < 0) {
LM_ERR("failed to get reason\n");
dlgb.release_dlg(dlg);
return RO_RETURN_ERROR;
}
if (str2int(&s_code, &code) != 0) {
LM_ERR("Bad response code: [%.*s]\n", s_code.len, s_code.s);
dlgb.release_dlg(dlg);
return RO_RETURN_FALSE;
}
// switch (code) {
// case 486:
// termcode = VS_TERMCODE_BUSYHERE;
// break;
// case 487:
// termcode = VS_TERMCODE_CANCELLED;
// break;
// case 480:
// case 408:
// /* subscriber not available */
// termcode = VS_TERMCODE_NOTFOUND;
// break;
// }
LM_DBG("Sending Stop record with code [%d] and reason [%.*s]\n", code, s_reason.len, s_reason.s);
LM_DBG("Found DLG [%d : %d]\n", dlg->h_id, dlg->h_entry);
ro_session = lookup_ro_session(dlg->h_entry, &dlg->callid, dir, 0);
if (ro_session == NULL) {
LM_DBG("no ro_session - ignoring\n");
dlgb.release_dlg(dlg);
return RO_RETURN_TRUE;
}
h_entry = ro_session->h_entry;
ro_session_entry = &(ro_session_table->entries[h_entry]);
ro_session_lock(ro_session_table, ro_session_entry);
if (ro_session->ccr_sent == 1) {
LM_DBG("Ro CCR already sent for session [%.*s]\n", ro_session->ro_session_id.len, ro_session->ro_session_id.s);
goto done;
}
send_ccr_stop_with_param(ro_session, code, &s_reason);
//TODO = check the CCR was sent successfully.
LM_DBG("Setting Ro session [%.*s] ccr_sent to 1\n", ro_session->ro_session_id.len, ro_session->ro_session_id.s);
ro_session->ccr_sent = 1;
ro_session->active = -1;
// counter_add(ims_charging_cnts_h.active_ro_sessions, -1);
done:
unref_ro_session(ro_session, 1, 0);
ro_session_unlock(ro_session_table, ro_session_entry);
dlgb.release_dlg(dlg);
return RO_RETURN_TRUE;
}
It has to be split to:
static int ki_ro_ccr_stop(sip_msg_t *msg, str* p_direction, int p_code, str* p_reason) {
struct ro_session* ro_session;
struct ro_session_entry *ro_session_entry;
unsigned int h_entry;
str s_reason;
unsigned int code;
int dir = 0; /*any side*/
char *c_direction;
c_direction = p_direction->s;
s_reason = *p_reason;
code = (unsigned int)p_code;
LM_DBG("Inside Ro_CCR_Stop with direction [%s]\n", c_direction);
if (strlen(c_direction) == 4) {
if (c_direction[0] == 'O' || c_direction[0] == 'o') {
dir = RO_ORIG_DIRECTION;
} else {
dir = RO_TERM_DIRECTION;
}
} else {
LM_ERR("Unknown direction [%s] to terminate\n", c_direction);
return RO_RETURN_FALSE;
}
struct dlg_cell* dlg = dlgb.get_dlg(msg);
if (!dlg) {
LM_ERR("Unable to find dialog to send CCR STOP record\n");
return RO_RETURN_ERROR;
}
// switch (code) {
// case 486:
// termcode = VS_TERMCODE_BUSYHERE;
// break;
// case 487:
// termcode = VS_TERMCODE_CANCELLED;
// break;
// case 480:
// case 408:
// /* subscriber not available */
// termcode = VS_TERMCODE_NOTFOUND;
// break;
// }
LM_DBG("Sending Stop record with code [%d] and reason [%.*s]\n", code, s_reason.len, s_reason.s);
LM_DBG("Found DLG [%d : %d]\n", dlg->h_id, dlg->h_entry);
ro_session = lookup_ro_session(dlg->h_entry, &dlg->callid, dir, 0);
if (ro_session == NULL) {
LM_DBG("no ro_session - ignoring\n");
dlgb.release_dlg(dlg);
return RO_RETURN_TRUE;
}
h_entry = ro_session->h_entry;
ro_session_entry = &(ro_session_table->entries[h_entry]);
ro_session_lock(ro_session_table, ro_session_entry);
if (ro_session->ccr_sent == 1) {
LM_DBG("Ro CCR already sent for session [%.*s]\n", ro_session->ro_session_id.len, ro_session->ro_session_id.s);
goto done;
}
send_ccr_stop_with_param(ro_session, code, &s_reason);
//TODO = check the CCR was sent successfully.
LM_DBG("Setting Ro session [%.*s] ccr_sent to 1\n", ro_session->ro_session_id.len, ro_session->ro_session_id.s);
ro_session->ccr_sent = 1;
ro_session->active = -1;
// counter_add(ims_charging_cnts_h.active_ro_sessions, -1);
done:
unref_ro_session(ro_session, 1, 0);
ro_session_unlock(ro_session_table, ro_session_entry);
dlgb.release_dlg(dlg);
return RO_RETURN_TRUE;
}
And:
static int w_ro_ccr_stop(struct sip_msg *msg, char* c_direction, char* _code, char* _reason) {
str s_direction, s_code, s_reason;
int code;
s_direction.s = c_direction;
s_direction.len = strlen(c_direction);
if (get_str_fparam(&s_code, msg, (fparam_t*) _code) < 0) {
LM_ERR("failed to get code\n");
dlgb.release_dlg(dlg);
return RO_RETURN_ERROR;
}
LM_DBG("Code is [%.*s]\n", s_code.len, s_code.s);
if (get_str_fparam(&s_reason, msg, (fparam_t*) _reason) < 0) {
LM_ERR("failed to get reason\n");
dlgb.release_dlg(dlg);
return RO_RETURN_ERROR;
}
if (str2int(&s_code, &code) != 0) {
LM_ERR("Bad response code: [%.*s]\n", s_code.len, s_code.s);
dlgb.release_dlg(dlg);
return RO_RETURN_FALSE;
}
return ki_ro_ccr_stop(msg, &s_direction, code, &s_reason);
}
Then the w_ro_ccr_stop()
remains exported to kamailio.cfg native scripting and ki_ro_ccr_stop()
is exported to kemi. You see that w_ro_ccr_stop()
keeps only the code related to fixing the parameters given by kamailio.cfg interpreter and then calls the ki_ro_ccr_stop()
which retains more or less the rest of the code from the initial function.
Note that the split of the code done above was done without any checking, aiming to give hints on how should be done, without any compiling or other checking. Optimizations can also be done, by getting rid of the c_direction and s_reason inside ki_ro_ccr_stop() and use the function parameters directly.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.