From e1faea548c7bb67d0287087ed1feb97aab98b45f Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Thu, 18 Nov 2010 02:45:25 +0100 Subject: [PATCH] moved call profile to own src file --- apps/sbc/CMakeLists.txt | 1 + apps/sbc/SBC.cpp | 181 ---------------------------------- apps/sbc/SBC.h | 61 +----------- apps/sbc/SBCCallProfile.cpp | 189 ++++++++++++++++++++++++++++++++++++ apps/sbc/SBCCallProfile.h | 77 +++++++++++++++ 5 files changed, 268 insertions(+), 241 deletions(-) create mode 100644 apps/sbc/SBCCallProfile.cpp create mode 100644 apps/sbc/SBCCallProfile.h diff --git a/apps/sbc/CMakeLists.txt b/apps/sbc/CMakeLists.txt index 5f015239..d25693e8 100644 --- a/apps/sbc/CMakeLists.txt +++ b/apps/sbc/CMakeLists.txt @@ -1,5 +1,6 @@ set (sbc_SRCS SBC.cpp +SBCCallProfile.cpp HeaderFilter.cpp ParamReplacer.cpp SDPFilter.cpp diff --git a/apps/sbc/SBC.cpp b/apps/sbc/SBC.cpp index 3fad5a43..0c66bb42 100644 --- a/apps/sbc/SBC.cpp +++ b/apps/sbc/SBC.cpp @@ -52,7 +52,6 @@ SBC - feature-wishlist #include "ParamReplacer.h" #include "SDPFilter.h" -#include using std::map; string SBCFactory::user; @@ -64,186 +63,6 @@ AmSessionEventHandlerFactory* SBCFactory::session_timer_fact = NULL; EXPORT_SESSION_FACTORY(SBCFactory,MOD_NAME); -bool SBCCallProfile::readFromConfiguration(const string& name, - const string profile_file_name) { - if (cfg.loadFile(profile_file_name)) { - ERROR("reading SBC call profile from '%s'\n", profile_file_name.c_str()); - return false; - } - - ruri = cfg.getParameter("RURI"); - from = cfg.getParameter("From"); - to = cfg.getParameter("To"); - - callid = cfg.getParameter("Call-ID"); - - force_outbound_proxy = cfg.getParameter("force_outbound_proxy") == "yes"; - outbound_proxy = cfg.getParameter("outbound_proxy"); - - next_hop_ip = cfg.getParameter("next_hop_ip"); - next_hop_port = cfg.getParameter("next_hop_port"); - - string hf_type = cfg.getParameter("header_filter", "transparent"); - if (hf_type=="transparent") - headerfilter = Transparent; - else if (hf_type=="whitelist") - headerfilter = Whitelist; - else if (hf_type=="blacklist") - headerfilter = Blacklist; - else { - ERROR("invalid header_filter mode '%s'\n", hf_type.c_str()); - return false; - } - - vector elems = explode(cfg.getParameter("header_list"), ","); - for (vector::iterator it=elems.begin(); it != elems.end(); it++) - headerfilter_list.insert(*it); - - string mf_type = cfg.getParameter("message_filter", "transparent"); - if (mf_type=="transparent") - messagefilter = Transparent; - else if (mf_type=="whitelist") - messagefilter = Whitelist; - else if (hf_type=="blacklist") - messagefilter = Blacklist; - else { - ERROR("invalid message_filter mode '%s'\n", mf_type.c_str()); - return false; - } - - elems = explode(cfg.getParameter("message_list"), ","); - for (vector::iterator it=elems.begin(); it != elems.end(); it++) - messagefilter_list.insert(*it); - - string sdp_filter = cfg.getParameter("sdp_filter"); - if (sdp_filter=="transparent") { - sdpfilter_enabled = true; - sdpfilter = Transparent; - } else if (sdp_filter=="whitelist") { - sdpfilter_enabled = true; - sdpfilter = Whitelist; - } else if (sdp_filter=="blacklist") { - sdpfilter_enabled = true; - sdpfilter = Blacklist; - } else { - sdpfilter_enabled = false; - } - if (sdpfilter_enabled) { - vector c_elems = explode(cfg.getParameter("sdpfilter_list"), ","); - for (vector::iterator it=c_elems.begin(); it != c_elems.end(); it++) { - string c = *it; - std::transform(c.begin(), c.end(), c.begin(), ::tolower); - sdpfilter_list.insert(c); - } - } - - sst_enabled = cfg.getParameter("enable_session_timer", "no") == "yes"; - use_global_sst_config = !cfg.hasParameter("session_expires"); - - auth_enabled = cfg.getParameter("enable_auth", "no") == "yes"; - auth_credentials.user = cfg.getParameter("auth_user"); - auth_credentials.pwd = cfg.getParameter("auth_pwd"); - - call_timer_enabled = cfg.getParameter("enable_call_timer", "no") == "yes"; - call_timer = cfg.getParameter("call_timer"); - - prepaid_enabled = cfg.getParameter("enable_prepaid", "no") == "yes"; - prepaid_accmodule = cfg.getParameter("prepaid_accmodule"); - prepaid_uuid = cfg.getParameter("prepaid_uuid"); - prepaid_acc_dest = cfg.getParameter("prepaid_acc_dest"); - - // check for acc module if configured statically - if (prepaid_enabled && - (prepaid_accmodule.find('$') == string::npos) && - (NULL == AmPlugIn::instance()->getFactory4Di(prepaid_accmodule))) { - ERROR("prepaid accounting module '%s' used in call profile " - "'%s' is not loaded\n", prepaid_accmodule.c_str(), name.c_str()); - return false; - } - - vector reply_translations_v = - explode(cfg.getParameter("reply_translations"), "|"); - for (vector::iterator it = - reply_translations_v.begin(); it != reply_translations_v.end(); it++) { - // expected: "603=>488 Not acceptable here" - vector trans_components = explode(*it, "=>"); - if (trans_components.size() != 2) { - ERROR("%s: entry '%s' in reply_translations could not be understood.\n", - name.c_str(), it->c_str()); - ERROR("expected 'from_code=>to_code reason'\n"); - return false; - } - - unsigned int from_code, to_code; - if (str2i(trans_components[0], from_code)) { - ERROR("%s: code '%s' in reply_translations not understood.\n", - name.c_str(), trans_components[0].c_str()); - return false; - } - unsigned int s_pos = 0; - string to_reply = trans_components[1]; - while (s_pos < to_reply.length() && to_reply[s_pos] != ' ') - s_pos++; - if (str2i(to_reply.substr(0, s_pos), to_code)) { - ERROR("%s: code '%s' in reply_translations not understood.\n", - name.c_str(), to_reply.substr(0, s_pos).c_str()); - return false; - } - - if (s_pos < to_reply.length()) - s_pos++; - // DBG("got translation %u => %u %s\n", - // from_code, to_code, to_reply.substr(s_pos).c_str()); - reply_translations[from_code] = make_pair(to_code, to_reply.substr(s_pos)); - } - - INFO("SBC: loaded SBC profile '%s':\n", name.c_str()); - - INFO("SBC: RURI = '%s'\n", ruri.c_str()); - INFO("SBC: From = '%s'\n", from.c_str()); - INFO("SBC: To = '%s'\n", to.c_str()); - if (!callid.empty()) { - INFO("SBC: Call-ID = '%s'\n", callid.c_str()); - } - - INFO("SBC: force outbound proxy: %s\n", force_outbound_proxy?"yes":"no"); - INFO("SBC: outbound proxy = '%s'\n", outbound_proxy.c_str()); - if (!next_hop_ip.empty()) { - INFO("SBC: next hop = %s%s\n", next_hop_ip.c_str(), - next_hop_port.empty()? "" : (":"+next_hop_port).c_str()); - } - - INFO("SBC: header filter is %s, %zd items in list\n", - FilterType2String(headerfilter), headerfilter_list.size()); - INFO("SBC: message filter is %s, %zd items in list\n", - FilterType2String(messagefilter), messagefilter_list.size()); - INFO("SBC: SDP filter is %sabled, %s, %zd items in list\n", - sdpfilter_enabled?"en":"dis", FilterType2String(sdpfilter), - sdpfilter_list.size()); - - INFO("SBC: SST %sabled\n", sst_enabled?"en":"dis"); - INFO("SBC: SIP auth %sabled\n", auth_enabled?"en":"dis"); - INFO("SBC: call timer %sabled\n", call_timer_enabled?"en":"dis"); - if (call_timer_enabled) { - INFO("SBC: %s seconds\n", call_timer.c_str()); - } - INFO("SBC: prepaid %sabled\n", prepaid_enabled?"en":"dis"); - if (prepaid_enabled) { - INFO("SBC: acc_module = '%s'\n", prepaid_accmodule.c_str()); - INFO("SBC: uuid = '%s'\n", prepaid_uuid.c_str()); - INFO("SBC: acc_dest = '%s'\n", prepaid_acc_dest.c_str()); - } - if (reply_translations.size()) { - string reply_trans_codes; - for(map >::iterator it= - reply_translations.begin(); it != reply_translations.end(); it++) - reply_trans_codes += int2str(it->first)+", "; - reply_trans_codes.erase(reply_trans_codes.length()-2); - INFO("SBC: reply translation for %s\n", reply_trans_codes.c_str()); - } - - return true; -} SBCFactory::SBCFactory(const string& _app_name) : AmSessionFactory(_app_name) diff --git a/apps/sbc/SBC.h b/apps/sbc/SBC.h index 960c4ab3..a2acbb12 100644 --- a/apps/sbc/SBC.h +++ b/apps/sbc/SBC.h @@ -27,11 +27,11 @@ #define _SBC_H #include "AmB2BSession.h" -#include "ampi/UACAuthAPI.h" #include "AmConfigReader.h" #include "AmUriParser.h" #include "HeaderFilter.h" +#include "SBCCallProfile.h" #include @@ -40,65 +40,6 @@ using std::string; #define SBC_TIMER_ID_CALL_TIMER 1 #define SBC_TIMER_ID_PREPAID_TIMEOUT 2 -struct SBCCallProfile { - - AmConfigReader cfg; - - string ruri; /* updated if set */ - string from; /* updated if set */ - string to; /* updated if set */ - - string callid; - - string outbound_proxy; - bool force_outbound_proxy; - - string next_hop_ip; - string next_hop_port; - unsigned short next_hop_port_i; - - FilterType headerfilter; - set headerfilter_list; - - FilterType messagefilter; - set messagefilter_list; - - bool sdpfilter_enabled; - FilterType sdpfilter; - set sdpfilter_list; - - bool sst_enabled; - bool use_global_sst_config; - - bool auth_enabled; - UACAuthCred auth_credentials; - - bool call_timer_enabled; - string call_timer; - - bool prepaid_enabled; - string prepaid_accmodule; - string prepaid_uuid; - string prepaid_acc_dest; - - map > reply_translations; - - // todo: RTP forwarding mode - // todo: RTP transcoding mode - - SBCCallProfile() - : headerfilter(Transparent), - messagefilter(Transparent), - sdpfilter_enabled(false), - sdpfilter(Transparent), - sst_enabled(false), - auth_enabled(false), - call_timer_enabled(false), - prepaid_enabled(false) - { } - - bool readFromConfiguration(const string& name, const string profile_file_name); -}; class SBCFactory: public AmSessionFactory { diff --git a/apps/sbc/SBCCallProfile.cpp b/apps/sbc/SBCCallProfile.cpp new file mode 100644 index 00000000..a0fd0a8a --- /dev/null +++ b/apps/sbc/SBCCallProfile.cpp @@ -0,0 +1,189 @@ +#include "SBCCallProfile.h" + +#include + +#include "log.h" +#include "AmUtils.h" +#include "AmPlugIn.h" + + +bool SBCCallProfile::readFromConfiguration(const string& name, + const string profile_file_name) { + if (cfg.loadFile(profile_file_name)) { + ERROR("reading SBC call profile from '%s'\n", profile_file_name.c_str()); + return false; + } + + ruri = cfg.getParameter("RURI"); + from = cfg.getParameter("From"); + to = cfg.getParameter("To"); + + callid = cfg.getParameter("Call-ID"); + + force_outbound_proxy = cfg.getParameter("force_outbound_proxy") == "yes"; + outbound_proxy = cfg.getParameter("outbound_proxy"); + + next_hop_ip = cfg.getParameter("next_hop_ip"); + next_hop_port = cfg.getParameter("next_hop_port"); + + string hf_type = cfg.getParameter("header_filter", "transparent"); + if (hf_type=="transparent") + headerfilter = Transparent; + else if (hf_type=="whitelist") + headerfilter = Whitelist; + else if (hf_type=="blacklist") + headerfilter = Blacklist; + else { + ERROR("invalid header_filter mode '%s'\n", hf_type.c_str()); + return false; + } + + vector elems = explode(cfg.getParameter("header_list"), ","); + for (vector::iterator it=elems.begin(); it != elems.end(); it++) + headerfilter_list.insert(*it); + + string mf_type = cfg.getParameter("message_filter", "transparent"); + if (mf_type=="transparent") + messagefilter = Transparent; + else if (mf_type=="whitelist") + messagefilter = Whitelist; + else if (hf_type=="blacklist") + messagefilter = Blacklist; + else { + ERROR("invalid message_filter mode '%s'\n", mf_type.c_str()); + return false; + } + + elems = explode(cfg.getParameter("message_list"), ","); + for (vector::iterator it=elems.begin(); it != elems.end(); it++) + messagefilter_list.insert(*it); + + string sdp_filter = cfg.getParameter("sdp_filter"); + if (sdp_filter=="transparent") { + sdpfilter_enabled = true; + sdpfilter = Transparent; + } else if (sdp_filter=="whitelist") { + sdpfilter_enabled = true; + sdpfilter = Whitelist; + } else if (sdp_filter=="blacklist") { + sdpfilter_enabled = true; + sdpfilter = Blacklist; + } else { + sdpfilter_enabled = false; + } + if (sdpfilter_enabled) { + vector c_elems = explode(cfg.getParameter("sdpfilter_list"), ","); + for (vector::iterator it=c_elems.begin(); it != c_elems.end(); it++) { + string c = *it; + std::transform(c.begin(), c.end(), c.begin(), ::tolower); + sdpfilter_list.insert(c); + } + } + + sst_enabled = cfg.getParameter("enable_session_timer", "no") == "yes"; + use_global_sst_config = !cfg.hasParameter("session_expires"); + + auth_enabled = cfg.getParameter("enable_auth", "no") == "yes"; + auth_credentials.user = cfg.getParameter("auth_user"); + auth_credentials.pwd = cfg.getParameter("auth_pwd"); + + call_timer_enabled = cfg.getParameter("enable_call_timer", "no") == "yes"; + call_timer = cfg.getParameter("call_timer"); + + prepaid_enabled = cfg.getParameter("enable_prepaid", "no") == "yes"; + prepaid_accmodule = cfg.getParameter("prepaid_accmodule"); + prepaid_uuid = cfg.getParameter("prepaid_uuid"); + prepaid_acc_dest = cfg.getParameter("prepaid_acc_dest"); + + // check for acc module if configured statically + if (prepaid_enabled && + (prepaid_accmodule.find('$') == string::npos) && + (NULL == AmPlugIn::instance()->getFactory4Di(prepaid_accmodule))) { + ERROR("prepaid accounting module '%s' used in call profile " + "'%s' is not loaded\n", prepaid_accmodule.c_str(), name.c_str()); + return false; + } + + vector reply_translations_v = + explode(cfg.getParameter("reply_translations"), "|"); + for (vector::iterator it = + reply_translations_v.begin(); it != reply_translations_v.end(); it++) { + // expected: "603=>488 Not acceptable here" + vector trans_components = explode(*it, "=>"); + if (trans_components.size() != 2) { + ERROR("%s: entry '%s' in reply_translations could not be understood.\n", + name.c_str(), it->c_str()); + ERROR("expected 'from_code=>to_code reason'\n"); + return false; + } + + unsigned int from_code, to_code; + if (str2i(trans_components[0], from_code)) { + ERROR("%s: code '%s' in reply_translations not understood.\n", + name.c_str(), trans_components[0].c_str()); + return false; + } + unsigned int s_pos = 0; + string to_reply = trans_components[1]; + while (s_pos < to_reply.length() && to_reply[s_pos] != ' ') + s_pos++; + if (str2i(to_reply.substr(0, s_pos), to_code)) { + ERROR("%s: code '%s' in reply_translations not understood.\n", + name.c_str(), to_reply.substr(0, s_pos).c_str()); + return false; + } + + if (s_pos < to_reply.length()) + s_pos++; + // DBG("got translation %u => %u %s\n", + // from_code, to_code, to_reply.substr(s_pos).c_str()); + reply_translations[from_code] = make_pair(to_code, to_reply.substr(s_pos)); + } + + INFO("SBC: loaded SBC profile '%s':\n", name.c_str()); + + INFO("SBC: RURI = '%s'\n", ruri.c_str()); + INFO("SBC: From = '%s'\n", from.c_str()); + INFO("SBC: To = '%s'\n", to.c_str()); + if (!callid.empty()) { + INFO("SBC: Call-ID = '%s'\n", callid.c_str()); + } + + INFO("SBC: force outbound proxy: %s\n", force_outbound_proxy?"yes":"no"); + INFO("SBC: outbound proxy = '%s'\n", outbound_proxy.c_str()); + if (!next_hop_ip.empty()) { + INFO("SBC: next hop = %s%s\n", next_hop_ip.c_str(), + next_hop_port.empty()? "" : (":"+next_hop_port).c_str()); + } + + INFO("SBC: header filter is %s, %zd items in list\n", + FilterType2String(headerfilter), headerfilter_list.size()); + INFO("SBC: message filter is %s, %zd items in list\n", + FilterType2String(messagefilter), messagefilter_list.size()); + INFO("SBC: SDP filter is %sabled, %s, %zd items in list\n", + sdpfilter_enabled?"en":"dis", FilterType2String(sdpfilter), + sdpfilter_list.size()); + + INFO("SBC: SST %sabled\n", sst_enabled?"en":"dis"); + INFO("SBC: SIP auth %sabled\n", auth_enabled?"en":"dis"); + INFO("SBC: call timer %sabled\n", call_timer_enabled?"en":"dis"); + if (call_timer_enabled) { + INFO("SBC: %s seconds\n", call_timer.c_str()); + } + INFO("SBC: prepaid %sabled\n", prepaid_enabled?"en":"dis"); + if (prepaid_enabled) { + INFO("SBC: acc_module = '%s'\n", prepaid_accmodule.c_str()); + INFO("SBC: uuid = '%s'\n", prepaid_uuid.c_str()); + INFO("SBC: acc_dest = '%s'\n", prepaid_acc_dest.c_str()); + } + if (reply_translations.size()) { + string reply_trans_codes; + for(map >::iterator it= + reply_translations.begin(); it != reply_translations.end(); it++) + reply_trans_codes += int2str(it->first)+", "; + reply_trans_codes.erase(reply_trans_codes.length()-2); + INFO("SBC: reply translation for %s\n", reply_trans_codes.c_str()); + } + + return true; +} diff --git a/apps/sbc/SBCCallProfile.h b/apps/sbc/SBCCallProfile.h new file mode 100644 index 00000000..f2f59f82 --- /dev/null +++ b/apps/sbc/SBCCallProfile.h @@ -0,0 +1,77 @@ + +#ifndef _SBCCallProfile_h +#define _SBCCallProfile_h + +#include "AmConfigReader.h" +#include "HeaderFilter.h" +#include "ampi/UACAuthAPI.h" + +#include +#include +#include + +using std::string; +using std::map; +using std::set; + +struct SBCCallProfile { + + AmConfigReader cfg; + + string ruri; /* updated if set */ + string from; /* updated if set */ + string to; /* updated if set */ + + string callid; + + string outbound_proxy; + bool force_outbound_proxy; + + string next_hop_ip; + string next_hop_port; + unsigned short next_hop_port_i; + + FilterType headerfilter; + set headerfilter_list; + + FilterType messagefilter; + set messagefilter_list; + + bool sdpfilter_enabled; + FilterType sdpfilter; + set sdpfilter_list; + + bool sst_enabled; + bool use_global_sst_config; + + bool auth_enabled; + UACAuthCred auth_credentials; + + bool call_timer_enabled; + string call_timer; + + bool prepaid_enabled; + string prepaid_accmodule; + string prepaid_uuid; + string prepaid_acc_dest; + + map > reply_translations; + + // todo: RTP forwarding mode + // todo: RTP transcoding mode + + SBCCallProfile() + : headerfilter(Transparent), + messagefilter(Transparent), + sdpfilter_enabled(false), + sdpfilter(Transparent), + sst_enabled(false), + auth_enabled(false), + call_timer_enabled(false), + prepaid_enabled(false) + { } + + bool readFromConfiguration(const string& name, const string profile_file_name); +}; + +#endif // _SBCCallProfile_h