Преглед на файлове

cnxcc: exported functions to kemi framework

Daniel-Constantin Mierla преди 7 години
родител
ревизия
b1899d2806
променени са 1 файла, в които са добавени 212 реда и са изтрити 115 реда
  1. 212 115
      src/modules/cnxcc/cnxcc_mod.c

+ 212 - 115
src/modules/cnxcc/cnxcc_mod.c

@@ -55,6 +55,7 @@
 #include "../../core/fmsg.h"
 #include "../../core/fmsg.h"
 #include "../../core/rpc.h"
 #include "../../core/rpc.h"
 #include "../../core/rpc_lookup.h"
 #include "../../core/rpc_lookup.h"
+#include "../../core/kemi.h"
 
 
 #include "cnxcc_mod.h"
 #include "cnxcc_mod.h"
 #include "cnxcc.h"
 #include "cnxcc.h"
@@ -1570,23 +1571,13 @@ static inline int get_pv_value(
 	return 0;
 	return 0;
 }
 }
 
 
-static int __set_max_credit(sip_msg_t *msg, char *pclient,
-		char *pcredit, char *pcps, char *pinitp, char *pfinishp)
+static int ki_set_max_credit(sip_msg_t *msg, str *sclient,
+		str *scredit, str *scps, int initp, int finishp)
 {
 {
 	credit_data_t *credit_data = NULL;
 	credit_data_t *credit_data = NULL;
 	call_t *call = NULL;
 	call_t *call = NULL;
-	str sclient;
-	str scredit;
-	str scps;
-	int initp;
-	int finishp;
-	double credit = 0, cost_per_second = 0;
 
 
-	if(msg==NULL || pclient==NULL || pcredit==NULL || pcps==NULL
-			|| pinitp==NULL || pfinishp==NULL) {
-		LM_ERR("invalid parameters\n");
-		return -1;
-	}
+	double credit = 0, cost_per_second = 0;
 
 
 	if(msg->first_line.type != SIP_REQUEST
 	if(msg->first_line.type != SIP_REQUEST
 			|| msg->first_line.u.request.method_value != METHOD_INVITE) {
 			|| msg->first_line.u.request.method_value != METHOD_INVITE) {
@@ -1599,41 +1590,20 @@ static int __set_max_credit(sip_msg_t *msg, char *pclient,
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
-		LM_ERR("failed to get client parameter\n");
-		return -1;
-	}
-	if(fixup_get_svalue(msg, (gparam_t*)pcredit, &scredit)<0) {
-		LM_ERR("failed to get credit parameter\n");
-		return -1;
-	}
-	if(fixup_get_svalue(msg, (gparam_t*)pcps, &scps)<0) {
-		LM_ERR("failed to get cps parameter\n");
-		return -1;
-	}
-	if(fixup_get_ivalue(msg, (gparam_t*)pinitp, &initp)<0) {
-		LM_ERR("failed to get init pulse parameter\n");
-		return -1;
-	}
-	if(fixup_get_ivalue(msg, (gparam_t*)pfinishp, &finishp)<0) {
-		LM_ERR("failed to get finish pulse parameter\n");
-		return -1;
-	}
-
-	if(sclient.len == 0 || sclient.s == NULL) {
+	if(sclient->len == 0 || sclient->s == NULL) {
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 				msg->callid->body.s);
 				msg->callid->body.s);
 		return -1;
 		return -1;
 	}
 	}
 
 
-	credit = str2double(&scredit);
+	credit = str2double(scredit);
 
 
 	if(credit <= 0) {
 	if(credit <= 0) {
 		LM_ERR("credit value must be > 0: %f", credit);
 		LM_ERR("credit value must be > 0: %f", credit);
 		return -1;
 		return -1;
 	}
 	}
 
 
-	cost_per_second = str2double(&scps);
+	cost_per_second = str2double(scps);
 
 
 	if(cost_per_second <= 0) {
 	if(cost_per_second <= 0) {
 		LM_ERR("cost_per_second value must be > 0: %f\n", cost_per_second);
 		LM_ERR("cost_per_second value must be > 0: %f\n", cost_per_second);
@@ -1643,16 +1613,16 @@ static int __set_max_credit(sip_msg_t *msg, char *pclient,
 	LM_DBG("Setting up new call for client [%.*s], max-credit[%f], "
 	LM_DBG("Setting up new call for client [%.*s], max-credit[%f], "
 			"cost-per-sec[%f], initial-pulse [%d], "
 			"cost-per-sec[%f], initial-pulse [%d], "
 			"final-pulse [%d], call-id[%.*s]\n",
 			"final-pulse [%d], call-id[%.*s]\n",
-			sclient.len, sclient.s, credit,
+			sclient->len, sclient->s, credit,
 			cost_per_second, initp, finishp,
 			cost_per_second, initp, finishp,
 			msg->callid->body.len, msg->callid->body.s);
 			msg->callid->body.len, msg->callid->body.s);
 
 
 	set_ctrl_flag(msg);
 	set_ctrl_flag(msg);
 
 
-	if((credit_data = __get_or_create_credit_data_entry(&sclient, CREDIT_MONEY))
+	if((credit_data = __get_or_create_credit_data_entry(sclient, CREDIT_MONEY))
 			== NULL) {
 			== NULL) {
 		LM_ERR("Error retrieving credit data from shared memory for client "
 		LM_ERR("Error retrieving credit data from shared memory for client "
-				"[%.*s]\n", sclient.len, sclient.s);
+				"[%.*s]\n", sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
@@ -1660,38 +1630,71 @@ static int __set_max_credit(sip_msg_t *msg, char *pclient,
 				cost_per_second, initp, finishp))
 				cost_per_second, initp, finishp))
 			== NULL) {
 			== NULL) {
 		LM_ERR("Unable to allocate new call for client [%.*s]\n",
 		LM_ERR("Unable to allocate new call for client [%.*s]\n",
-				sclient.len, sclient.s);
+				sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_MONEY) != 0) {
 	if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_MONEY) != 0) {
 		LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n",
 		LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n",
-				sclient.len, sclient.s);
+				sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	return 1;
 	return 1;
 }
 }
 
 
-static int __terminate_all(sip_msg_t *msg, char *pclient, char *p2)
+static int __set_max_credit(sip_msg_t *msg, char *pclient,
+		char *pcredit, char *pcps, char *pinitp, char *pfinishp)
 {
 {
-	credit_data_t *credit_data = NULL;
 	str sclient;
 	str sclient;
+	str scredit;
+	str scps;
+	int initp;
+	int finishp;
+
+	if(msg==NULL || pclient==NULL || pcredit==NULL || pcps==NULL
+			|| pinitp==NULL || pfinishp==NULL) {
+		LM_ERR("invalid parameters\n");
+		return -1;
+	}
 
 
 	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
 	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
 		LM_ERR("failed to get client parameter\n");
 		LM_ERR("failed to get client parameter\n");
 		return -1;
 		return -1;
 	}
 	}
+	if(fixup_get_svalue(msg, (gparam_t*)pcredit, &scredit)<0) {
+		LM_ERR("failed to get credit parameter\n");
+		return -1;
+	}
+	if(fixup_get_svalue(msg, (gparam_t*)pcps, &scps)<0) {
+		LM_ERR("failed to get cps parameter\n");
+		return -1;
+	}
+	if(fixup_get_ivalue(msg, (gparam_t*)pinitp, &initp)<0) {
+		LM_ERR("failed to get init pulse parameter\n");
+		return -1;
+	}
+	if(fixup_get_ivalue(msg, (gparam_t*)pfinishp, &finishp)<0) {
+		LM_ERR("failed to get finish pulse parameter\n");
+		return -1;
+	}
 
 
-	if(sclient.len == 0 || sclient.s == NULL) {
+	return ki_set_max_credit(msg, &sclient, &scredit, &scps, initp, finishp);
+}
+
+static int ki_terminate_all(sip_msg_t *msg, str *sclient)
+{
+	credit_data_t *credit_data = NULL;
+
+	if(sclient->len == 0 || sclient->s == NULL) {
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 				msg->callid->body.s);
 				msg->callid->body.s);
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(try_get_credit_data_entry(&sclient, &credit_data) != 0) {
+	if(try_get_credit_data_entry(sclient, &credit_data) != 0) {
 		LM_DBG("credit data for [%.*s] on [%.*s] not found\n",
 		LM_DBG("credit data for [%.*s] on [%.*s] not found\n",
-				sclient.len, sclient.s,
+				sclient->len, sclient->s,
 				msg->callid->body.len, msg->callid->body.s);
 				msg->callid->body.len, msg->callid->body.s);
 		return -1;
 		return -1;
 	}
 	}
@@ -1700,36 +1703,41 @@ static int __terminate_all(sip_msg_t *msg, char *pclient, char *p2)
 	return 1;
 	return 1;
 }
 }
 
 
