Skip to content

Commit

Permalink
Added call token to callcontrol to help detect callid duplicates
Browse files Browse the repository at this point in the history
  • Loading branch information
saghul committed Sep 9, 2011
1 parent 0958d16 commit ca6e9a5
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 12 deletions.
45 changes: 34 additions & 11 deletions modules/call_control/README
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ Irina-Maria Stanescu
1.5.6. diverter_avp_id (string)
1.5.7. prepaid_account_flag (int)
1.5.8. call_limit_avp (string)
1.5.9. init (string)
1.5.10. start (string)
1.5.11. stop (string)
1.5.9. call_token_avp (string)
1.5.10. init (string)
1.5.11. start (string)
1.5.12. stop (string)

1.6. Exported Functions

Expand All @@ -62,10 +63,11 @@ Irina-Maria Stanescu
1.6. Setting the diverter_avp_id parameter
1.7. Setting the prepaid_account_flag parameter
1.8. Setting the call_limit_avp parameter
1.9. Setting the init parameter
1.10. Setting the start parameter
1.11. Setting the stop parameter
1.12. Using the call_control function
1.9. Setting the call_token_avp parameter
1.10. Setting the init parameter
1.11. Setting the start parameter
1.12. Setting the stop parameter
1.13. Using the call_control function

Chapter 1. Admin Guide

Expand Down Expand Up @@ -161,6 +163,9 @@ Features
(From user or diverter) is able to make. If the limit is
reached the call_control function will return a specific
error value.
* The call_token_avp may be used to detect calls with a
duplicated CallID that could create potential problems in
call rating engines.

Dependencies

Expand Down Expand Up @@ -327,6 +332,24 @@ call_limit_avp (string)
modparam("call_control", "call_limit_avp", "$avp(cc_call_limit)")
...

call_token_avp (string)

Specification of the AVP which holds an optional application
defined token. This token will be used to check if two calls
with the same CallID actually refer to the same call. If
call_control() is called multiple times for the same call (thus
same CallID) the token needs to be the same or call_control
will return -3 error, indicating that the CallID is duplicated.

Default value is “$avp(cc_call_token)”.

Example 1.9. Setting the call_token_avp parameter
...
modparam("call_control", "call_token_avp", "$avp(cc_call_token)")
...
$avp(cc_call_token) := $RANDOM;
...

init (string)

This parameter is used to describe custom call control
Expand All @@ -345,7 +368,7 @@ init (string)

Default value is “NULL”.

Example 1.9. Setting the init parameter
Example 1.10. Setting the init parameter

