void DSMFactory::registerApplication(const AmArg& args, AmArg& ret) { string diag_name = args.get(0).asCStr(); string conf_name; if (args.size()>1 && isArgCStr(args.get(1))) conf_name = args.get(1).asCStr(); bool has_diag; ScriptConfigs_mut.lock(); try { has_diag = hasDSM(diag_name, conf_name); } catch(...) { ScriptConfigs_mut.unlock(); throw; } ScriptConfigs_mut.unlock(); if (!has_diag) { ret.push(400); ret.push("unknown application (DSM)"); return; } bool res = AmPlugIn::instance()->registerFactory4App(diag_name,this); if(res) { INFO("DSM state machine registered: %s.\n",diag_name.c_str()); ret.push(200); ret.push("registered DSM application"); } else { ret.push(500); ret.push("Error registering DSM application (already registered?)"); } }
void DSMFactory::listDSMs(const AmArg& args, AmArg& ret) { vector<string> names; ScriptConfigs_mut.lock(); try { if (isArgUndef(args) || !args.size()) names = MainScriptConfig.diags->getDiagramNames(); else { if (isArgCStr(args.get(0))) { map<string, DSMScriptConfig>::iterator i= ScriptConfigs.find(args.get(0).asCStr()); if (i!= ScriptConfigs.end()) names = i->second.diags->getDiagramNames(); } } } catch (...) { ScriptConfigs_mut.unlock(); throw; } ScriptConfigs_mut.unlock(); for (vector<string>::iterator it= names.begin(); it != names.end(); it++) { ret.push(*it); } }
void DSMFactory::hasDSM(const AmArg& args, AmArg& ret) { string conf_name; if (args.size()>1 && isArgCStr(args.get(1))) conf_name = args.get(1).asCStr(); bool res; ScriptConfigs_mut.lock(); try { res = hasDSM(args.get(0).asCStr(), conf_name); } catch(...) { ScriptConfigs_mut.unlock(); throw; } ScriptConfigs_mut.unlock(); if (res) ret.push("1"); else ret.push("0"); }
void CCBLRedis::start(const string& cc_name, const string& ltag, SBCCallProfile* call_profile, int start_ts_sec, int start_ts_usec, const AmArg& values, int timer_id, AmArg& res) { // start code here res.push(AmArg()); AmArg& res_cmd = res[0]; #define MAX_ARGV_ITEMS 20 const char* argv[MAX_ARGV_ITEMS]; size_t argvlen[MAX_ARGV_ITEMS]; unsigned int argv_max = 0; if (!values.hasMember("argc") || str2i(values["argc"].asCStr(), argv_max) || (!argv_max)) { ERROR("deciphering argc\n"); res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 500; res_cmd[SBC_CC_REFUSE_REASON] = SIP_REPLY_SERVER_INTERNAL_ERROR; return; } unsigned int argv_index=0; string query; for (; argv_index<argv_max;argv_index++) { argv[argv_index] = values["argv_"+int2str(argv_index)].asCStr(); argvlen[argv_index] = strlen(argv[argv_index]); if (query.length()) query+=" "; query+=string(argv[argv_index], argvlen[argv_index]); } DBG("query to REDIS: '%s'\n", query.c_str()); bool hit = false; unsigned int retries = 0; for (;retries<max_retries;retries++) { redisContext* redis_context = connection_pool.getActiveConnection(); if (NULL == redis_context) { INFO("no connection to REDIS\n"); if (!pass_on_bl_unavailable) { res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 500; res_cmd[SBC_CC_REFUSE_REASON] = SIP_REPLY_SERVER_INTERNAL_ERROR; } return; } DBG("using redis connection [%p]\n", redis_context); redisReply* reply = (redisReply *) redisCommandArgv(redis_context, argv_index, argv, argvlen); int ret = handle_redis_reply(redis_context, reply, hit); if (ret == RWT_E_CONNECTION) { WARN("connection [%p] failed - retrying\n", redis_context); connection_pool.returnFailedConnection(redis_context); continue; } connection_pool.returnConnection(redis_context); break; } if (retries == max_retries) { if (!pass_on_bl_unavailable) { res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 500; res_cmd[SBC_CC_REFUSE_REASON] = SIP_REPLY_SERVER_INTERNAL_ERROR; } return; } if (hit) { if (values.hasMember("action") && isArgCStr(values["action"]) && values["action"] == "drop") { DBG("Blacklist: Dropping call\n"); res_cmd[SBC_CC_ACTION] = SBC_CC_DROP_ACTION; } else { DBG("Blacklist: Refusing call\n"); res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 403; res_cmd[SBC_CC_REFUSE_REASON] = "Unauthorized"; } } }
bool SCDIAction::execute(AmSession* sess, DSMCondition::EventType event, map<string,string>* event_params) { GET_SCSESSION(); if (params.size() < 2) { ERROR("DI needs at least: mod_name, " "function_name (in '%s'\n", name.c_str()); return false; } vector<string>::iterator p_it=params.begin(); string fact_name = trim(*p_it, " \""); AmDynInvokeFactory* fact = AmPlugIn::instance()->getFactory4Di(fact_name); if(!fact) { ERROR("load module for factory '%s'.\n", fact_name.c_str()); return false; } AmDynInvoke* di_inst = fact->getInstance(); if(!di_inst) { ERROR("load module for factory '%s'\n", fact_name.c_str()); return false; } p_it++; string func_name = trim(*p_it, " \""); p_it++; AmArg di_args; while (p_it != params.end()) { string p = trim(*p_it, " \t"); if (p.length() && p[0] == '"') { di_args.push(trim(p,"\"").c_str()); } else if (p.length() > 5 && p.substr(0, 5) =="(int)") { p = resolveVars(p.substr(5), sess, sc_sess, event_params); char* endptr = NULL; long p_i = strtol(p.c_str(), &endptr, 10); if (endptr && *endptr == '\0') { di_args.push((int)p_i); } else { ERROR("converting value '%s' to int\n", p.c_str()); return false; } } else { di_args.push(resolveVars(p, sess, sc_sess, event_params).c_str()); } p_it++; } sc_sess->di_res.clear(); DBG("executing DI function '%s'\n", func_name.c_str()); try { di_inst->invoke(func_name, di_args, sc_sess->di_res); } catch (const AmDynInvoke::NotImplemented& ni) { ERROR("not implemented DI function '%s'\n", ni.what.c_str()); return false; } catch (const AmArg::OutOfBoundsException& oob) { ERROR("out of bounds in DI call '%s'\n", name.c_str()); return false; } catch (const AmArg::TypeMismatchException& oob) { ERROR("type mismatch in DI call '%s'\n", name.c_str()); return false; } catch (...) { ERROR("unexpected Exception in DI call '%s'\n", name.c_str()); return false; } if (get_res) { // rudimentary variables conversion... if (isArgCStr(sc_sess->di_res)) sc_sess->var["DI_res"] = sc_sess->di_res.asCStr(); else if (isArgInt(sc_sess->di_res)) sc_sess->var["DI_res"] = int2str(sc_sess->di_res.asInt()); else if (isArgArray(sc_sess->di_res)) { // copy results to $DI_res0..$DI_resn for (size_t i=0;i<sc_sess->di_res.size();i++) { switch (sc_sess->di_res.get(i).getType()) { case AmArg::CStr: { sc_sess->var["DI_res"+int2str(i)] = sc_sess->di_res.get(i).asCStr(); } break; case AmArg::Int: { sc_sess->var["DI_res"+int2str(i)] = int2str(sc_sess->di_res.get(i).asInt()); } break; default: { ERROR("unsupported AmArg return type!"); } } } } else { ERROR("unsupported AmArg return type!"); } } return false; }