From b1c8aa3f2c56d7dee603ff758672ad54025e8238 Mon Sep 17 00:00:00 2001 From: Marco Capetta Date: Thu, 29 Dec 2022 10:14:24 +0100 Subject: [PATCH] MT#55831 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. (real ticket number: TT#71001) Change-Id: If8bae22b071f337d3f3580c057bc16325a0818c5 --- apps/sw_vsc/SW_Vsc.cpp | 274 ++++++++++++++++++++---------------- apps/sw_vsc/SW_Vsc.h | 6 + apps/sw_vsc/etc/sw_vsc.conf | 3 + 3 files changed, 159 insertions(+), 124 deletions(-) diff --git a/apps/sw_vsc/SW_Vsc.cpp b/apps/sw_vsc/SW_Vsc.cpp index 818cc09d..d69a5d26 100644 --- 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 string &_app_name) 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(MYSQL *my_handler, const char *uuid, } 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(MYSQL *my_handler, u_int64_t subscriberId, 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 AmSipRequest &req) string failAnnouncement; string unknownAnnouncement; + string cfOffAnnouncement; string cfuOnAnnouncement; string cfuOffAnnouncement; string cfbOnAnnouncement; @@ -958,6 +1007,96 @@ void SW_VscDialog::onInvite(const AmSipRequest &req) 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 AmSipRequest &req) 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) - { - 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)) + if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu", &foundPref, &prefStr, uuid.c_str())) { 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 AmSipRequest &req) { CHECK_ANNOUNCEMENT_PATH(cfbOffAnnouncement, "cfb_off_announcement"); - if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb")) + if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb", &foundPref, &prefStr, uuid.c_str())) { filename = failAnnouncement; goto out; } - u_int64_t attId = getAttributeId(my_handler, "cfb"); - 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 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 AmSipRequest &req) { 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) - { - filename = failAnnouncement; - goto out; - } - else if (!foundPref) - { - INFO("Unnecessary VSC CFT removal for uuid '%s'", - uuid.c_str()); - } - else if (!deletePreferenceId(my_handler, prefId)) + if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFT, "cft", &foundPref, &prefStr, uuid.c_str())) { 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 AmSipRequest &req) { 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; diff --git a/apps/sw_vsc/SW_Vsc.h b/apps/sw_vsc/SW_Vsc.h index c18f2880..2b8fc841 100644 --- 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); diff --git a/apps/sw_vsc/etc/sw_vsc.conf b/apps/sw_vsc/etc/sw_vsc.conf index 18c348d3..c52146b0 100644 --- a/apps/sw_vsc/etc/sw_vsc.conf +++ b/apps/sw_vsc/etc/sw_vsc.conf @@ -10,6 +10,9 @@ unknown_announcement = sw_vsc_unavailable.wav 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)?.*$