...
modparam("call_control", "init", "call-id=$ci to=$tu from=$fu
Expand All @@ -369,7 +392,7 @@ start (string)

Default value is “NULL”.

Example 1.10. Setting the start parameter
Example 1.11. Setting the start parameter

...
modparam("call_control", "start", "call-id=$ci to=$tu from=$fu
Expand All @@ -393,7 +416,7 @@ stop (string)

Default value is “NULL”.

Example 1.11. Setting the stop parameter
Example 1.12. Setting the stop parameter

...
modparam("call_control", "stop", "call-id=$ci to=$tu from=$fu
Expand Down Expand Up @@ -428,7 +451,7 @@ call_control()

This function can be used from REQUEST_ROUTE.

Example 1.12. Using the call_control function
Example 1.13. Using the call_control function

...
if (is_avp_set("$avp(805)")) {
Expand Down
48 changes: 47 additions & 1 deletion modules/call_control/call_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#define SIGNALING_IP_AVP_SPEC "$avp(cc_signaling_ip)"
#define DIVERTER_AVP_SPEC "$avp(805)"
#define CALL_LIMIT_AVP_SPEC "$avp(cc_call_limit)"
#define CALL_TOKEN_AVP_SPEC "$avp(cc_call_token)"

// Although `AF_LOCAL' is mandated by POSIX.1g, `AF_UNIX' is portable to
// more systems. `AF_UNIX' was the traditional name stemming from BSD, so
Expand Down Expand Up @@ -149,6 +150,9 @@ static AVP_Param signaling_ip_avp = {str_init(SIGNALING_IP_AVP_SPEC), -1, 0};
/* The AVP where the call limit is stored (if defined) */
static AVP_Param call_limit_avp = {str_init(CALL_LIMIT_AVP_SPEC), -1, 0};

/* The AVP where the call token is stored (if defined) */
static AVP_Param call_token_avp = {str_init(CALL_TOKEN_AVP_SPEC), -1, 0};


struct tm_binds tm_api;
struct dlg_binds dlg_api;
Expand All @@ -174,6 +178,7 @@ static param_export_t parameters[] = {
{"canonical_uri_avp", STR_PARAM, &(canonical_uri_avp.spec.s)},
{"signaling_ip_avp", STR_PARAM, &(signaling_ip_avp.spec.s)},
{"call_limit_avp", STR_PARAM, &(call_limit_avp.spec.s)},
{"call_token_avp", STR_PARAM, &(call_token_avp.spec.s)},
{"prepaid_account_flag", INT_PARAM, &prepaid_account_flag},
{0, 0, 0}
};
Expand Down Expand Up @@ -223,6 +228,7 @@ typedef struct CallInfo {
str callid;
str from;
str from_tag;
str call_token;
char* prepaid_account;
int call_limit;
} CallInfo;
Expand Down Expand Up @@ -468,6 +474,28 @@ get_call_limit(struct sip_msg* msg)
}


static str
get_call_token(struct sip_msg* msg)
{
int_str value;
struct usr_avp *avp;
static str call_token;

call_token.s = "None";
call_token.len = 4;

avp = search_first_avp(call_token_avp.type, call_token_avp.name, &value, NULL);
if (avp) {
if (avp->flags & AVP_VAL_STR) {
call_token = value.s;
} else {
call_token.s = int2str(value.n, &call_token.len);
}
}
return call_token;
}


static CallInfo*
get_call_info(struct sip_msg *msg, CallControlAction action)
{
Expand Down Expand Up @@ -537,6 +565,7 @@ get_call_info(struct sip_msg *msg, CallControlAction action)
call_info.diverter = get_diverter(msg);
call_info.source_ip = get_signaling_ip(msg);
call_info.call_limit = get_call_limit(msg);
call_info.call_token = get_call_token(msg);
if (prepaid_account_flag >= 0) {
call_info.prepaid_account = isflagset(msg, prepaid_account_flag)==1 ? "true" : "false";
} else {
Expand Down Expand Up @@ -613,6 +642,7 @@ make_default_request(CallInfo *call)
"fromtag: %.*s\r\n"
"prepaid: %s\r\n"
"call_limit: %d\r\n"
"call_token: %.*s\r\n"
"\r\n",
call->ruri.len, call->ruri.s,
call->diverter.len, call->diverter.s,
Expand All @@ -621,7 +651,8 @@ make_default_request(CallInfo *call)
call->from.len, call->from.s,
call->from_tag.len, call->from_tag.s,
call->prepaid_account,
call->call_limit);
call->call_limit,
call->call_token.len, call->call_token.s);

if (len >= sizeof(request)) {
LM_ERR("callcontrol request is longer than %ld bytes\n", (unsigned long)sizeof(request));
Expand Down Expand Up @@ -1115,6 +1146,21 @@ mod_init(void)
return -1;
}

// initialize the call_token_avp structure
if (call_token_avp.spec.s==NULL || *(call_token_avp.spec.s)==0) {
LM_ERR("missing/empty call_token_avp parameter. using default.\n");
call_token_avp.spec.s = CALL_TOKEN_AVP_SPEC;
}
call_token_avp.spec.len = strlen(call_token_avp.spec.s);
if (pv_parse_spec(&(call_token_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
LM_CRIT("invalid AVP specification for call_token_avp: `%s'\n", call_token_avp.spec.s);
return -1;
}
if (pv_get_avp_name(0, &(avp_spec.pvp), &(call_token_avp.name), &(call_token_avp.type))!=0) {
LM_CRIT("invalid AVP specification for call_token_avp: `%s'\n", call_token_avp.spec.s);
return -1;
}

// initialize the diverter_avp_id structure
if (diverter_avp_id.spec.s==NULL || *(diverter_avp_id.spec.s)==0) {
LM_ERR("missing/empty diverter_avp parameter. using default.\n");
Expand Down
37 changes: 37 additions & 0 deletions modules/call_control/doc/call_control_admin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,14 @@
is reached the call_control function will return a specific error value.
</para>
</listitem>

<listitem>
<para>
The call_token_avp may be used to detect calls with a duplicated CallID that could
create potential problems in call rating engines.
</para>
</listitem>

</itemizedlist>
</para>
</section>
Expand Down Expand Up @@ -416,6 +424,35 @@ modparam("call_control", "call_limit_avp", "$avp(cc_call_limit)")
</example>
</section>

<section>
<title><varname>call_token_avp</varname> (string)</title>
<para>
Specification of the AVP which holds an optional application defined
token. This token will be used to check if two calls with the same
CallID actually refer to the same call. If call_control() is called
multiple times for the same call (thus same CallID) the token needs
to be the same or call_control will return -3 error, indicating that
the CallID is duplicated.
</para>

<para>
<emphasis>
Default value is <quote>$avp(cc_call_token)</quote>.
</emphasis>
</para>

<example>
<title>Setting the <varname>call_token_avp</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("call_control", "call_token_avp", "$avp(cc_call_token)")
...
$avp(cc_call_token) := $RANDOM;
...
</programlisting>
</example>
</section>

<section>
<title><varname>init</varname> (string)</title>
<para>
Expand Down

0 comments on commit ca6e9a5

Please sign in to comment.