-static int __get_channel_count(sip_msg_t *msg, char *pclient, char *pcount)
+static int __terminate_all(sip_msg_t *msg, char *pclient, char *p2)
 {
 {
-	credit_data_t *credit_data = NULL;
-	pv_spec_t *pvcount = (pv_spec_t *)pcount;
+	str sclient;
+
+	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
+		LM_ERR("failed to get client parameter\n");
+		return -1;
+	}
+
+	return ki_terminate_all(msg, &sclient);
+}
 
 
+static int __get_channel_count_helper(sip_msg_t *msg, str *sclient,
+		pv_spec_t *pvcount)
+{
+	credit_data_t *credit_data = NULL;
 	pv_value_t countval;
 	pv_value_t countval;
 	int value = -1;
 	int value = -1;
-	str sclient;
 
 
 	if(!pv_is_w(pvcount)) {
 	if(!pv_is_w(pvcount)) {
 		LM_ERR("pvar is not writable\n");
 		LM_ERR("pvar is not writable\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
-		LM_ERR("failed to get client parameter\n");
-		return -1;
-	}
-
-	if(sclient.len == 0 || sclient.s == NULL) {
+	if(sclient->len == 0 || sclient->s == NULL) {
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 				msg->callid->body.s);
 				msg->callid->body.s);
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(try_get_credit_data_entry(&sclient, &credit_data) == 0)
+	if(try_get_credit_data_entry(sclient, &credit_data) == 0)
 		value = credit_data->number_of_calls;
 		value = credit_data->number_of_calls;
 	else
 	else
-		LM_ALERT("[%.*s] not found\n", msg->callid->body.len,
-				msg->callid->body.s);
+		LM_ALERT("[%.*s] [%.*s] not found\n", sclient->len, sclient->s,
+				msg->callid->body.len, msg->callid->body.s);
 
 
 	memset(&countval, 0, sizeof(countval));
 	memset(&countval, 0, sizeof(countval));
 
 
@@ -1745,12 +1753,36 @@ static int __get_channel_count(sip_msg_t *msg, char *pclient, char *pcount)
 	return 1;
 	return 1;
 }
 }
 
 
-static int __set_max_channels(sip_msg_t *msg, char *pclient, char *pmaxchan)
+static int __get_channel_count(sip_msg_t *msg, char *pclient, char *pcount)
+{
+	pv_spec_t *pvcount = (pv_spec_t *)pcount;
+	str sclient;
+
+	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
+		LM_ERR("failed to get client parameter\n");
+		return -1;
+	}
+
+	return __get_channel_count_helper(msg, &sclient, (pv_spec_t *)pcount);
+}
+
+static int ki_get_channel_count(sip_msg_t *msg, str *sclient, str *pvname)
+{
+	pv_spec_t *pvcount = NULL;
+
+	pvcount = pv_cache_get(pvname);
+
+	if(pvcount==NULL) {
+		LM_ERR("failed to get pv spec for [%.*s]\n", pvname->len, pvname->s);
+		return -1;
+	}
+	return __get_channel_count_helper(msg, sclient, pvcount);
+}
+
+static int ki_set_max_channels(sip_msg_t *msg, str *sclient, int max_chan)
 {
 {
 	credit_data_t *credit_data = NULL;
 	credit_data_t *credit_data = NULL;
 	call_t *call = NULL;
 	call_t *call = NULL;
-	str sclient;
-	int max_chan = 0;
 
 
 	if(parse_headers(msg, HDR_CALLID_F, 0) != 0) {
 	if(parse_headers(msg, HDR_CALLID_F, 0) != 0) {
 		LM_ERR("Error parsing Call-ID");
 		LM_ERR("Error parsing Call-ID");
@@ -1767,15 +1799,6 @@ static int __set_max_channels(sip_msg_t *msg, char *pclient, char *pmaxchan)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
-		LM_ERR("failed to get client parameter\n");
-		return -1;
-	}
-	if(fixup_get_ivalue(msg, (gparam_t*)pmaxchan, &max_chan)<0) {
-		LM_ERR("failed to get max chan parameter\n");
-		return -1;
-	}
-
 	set_ctrl_flag(msg);
 	set_ctrl_flag(msg);
 
 
 	if(max_chan <= 0) {
 	if(max_chan <= 0) {
@@ -1784,7 +1807,7 @@ static int __set_max_channels(sip_msg_t *msg, char *pclient, char *pmaxchan)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(sclient.len == 0 || sclient.s == NULL) {
+	if(sclient->len == 0 || sclient->s == NULL) {
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 				msg->callid->body.s);
 				msg->callid->body.s);
 		return -1;
 		return -1;
@@ -1792,13 +1815,13 @@ static int __set_max_channels(sip_msg_t *msg, char *pclient, char *pmaxchan)
 
 
 	LM_DBG("Setting up new call for client [%.*s], max-chan[%d], "
 	LM_DBG("Setting up new call for client [%.*s], max-chan[%d], "
 			"call-id[%.*s]\n",
 			"call-id[%.*s]\n",
-			sclient.len, sclient.s, max_chan,
+			sclient->len, sclient->s, max_chan,
 			msg->callid->body.len, msg->callid->body.s);
 			msg->callid->body.len, msg->callid->body.s);
 
 
-	if((credit_data = __get_or_create_credit_data_entry(&sclient,
+	if((credit_data = __get_or_create_credit_data_entry(sclient,
 				CREDIT_CHANNEL)) == NULL) {
 				CREDIT_CHANNEL)) == NULL) {
 		LM_ERR("Error retrieving credit data from shared memory for client "
 		LM_ERR("Error retrieving credit data from shared memory for client "
-				"[%.*s]\n", sclient.len, sclient.s);
+				"[%.*s]\n", sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
@@ -1811,28 +1834,41 @@ static int __set_max_channels(sip_msg_t *msg, char *pclient, char *pmaxchan)
 	if((call = alloc_new_call_by_channel(credit_data, msg, max_chan))
 	if((call = alloc_new_call_by_channel(credit_data, msg, max_chan))
 			== NULL) {
 			== NULL) {
 		LM_ERR("Unable to allocate new call for client [%.*s]\n",
 		LM_ERR("Unable to allocate new call for client [%.*s]\n",
-				sclient.len, sclient.s);
+				sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_CHANNEL)
 	if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_CHANNEL)
 			!= 0) {
 			!= 0) {
 		LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n",
 		LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n",
-				sclient.len, sclient.s);
+				sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	return 1;
 	return 1;
 }
 }
 
 
-static int __set_max_time(sip_msg_t *msg, char *pclient, char *pmaxsecs)
+static int __set_max_channels(sip_msg_t *msg, char *pclient, char *pmaxchan)
 {
 {
-	credit_data_t *credit_data = NULL;
-	call_t *call = NULL;
 	str sclient;
 	str sclient;
-	int max_secs = 0;
+	int max_chan = 0;
 
 
-	set_ctrl_flag(msg);
+	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
+		LM_ERR("failed to get client parameter\n");
+		return -1;
+	}
+	if(fixup_get_ivalue(msg, (gparam_t*)pmaxchan, &max_chan)<0) {
+		LM_ERR("failed to get max chan parameter\n");
+		return -1;
+	}
+
+	return ki_set_max_channels(msg, &sclient, max_chan);
+}
+
+static int ki_set_max_time(sip_msg_t *msg, str *sclient, int max_secs)
+{
+	credit_data_t *credit_data = NULL;
+	call_t *call = NULL;
 
 
 	if(parse_headers(msg, HDR_CALLID_F, 0) != 0) {
 	if(parse_headers(msg, HDR_CALLID_F, 0) != 0) {
 		LM_ERR("Error parsing Call-ID");
 		LM_ERR("Error parsing Call-ID");
@@ -1850,14 +1886,7 @@ static int __set_max_time(sip_msg_t *msg, char *pclient, char *pmaxsecs)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
-		LM_ERR("failed to get client parameter\n");
-		return -1;
-	}
-	if(fixup_get_ivalue(msg, (gparam_t*)pmaxsecs, &max_secs)<0) {
-		LM_ERR("failed to get max secs parameter\n");
-		return -1;
-	}
+	set_ctrl_flag(msg);
 
 
 	if(max_secs <= 0) {
 	if(max_secs <= 0) {
 		LM_ERR("[%.*s] MAXSECS cannot be less than or equal to zero: %d\n",
 		LM_ERR("[%.*s] MAXSECS cannot be less than or equal to zero: %d\n",
@@ -1865,7 +1894,7 @@ static int __set_max_time(sip_msg_t *msg, char *pclient, char *pmaxsecs)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(sclient.len == 0 || sclient.s == NULL) {
+	if(sclient->len <= 0 || sclient->s == NULL) {
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 				msg->callid->body.s);
 				msg->callid->body.s);
 		return -1;
 		return -1;
@@ -1873,51 +1902,57 @@ static int __set_max_time(sip_msg_t *msg, char *pclient, char *pmaxsecs)
 
 
 	LM_DBG("Setting up new call for client [%.*s], max-secs[%d], "
 	LM_DBG("Setting up new call for client [%.*s], max-secs[%d], "
 			"call-id[%.*s]\n",
 			"call-id[%.*s]\n",
-			sclient.len, sclient.s, max_secs,
+			sclient->len, sclient->s, max_secs,
 			msg->callid->body.len, msg->callid->body.s);
 			msg->callid->body.len, msg->callid->body.s);
 
 
-	if((credit_data = __get_or_create_credit_data_entry(&sclient, CREDIT_TIME))
+	if((credit_data = __get_or_create_credit_data_entry(sclient, CREDIT_TIME))
 			== NULL) {
 			== NULL) {
 		LM_ERR("Error retrieving credit data from shared memory for client "
 		LM_ERR("Error retrieving credit data from shared memory for client "
-				"[%.*s]\n", sclient.len, sclient.s);
+				"[%.*s]\n", sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	if((call = __alloc_new_call_by_time(credit_data, msg, max_secs))
 	if((call = __alloc_new_call_by_time(credit_data, msg, max_secs))
 			== NULL) {
 			== NULL) {
 		LM_ERR("Unable to allocate new call for client [%.*s]\n",
 		LM_ERR("Unable to allocate new call for client [%.*s]\n",
-				sclient.len, sclient.s);
+				sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_TIME) != 0) {
 	if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_TIME) != 0) {
 		LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n",
 		LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n",
-				sclient.len, sclient.s);
+				sclient->len, sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	return 1;
 	return 1;
 }
 }
 
 
-static int __update_max_time(sip_msg_t *msg, char *pclient, char *psecs)
+static int __set_max_time(sip_msg_t *msg, char *pclient, char *pmaxsecs)
 {
 {
-	credit_data_t *credit_data = NULL;
 	str sclient;
 	str sclient;
-	int secs = 0;
-
-	set_ctrl_flag(msg);
-
-	if(parse_headers(msg, HDR_CALLID_F, 0) != 0) {
-		LM_ERR("Error parsing Call-ID");
-		return -1;
-	}
+	int max_secs = 0;
 
 
 	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
 	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
 		LM_ERR("failed to get client parameter\n");
 		LM_ERR("failed to get client parameter\n");
 		return -1;
 		return -1;
 	}
 	}
-	if(fixup_get_ivalue(msg, (gparam_t*)psecs, &secs)<0) {
-		LM_ERR("failed to get secs parameter\n");
+	if(fixup_get_ivalue(msg, (gparam_t*)pmaxsecs, &max_secs)<0) {
+		LM_ERR("failed to get max secs parameter\n");
+		return -1;
+	}
+
+	return ki_set_max_time(msg, &sclient, max_secs);
+}
+
+static int ki_update_max_time(sip_msg_t *msg, str *sclient, int secs)
+{
+	credit_data_t *credit_data = NULL;
+
+	set_ctrl_flag(msg);
+
+	if(parse_headers(msg, HDR_CALLID_F, 0) != 0) {
+		LM_ERR("Error parsing Call-ID");
 		return -1;
 		return -1;
 	}
 	}
 
 
@@ -1927,14 +1962,14 @@ static int __update_max_time(sip_msg_t *msg, char *pclient, char *psecs)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(sclient.len == 0 || sclient.s == NULL) {
+	if(sclient->len == 0 || sclient->s == NULL) {
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len,
 				msg->callid->body.s);
 				msg->callid->body.s);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	LM_DBG("Updating call for client [%.*s], max-secs[%d], call-id[%.*s]\n",
 	LM_DBG("Updating call for client [%.*s], max-secs[%d], call-id[%.*s]\n",
-			sclient.len, sclient.s, secs,
+			sclient->len, sclient->s, secs,
 			msg->callid->body.len, msg->callid->body.s);
 			msg->callid->body.len, msg->callid->body.s);
 
 
 
 
@@ -1945,12 +1980,12 @@ static int __update_max_time(sip_msg_t *msg, char *pclient, char *psecs)
 	call_t *call = NULL, *tmp_call = NULL;
 	call_t *call = NULL, *tmp_call = NULL;
 
 
 	cnxcc_lock(_data.time.lock);
 	cnxcc_lock(_data.time.lock);
-	e = str_hash_get(ht, sclient.s, sclient.len);
+	e = str_hash_get(ht, sclient->s, sclient->len);
 	cnxcc_unlock(_data.time.lock);
 	cnxcc_unlock(_data.time.lock);
 
 
 	if(e == NULL) {
 	if(e == NULL) {
-		LM_ERR("Client [%.*s] was not found\n", sclient.len,
-				sclient.s);
+		LM_ERR("Client [%.*s] was not found\n", sclient->len,
+				sclient->s);
 		return -1;
 		return -1;
 	}
 	}
 
 
@@ -1975,12 +2010,28 @@ static int __update_max_time(sip_msg_t *msg, char *pclient, char *psecs)
 
 
 	//redit_data->consumed_amount = 0;
 	//redit_data->consumed_amount = 0;
 
 
-
 	cnxcc_unlock(credit_data->lock);
 	cnxcc_unlock(credit_data->lock);
 
 
 	return 1;
 	return 1;
 }
 }
 
 
+static int __update_max_time(sip_msg_t *msg, char *pclient, char *psecs)
+{
+	str sclient;
+	int secs = 0;
+
+	if(fixup_get_svalue(msg, (gparam_t*)pclient, &sclient)<0) {
+		LM_ERR("failed to get client parameter\n");
+		return -1;
+	}
+	if(fixup_get_ivalue(msg, (gparam_t*)psecs, &secs)<0) {
+		LM_ERR("failed to get secs parameter\n");
+		return -1;
+	}
+
+	return ki_update_max_time(msg, &sclient, secs);
+}
+
 static int __has_to_tag(struct sip_msg *msg)
 static int __has_to_tag(struct sip_msg *msg)
 {
 {
 	if(msg->to == NULL && parse_headers(msg, HDR_TO_F, 0) != 0) {
 	if(msg->to == NULL && parse_headers(msg, HDR_TO_F, 0) != 0) {
@@ -2054,4 +2105,50 @@ void rpc_credit_control_stats(rpc_t *rpc, void *ctx)
 	rpc->struct_add(rh, "sddd", "info", "CNX Credit Control", "active",
 	rpc->struct_add(rh, "sddd", "info", "CNX Credit Control", "active",
 			_data.stats->active, "dropped", _data.stats->dropped, "total",
 			_data.stats->active, "dropped", _data.stats->dropped, "total",
 			_data.stats->total);
 			_data.stats->total);
+}
+
+/**
+ *
+ */
+/* clang-format off */
+static sr_kemi_t sr_kemi_cnxcc_exports[] = {
+	{ str_init("cnxcc"), str_init("set_max_credit"),
+		SR_KEMIP_INT, ki_set_max_credit,
+		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
+			SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE }
+	},
+	{ str_init("cnxcc"), str_init("set_max_time"),
+		SR_KEMIP_INT, ki_set_max_time,
+		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("cnxcc"), str_init("update_max_time"),
+		SR_KEMIP_INT, ki_update_max_time,
+		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("cnxcc"), str_init("set_max_channels"),
+		SR_KEMIP_INT, ki_set_max_channels,
+		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("cnxcc"), str_init("get_channel_count"),
+		SR_KEMIP_INT, ki_get_channel_count,
+		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("cnxcc"), str_init("terminate_all"),
+		SR_KEMIP_INT, ki_terminate_all,
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+
+	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
+};
+/* clang-format on */
+
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+	sr_kemi_modules_add(sr_kemi_cnxcc_exports);
+	return 0;
 }
 }