Example #1
0
// todo: convert errors to exceptions
void replyRequest(DSMSession* sc_sess, AmSession* sess, 
		  EventParamT* event_params,
		  const string& par1, const string& par2,
		  const AmSipRequest& req) {
  string code = resolveVars(par1, sess, sc_sess, event_params);
  string reason = resolveVars(par2, sess, sc_sess, event_params);
  unsigned int code_i;
  if (str2i(code, code_i)) {
    ERROR("decoding reply code '%s'\n", code.c_str());
    sc_sess->SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
    return;
  }

  if (!sc_sess->last_req.get()) {
    ERROR("no last request to reply\n");
    sc_sess->SET_ERRNO(DSM_ERRNO_GENERAL);
    sc_sess->SET_STRERROR("no last request to reply");
    return;
  }

  if (sess->dlg.reply(req, code_i, reason)) {
    sc_sess->SET_ERRNO(DSM_ERRNO_GENERAL);
    sc_sess->SET_STRERROR("error sending reply");
  } else
    sc_sess->CLR_ERRNO;
}
bool TestDSMCondition::match(AmSession* sess, DSMCondition::EventType event,
			  map<string,string>* event_params) {
  if (ttype == None || (type != DSMCondition::Any && type != event))
    return false;

  if (ttype == Always)
    return true;

  DSMSession* sc_sess = dynamic_cast<DSMSession*>(sess);
  if (!sc_sess) {
    ERROR("wrong session type\n");
    return false;
  }
  
  string l;
  string r;
  if (lhs.length() > 5 && 
      (lhs.substr(0, 4) == "len(") && lhs[lhs.length()-1] == ')') {
    l = int2str(resolveVars(lhs.substr(4, lhs.length()-5), sess, sc_sess, event_params).length());
  } else {    
    l   = resolveVars(lhs, sess, sc_sess, event_params);
  }
  if (rhs.length() > 5 && 
      rhs.substr(0, 4) == "len(" && rhs[rhs.length()-1] == ')') {
    r = resolveVars(rhs.substr(4, rhs.length()-5), sess, sc_sess, event_params).length();
  } else {    
    r   = resolveVars(rhs, sess, sc_sess, event_params);
  }

//   string r = resolveVars(rhs, sess, sc_sess, event_params);

  DBG("test '%s' vs '%s'\n", l.c_str(), r.c_str());

  switch (ttype) {
  case Eq: return l == r;
  case Neq: return l != r;
  case Less: {
    char* endptr = NULL;
    long l_i = strtol(l.c_str(), &endptr, 10);
    if (endptr && *endptr  == '\0') {
      long r_i = strtol(r.c_str(), &endptr, 10);
      if (endptr && *endptr  == '\0') 
	return l_i < r_i;
      }
    return l < r;
  }
  case Gt: {
    char* endptr = NULL;
    long l_i = strtol(l.c_str(), &endptr, 10);
    if (endptr && *endptr  == '\0') {
      long r_i = strtol(r.c_str(), &endptr, 10);
      if (endptr && *endptr  == '\0') 
	return l_i > r_i;
      }
    return l > r;
  } 
  default: return false;
  }  
}
bool MonLogAddAction::execute(AmSession* sess, 
			   DSMCondition::EventType event,
			   map<string,string>* event_params) {
  GET_SCSESSION();

  string prop = resolveVars(par1, sess, sc_sess, event_params);
  string val  = resolveVars(par2, sess, sc_sess, event_params);
  
  MONITORING_LOG_ADD(sess->getLocalTag().c_str(), prop.c_str(), val.c_str());

  return false;
}
bool SCPlayFileAction::execute(AmSession* sess, 
			       DSMCondition::EventType event,
			       map<string,string>* event_params) {
  GET_SCSESSION();

  bool loop = 
    resolveVars(par2, sess, sc_sess, event_params) == "true";
  DBG("par1 = '%s', par2 = %s\n", par1.c_str(), par2.c_str());
  sc_sess->playFile(resolveVars(par1, sess, sc_sess, event_params), 
		    loop);
  return false;
}
bool SCLogAction::execute(AmSession* sess, 
			  DSMCondition::EventType event,
			  map<string,string>* event_params) {
  GET_SCSESSION();
  
  unsigned int lvl;
  if (str2i(resolveVars(par1, sess, sc_sess, event_params), lvl)) {
    ERROR("unknown log level '%s'\n", par1.c_str());
    return false;
  }
  string l_line = resolveVars(par2, sess, sc_sess, event_params).c_str();
  _LOG((int)lvl, "FSM: %s %s\n", (par2 != l_line)?par2.c_str():"",
       l_line.c_str());
  return false;
}
DSMAction::SEAction SCCallFSMAction::getSEAction(string& param,
						 AmSession* sess, DSMSession* sc_sess,
						 DSMCondition::EventType event,
						 map<string,string>* event_params) {
  param = resolveVars(arg, sess, sc_sess, event_params);
  return Call; 
}
bool SCRecordFileAction::execute(AmSession* sess, 
				 DSMCondition::EventType event,
				 map<string,string>* event_params) {
  GET_SCSESSION();
  sc_sess->recordFile(resolveVars(arg, sess, sc_sess, event_params));
  return false;
}
string replaceParams(const string& q, AmSession* sess, DSMSession* sc_sess, 
		     map<string,string>* event_params) {
  string res = q;
  size_t repl_pos = 0;
  while (repl_pos<res.length()) {
    size_t rstart = res.find_first_of("$#@", repl_pos);
    repl_pos = rstart+1;
    if (rstart == string::npos) 
      break;
    if (rstart && res[rstart-1] == '\\') // escaped
      continue;
    size_t rend;
    if (res.length() > rstart+1 && 
	(res[rstart+1] == '(' ||
	 res[rstart+1] == '"' ||
	 res[rstart+1] == '\''
	 ))
      rend = res.find_first_of(" ,()[]$#@\t;:'\"", rstart+2);
    else 
      rend = res.find_first_of(" ,()[]$#@\t;:'\"", rstart+1);
    if (rend==string::npos)
      rend = res.length();
    string keyname = res.substr(rstart+1, rend-rstart-1);

    if (keyname.length()>2) {
      if ((keyname[0] == '(' && res[rend] == ')') ||
	  (keyname[0] == res[rend] &&
	   (keyname[0] == '"' ||keyname[0] == '\''))) {
	keyname = keyname.substr(1);
	if (rend != res.length())
	  rend++;
      }
    }
    // todo: simply use resolveVars (?)
    switch(res[rstart]) {
    case '$': {
      
      if (sc_sess->var.find(keyname) == sc_sess->var.end())
	res.erase(rstart, rend-rstart); 
      else 
	res.replace(rstart, rend-rstart, sc_sess->var[keyname]); 
    } break;
    case '#':
      if (NULL!=event_params) {
	if (event_params->find(keyname) != event_params->end())
	  res.replace(rstart, rend-rstart, (*event_params)[keyname]);
	else
	  res.erase(rstart, rend-rstart);	
      } break;
    case '@': {
      // todo: optimize 
      res.replace(rstart, rend-rstart, 
		  resolveVars("@"+keyname, sess, sc_sess, event_params));
    } break;
    default: break;
    }
  }
  return res;
}
bool SCClosePlaylistAction::execute(AmSession* sess, 
				    DSMCondition::EventType event,
				    map<string,string>* event_params) {
  GET_SCSESSION();
  bool notify = 
    resolveVars(arg, sess, sc_sess, event_params) == "true";
  sc_sess->closePlaylist(notify);
  return false;
}
bool SCStopAction::execute(AmSession* sess, 
			   DSMCondition::EventType event,
			   map<string,string>* event_params) {
  GET_SCSESSION();
  if (resolveVars(arg, sess, sc_sess, event_params) == "true") {
    DBG("sending bye\n");
    sess->dlg.bye();
  }
  sess->setStopped();
  return false;
}
bool SCSetAction::execute(AmSession* sess, 
			  DSMCondition::EventType event,
			  map<string,string>* event_params) {
  GET_SCSESSION();
  string var_name = (par1.length() && par1[0] == '$')?
    par1.substr(1) : par1;

  sc_sess->var[var_name] = resolveVars(par2, sess, sc_sess, event_params);
  DBG("set variable '%s'='%s'\n", 
      var_name.c_str(), sc_sess->var[var_name].c_str());
  return false;
}
bool SCSetTimerAction::execute(AmSession* sess, 
			       DSMCondition::EventType event,
			       map<string,string>* event_params) {
  GET_SCSESSION();

  unsigned int timerid;
  if (str2i(resolveVars(par1, sess, sc_sess, event_params), timerid)) {
    ERROR("timer id '%s' not decipherable\n", 
	  resolveVars(par1, sess, sc_sess, event_params).c_str());
    return false;
  }

  unsigned int timeout;
  if (str2i(resolveVars(par2, sess, sc_sess, event_params), timeout)) {
    ERROR("timeout value '%s' not decipherable\n", 
	  resolveVars(par2, sess, sc_sess, event_params).c_str());
    return false;
  }

  DBG("setting timer %u with timeout %u\n", timerid, timeout);
  AmDynInvokeFactory* user_timer_fact = 
    AmPlugIn::instance()->getFactory4Di("user_timer");

  if(!user_timer_fact) {
    ERROR("load sess_timer module for timers.\n");
    return false;
  }
  AmDynInvoke* user_timer = user_timer_fact->getInstance();
  if(!user_timer) {
    ERROR("load sess_timer module for timers.\n");
    return false;
  }

  AmArg di_args,ret;
  di_args.push((int)timerid);
  di_args.push((int)timeout);      // in seconds
  di_args.push(sess->getLocalTag().c_str());
  user_timer->invoke("setTimer", di_args, ret);
  return false;
}
void log_vars(const string& l_arg, AmSession* sess,
	      DSMSession* sc_sess, map<string,string>* event_params) {
  unsigned int lvl;
  if (str2i(resolveVars(l_arg, sess, sc_sess, event_params), lvl)) {
    ERROR("unknown log level '%s'\n", l_arg.c_str());
    return;
  }

  _LOG((int)lvl, "FSM: variables set ---\n");
  for (map<string, string>::iterator it = 
	 sc_sess->var.begin(); it != sc_sess->var.end(); it++) {
    _LOG((int)lvl, "FSM:  $%s='%s'\n", it->first.c_str(), it->second.c_str());
  }
  _LOG((int)lvl, "FSM: variables end ---\n");
}
void log_selects(const string& l_arg, AmSession* sess,
		 DSMSession* sc_sess, map<string,string>* event_params) {
  unsigned int lvl;
  if (str2i(resolveVars(l_arg, sess, sc_sess, event_params), lvl)) {
    ERROR("unknown log level '%s'\n", l_arg.c_str());
    return;
  }

  _LOG((int)lvl, "FSM: selects set ---\n");

#define SELECT_LOG(select_name)					\
  _LOG((int)lvl, "FSM:  @%s='%s'\n", select_name,			\
       resolveVars("@" select_name, sess, sc_sess, event_params).c_str());	

  SELECT_LOG("local_tag");
  SELECT_LOG("user");
  SELECT_LOG("domain");
  SELECT_LOG("remote_tag");
  SELECT_LOG("callid");
  SELECT_LOG("local_uri");
  SELECT_LOG("remote_uri");
#undef SELECT_LOG
  _LOG((int)lvl, "FSM: selects end ---\n");
}
Example #15
0
string resolveVars(const string ts, AmSession* sess,
		   DSMSession* sc_sess, map<string,string>* event_params,
		   bool eval_ops) {
  string s = ts;
  if (s.length()) {

    if(eval_ops) {
      // remove all spaces
      string::size_type p;
      for (p = s.find (" ", 0 ); 
  	p != string::npos; p = s.find(" ", p)) {
        s.erase (p, 1);
      }

      // evaluate operators
      string a,b;
      if((p = s.find("-")) != string::npos) {
        a = resolveVars(s.substr(0, p), sess, sc_sess, event_params, true);
        b = resolveVars(s.substr(p+1, string::npos), sess, sc_sess, event_params, true);
        if(isNumber(a) && isNumber(b)) {
          std::stringstream res; res << atoi(a.c_str()) - atoi(b.c_str());
          return res.str();
        }
      }
      else if((p = s.find("+")) != string::npos) {
        a = resolveVars(s.substr(0, p), sess, sc_sess, event_params, true);
        b = resolveVars(s.substr(p+1, string::npos), sess, sc_sess, event_params, true);
        if(isNumber(a) && isNumber(b)) {
          std::stringstream res; res << atoi(a.c_str()) + atoi(b.c_str());
          return res.str();
        }
      }
    }

    switch(s[0]) {
    case '$': {
      if (s.substr(1, 1)=="$")
	return "$";
      map<string, string>::iterator it = sc_sess->var.find(s.substr(1));
      if (it != sc_sess->var.end())
	return it->second;
      return "";
    }
    case '#': 
      if (s.substr(1, 1)=="#")
	return "#";
      if (event_params) {
	map<string, string>::iterator it = event_params->find(s.substr(1));
	if (it != event_params->end())
	  return it->second;
	return  "";
      }else 
	return string();
    case '@': {
      if (s.substr(1, 1)=="@")
	return "@";
      if (s.length() < 2)
	return "@";

      string s1 = s.substr(1); 
      if (s1 == "local_tag")
	return sess->getLocalTag();	
      else if (s1 == "user")
	return sess->dlg->getUser();
      else if (s1 == "domain")
	return sess->dlg->getDomain();
      else if (s1 == "remote_tag")
	return sess->getRemoteTag();
      else if (s1 == "callid")
	return sess->getCallID();
      else if (s1 == "local_uri")
	return sess->dlg->getLocalUri();
      else if (s1 == "local_party")
	return sess->dlg->getLocalParty();
      else if (s1 == "remote_uri")
	return sess->dlg->getRemoteUri();
      else if (s1 == "remote_party")
	return sess->dlg->getRemoteParty();
      else
	return string();
    } 
    default: return trim(s, "\"");
    }
  }
  return s;
}
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;
}