enclosed find diff to 1.4 sbc app that adds simultaneous call control
via profile vars:
enable_call_control=yes
call_control_uuid=$fu
call_control_max_calls=$P(max_calls)
it is ok with me to change code to utilize a general purpose call
control api once available.
one thing i feel uncomfortable is cancel handling. i added to
onSipRequest:
if (req.method == "CANCEL") decCallControlCalls();
what if caller sends many cancels back-to-back? will each of them cause
decCallControlCalls() call? if so, how to avoid it?
-- juha
diff -c -r /usr/src/orig/sems/apps/sbc//SBCCallProfile.cpp ./SBCCallProfile.cpp
*** /usr/src/orig/sems/apps/sbc//SBCCallProfile.cpp 2011-09-17
14:08:27.000000000 +0300
--- ./SBCCallProfile.cpp 2011-09-17 13:43:05.000000000 +0300
***************
*** 123,128 ****
--- 123,132 ----
prepaid_uuid = cfg.getParameter("prepaid_uuid");
prepaid_acc_dest = cfg.getParameter("prepaid_acc_dest");
+ call_control_enabled = cfg.getParameter("enable_call_control", "no") ==
"yes";
+ call_control_uuid = cfg.getParameter("call_control_uuid");
+ call_control_max_calls = cfg.getParameter("call_control_max_calls");
+
// check for acc module if configured statically
if (prepaid_enabled &&
(prepaid_accmodule.find('$') == string::npos) &&
***************
*** 238,243 ****
--- 242,252 ----
INFO("SBC: uuid = '%s'\n",
prepaid_uuid.c_str());
INFO("SBC: acc_dest = '%s'\n",
prepaid_acc_dest.c_str());
}
+ INFO("SBC: call_control %sabled\n", call_control_enabled?"en":"dis");
+ if (call_control_enabled) {
+ INFO("SBC: uuid = '%s'\n",
call_control_uuid.c_str());
+ INFO("SBC: max_calls = '%s'\n",
call_control_max_calls.c_str());
+ }
if (reply_translations.size()) {
string reply_trans_codes;
for(map<unsigned int, std::pair<unsigned int, string> >::iterator it=
***************
*** 277,282 ****
--- 286,292 ----
auth_enabled == rhs.auth_enabled &&
call_timer_enabled == rhs.call_timer_enabled &&
prepaid_enabled == rhs.prepaid_enabled &&
+ call_control_enabled == rhs.call_control_enabled &&
reply_translations == rhs.reply_translations &&
append_headers == rhs.append_headers &&
refuse_with == rhs.refuse_with &&
***************
*** 304,309 ****
--- 314,324 ----
prepaid_uuid == rhs.prepaid_uuid &&
prepaid_acc_dest == rhs.prepaid_acc_dest;
}
+ if (call_control_enabled) {
+ res = res &&
+ call_control_uuid == rhs.call_control_uuid &&
+ call_control_max_calls == rhs.call_control_max_calls;
+ }
return res;
}
***************
*** 346,351 ****
--- 361,369 ----
res += "prepaid_accmodule: " + prepaid_accmodule + "\n";
res += "prepaid_uuid: " + prepaid_uuid + "\n";
res += "prepaid_acc_dest: " + prepaid_acc_dest + "\n";
+ res += "call_control_enabled: " +
string(call_control_enabled?"true":"false") + "\n";
+ res += "call_control_uuid: " + call_control_uuid + "\n";
+ res += "call_control_max_calls: " + call_control_max_calls + "\n";
res += "rtprelay_enabled: " + string(rtprelay_enabled?"true":"false") +
"\n";
res += "force_symmetric_rtp: " + force_symmetric_rtp;
res += "msgflags_symmetric_rtp: " +
string(msgflags_symmetric_rtp?"true":"false") + "\n";
diff -c -r /usr/src/orig/sems/apps/sbc//SBCCallProfile.h ./SBCCallProfile.h
*** /usr/src/orig/sems/apps/sbc//SBCCallProfile.h 2011-09-17
14:08:27.000000000 +0300
--- ./SBCCallProfile.h 2011-09-17 12:00:23.000000000 +0300
***************
*** 82,87 ****
--- 82,92 ----
string prepaid_uuid;
string prepaid_acc_dest;
+ bool call_control_enabled;
+ string call_control_uuid;
+ string call_control_max_calls;
+ unsigned short call_control_max_calls_i;
+
map<unsigned int, std::pair<unsigned int, string> > reply_translations;
string append_headers;
***************
*** 105,110 ****
--- 110,116 ----
auth_enabled(false),
call_timer_enabled(false),
prepaid_enabled(false),
+ call_control_enabled(false),
rtprelay_enabled(false)
{ }
diff -c -r /usr/src/orig/sems/apps/sbc//SBC.cpp ./SBC.cpp
*** /usr/src/orig/sems/apps/sbc//SBC.cpp 2011-09-17 14:08:27.000000000
+0300
--- ./SBC.cpp 2011-09-17 14:04:05.000000000 +0300
***************
*** 53,58 ****
--- 53,61 ----
AmSessionEventHandlerFactory* SBCFactory::session_timer_fact = NULL;
RegexMapper SBCFactory::regex_mappings;
+ static map <string, unsigned short> call_control_calls;
+ static AmMutex call_control_calls_mut;
+
EXPORT_MODULE_FACTORY(SBCFactory);
DEFINE_MODULE_INSTANCE(SBCFactory, MOD_NAME);
***************
*** 697,702 ****
--- 700,751 ----
}
}
+ if (call_profile.call_control_enabled) {
+ unsigned int call_control_max_calls_i;
+ call_profile.call_control_uuid =
+ replaceParameters(call_profile.call_control_uuid,
+ "call_control_uuid", REPLACE_VALS);
+ if (!call_profile.call_control_max_calls.empty()) {
+ call_profile.call_control_max_calls =
+ replaceParameters(call_profile.call_control_max_calls,
+ "call_control_max_calls", REPLACE_VALS);
+ if (str2i(call_profile.call_control_max_calls,
+ call_control_max_calls_i)) {
+ ERROR("call_control_max_calls '%s' not understood\n",
+ call_profile.call_control_max_calls.c_str());
+ throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
+ }
+ if (call_control_max_calls_i > 255) {
+ ERROR("call_control_max_calls value '%u' too large\n",
+ call_control_max_calls_i);
+ throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
+ }
+ } else {
+ call_control_max_calls_i = 1;
+ }
+ call_profile.call_control_max_calls_i = call_control_max_calls_i;
+ INFO("set call_control_max_calls to '%u'\n", call_control_max_calls_i);
+ call_control_calls_mut.lock();
+ map<string, unsigned short>::iterator it =
+ call_control_calls.find(call_profile.call_control_uuid);
+ if (it == call_control_calls.end()) {
+ INFO("call_control call count for '%s' not found\n",
+ call_profile.call_control_uuid.c_str());
+ call_control_calls[call_profile.call_control_uuid] = 1;
+ } else {
+ if (it->second >= call_control_max_calls_i) {
+ call_control_calls_mut.unlock();
+ throw AmSession::Exception(402, "Too Many Simultaneous Calls");
+ } else {
+ call_control_calls[call_profile.call_control_uuid]++;
+ }
+ }
+ INFO("call_control active calls for uuid '%s' is '%u'\n",
+ call_profile.call_control_uuid.c_str(),
+ call_control_calls[call_profile.call_control_uuid]);
+ call_control_calls_mut.unlock();
+ }
+
#undef REPLACE_VALS
DBG("SBC: connecting to '%s'\n",ruri.c_str());
***************
*** 810,815 ****
--- 859,866 ----
CALL_EVENT_H(onSipRequest,req);
}
+ if (req.method == "CANCEL") decCallControlCalls();
+
if (fwd && call_profile.messagefilter != Transparent) {
bool is_filtered = (call_profile.messagefilter == Whitelist) ^
(call_profile.messagefilter_list.find(req.method) !=
***************
*** 859,864 ****
--- 910,916 ----
}
else {
DBG("Callee final error with code %d\n",reply.code);
+ decCallControlCalls();
ret = AmB2BCallerSession::onOtherReply(reply);
}
}
***************
*** 869,874 ****
--- 921,927 ----
void SBCDialog::onOtherBye(const AmSipRequest& req)
{
stopPrepaidAccounting();
+ decCallControlCalls();
stopCallTimer();
AmB2BCallerSession::onOtherBye(req);
}
***************
*** 891,896 ****
--- 944,950 ----
void SBCDialog::stopCall() {
if (m_state == BB_Connected) {
stopPrepaidAccounting();
+ decCallControlCalls();
stopCallTimer();
}
terminateOtherLeg();
***************
*** 987,992 ****
--- 1041,1068 ----
}
}
+ void SBCDialog::decCallControlCalls() {
+
+ if (!call_profile.call_control_enabled)
+ return;
+
+ call_control_calls_mut.lock();
+ std::map<string, unsigned short>::iterator it =
+ call_control_calls.find(call_profile.call_control_uuid);
+ if (it == call_control_calls.end()) {
+ call_control_calls_mut.unlock();
+ return;
+ }
+ if (it->second > 1) {
+ call_control_calls[call_profile.call_control_uuid]--;
+ } else {
+ call_control_calls.erase(it);
+ }
+ call_control_calls_mut.unlock();
+ call_control_calls_mut.unlock();
+ return;
+ }
+
void SBCDialog::createCalleeSession()
{
SBCCalleeSession* callee_session = new SBCCalleeSession(this, call_profile);
diff -c -r /usr/src/orig/sems/apps/sbc//SBC.h ./SBC.h
*** /usr/src/orig/sems/apps/sbc//SBC.h 2011-09-17 14:08:27.000000000 +0300
--- ./SBC.h 2011-09-17 10:32:24.000000000 +0300
***************
*** 122,127 ****
--- 122,130 ----
void startPrepaidAccounting();
void stopPrepaidAccounting();
+ // call control
+ void decCallControlCalls();
+
bool getPrepaidInterface();
public:
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev