diff --git a/debian/patches/series b/debian/patches/series index 7795481a..86789f59 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -5,5 +5,14 @@ sipwise/0003-dsm-mod_utils-utils.getCountRight-getCountLeft-actio.patch sipwise/0004-dsm-arrayIndex-action-get-the-index-of-a-string-in-a.patch sipwise/0005-dsm-clearArray-and-clearStruct-actions.patch sipwise/0006-rename_xdigits.patch +sipwise/0007-dsm-another-way-for-writing-comments-lines-starting-.patch +sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch +sipwise/0009-dsm-syntax-allow-and-for-and-in-sets-action.patch +sipwise/0010-dsm-log-event-type-when-processing-events.patch +sipwise/0011-dsm-logs-dgb-info-warn-error-actions-for-easy-loggin.patch +sipwise/0012-b-f-dsm-mod_groups-really-lock-the-groups-list.patch +sipwise/0013-dsm-mod_groups-functions-to-get-group-participants-a.patch +sipwise/0014-dsm-mod_conference-flushMixInList-action-loop-for-mi.patch +sipwise/0015-confpin-simple-pin-conference-app.patch no_config.patch py_sems_path.patch diff --git a/debian/patches/sipwise/0007-dsm-another-way-for-writing-comments-lines-starting-.patch b/debian/patches/sipwise/0007-dsm-another-way-for-writing-comments-lines-starting-.patch new file mode 100644 index 00000000..f9893252 --- /dev/null +++ b/debian/patches/sipwise/0007-dsm-another-way-for-writing-comments-lines-starting-.patch @@ -0,0 +1,46 @@ +From 0f3accb12d7179653e31890fe4e26682815cc3a7 Mon Sep 17 00:00:00 2001 +From: Stefan Sayer +Date: Thu, 20 Nov 2014 19:45:43 +0100 +Subject: [PATCH 1/3] dsm: another way for writing comments: lines starting + with # (hash) + +--- + apps/dsm/DSMStateDiagramCollection.cpp | 6 +++--- + doc/dsm/dsm_syntax.txt | 2 ++ + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/apps/dsm/DSMStateDiagramCollection.cpp b/apps/dsm/DSMStateDiagramCollection.cpp +index 79c5ff0..749d223 100644 +--- a/apps/dsm/DSMStateDiagramCollection.cpp ++++ b/apps/dsm/DSMStateDiagramCollection.cpp +@@ -50,11 +50,11 @@ bool DSMStateDiagramCollection::readFile(const string& filename, const string& n + while (ifs.good() && !ifs.eof()) { + string r; + getline(ifs, r); +- // skip comments ++ // skip comments: lines starting with -- or # + size_t fpos = r.find_first_not_of(" \t"); + if (fpos != string::npos) { +- if (r.length() > fpos+1 && +- r.substr(fpos, 2) == "--") ++ if ((r.length() > fpos+1 && r.substr(fpos, 2) == "--") || ++ ((r.length() >= fpos+1 && r.substr(fpos, 1) == "#" && r.substr(fpos, 8) != "#include") )) + continue; + + if (r.length() > fpos+1 && +diff --git a/doc/dsm/dsm_syntax.txt b/doc/dsm/dsm_syntax.txt +index 3a4019e..cf29e6e 100644 +--- a/doc/dsm/dsm_syntax.txt ++++ b/doc/dsm/dsm_syntax.txt +@@ -4,6 +4,8 @@ DSM quick reference + Syntax + ====== + -- comment ++# also comment ++ + #include "script.dsm" + #include "/path/to/anotherscript.dsm" + import(mod_name); +-- +1.9.3 (Apple Git-50) + diff --git a/debian/patches/sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch b/debian/patches/sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch new file mode 100644 index 00000000..7f322498 --- /dev/null +++ b/debian/patches/sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch @@ -0,0 +1,55 @@ +From 4ec1e1d2d06359c599d9fc551478d443934c616c Mon Sep 17 00:00:00 2001 +From: Stefan Sayer +Date: Thu, 20 Nov 2014 19:46:49 +0100 +Subject: [PATCH 2/3] dsm: helper functions / macros for modules: + replaceParams/SET_ERROR/CLR_ERROR + +use resolveVars in module actions/condition to replace only one variable/param, +use replaceParams to replace substrings as well, + +e.g. myAction($myvar) - resolveVars + myOtherAction("this is $(myvar) and #(myparam) replaced") - replaceParams +--- + apps/dsm/DSMCoreModule.h | 4 ++++ + apps/dsm/DSMSession.h | 12 ++++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/apps/dsm/DSMCoreModule.h b/apps/dsm/DSMCoreModule.h +index 328e18e..ff8cee3 100644 +--- a/apps/dsm/DSMCoreModule.h ++++ b/apps/dsm/DSMCoreModule.h +@@ -160,4 +160,8 @@ class TestDSMCondition + map* event_params); + }; + ++/** return string q with variables/params/selects replaced */ ++string replaceParams(const string& q, AmSession* sess, DSMSession* sc_sess, ++ map* event_params); ++ + #endif +diff --git a/apps/dsm/DSMSession.h b/apps/dsm/DSMSession.h +index 5607c9d..f7841a7 100644 +--- a/apps/dsm/DSMSession.h ++++ b/apps/dsm/DSMSession.h +@@ -97,6 +97,18 @@ using std::map; + #define CLR_STRERROR \ + var["strerror"] = ""; + ++#define SET_ERROR(s, errno, errstr) \ ++ do { \ ++ s->SET_ERRNO(errno); \ ++ s->SET_STRERROR(errstr); \ ++ } while (0) ++ ++#define CLR_ERROR(s) \ ++ do { \ ++ s->CLR_ERRNO; \ ++ s->CLR_STRERROR; \ ++ } while (0) ++ + typedef map VarMapT; + typedef map AVarMapT; + +-- +1.9.3 (Apple Git-50) + diff --git a/debian/patches/sipwise/0009-dsm-syntax-allow-and-for-and-in-sets-action.patch b/debian/patches/sipwise/0009-dsm-syntax-allow-and-for-and-in-sets-action.patch new file mode 100644 index 00000000..1664226b --- /dev/null +++ b/debian/patches/sipwise/0009-dsm-syntax-allow-and-for-and-in-sets-action.patch @@ -0,0 +1,46 @@ +From 34b7598451dc639ed1a526d244b496adff9a130b Mon Sep 17 00:00:00 2001 +From: Stefan Sayer +Date: Thu, 20 Nov 2014 20:50:20 +0100 +Subject: [PATCH 3/3] dsm:syntax - allow @@,## and $$ for @, # and $$ in sets() + action + +Conflicts: + + doc/dsm/dsm_syntax.txt +--- + apps/dsm/DSMCoreModule.cpp | 4 ++++ + doc/dsm/dsm_syntax.txt | 5 ++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/apps/dsm/DSMCoreModule.cpp b/apps/dsm/DSMCoreModule.cpp +index 37c2344..c4f18af 100644 +--- a/apps/dsm/DSMCoreModule.cpp ++++ b/apps/dsm/DSMCoreModule.cpp +@@ -627,6 +627,10 @@ string replaceParams(const string& q, AmSession* sess, DSMSession* sc_sess, + repl_pos = rstart+1; + if (rstart == string::npos) + break; ++ if (rstart && (res.length() > rstart) && (res[rstart]==res[repl_pos])) { ++ res.erase(rstart, 1); ++ continue; ++ } + if (rstart && res[rstart-1] == '\\') // escaped + continue; + size_t rend; +diff --git a/doc/dsm/dsm_syntax.txt b/doc/dsm/dsm_syntax.txt +index cf29e6e..05fd2db 100644 +--- a/doc/dsm/dsm_syntax.txt ++++ b/doc/dsm/dsm_syntax.txt +@@ -89,6 +89,9 @@ DSM flow + e.g. set($var="text"); set($var=$var2); set($var=#key) + sets($var=value) + e.g. sets($var="text and some $variable and some #param"); ++ sets($var="$(variable1)$(variable2)"); ++ sets($var="this is a single hash: ##") ++ sets($var="a single at on a date with a single dollar: @@$$") + var($dstvar=srcvarname) + e.g. var($dstvar=$var_counter) + param($dstvar=srcparamname) +-- +1.9.3 (Apple Git-50) + diff --git a/debian/patches/sipwise/0010-dsm-log-event-type-when-processing-events.patch b/debian/patches/sipwise/0010-dsm-log-event-type-when-processing-events.patch new file mode 100644 index 00000000..e66d6945 --- /dev/null +++ b/debian/patches/sipwise/0010-dsm-log-event-type-when-processing-events.patch @@ -0,0 +1,97 @@ +--- a/apps/dsm/DSMStateEngine.cpp ++++ b/apps/dsm/DSMStateEngine.cpp +@@ -37,6 +37,57 @@ + + #include "DSM.h" // for DSMFactory::MonitoringFullCallgraph + ++const char* DSMCondition::type2str(EventType event) { ++#define rt(e) case e: return #e; ++ ++ switch (event) { ++ rt(Any); ++ rt(Invite); ++ rt(SessionStart); ++ rt(Ringing); ++ rt(EarlySession); ++ rt(FailedCall); ++ rt(SipRequest); ++ rt(SipReply); ++ ++ rt(Hangup); ++ rt(Hold); ++ rt(UnHold); ++ ++ rt(B2BOtherReply); ++ rt(B2BOtherBye); ++ ++ rt(SessionTimeout); ++ rt(RtpTimeout); ++ rt(RemoteDisappeared); ++ ++ rt(Key); ++ rt(Timer); ++ ++ rt(NoAudio); ++ rt(PlaylistSeparator); ++ ++ rt(DSMEvent); ++ rt(DSMException); ++ ++ rt(XmlrpcResponse); ++ ++ rt(JsonRpcResponse); ++ rt(JsonRpcRequest); ++ ++ rt(Startup); ++ rt(Reload); ++ rt(System); ++ ++ rt(SIPSubscription); ++ ++ rt(RTPTimeout); ++ ++ default: return ""; ++#undef rt ++ }; ++} ++ + DSMStateDiagram::DSMStateDiagram(const string& name) + : name(name) { + } +@@ -526,14 +577,14 @@ void DSMStateEngine::runEvent(AmSession* + map exception_params; + bool is_exception = run_exception; + +- DBG("o v DSM processing event, current state '%s' v\n", current->name.c_str()); ++ DBG("o v DSM current state '%s', processing '%s' event v\n", ++ current->name.c_str(), DSMCondition::type2str(event)); ++ + bool is_consumed = true; + do { + try { + is_consumed = true; + +- +- DBG(" > state '%s'\n", current->name.c_str()); + for (vector::iterator tr = current->transitions.begin(); + tr != current->transitions.end();tr++) { + if (tr->is_exception != is_exception) +@@ -617,7 +668,6 @@ void DSMStateEngine::runEvent(AmSession* + break; + } + } +- DBG(" >>o arrived in state '%s'\n", current->name.c_str()); + + break; + } +--- a/apps/dsm/DSMStateEngine.h ++++ b/apps/dsm/DSMStateEngine.h +@@ -123,6 +123,8 @@ class DSMCondition + RelayOnB2BReply + }; + ++ static const char* type2str(EventType event); ++ + bool invert; + + DSMCondition() : invert(false) { } diff --git a/debian/patches/sipwise/0011-dsm-logs-dgb-info-warn-error-actions-for-easy-loggin.patch b/debian/patches/sipwise/0011-dsm-logs-dgb-info-warn-error-actions-for-easy-loggin.patch new file mode 100644 index 00000000..ad6e5e57 --- /dev/null +++ b/debian/patches/sipwise/0011-dsm-logs-dgb-info-warn-error-actions-for-easy-loggin.patch @@ -0,0 +1,128 @@ +From b1dfeab659a0188304bcc6715672af462f75afae Mon Sep 17 00:00:00 2001 +From: Stefan Sayer +Date: Fri, 20 Feb 2015 20:49:31 +0100 +Subject: [PATCH 2/7] dsm: logs(), dgb(), info(), warn(), error() actions for + easy logging + +--- + apps/dsm/DSMCoreModule.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- + apps/dsm/DSMCoreModule.h | 5 +++++ + doc/dsm/dsm_syntax.txt | 7 ++++++- + 3 files changed, 49 insertions(+), 3 deletions(-) + +diff --git a/apps/dsm/DSMCoreModule.cpp b/apps/dsm/DSMCoreModule.cpp +index 1da9ad1..b4ae758 100644 +--- a/apps/dsm/DSMCoreModule.cpp ++++ b/apps/dsm/DSMCoreModule.cpp +@@ -92,6 +92,11 @@ DSMAction* DSMCoreModule::getAction(const string& from_str) { + DEF_CMD("substr", SCSubStrAction); + DEF_CMD("inc", SCIncAction); + DEF_CMD("log", SCLogAction); ++ DEF_CMD("logs", SCLogsAction); ++ DEF_CMD("dbg", SCDbgAction); ++ DEF_CMD("info", SCInfoAction); ++ DEF_CMD("warn", SCWarnAction); ++ DEF_CMD("error", SCErrorAction); + DEF_CMD("clear", SCClearAction); + DEF_CMD("clearStruct", SCClearStructAction); + DEF_CMD("clearArray", SCClearArrayAction); +@@ -516,6 +521,37 @@ EXEC_ACTION_START(SCLogAction) { + l_line.c_str()); + } EXEC_ACTION_END; + ++CONST_ACTION_2P(SCLogsAction, ',', false); ++EXEC_ACTION_START(SCLogsAction) { ++ unsigned int lvl; ++ if (str2i(resolveVars(par1, sess, sc_sess, event_params), lvl)) { ++ ERROR("unknown log level '%s'\n", par1.c_str()); ++ EXEC_ACTION_STOP; ++ } ++ string l_line = replaceParams(par2, sess, sc_sess, event_params); ++ _LOG((int)lvl, "FSM: '%s'\n", l_line.c_str()); ++} EXEC_ACTION_END; ++ ++EXEC_ACTION_START(SCDbgAction) { ++ string l_line = replaceParams(arg, sess, sc_sess, event_params); ++ DBG("FSM: '%s'\n", l_line.c_str()); ++} EXEC_ACTION_END; ++ ++EXEC_ACTION_START(SCInfoAction) { ++ string l_line = replaceParams(arg, sess, sc_sess, event_params); ++ INFO("FSM: '%s'\n", l_line.c_str()); ++} EXEC_ACTION_END; ++ ++EXEC_ACTION_START(SCWarnAction) { ++ string l_line = replaceParams(arg, sess, sc_sess, event_params); ++ WARN("FSM: '%s'\n", l_line.c_str()); ++} EXEC_ACTION_END; ++ ++EXEC_ACTION_START(SCErrorAction) { ++ string l_line = replaceParams(arg, sess, sc_sess, event_params); ++ ERROR("FSM: '%s'\n", l_line.c_str()); ++} EXEC_ACTION_END; ++ + void log_vars(const string& l_arg, AmSession* sess, + DSMSession* sc_sess, map* event_params) { + unsigned int lvl; +@@ -1199,7 +1235,7 @@ EXEC_ACTION_START(SCDIAction) { + p.erase(0, 8); + AmArg var_struct; + string varprefix = p+"."; +- bool has_vars = false; ++ //bool has_vars = false; + map::iterator lb = sc_sess->var.lower_bound(varprefix); + while (lb != sc_sess->var.end()) { + if ((lb->first.length() < varprefix.length()) || +@@ -1213,7 +1249,7 @@ EXEC_ACTION_START(SCDIAction) { + string2argarray(varname, lb->second, var_struct); + + lb++; +- has_vars = true; ++ //has_vars = true; + } + di_args.push(var_struct); + } else if (p.length() > 7 && +diff --git a/apps/dsm/DSMCoreModule.h b/apps/dsm/DSMCoreModule.h +index a91a10f..a74241b 100644 +--- a/apps/dsm/DSMCoreModule.h ++++ b/apps/dsm/DSMCoreModule.h +@@ -98,6 +98,11 @@ DEF_ACTION_2P(SCSetTimerAction); + DEF_ACTION_1P(SCRemoveTimerAction); + DEF_ACTION_1P(SCRemoveTimersAction); + DEF_ACTION_2P(SCLogAction); ++DEF_ACTION_2P(SCLogsAction); ++DEF_ACTION_1P(SCDbgAction); ++DEF_ACTION_1P(SCInfoAction); ++DEF_ACTION_1P(SCWarnAction); ++DEF_ACTION_1P(SCErrorAction); + DEF_ACTION_1P(SCLogVarsAction); + DEF_ACTION_1P(SCLogParamsAction); + DEF_ACTION_1P(SCLogSelectsAction); +diff --git a/doc/dsm/dsm_syntax.txt b/doc/dsm/dsm_syntax.txt +index 9c42ead..8b45676 100644 +--- a/doc/dsm/dsm_syntax.txt ++++ b/doc/dsm/dsm_syntax.txt +@@ -246,6 +246,7 @@ B2B call control + + log(level, text) + e.g. log(1, $var1) ++ logs(level, "text with $(variable_name) and #(paramname) replacements") + -- log all variables: + logVars(level) + -- log all selects: +@@ -253,7 +254,11 @@ B2B call control + -- log all Params (only in actions of a transition): + logParams(level) + -- log everything: +- logAll(level) ++ logAll(level) ++ dbg("some debug with $(replaced_var)") ++ info("some info $(message)") ++ warn("warn #(message_parameter)") ++ error("error in call @(local_tag)") + + Timers + ------ +-- +1.9.3 (Apple Git-50) + diff --git a/debian/patches/sipwise/0012-b-f-dsm-mod_groups-really-lock-the-groups-list.patch b/debian/patches/sipwise/0012-b-f-dsm-mod_groups-really-lock-the-groups-list.patch new file mode 100644 index 00000000..f3ed0593 --- /dev/null +++ b/debian/patches/sipwise/0012-b-f-dsm-mod_groups-really-lock-the-groups-list.patch @@ -0,0 +1,25 @@ +From 7392ee5ea6b27f3d8b06d854dd9be2311b528ef5 Mon Sep 17 00:00:00 2001 +From: Stefan Sayer +Date: Fri, 20 Feb 2015 21:17:44 +0100 +Subject: [PATCH 3/7] b/f: dsm:mod_groups: really lock the groups list + +--- + apps/dsm/mods/mod_groups/ModGroups.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/apps/dsm/mods/mod_groups/ModGroups.cpp b/apps/dsm/mods/mod_groups/ModGroups.cpp +index 15a19f1..60a1edd 100644 +--- a/apps/dsm/mods/mod_groups/ModGroups.cpp ++++ b/apps/dsm/mods/mod_groups/ModGroups.cpp +@@ -144,7 +144,7 @@ EXEC_ACTION_START(GroupsPostEventAction) { + + + DBG("posting event to group '%s'\n", groupname.c_str()); +- GroupsModule::groups_mut.unlock(); ++ GroupsModule::groups_mut.lock(); + GroupMap::iterator grp = GroupsModule::groups.find(groupname); + bool posted = false; + if (grp != GroupsModule::groups.end()) { +-- +1.9.3 (Apple Git-50) + diff --git a/debian/patches/sipwise/0013-dsm-mod_groups-functions-to-get-group-participants-a.patch b/debian/patches/sipwise/0013-dsm-mod_groups-functions-to-get-group-participants-a.patch new file mode 100644 index 00000000..618e7d7f --- /dev/null +++ b/debian/patches/sipwise/0013-dsm-mod_groups-functions-to-get-group-participants-a.patch @@ -0,0 +1,101 @@ +From a94e8565eabf8e5269c7d2b86b5ecfa09971bfc0 Mon Sep 17 00:00:00 2001 +From: Stefan Sayer +Date: Fri, 20 Feb 2015 21:18:15 +0100 +Subject: [PATCH 4/7] dsm:mod_groups: functions to get group participants and + size + +--- + apps/dsm/mods/mod_groups/ModGroups.cpp | 40 +++++++++++++++++++++++++++++++++- + apps/dsm/mods/mod_groups/ModGroups.h | 3 ++- + doc/dsm/mods/Readme.mod_groups.txt | 3 +++ + 3 files changed, 44 insertions(+), 2 deletions(-) + +diff --git a/apps/dsm/mods/mod_groups/ModGroups.cpp b/apps/dsm/mods/mod_groups/ModGroups.cpp +index 60a1edd..9af9a79 100644 +--- a/apps/dsm/mods/mod_groups/ModGroups.cpp ++++ b/apps/dsm/mods/mod_groups/ModGroups.cpp +@@ -47,7 +47,8 @@ MOD_ACTIONEXPORT_BEGIN(MOD_CLS_NAME) { + DEF_CMD("groups.join", GroupsJoinAction); + DEF_CMD("groups.leave", GroupsLeaveAction); + DEF_CMD("groups.leaveAll", GroupsLeaveAllAction); +- // DEF_CMD("groups.get", GroupsGetAction); ++ DEF_CMD("groups.get", GroupsGetAction); ++ DEF_CMD("groups.getSize", GroupsGetSizeAction); + // DEF_CMD("groups.getMembers", GroupsGetMembersAction); + DEF_CMD("groups.postEvent", GroupsPostEventAction); + +@@ -125,6 +126,43 @@ EXEC_ACTION_START(GroupsLeaveAllAction) { + GroupsModule::leave_all_groups(ltag); + } EXEC_ACTION_END; + ++CONST_ACTION_2P(GroupsGetAction, '=', false); ++EXEC_ACTION_START(GroupsGetAction) { ++ string var = par1; ++ if (var.size() && var[0]=='$') var.erase(0,1); ++ string groupname = resolveVars(par2, sess, sc_sess, event_params); ++ GroupsModule::groups_mut.lock(); ++ GroupMap::iterator grp = GroupsModule::groups.find(groupname); ++ int i=0; ++ if (grp != GroupsModule::groups.end()) { ++ for (set::iterator it = ++ grp->second.begin(); it != grp->second.end(); it++) { ++ sc_sess->var[var+"["+int2str(i)+"]"] = *it; ++ i++; ++ } ++ } ++ GroupsModule::groups_mut.unlock(); ++ DBG("get %d group members of '%s' in $%s[]\n", i, groupname.c_str(), var.c_str()); ++ ++} EXEC_ACTION_END; ++ ++CONST_ACTION_2P(GroupsGetSizeAction, '=', false); ++EXEC_ACTION_START(GroupsGetSizeAction) { ++ string var = par1; ++ if (var.size() && var[0]=='$') var.erase(0,1); ++ string groupname = resolveVars(par2, sess, sc_sess, event_params); ++ DBG("posting event to group '%s'\n", groupname.c_str()); ++ GroupsModule::groups_mut.lock(); ++ int size = 0; ++ GroupMap::iterator grp = GroupsModule::groups.find(groupname); ++ if (grp != GroupsModule::groups.end()) { ++ size = grp->second.size(); ++ } ++ GroupsModule::groups_mut.unlock(); ++ sc_sess->var[var] = int2str(size); ++ DBG("get group '%s' size $%s=%d\n", groupname.c_str(), var.c_str(), size); ++} EXEC_ACTION_END; ++ + CONST_ACTION_2P(GroupsPostEventAction, ',', true); + EXEC_ACTION_START(GroupsPostEventAction) { + string groupname = resolveVars(par1, sess, sc_sess, event_params); +diff --git a/apps/dsm/mods/mod_groups/ModGroups.h b/apps/dsm/mods/mod_groups/ModGroups.h +index 4305e9a..37c1c0f 100644 +--- a/apps/dsm/mods/mod_groups/ModGroups.h ++++ b/apps/dsm/mods/mod_groups/ModGroups.h +@@ -60,7 +60,8 @@ DECLARE_MODULE_END; + DEF_ACTION_1P(GroupsJoinAction); + DEF_ACTION_1P(GroupsLeaveAction); + DEF_ACTION_1P(GroupsLeaveAllAction); +-/* DEF_ACTION_1P(GroupsGetAction); */ ++DEF_ACTION_2P(GroupsGetAction); ++DEF_ACTION_2P(GroupsGetSizeAction); + /* DEF_ACTION_1P(GroupsGetMembersAction); */ + DEF_ACTION_2P(GroupsPostEventAction); + +diff --git a/doc/dsm/mods/Readme.mod_groups.txt b/doc/dsm/mods/Readme.mod_groups.txt +index 63248a1..4551229 100644 +--- a/doc/dsm/mods/Readme.mod_groups.txt ++++ b/doc/dsm/mods/Readme.mod_groups.txt +@@ -21,6 +21,9 @@ Actions: + groups.postEvent(groupname, var1;var2) - post event to groupname with var1 and var2 + groups.postEvent(groupname, var) - post event to groupname with all variables + ++ groups.get(arrayname=groupname) - get all ltags of troupname in arrayname ++ groups.getSize(varname=groupname) - get size of group in varname ++ + + Example: + import(mod_groups); +-- +1.9.3 (Apple Git-50) + diff --git a/debian/patches/sipwise/0014-dsm-mod_conference-flushMixInList-action-loop-for-mi.patch b/debian/patches/sipwise/0014-dsm-mod_conference-flushMixInList-action-loop-for-mi.patch new file mode 100644 index 00000000..d01bcd7f --- /dev/null +++ b/debian/patches/sipwise/0014-dsm-mod_conference-flushMixInList-action-loop-for-mi.patch @@ -0,0 +1,98 @@ +From 63d6e04f30e86f6d973dfe55ac6765c442ade026 Mon Sep 17 00:00:00 2001 +From: Stefan Sayer +Date: Fri, 20 Feb 2015 21:36:49 +0100 +Subject: [PATCH 6/7] dsm:mod_conference: flushMixInList action, loop for mix + in list + +--- + apps/dsm/mods/mod_conference/ModConference.cpp | 24 ++++++++++++++++++++---- + apps/dsm/mods/mod_conference/ModConference.h | 4 ++-- + doc/dsm/mods/Readme.mod_conference.txt | 5 ++++- + 3 files changed, 26 insertions(+), 7 deletions(-) + +diff --git a/apps/dsm/mods/mod_conference/ModConference.cpp b/apps/dsm/mods/mod_conference/ModConference.cpp +index 236cdd2..0028a14 100644 +--- a/apps/dsm/mods/mod_conference/ModConference.cpp ++++ b/apps/dsm/mods/mod_conference/ModConference.cpp +@@ -51,6 +51,7 @@ MOD_ACTIONEXPORT_BEGIN(MOD_CLS_NAME) { + DEF_CMD("conference.setupMixIn", ConfSetupMixInAction); + DEF_CMD("conference.playMixIn", ConfPlayMixInAction); + DEF_CMD("conference.playMixInList", ConfPlayMixInListAction); ++ DEF_CMD("conference.flushMixInList", ConfFlushMixInListAction); + + } MOD_ACTIONEXPORT_END; + +@@ -402,9 +403,10 @@ EXEC_ACTION_START(ConfPlayMixInAction) { + + } EXEC_ACTION_END; + +- ++CONST_ACTION_2P(ConfPlayMixInListAction, ',', true); + EXEC_ACTION_START(ConfPlayMixInListAction) { +- string filename = resolveVars(arg, sess, sc_sess, event_params); ++ string filename = resolveVars(par1, sess, sc_sess, event_params); ++ bool loop = resolveVars(par2, sess, sc_sess, event_params) == "true"; + + bool has_playlist = true; + // get playlist +@@ -434,9 +436,10 @@ EXEC_ACTION_START(ConfPlayMixInListAction) { + throw DSMException("file", "path", filename); + } + sc_sess->transferOwnership(af); ++ af->loop.set(loop); + +- DBG("adding file '%s' to mixin playlist\n", filename.c_str()); +- l->addToPlaylist(new AmPlaylistItem(af, NULL)); ++ DBG("adding file '%s' to mixin playlist\n", filename.c_str()); ++ l->addToPlaylist(new AmPlaylistItem(af, NULL)); + + if (!has_playlist) { + // get mixin mixer +@@ -450,3 +453,16 @@ EXEC_ACTION_START(ConfPlayMixInListAction) { + m->mixin(l); + } + } EXEC_ACTION_END; ++ ++EXEC_ACTION_START(ConfFlushMixInListAction) { ++ // get playlist ++ DSMDisposableT* l_obj = ++ getDSMConfChannel >(sc_sess, CONF_AKEY_MIXLIST); ++ if (NULL == l_obj) { ++ DBG("no mix list present - not flushing list\n"); ++ EXEC_ACTION_STOP; ++ } ++ AmPlaylist* l = l_obj->get(); ++ l->close(false); ++ DBG("flushed mixInList\n"); ++} EXEC_ACTION_END; +diff --git a/apps/dsm/mods/mod_conference/ModConference.h b/apps/dsm/mods/mod_conference/ModConference.h +index 73c2f5b..c6cdc72 100644 +--- a/apps/dsm/mods/mod_conference/ModConference.h ++++ b/apps/dsm/mods/mod_conference/ModConference.h +@@ -95,6 +95,6 @@ DEF_ACTION_1P(ConfTeeLeaveAction); + + DEF_ACTION_2P(ConfSetupMixInAction); + DEF_ACTION_1P(ConfPlayMixInAction); +-DEF_ACTION_1P(ConfPlayMixInListAction); +- ++DEF_ACTION_2P(ConfPlayMixInListAction); ++DEF_ACTION_1P(ConfFlushMixInListAction); + #endif +diff --git a/doc/dsm/mods/Readme.mod_conference.txt b/doc/dsm/mods/Readme.mod_conference.txt +index f4c0acc..a626c96 100644 +--- a/doc/dsm/mods/Readme.mod_conference.txt ++++ b/doc/dsm/mods/Readme.mod_conference.txt +@@ -49,6 +49,9 @@ conference.setupMixIn(float level, unsigned int seconds) + conference.playMixIn(string filename) + - mix in a file + +-conference.playMixInList(string filename) ++conference.playMixInList(string filename [, loop=true]) + - add a file to the mix-in playlist + - the list is setup when this is called for the first time and set as mixin source ++ ++conference.flushMixInList() ++ - flush mix-in playlist +-- +1.9.3 (Apple Git-50) + diff --git a/debian/patches/sipwise/0015-confpin-simple-pin-conference-app.patch b/debian/patches/sipwise/0015-confpin-simple-pin-conference-app.patch new file mode 100644 index 00000000..7d260b54 --- /dev/null +++ b/debian/patches/sipwise/0015-confpin-simple-pin-conference-app.patch @@ -0,0 +1,608 @@ +From fe53372de8a97d3af08dc3e54d842a4291449190 Mon Sep 17 00:00:00 2001 +From: Stefan Sayer +Date: Fri, 20 Feb 2015 21:55:59 +0100 +Subject: [PATCH 7/7] confpin: simple pin conference app + +--- + apps/confpin/confpin.conf | 39 +++++ + apps/confpin/lib/confpin.dsm | 237 ++++++++++++++++++++++++++ + apps/confpin/lib/sw_audio.dsm | 50 ++++++ + apps/confpin/lib/sw_audio_api.dsm | 66 +++++++ + apps/confpin/prompts/Makefile | 22 +++ + apps/confpin/prompts/conference_first.txt | 1 + + apps/confpin/prompts/conference_greeting.txt | 1 + + apps/confpin/prompts/conference_join.txt | 1 + + apps/confpin/prompts/conference_joined.txt | 1 + + apps/confpin/prompts/conference_leave.txt | 1 + + apps/confpin/prompts/conference_music.txt | 1 + + apps/confpin/prompts/conference_pin_wrong.txt | 1 + + apps/confpin/prompts/goodbye.txt | 1 + + apps/confpin/tools/clear_file | 14 ++ + apps/confpin/tools/fetch_file | 14 ++ + apps/confpin/tools/push_file | 14 ++ + 16 files changed, 464 insertions(+) + create mode 100644 apps/confpin/confpin.conf + create mode 100644 apps/confpin/lib/confpin.dsm + create mode 100644 apps/confpin/lib/sw_audio.dsm + create mode 100644 apps/confpin/lib/sw_audio_api.dsm + create mode 100644 apps/confpin/prompts/Makefile + create mode 100644 apps/confpin/prompts/conference_first.txt + create mode 100644 apps/confpin/prompts/conference_greeting.txt + create mode 100644 apps/confpin/prompts/conference_join.txt + create mode 100644 apps/confpin/prompts/conference_joined.txt + create mode 100644 apps/confpin/prompts/conference_leave.txt + create mode 100644 apps/confpin/prompts/conference_music.txt + create mode 100644 apps/confpin/prompts/conference_pin_wrong.txt + create mode 100644 apps/confpin/prompts/goodbye.txt + create mode 100755 apps/confpin/tools/clear_file + create mode 100755 apps/confpin/tools/fetch_file + create mode 100755 apps/confpin/tools/push_file + +diff --git a/apps/confpin/confpin.conf b/apps/confpin/confpin.conf +new file mode 100644 +index 0000000..2af4d14 +--- /dev/null ++++ b/apps/confpin/confpin.conf +@@ -0,0 +1,39 @@ ++# configuration for confpin app ++ ++ ++# audio cache configuration ++# audio_cache - same as cache_dir in audio_cache.conf ++#audio_cache=/tmp ++#audio_cache=/home/stefan/frafos/customers/sipwise/pbx/new_repo/sipwise_modules/callqueues/prompts ++audio_cache=../apps/confpin/cache/ ++# MySQL database connection for downloading audio prompts ++db_url=mysql://root:frafos@127.0.0.1/provisioning ++ ++# default sound set if non provisioned with app-param ++sound_set_id=1 ++ ++digit_collection_timeout=10 ++ ++###### digits - to be put into DB ++#digits_right=yes or no ++# single digits before 10s - for e.g. German: no, for eg. English: yes ++digits_right=yes ++# directory with digits - e.g. cache directory ++# the language (lng app param) will be added at the end, e.g. ++# digits_dir=../apps/callingcard/prompts/es/ ++digits_dir=../../sipwise_modules/callqueues/prompts/ ++ ++####### ++# it's best to leave those below as-is ++#diag_path=/usr/lib/sems/dsm/confpin ++#mod_path=/usr/lib/sems/dsm/ ++ ++# in-tree testing: ++diag_path=../apps/confpin/lib ++mod_path=../apps/dsm/mods/lib/ ++ ++load_diags=confpin,sw_audio_api ++register_apps=confpin ++run_invite_event=yes ++set_param_variables=yes ++run_system_dsms=sw_audio_api +diff --git a/apps/confpin/lib/confpin.dsm b/apps/confpin/lib/confpin.dsm +new file mode 100644 +index 0000000..2f4f6de +--- /dev/null ++++ b/apps/confpin/lib/confpin.dsm +@@ -0,0 +1,237 @@ ++#[% TAGS [- -] %] ++--- ++-- This DSM app ++-- * asks caller to enter pin for conference room ++-- * puts caller in conference room identified by roompin ++-- ++-- Parameters (P-App-Param): ++-- confpin - dsm app ++-- roompin - pin from db for particular subscriber ++-- room - conference room consists subscriber and roompin ++-- sound_set_id - sound set to use ++-- ++-- Example: P-App-Param: confpin;roompin="pin_from_db";room="$fU"_"pin_from_db";sound_set_id=3 ++-- ++ ++import(mod_conference); ++import(mod_dlg); ++import(mod_utils); ++import(mod_groups); ++ ++#include "sw_audio.dsm" ++ ++function stopCall() { ++ stop(true); ++}; ++ ++function refuseWith500() { ++ set(connect_session=0); ++ dlg.reply(500, "Server Internal Error"); ++ stop(false); ++}; ++ ++function enterConference() { ++ set($audio_id="conference_joined"); ++ swMixInFile(); ++ info(">> entering conference in room '$room'"); ++ conference.setPlayoutType(adaptive); ++ conference.join($room); ++ set($joined=true); ++ groups.postEvent($room, joined); ++ groups.join($room); ++ groups.getSize($roomsize=$room); ++ if test($roomsize==1) { ++ set($audio_id="conference_first"); ++ swMixInFile(); ++ set($audio_id="conference_music"); ++ set($sw_audio_loop="true"); ++ swMixInFile(); ++ clear($sw_audio_loop); ++ set($lonely_user=true); ++ } ++ info("entered conference, $roomsize people in here<<"); ++}; ++initial state START; ++ ++transition "DB exception" START - exception / { ++ error("Error in initializing :"); ++ refuseWith500(); ++} -> END; ++ ++transition "check for sound_set_id provisioning" START - invite; test($sound_set_id=="") / { ++ error("Error in provisioning: no sound_set_id application parameter set"); ++ refuseWith500(); ++} -> END; ++ ++transition "Fetching File exception" START - exception; test(#type=="result") / { ++ error("error in DB query for fetching audio file:"); ++ logAll(1); ++ stop(true); ++} -> END; ++ ++transition "call starts" START - invite / { ++ -- process session establishment in DSM app ++ set(connect_session=0); ++ dlg.acceptInvite(); ++ connectMedia(); ++ ++ -- connect to DB ++ mysql.connect(); ++ ++ if test($roompin=="") ++ { ++ info(pin is empty); ++ set($autoEnter=1); ++ repost(); ++ } ++ else ++ { ++ info(">> start_pin_entry"); ++ set($tryAgain=0); ++ set($pin=""); ++ ++ -- rfc4240 ++ if test($room=="") { ++ info("room is empty"); ++ dlg.reply(404,"Not found"); ++ } else { ++ set($audio_id="conference_greeting"); ++ swPlayFile(); ++ } ++ info("start_pin_entry <<"); ++ } ++} -> COLLECT_PIN; ++ ++-------------------------------------------------------- ++state COLLECT_PIN; ++transition "prompt ends, start collection timer" COLLECT_PIN - noAudio / setTimer(1, $config.digit_collection_timeout) -> COLLECT_PIN; ++ ++transition "roompin empty, enter conference" COLLECT_PIN - test($autoEnter==1) / { ++ info(">> empty_pin"); ++ enterConference(); ++} -> CONFERENCE; ++ ++transition "timer, short pin, too many tries" COLLECT_PIN - timer(#id==1); test(len($pin)<3); test($pin_tries==$config.pin_max_retries) / { ++ stopCall(); ++} -> END; ++transition "timer, short pin, too many tries" COLLECT_PIN - timer(#id==1); test(len($pin)<3); test($pin_tries>$config.pin_max_retries) / { ++ stopCall(); ++} -> END; ++transition "hash entered, short pin, too many tries" COLLECT_PIN - key(#key==11); test(len($pin)<3); test($pin_tries>$config.pin_max_retries) / { ++ stopCall(); ++} -> END; ++transition "hash entered, short pin, too many tries" COLLECT_PIN - key(#key==11); test(len($pin)<3); test($pin_tries==$config.pin_max_retries) / { ++ stopCall(); ++} -> END; ++ ++transition "collect pin timer hit, short pin" COLLECT_PIN - timer(#id==1); test(len($pin)<3) / { ++ set($audio_id="conference_pin_wrong"); ++ swPlayFile(); ++ inc($pin_tries); ++} -> COLLECT_PIN; ++ ++transition "hash entered, short pin" COLLECT_PIN - key(#key==11); test(len($pin)<3) / { ++ set($audio_id="conference_pin_wrong"); ++ swPlayFile(); ++ inc($pin_tries); ++} -> COLLECT_PIN; ++ ++transition "number entered" COLLECT_PIN - key(#key<10) / { ++ -- stop prompt ++ closePlaylist(false); ++ append($pin, #key); ++ info("USER ENTERED key '#key'"); ++ setTimer(1, $config.digit_collection_timeout); ++} -> COLLECT_PIN; ++ ++transition "collect pin timer hit" COLLECT_PIN - timer(#id==1) -> TESTPINRESULT; ++transition "hash entered, finished pin" COLLECT_PIN - key(#key==11) / removeTimer(1) -> TESTPINRESULT; ++ ++-------------------------------------------------------- ++state TESTPINRESULT ++enter { ++ info("Key #key pressed, tryAgain is $tryAgain"); ++ repost(); ++}; ++ ++transition "incorrect_retry" TESTPINRESULT - test($pin!=$roompin); test($tryAgain<3) / { ++ info(">> incorrect_retry, pin '$pin', tryAgain '$tryAgain'"); ++ inc($tryAgain); ++ set($pin=""); ++ set($audio_id="conference_pin_wrong"); ++ swPlayFile(); ++ info("incorrect_retry <<"); ++} -> COLLECT_PIN; ++ ++transition "incorrect_no_retry" TESTPINRESULT - test($pin!=$roompin); test($tryAgain==3) / { ++ info(">> incorrect_no_retry, tryAgain '$tryAgain'"); ++ set($audio_id="goodbye"); ++ swPlayFile(); ++ info("incorrect_no_retry <<"); ++} -> PLAY_FIN; ++ ++-------------------------------------------------------- ++state PLAY_FIN; ++transition "bye_after_fin" PLAY_FIN - noAudio / stopCall() -> END; ++ ++-------------------------------------------------------- ++ ++transition "correct_pin" TESTPINRESULT - test($pin==$roompin) / { ++ info(">> correct_pin"); ++ enterConference(); ++} -> CONFERENCE; ++ ++state CONFERENCE; ++ ++transition "got leave event" CONFERENCE - event(#leave==true) / { ++ logParams(); ++ set($audio_id="conference_leave"); ++ swMixInFile(); ++} -> CONFERENCE; ++ ++transition "got join event" CONFERENCE - event(#joined==true) / { ++ logParams(); ++ if test($lonely_user==true) { ++ conference.flushMixInList(); ++ } ++ set($audio_id="conference_join"); ++ swMixInFile(); ++} -> CONFERENCE; ++ ++transition "kick_event" CONFERENCE - eventTest(#action==kick) / { ++ info(">> kick_event"); ++ closePlaylist(); ++ conference.leave(); ++ set($leave=true); ++ groups.leaveAll(); ++ groups.postEvent($room, leave); ++ stop(true); ++ info("kick_event <<"); ++} -> END; ++ ++# is this the same as kick? ++transition "leave_event" CONFERENCE - eventTest(#action==leave) / { ++ info(">> leave_event"); ++ closePlaylist(); ++ conference.leave(); ++ set($leave=true); ++ groups.leaveAll(); ++ groups.postEvent($room, leave); ++ stop(true); ++ info("leave_event <<"); ++} -> END; ++ ++transition "leave_conference" CONFERENCE - hangup / { ++ info(">> leave_conference"); ++ closePlaylist(); ++ conference.leave(); ++ set($leave=true); ++ groups.leaveAll(); ++ groups.postEvent($room, leave); ++ stop(false); ++ info("leave_conference <<"); ++} -> END; ++ ++transition "bye_recvd" (START,COLLECT_PIN,PLAY_FIN,TESTPINRESULT) - hangup / stop(false) -> END; ++ ++state END; +diff --git a/apps/confpin/lib/sw_audio.dsm b/apps/confpin/lib/sw_audio.dsm +new file mode 100644 +index 0000000..322266b +--- /dev/null ++++ b/apps/confpin/lib/sw_audio.dsm +@@ -0,0 +1,50 @@ ++-- sw_audio ++-- ++-- The playFile() function plays a file with ID $audio_id from the $config.audio_cache directory. ++-- $sound_set_id is used as subdirectory under $config.audio_cache. ++-- If it doesn't exist, it is tried to be fetched from the MySQL DB, using the $audio_id. ++-- If that fails, an exception with type playFile is thrown ++-- ++-- swMixInFile() mixes the file in to a mixInList setup by the conference module. it uses ++-- the $has_mixin variable to record that state, and setup the mixin if it's not there. ++-- ++-- set($sw_audio_loop="true") makes the file to be looped ++ ++import(mod_sys); ++import(mod_mysql); ++import(mod_conference); ++ ++function swPlayFile() { ++ sets($__file_cache_path="$(config.audio_cache)/$(sound_set_id)/"); ++ sets($__file_path="$(__file_cache_path)$(audio_id).wav"); ++ ++ if sys.file_not_exists($__file_path) { ++ if sys.file_not_exists($__file_cache_path) { ++ sys.mkdir($__file_cache_path); ++ } ++ -- connect to DB ++ if not mysql.connected() { ++ mysql.connect(); ++ throwOnError(); ++ } ++ ++ mysql.getFileFromDB('SELECT data FROM provisioning.voip_sound_files vsf, provisioning.voip_sound_handles vsh WHERE vsh.name="$audio_id" AND vsf.set_id=$sound_set_id AND vsh.id=vsf.handle_id',$__file_path); ++ throwOnError(); ++ } ++ if test($mix_file==true) { ++ conference.playMixInList($__file_path, $sw_audio_loop); ++ } else { ++ playFile($__file_path, $sw_audio_loop); ++ } ++ clear($__file_path); ++ clear($__file_cache_path); ++}; ++ ++function swMixInFile() { ++ set($mix_file=true); ++ if test($has_mixin!=true) { ++ conference.setupMixIn(0.5, 0); ++ set($has_mixin=true); ++ } ++ swPlayFile(); ++}; +\ No newline at end of file +diff --git a/apps/confpin/lib/sw_audio_api.dsm b/apps/confpin/lib/sw_audio_api.dsm +new file mode 100644 +index 0000000..aba8d25 +--- /dev/null ++++ b/apps/confpin/lib/sw_audio_api.dsm +@@ -0,0 +1,66 @@ ++-- sw_audio_api ++-- ++-- this SystemDSM implements API functions to handle the prompt cache ++-- ++ ++import(mod_sys); ++import(mod_mysql); ++ ++initial state SW_AUDIO_START; ++ ++transition "server startup" SW_AUDIO_START - startup / { ++ log(2, "sw_audio cache handler started"); ++ registerEventQueue("sw_audio"); ++ mysql.connect(); ++ logAll(3); ++} -> SW_AUDIO_WAIT_EVENT; ++ ++state SW_AUDIO_WAIT_EVENT; ++ ++transition "exception in server startup" (SW_AUDIO_START,SW_AUDIO_WAIT_EVENT) - exception / { ++ logAll(1); ++} -> SW_AUDIO_WAIT_EVENT; ++ ++transition "server shutdown" SW_AUDIO_WAIT_EVENT - system(#type=="ServerShutdown") / { ++ log(2, "sw_audio cache handler stopping"); ++ unregisterEventQueue("sw_audio"); ++ stop(false); ++} -> SW_AUDIO_END; ++ ++transition "clear File" SW_AUDIO_WAIT_EVENT - event(#cmd=="clearFile") / { ++ log(3, "sw_audio cache handler: clearFile"); ++ logParams(3); ++ sets($__file_path="$(config.audio_cache)/#(sound_set_id)/#(audio_id).wav"); ++ sys.unlink($__file_path); ++ clear($__file_path); ++} -> SW_AUDIO_WAIT_EVENT; ++ ++transition "fetch File" SW_AUDIO_WAIT_EVENT - event(#cmd=="fetchFile") / { ++ log(3, "sw_audio cache handler: fetchFile"); ++ logParams(3); ++ sets($__file_path="$(config.audio_cache)/#(sound_set_id)/#(audio_id).wav"); ++ mysql.getFileFromDB(SELECT data FROM provisioning.audio_files WHERE id="#audio_id",$__file_path); ++ clear($__file_path); ++} -> SW_AUDIO_WAIT_EVENT; ++ ++transition "push File" SW_AUDIO_WAIT_EVENT - event(#cmd=="pushFile") / { ++ log(3, "sw_audio cache handler: pushFile"); ++ log(3, "WARNING! for debug purposes only"); ++ logParams(3); ++ sets($__file_path="$(config.audio_cache)/#(sound_set_id)/#(audio_id).wav"); ++ mysql.connect(); ++ mysql.query(SELECT id as vsh_id FROM provisioning.voip_sound_handles where name="#audio_id"); ++ logAll(3); ++ if test($db.rows==0) { ++ mysql.execute(INSERT INTO provisioning.voip_sound_handles (name) VALUES ("#audio_id")); ++ set($vsh_id=$db.insert_id); ++ } else { ++ mysql.getResult(0); ++ }; ++ log(3, $vsh_id); ++ mysql.putFileToDB('INSERT INTO provisioning.voip_sound_files (handle_id,set_id,data) VALUES ($vsh_id,#sound_set_id, "__FILE__")', $__file_path); ++ logAll(3); ++ clear($__file_path); ++} -> SW_AUDIO_WAIT_EVENT; ++ ++state SW_AUDIO_END; +\ No newline at end of file +diff --git a/apps/confpin/prompts/Makefile b/apps/confpin/prompts/Makefile +new file mode 100644 +index 0000000..25028e8 +--- /dev/null ++++ b/apps/confpin/prompts/Makefile +@@ -0,0 +1,22 @@ ++SRCS=$(wildcard *.txt) ++WAVS=$(SRCS:.txt=.wav) ++DBS=$(SRCS:.txt=.dbs) ++ ++all: $(WAVS) ++ ++db_upload: $(DBS) ++ ++%.wav : %.txt Makefile ++ flite -f $< -o $(basename $@)_16k.wav ++## text2wave $< -o $(basename $@)_16k.wav ++ sox $(basename $@)_16k.wav -r 8000 $@ ++ rm $(basename $@)_16k.wav ++ ++%.dbs: %.wav Makefile ++ mkdir -p ../cache/1 ++ cp $(basename $@).wav ../cache/1 ++ ../tools/push_file $(basename $@) 1 ++ touch $(basename $@).dbs ++ ++clean: ++ rm -f *.dbs *.wav +\ No newline at end of file +diff --git a/apps/confpin/prompts/conference_first.txt b/apps/confpin/prompts/conference_first.txt +new file mode 100644 +index 0000000..1589216 +--- /dev/null ++++ b/apps/confpin/prompts/conference_first.txt +@@ -0,0 +1 @@ ++you are the first participant in the conference. +diff --git a/apps/confpin/prompts/conference_greeting.txt b/apps/confpin/prompts/conference_greeting.txt +new file mode 100644 +index 0000000..ac5cadc +--- /dev/null ++++ b/apps/confpin/prompts/conference_greeting.txt +@@ -0,0 +1 @@ ++welcome to the conference, please enter your pin number +diff --git a/apps/confpin/prompts/conference_join.txt b/apps/confpin/prompts/conference_join.txt +new file mode 100644 +index 0000000..58e771a +--- /dev/null ++++ b/apps/confpin/prompts/conference_join.txt +@@ -0,0 +1 @@ ++someone joined the conference +diff --git a/apps/confpin/prompts/conference_joined.txt b/apps/confpin/prompts/conference_joined.txt +new file mode 100644 +index 0000000..29a4feb +--- /dev/null ++++ b/apps/confpin/prompts/conference_joined.txt +@@ -0,0 +1 @@ ++you joined the conference +diff --git a/apps/confpin/prompts/conference_leave.txt b/apps/confpin/prompts/conference_leave.txt +new file mode 100644 +index 0000000..2a5a881 +--- /dev/null ++++ b/apps/confpin/prompts/conference_leave.txt +@@ -0,0 +1 @@ ++someone left the conference +diff --git a/apps/confpin/prompts/conference_music.txt b/apps/confpin/prompts/conference_music.txt +new file mode 100644 +index 0000000..d075594 +--- /dev/null ++++ b/apps/confpin/prompts/conference_music.txt +@@ -0,0 +1 @@ ++bum bada bum bum bamm, bamm bada bamm bamm bamm, hum di dum di dum dum dumm +diff --git a/apps/confpin/prompts/conference_pin_wrong.txt b/apps/confpin/prompts/conference_pin_wrong.txt +new file mode 100644 +index 0000000..16a203a +--- /dev/null ++++ b/apps/confpin/prompts/conference_pin_wrong.txt +@@ -0,0 +1 @@ ++sorry, that pin is wrong. please try again +diff --git a/apps/confpin/prompts/goodbye.txt b/apps/confpin/prompts/goodbye.txt +new file mode 100644 +index 0000000..024d23d +--- /dev/null ++++ b/apps/confpin/prompts/goodbye.txt +@@ -0,0 +1 @@ ++good bye +diff --git a/apps/confpin/tools/clear_file b/apps/confpin/tools/clear_file +new file mode 100755 +index 0000000..a3bf106 +--- /dev/null ++++ b/apps/confpin/tools/clear_file +@@ -0,0 +1,14 @@ ++#!/usr/bin/python ++# -*- coding: utf-8 -*- ++import sys ++from xmlrpclib import * ++ ++if len(sys.argv) != 3: ++ print "usage: %s " % sys.argv[0] ++ sys.exit(1) ++ ++s = ServerProxy('http://localhost:8090') ++print "Active calls: %d" % s.calls() ++#p ={ 'name' : sys.argv[1], 'path' : sys.argv[2] } ++#print s.di('sbc','loadProfile',p) ++print s.di('dsm', 'postDSMEvent', 'sw_audio', [['cmd', 'clearFile'],['audio_id', sys.argv[1]],['sound_set_id', sys.argv[2]]]) +\ No newline at end of file +diff --git a/apps/confpin/tools/fetch_file b/apps/confpin/tools/fetch_file +new file mode 100755 +index 0000000..bb54ae6 +--- /dev/null ++++ b/apps/confpin/tools/fetch_file +@@ -0,0 +1,14 @@ ++#!/usr/bin/python ++# -*- coding: utf-8 -*- ++import sys ++from xmlrpclib import * ++ ++if len(sys.argv) != 3: ++ print "usage: %s " % sys.argv[0] ++ sys.exit(1) ++ ++s = ServerProxy('http://localhost:8090') ++print "Active calls: %d" % s.calls() ++#p ={ 'name' : sys.argv[1], 'path' : sys.argv[2] } ++#print s.di('sbc','loadProfile',p) ++print s.di('dsm', 'postDSMEvent', 'sw_audio', [['cmd', 'fetchFile'],['audio_id', sys.argv[1]],['sound_set_id', sys.argv[2]]]) +\ No newline at end of file +diff --git a/apps/confpin/tools/push_file b/apps/confpin/tools/push_file +new file mode 100755 +index 0000000..d949d99 +--- /dev/null ++++ b/apps/confpin/tools/push_file +@@ -0,0 +1,14 @@ ++#!/usr/bin/python ++# -*- coding: utf-8 -*- ++import sys ++from xmlrpclib import * ++ ++if len(sys.argv) != 3: ++ print "usage: %s " % sys.argv[0] ++ sys.exit(1) ++ ++s = ServerProxy('http://localhost:8090') ++print "Active calls: %d" % s.calls() ++#p ={ 'name' : sys.argv[1], 'path' : sys.argv[2] } ++#print s.di('sbc','loadProfile',p) ++print s.di('dsm','postDSMEvent', 'sw_audio', [['cmd', 'pushFile'],['audio_id', sys.argv[1]],['sound_set_id', sys.argv[2]]]) +-- +1.9.3 (Apple Git-50) +