Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
9bf2726e
提交
9bf2726e
authored
3月 15, 2012
作者:
Jeff Lenk
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
FS-3950 --resolve nibblebill changes!
上级
842203f7
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
73 行增加
和
42 行删除
+73
-42
mod_nibblebill.c
src/mod/applications/mod_nibblebill/mod_nibblebill.c
+73
-42
没有找到文件。
src/mod/applications/mod_nibblebill/mod_nibblebill.c
浏览文件 @
9bf2726e
...
...
@@ -52,19 +52,20 @@
typedef
struct
{
switch_time_t
lastts
;
/* Last time we did any billing */
float
total
;
/* Total amount billed so far */
double
total
;
/* Total amount billed so far */
switch_time_t
pausets
;
/* Timestamp of when a pause action started. 0 if not paused */
float
bill_adjustments
;
/* Adjustments to make to the next billing, based on pause/resume events */
double
bill_adjustments
;
/* Adjustments to make to the next billing, based on pause/resume events */
int
lowbal_action_executed
;
/* Set to 1 once lowbal_action has been executed */
}
nibble_data_t
;
typedef
struct
nibblebill_results
{
float
balance
;
double
balance
;
float
percall_max
;
/* Overrides global on a per-user level */
float
lowbal_amt
;
/* ditto */
double
percall_max
;
/* Overrides global on a per-user level */
double
lowbal_amt
;
/* ditto */
}
nibblebill_results_t
;
...
...
@@ -80,11 +81,11 @@ static struct {
switch_mutex_t
*
mutex
;
/* Global billing config options */
float
percall_max_amt
;
/* Per-call billing limit (safety check, for fraud) */
double
percall_max_amt
;
/* Per-call billing limit (safety check, for fraud) */
char
*
percall_action
;
/* Exceeded length of per-call action */
float
lowbal_amt
;
/* When we warn them they are near depletion */
double
lowbal_amt
;
/* When we warn them they are near depletion */
char
*
lowbal_action
;
/* Low balance action */
float
nobal_amt
;
/* Minimum amount that must remain in the account */
double
nobal_amt
;
/* Minimum amount that must remain in the account */
char
*
nobal_action
;
/* Drop action */
/* Other options */
...
...
@@ -136,7 +137,7 @@ static int nibblebill_callback(void *pArg, int argc, char **argv, char **columnN
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
if
(
!
strcasecmp
(
columnNames
[
i
],
"nibble_balance"
))
{
cbt
->
balance
=
(
float
)
atof
(
argv
[
0
]);
cbt
->
balance
=
atof
(
argv
[
0
]);
}
}
...
...
@@ -179,15 +180,15 @@ static switch_status_t load_config(void)
}
else
if
(
!
strcasecmp
(
var
,
"percall_action"
))
{
set_global_percall_action
(
val
);
}
else
if
(
!
strcasecmp
(
var
,
"percall_max_amt"
))
{
globals
.
percall_max_amt
=
(
float
)
atof
(
val
);
globals
.
percall_max_amt
=
atof
(
val
);
}
else
if
(
!
strcasecmp
(
var
,
"lowbal_action"
))
{
set_global_lowbal_action
(
val
);
}
else
if
(
!
strcasecmp
(
var
,
"lowbal_amt"
))
{
globals
.
lowbal_amt
=
(
float
)
atof
(
val
);
globals
.
lowbal_amt
=
atof
(
val
);
}
else
if
(
!
strcasecmp
(
var
,
"nobal_action"
))
{
set_global_nobal_action
(
val
);
}
else
if
(
!
strcasecmp
(
var
,
"nobal_amt"
))
{
globals
.
nobal_amt
=
(
float
)
atof
(
val
);
globals
.
nobal_amt
=
atof
(
val
);
}
else
if
(
!
strcasecmp
(
var
,
"global_heartbeat"
))
{
globals
.
global_heartbeat
=
atoi
(
val
);
}
...
...
@@ -252,6 +253,23 @@ void debug_event_handler(switch_event_t *event)
}
}
static
switch_status_t
exec_app
(
switch_core_session_t
*
session
,
const
char
*
app_string
)
{
switch_status_t
status
;
char
*
strings
[
2
]
=
{
0
};
char
*
dup
;
if
(
!
app_string
)
{
return
SWITCH_STATUS_FALSE
;
}
dup
=
strdup
(
app_string
);
switch_assert
(
dup
);
switch_separate_string
(
dup
,
' '
,
strings
,
sizeof
(
strings
)
/
sizeof
(
strings
[
0
]));
status
=
switch_core_session_execute_application
(
session
,
strings
[
0
],
strings
[
1
]);
free
(
dup
);
return
status
;
}
static
void
transfer_call
(
switch_core_session_t
*
session
,
char
*
destination
)
{
...
...
@@ -292,9 +310,8 @@ static void transfer_call(switch_core_session_t *session, char *destination)
free
(
mydup
);
}
/* At this time, billing never succeeds if you don't have a database. */
static
switch_status_t
bill_event
(
float
billamount
,
const
char
*
billaccount
,
switch_channel_t
*
channel
)
static
switch_status_t
bill_event
(
double
billamount
,
const
char
*
billaccount
,
switch_channel_t
*
channel
)
{
char
*
sql
=
NULL
,
*
dsql
=
NULL
;
switch_odbc_statement_handle_t
stmt
=
NULL
;
...
...
@@ -306,7 +323,7 @@ static switch_status_t bill_event(float billamount, const char *billaccount, swi
if
(
globals
.
custom_sql_save
)
{
if
(
switch_string_var_check_const
(
globals
.
custom_sql_save
)
||
switch_string_has_escaped_data
(
globals
.
custom_sql_save
))
{
switch_channel_set_variable_printf
(
channel
,
"nibble_
increment
"
,
"%f"
,
billamount
,
SWITCH_FALSE
);
switch_channel_set_variable_printf
(
channel
,
"nibble_
bill
"
,
"%f"
,
billamount
,
SWITCH_FALSE
);
sql
=
switch_channel_expand_variables
(
channel
,
globals
.
custom_sql_save
);
if
(
sql
!=
globals
.
custom_sql_save
)
dsql
=
sql
;
}
else
{
...
...
@@ -339,14 +356,14 @@ static switch_status_t bill_event(float billamount, const char *billaccount, swi
}
static
float
get_balance
(
const
char
*
billaccount
,
switch_channel_t
*
channel
)
static
double
get_balance
(
const
char
*
billaccount
,
switch_channel_t
*
channel
)
{
char
*
dsql
=
NULL
,
*
sql
=
NULL
;
nibblebill_results_t
pdata
;
float
balance
=
0
.
00
f
;
double
balance
=
0
.
0
;
if
(
!
switch_odbc_available
())
{
return
-
1
.
0
0
f
;
return
-
1
.
0
;
}
memset
(
&
pdata
,
0
,
sizeof
(
pdata
));
...
...
@@ -369,7 +386,7 @@ static float get_balance(const char *billaccount, switch_channel_t *channel)
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Error running this query: [%s]
\n
"
,
sql
);
/* Return -1 for safety */
balance
=
-
1
.
0
0
f
;
balance
=
-
1
.
0
;
}
else
{
/* Successfully retrieved! */
balance
=
pdata
.
balance
;
...
...
@@ -391,7 +408,7 @@ static switch_status_t do_billing(switch_core_session_t *session)
/* Local vars */
nibble_data_t
*
nibble_data
;
switch_time_t
ts
=
switch_micro_time_now
();
float
billamount
;
double
billamount
;
char
date
[
80
]
=
""
;
char
*
uuid
;
switch_size_t
retsize
;
...
...
@@ -399,9 +416,9 @@ static switch_status_t do_billing(switch_core_session_t *session)
const
char
*
billrate
;
const
char
*
billincrement
;
const
char
*
billaccount
;
float
nobal_amt
=
globals
.
nobal_amt
;
//float
lowbal_amt = globals.lowbal_amt;
float
balance
;
double
nobal_amt
=
globals
.
nobal_amt
;
double
lowbal_amt
=
globals
.
lowbal_amt
;
double
balance
;
if
(
!
session
)
{
/* Why are we here? */
...
...
@@ -421,13 +438,13 @@ static switch_status_t do_billing(switch_core_session_t *session)
billaccount
=
switch_channel_get_variable
(
channel
,
"nibble_account"
);
if
(
!
zstr
(
switch_channel_get_variable
(
channel
,
"nobal_amt"
)))
{
nobal_amt
=
(
float
)
atof
(
switch_channel_get_variable
(
channel
,
"nobal_amt"
));
nobal_amt
=
atof
(
switch_channel_get_variable
(
channel
,
"nobal_amt"
));
}
/*
if
(
!
zstr
(
switch_channel_get_variable
(
channel
,
"lowbal_amt"
)))
{
lowbal_amt =
(float)
atof(switch_channel_get_variable(channel, "lowbal_amt"));
lowbal_amt
=
atof
(
switch_channel_get_variable
(
channel
,
"lowbal_amt"
));
}
*/
/* Return if there's no billing information on this session */
if
(
!
billrate
||
!
billaccount
)
{
return
SWITCH_STATUS_SUCCESS
;
...
...
@@ -497,11 +514,15 @@ static switch_status_t do_billing(switch_core_session_t *session)
if
((
ts
-
nibble_data
->
lastts
)
>=
0
)
{
/* If billincrement is set we bill by it and not by time elapsed */
if
(
!
(
switch_strlen_zero
(
billincrement
)))
{
float
chargedunits
=
((
int
)((
ts
-
nibble_data
->
lastts
)
/
1000000
)
<=
(
int
)
atof
(
billincrement
))
?
((
float
)
atof
(
billincrement
)
*
1000000
)
:
ceil
((
ts
-
nibble_data
->
lastts
)
/
((
float
)
atof
(
billincrement
)
*
1000000
))
*
((
float
)
atof
(
billincrement
)
*
1000000
);
billamount
=
((
float
)
atof
(
billrate
)
/
1000000
/
60
)
*
chargedunits
-
nibble_data
->
bill_adjustments
;
switch_time_t
chargedunits
=
(
ts
-
nibble_data
->
lastts
)
/
1000000
<=
atol
(
billincrement
)
?
atol
(
billincrement
)
*
1000000
:
(
switch_time_t
)(
ceil
((
ts
-
nibble_data
->
lastts
)
/
(
atol
(
billincrement
)
*
1000000
.
0
)))
*
atol
(
billincrement
)
*
1000000
;
billamount
=
(
atof
(
billrate
)
/
1000000
/
60
)
*
chargedunits
-
nibble_data
->
bill_adjustments
;
/* Account for the prepaid amount */
nibble_data
->
lastts
+=
chargedunits
;
}
else
{
/* Convert billrate into microseconds and multiply by # of microseconds that have passed since last *successful* bill */
billamount
=
((
float
)
atof
(
billrate
)
/
1000000
/
60
)
*
((
ts
-
nibble_data
->
lastts
))
-
nibble_data
->
bill_adjustments
;
billamount
=
(
atof
(
billrate
)
/
1000000
/
60
)
*
((
ts
-
nibble_data
->
lastts
))
-
nibble_data
->
bill_adjustments
;
/* Update the last time we billed */
nibble_data
->
lastts
=
ts
;
}
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
session
),
SWITCH_LOG_DEBUG
,
"Billing $%f to %s (Call: %s / %f so far)
\n
"
,
billamount
,
billaccount
,
...
...
@@ -521,21 +542,31 @@ static switch_status_t do_billing(switch_core_session_t *session)
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
session
),
SWITCH_LOG_CRIT
,
"Failed to log to database!
\n
"
);
}
}
else
{
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
session
),
SWITCH_LOG_WARNING
,
"Just tried to bill %s negative minutes! That should be impossible.
\n
"
,
uuid
);
if
(
switch_strlen_zero
(
billincrement
))
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
session
),
SWITCH_LOG_WARNING
,
"Just tried to bill %s negative minutes! That should be impossible.
\n
"
,
uuid
);
}
/* Update the last time we billed */
nibble_data
->
lastts
=
ts
;
/* Save this location */
if
(
channel
)
{
switch_channel_set_private
(
channel
,
"_nibble_data_"
,
nibble_data
);
/* don't verify balance and transfer to nobal if we're done with call */
if
(
switch_channel_get_state
(
channel
)
!=
CS_REPORTING
&&
switch_channel_get_state
(
channel
)
!=
CS_HANGUP
)
{
/* See if this person has enough money left to continue the call */
balance
=
get_balance
(
billaccount
,
channel
);
/* See if we've achieved low balance */
if
(
!
nibble_data
->
lowbal_action_executed
&&
balance
<=
lowbal_amt
)
{
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
session
),
SWITCH_LOG_DEBUG
,
"Balance of %f fell below low balance amount of %f! (Account %s)
\n
"
,
balance
,
lowbal_amt
,
billaccount
);
if
(
exec_app
(
session
,
globals
.
lowbal_action
)
!=
SWITCH_STATUS_SUCCESS
)
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
session
),
SWITCH_LOG_ERROR
,
"Low balance action didn't execute
\n
"
);
else
nibble_data
->
lowbal_action_executed
=
1
;
}
/* See if this person has enough money left to continue the call */
if
(
balance
<=
nobal_amt
)
{
/* Not enough money - reroute call to nobal location */
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
session
),
SWITCH_LOG_CRIT
,
"Balance of %f fell below allowed amount of %f! (Account %s)
\n
"
,
...
...
@@ -665,7 +696,7 @@ static void nibblebill_resume(switch_core_session_t *session)
billrate
=
switch_channel_get_variable
(
channel
,
"nibble_rate"
);
/* Calculate how much was "lost" to billings during pause - we do this here because you never know when the billrate may change during a call */
nibble_data
->
bill_adjustments
+=
(
(
float
)
atof
(
billrate
)
/
1000000
/
60
)
*
((
ts
-
nibble_data
->
pausets
));
nibble_data
->
bill_adjustments
+=
(
atof
(
billrate
)
/
1000000
/
60
)
*
((
ts
-
nibble_data
->
pausets
));
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
session
),
SWITCH_LOG_INFO
,
"Resumed billing! Subtracted %f from this billing cycle.
\n
"
,
(
atof
(
billrate
)
/
1000000
/
60
)
*
((
ts
-
nibble_data
->
pausets
)));
...
...
@@ -711,11 +742,11 @@ static void nibblebill_reset(switch_core_session_t *session)
}
}
static
float
nibblebill_check
(
switch_core_session_t
*
session
)
static
double
nibblebill_check
(
switch_core_session_t
*
session
)
{
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
nibble_data_t
*
nibble_data
;
float
amount
=
0
;
double
amount
=
0
;
if
(
!
channel
)
{
return
-
99999
;
...
...
@@ -744,7 +775,7 @@ static float nibblebill_check(switch_core_session_t *session)
return
amount
;
}
static
void
nibblebill_adjust
(
switch_core_session_t
*
session
,
float
amount
)
static
void
nibblebill_adjust
(
switch_core_session_t
*
session
,
double
amount
)
{
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
const
char
*
billaccount
;
...
...
@@ -780,7 +811,7 @@ SWITCH_STANDARD_APP(nibblebill_app_function)
if
(
!
zstr
(
data
)
&&
(
lbuf
=
strdup
(
data
))
&&
(
argc
=
switch_separate_string
(
lbuf
,
' '
,
argv
,
(
sizeof
(
argv
)
/
sizeof
(
argv
[
0
])))))
{
if
(
!
strcasecmp
(
argv
[
0
],
"adjust"
)
&&
argc
==
2
)
{
nibblebill_adjust
(
session
,
(
float
)
atof
(
argv
[
1
]));
nibblebill_adjust
(
session
,
atof
(
argv
[
1
]));
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"flush"
))
{
do_billing
(
session
);
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"pause"
))
{
...
...
@@ -812,7 +843,7 @@ SWITCH_STANDARD_API(nibblebill_api_function)
char
*
uuid
=
argv
[
0
];
if
((
psession
=
switch_core_session_locate
(
uuid
)))
{
if
(
!
strcasecmp
(
argv
[
1
],
"adjust"
)
&&
argc
==
3
)
{
nibblebill_adjust
(
psession
,
(
float
)
atof
(
argv
[
2
]));
nibblebill_adjust
(
psession
,
atof
(
argv
[
2
]));
}
else
if
(
!
strcasecmp
(
argv
[
1
],
"flush"
))
{
do_billing
(
psession
);
}
else
if
(
!
strcasecmp
(
argv
[
1
],
"pause"
))
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论