From 7ce85a46b4d4ba01c1c98309a5c6d28c654efae3 Mon Sep 17 00:00:00 2001 From: Marco Capetta Date: Wed, 20 Nov 2019 12:09:14 +0100 Subject: [PATCH] TT#71001 Add VSC to disable all active call forwards at once This feature gives the user the ability to disable all active call forwards (CFU, CFB, CFT, CFNA, CFS, CFR, CFO) by triggering a VSC on the phone. Additionally create function SW_VscDialog::deleteCF to group all the common operations that are done to delete a CF. Change-Id: I49f5ec6b23899768325db92ae023601922430f42 --- debian/patches/series | 1 + .../sipwise/add-vsc-to-disable_all_cf.patch | 425 ++++++++++++++++++ 2 files changed, 426 insertions(+) create mode 100644 debian/patches/sipwise/add-vsc-to-disable_all_cf.patch diff --git a/debian/patches/series b/debian/patches/series index 42bf7961..cfef2177 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -33,3 +33,4 @@ sipwise/session_timers sipwise/introduce_forcesdp_from_pbx.patch sipwise/0001-TT-34704-Fix-sems-and-sems-pbx-to-write-pid-file-whe.patch sipwise/0001-TT-53685-add_header_pattern_match_support.patch +sipwise/add-vsc-to-disable_all_cf.patch diff --git a/debian/patches/sipwise/add-vsc-to-disable_all_cf.patch b/debian/patches/sipwise/add-vsc-to-disable_all_cf.patch new file mode 100644 index 00000000..7e50c554 --- /dev/null +++ b/debian/patches/sipwise/add-vsc-to-disable_all_cf.patch @@ -0,0 +1,425 @@ +--- a/apps/sw_vsc/SW_Vsc.cpp ++++ b/apps/sw_vsc/SW_Vsc.cpp +@@ -72,6 +72,9 @@ using namespace pcrecpp; + #define SW_VSC_DESTSET_CFB "cfb_by_vsc" + #define SW_VSC_DESTSET_CFT "cft_by_vsc" + #define SW_VSC_DESTSET_CFNA "cfna_by_vsc" ++#define SW_VSC_DESTSET_CFS "cfs_by_vsc" ++#define SW_VSC_DESTSET_CFR "cfr_by_vsc" ++#define SW_VSC_DESTSET_CFO "cfc_by_vsc" + + #define CHECK_ANNOUNCEMENT_CONFIG(member, config_var) \ + m_patterns.member = cfg.getParameter(config_var, ""); \ +@@ -114,6 +117,7 @@ SW_VscFactory::SW_VscFactory(const strin + + SW_VscFactory::~SW_VscFactory() + { ++ regfree(&m_patterns.cfOffPattern); + regfree(&m_patterns.cfuOnPattern); + regfree(&m_patterns.cfuOffPattern); + regfree(&m_patterns.cfbOnPattern); +@@ -131,6 +135,7 @@ SW_VscFactory::~SW_VscFactory() + + int SW_VscFactory::onLoad() + { ++ string cfOffPattern; + string cfuOnPattern; + string cfuOffPattern; + string cfbOnPattern; +@@ -188,6 +193,7 @@ int SW_VscFactory::onLoad() + + CHECK_ANNOUNCEMENT_CONFIG(failAnnouncement, "error_announcement"); + CHECK_ANNOUNCEMENT_CONFIG(unknownAnnouncement, "unknown_announcement"); ++ CHECK_ANNOUNCEMENT_CONFIG(cfOffAnnouncement, "cf_off_announcement"); + CHECK_ANNOUNCEMENT_CONFIG(cfuOnAnnouncement, "cfu_on_announcement"); + CHECK_ANNOUNCEMENT_CONFIG(cfuOffAnnouncement, "cfu_off_announcement"); + CHECK_ANNOUNCEMENT_CONFIG(cfbOnAnnouncement, "cfb_on_announcement"); +@@ -213,6 +219,7 @@ int SW_VscFactory::onLoad() + m_patterns.voicemailNumber = "invalid_default_value"; + } + ++ COMPILE_MATCH_PATTERN(cfOffPattern, "cf_off_pattern"); + COMPILE_MATCH_PATTERN(cfuOnPattern, "cfu_on_pattern"); + COMPILE_MATCH_PATTERN(cfuOffPattern, "cfu_off_pattern"); + COMPILE_MATCH_PATTERN(cfbOnPattern, "cfb_on_pattern"); +@@ -398,11 +405,14 @@ u_int64_t SW_VscDialog::getSubscriberId( + } + + u_int64_t SW_VscDialog::getPreference(MYSQL *my_handler, u_int64_t subscriberId, +- u_int64_t attributeId, int *foundPref, +- string *value) ++ u_int64_t attributeId, ++ int *foundPref, string *value) + { +- MYSQL_RES *res; MYSQL_ROW row; char query[1024] = +- ""; u_int64_t id; *foundPref = 0; ++ MYSQL_RES *res; ++ MYSQL_ROW row; ++ char query[1024] = ""; ++ u_int64_t id; ++ *foundPref = 0; + + snprintf(query, sizeof(query), SW_VSC_GET_PREFERENCE_ID, + (unsigned long long int)subscriberId, +@@ -859,6 +869,44 @@ u_int64_t SW_VscDialog::deleteCFMap(MYSQ + return 1; + } + ++u_int64_t SW_VscDialog::deleteCF(MYSQL *my_handler, u_int64_t subscriberId, ++ const char *mapName, const char *type, ++ int *foundPref, string *value, const char *uuid) ++{ ++ if (!deleteCFMap(my_handler, subscriberId, mapName, type)) ++ { ++ return 0; ++ } ++ ++ u_int64_t attId = getAttributeId(my_handler, type); ++ if (!attId) ++ { ++ return 0; ++ } ++ ++ u_int64_t prefId = getPreference(my_handler, subscriberId, attId, foundPref, value); ++ if (!prefId) ++ { ++ return 0; ++ } ++ else if (!*foundPref) ++ { ++ INFO("Unnecessary VSC %s removal for uuid '%s'", ++ type, uuid); ++ } ++ else if (!deletePreferenceId(my_handler, prefId)) ++ { ++ return 0; ++ } ++ else ++ { ++ INFO("Successfully removed VSC %s for uuid '%s'", ++ type, uuid); ++ } ++ ++ return 1; ++} ++ + void SW_VscDialog::onInvite(const AmSipRequest &req) + { + /// fooooo +@@ -880,6 +928,7 @@ void SW_VscDialog::onInvite(const AmSipR + + string failAnnouncement; + string unknownAnnouncement; ++ string cfOffAnnouncement; + string cfuOnAnnouncement; + string cfuOffAnnouncement; + string cfbOnAnnouncement; +@@ -958,6 +1007,96 @@ void SW_VscDialog::onInvite(const AmSipR + + setReceiving(false); + ++ if ((ret = regexec(&m_patterns->cfOffPattern, ++ req.user.c_str(), 0, 0, 0)) == 0) ++ { ++ u_int64_t attId, prefId; ++ ++ CHECK_ANNOUNCEMENT_PATH(cfOffAnnouncement, "cf_off_announcement"); ++ ++ /// Remove CFU ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu", &foundPref, &prefStr, uuid.c_str())) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ ++ /// Remove CFB ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb", &foundPref, &prefStr, uuid.c_str())) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ ++ /// Remove CFT ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFT, "cft", &foundPref, &prefStr, uuid.c_str())) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ ++ attId = getAttributeId(my_handler, "ringtimeout"); ++ if (!attId) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ ++ prefId = getPreference(my_handler, subId, attId, &foundPref, &prefStr); ++ if (!prefId) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ else if (foundPref && !deletePreferenceId(my_handler, prefId)) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ else ++ { ++ INFO("Successfully removed VSC cft ringtimeout for uuid '%s'", ++ uuid.c_str()); ++ } ++ ++ /// Remove CFNA ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna", &foundPref, &prefStr, uuid.c_str())) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ ++ /// Remove CFS ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFS, "cfs", &foundPref, &prefStr, uuid.c_str())) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ ++ /// Remove CFR ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFR, "cfr", &foundPref, &prefStr, uuid.c_str())) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ ++ /// Remove CFO ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFO, "cfo", &foundPref, &prefStr, uuid.c_str())) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ ++ /// END ++ filename = cfOffAnnouncement; ++ goto out; ++ } ++ else if (ret != REG_NOMATCH) ++ { ++ filename = failAnnouncement; ++ goto out; ++ } ++ + if ((ret = regexec(&m_patterns->cfuOnPattern, + req.user.c_str(), 0, 0, 0)) == 0) + { +@@ -1034,41 +1173,13 @@ void SW_VscDialog::onInvite(const AmSipR + if ((ret = regexec(&m_patterns->cfuOffPattern, + req.user.c_str(), 0, 0, 0)) == 0) + { +- CHECK_ANNOUNCEMENT_PATH(cfuOffAnnouncement, "cfu_off_announcement"); ++ CHECK_ANNOUNCEMENT_PATH(cfuOffAnnouncement, "cfu_off_announcement"); + +- if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu")) +- { +- filename = failAnnouncement; +- goto out; +- } +- u_int64_t attId = getAttributeId(my_handler, "cfu"); +- if (!attId) ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu", &foundPref, &prefStr, uuid.c_str())) + { + filename = failAnnouncement; + goto out; + } +- u_int64_t prefId = getPreference(my_handler, subId, attId, +- &foundPref, &prefStr); +- if (!prefId) +- { +- filename = failAnnouncement; +- goto out; +- } +- else if (!foundPref) +- { +- INFO("Unnecessary VSC CFU removal for uuid '%s'", +- uuid.c_str()); +- } +- else if (!deletePreferenceId(my_handler, prefId)) +- { +- filename = failAnnouncement; +- goto out; +- } +- else +- { +- INFO("Successfully removed VSC CFU for uuid '%s'", +- uuid.c_str()); +- } + + filename = cfuOffAnnouncement; + goto out; +@@ -1157,39 +1268,11 @@ void SW_VscDialog::onInvite(const AmSipR + { + CHECK_ANNOUNCEMENT_PATH(cfbOffAnnouncement, "cfb_off_announcement"); + +- if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb")) +- { +- filename = failAnnouncement; +- goto out; +- } +- u_int64_t attId = getAttributeId(my_handler, "cfb"); +- if (!attId) ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb", &foundPref, &prefStr, uuid.c_str())) + { + filename = failAnnouncement; + goto out; + } +- u_int64_t prefId = getPreference(my_handler, subId, attId, +- &foundPref, &prefStr); +- if (!prefId) +- { +- filename = failAnnouncement; +- goto out; +- } +- else if (!foundPref) +- { +- INFO("Unnecessary VSC CFB removal for uuid '%s'", +- uuid.c_str()); +- } +- else if (!deletePreferenceId(my_handler, prefId)) +- { +- filename = failAnnouncement; +- goto out; +- } +- else +- { +- INFO("Successfully removed VSC CFB for uuid '%s'", +- uuid.c_str()); +- } + + filename = cfbOffAnnouncement; + goto out; +@@ -1316,48 +1399,19 @@ void SW_VscDialog::onInvite(const AmSipR + { + CHECK_ANNOUNCEMENT_PATH(cftOffAnnouncement, "cft_off_announcement"); + +- if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFT, "cft")) +- { +- filename = failAnnouncement; +- goto out; +- } +- u_int64_t attId = getAttributeId(my_handler, "cft"); +- if (!attId) +- { +- filename = failAnnouncement; +- goto out; +- } +- +- u_int64_t prefId = getPreference(my_handler, subId, attId, +- &foundPref, &prefStr); +- if (!prefId) ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFT, "cft", &foundPref, &prefStr, uuid.c_str())) + { + filename = failAnnouncement; + goto out; + } +- else if (!foundPref) +- { +- INFO("Unnecessary VSC CFT removal for uuid '%s'", +- uuid.c_str()); +- } +- else if (!deletePreferenceId(my_handler, prefId)) +- { +- filename = failAnnouncement; +- goto out; +- } +- else +- { +- INFO("Successfully removed VSC CFT for uuid '%s'", +- uuid.c_str()); +- } + +- attId = getAttributeId(my_handler, "ringtimeout"); ++ u_int64_t attId = getAttributeId(my_handler, "ringtimeout"); + if (!attId) + { + filename = failAnnouncement; + goto out; + } +- prefId = getPreference(my_handler, subId, attId, &foundPref, &prefStr); ++ u_int64_t prefId = getPreference(my_handler, subId, attId, &foundPref, &prefStr); + if (!prefId) + { + filename = failAnnouncement; +@@ -1462,39 +1516,11 @@ void SW_VscDialog::onInvite(const AmSipR + { + CHECK_ANNOUNCEMENT_PATH(cfnaOffAnnouncement, "cfna_off_announcement"); + +- if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna")) ++ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna", &foundPref, &prefStr, uuid.c_str())) + { + filename = failAnnouncement; + goto out; + } +- u_int64_t attId = getAttributeId(my_handler, "cfna"); +- if (!attId) +- { +- filename = failAnnouncement; +- goto out; +- } +- u_int64_t prefId = getPreference(my_handler, subId, attId, +- &foundPref, &prefStr); +- if (!prefId) +- { +- filename = failAnnouncement; +- goto out; +- } +- else if (!foundPref) +- { +- INFO("Unnecessary VSC CFNA removal for uuid '%s'", +- uuid.c_str()); +- } +- else if (!deletePreferenceId(my_handler, prefId)) +- { +- filename = failAnnouncement; +- goto out; +- } +- else +- { +- INFO("Successfully removed VSC CFNA for uuid '%s'", +- uuid.c_str()); +- } + + filename = cfnaOffAnnouncement; + goto out; +--- a/apps/sw_vsc/SW_Vsc.h ++++ b/apps/sw_vsc/SW_Vsc.h +@@ -29,6 +29,9 @@ typedef struct + string unknownAnnouncement; + string voicemailNumber; + ++ regex_t cfOffPattern; ++ string cfOffAnnouncement; ++ + regex_t cfuOnPattern; + string cfuOnAnnouncement; + +@@ -118,6 +121,9 @@ class SW_VscDialog : public AmSession, + const char *mapName, const char *type); + u_int64_t deleteCFMap(MYSQL *my_handler, u_int64_t subscriberId, + const char *mapName, const char *type); ++ u_int64_t deleteCF(MYSQL *my_handler, u_int64_t subscriberId, ++ const char *mapName, const char *type, ++ int *foundPref, string *value, const char *uuid); + + + +--- a/apps/sw_vsc/etc/sw_vsc.conf ++++ b/apps/sw_vsc/etc/sw_vsc.conf +@@ -10,6 +10,9 @@ unknown_announcement = sw_vsc_unavailabl + + voicemail_number = 2000 + ++cf_off_pattern = ^(\%23)99(\%23)?.*$ ++cf_off_announcement = sw_vsc_deactivated.wav ++ + cfu_on_pattern = ^\*72\*[0-9]+$ + cfu_on_announcement = sw_vsc_activated.wav + cfu_off_pattern = ^(\%23)72(\%23)?.*$