Пример #1
0
// outgoing call
AmSession* DSMFactory::onInvite(const AmSipRequest& req,
				AmArg& session_params) 
{

  string start_diag;

  if (req.cmd == MOD_NAME) {
    if (OutboundStartDiag.empty()) {
      ERROR("no outbound calls allowed\n");
    throw AmSession::Exception(488, "Not Acceptable Here");
    }
  } else {
    start_diag = req.cmd;
  }

  UACAuthCred* cred = NULL;
  map<string, string> vars;
  // Creds
  if (session_params.getType() == AmArg::AObject) {
    ArgObject* cred_obj = session_params.asObject();
    if (cred_obj)
      cred = dynamic_cast<UACAuthCred*>(cred_obj);
  } else if (session_params.getType() == AmArg::Array) {
    DBG("session params is array - size %d\n", session_params.size());
    // Creds
    if (session_params.get(0).getType() == AmArg::AObject) {
      ArgObject* cred_obj = session_params.get(0).asObject();
      if (cred_obj)
	cred = dynamic_cast<UACAuthCred*>(cred_obj);
    }
    // Creds + vars
    if (session_params.size()>1 && 
	session_params.get(1).getType() == AmArg::Struct) {
      AmArg2DSMStrMap(session_params.get(1), vars);
    }
  } else if (session_params.getType() == AmArg::Struct) {
    // vars
    AmArg2DSMStrMap(session_params, vars);
  }

  DSMScriptConfig call_config;
  ScriptConfigs_mut.lock();
  map<string, DSMScriptConfig>::iterator sc=ScriptConfigs.find(start_diag);
  if (sc == ScriptConfigs.end())
    call_config = MainScriptConfig;
  else 
    call_config = sc->second;

  DSMCall* s = new DSMCall(call_config, &prompts, *call_config.diags, start_diag, cred); 

  ScriptConfigs_mut.unlock();

  prepareSession(s);  

  addVariables(s, "config.", call_config.config_vars);
  if (!vars.empty())
    addVariables(s, "", vars);

  if (call_config.SetParamVariables) 
    addParams(s, req.hdrs); 

  if (NULL == cred) {
    WARN("discarding unknown session parameters.\n");
  } else {
    AmSessionEventHandlerFactory* uac_auth_f = 
      AmPlugIn::instance()->getFactory4Seh("uac_auth");
    if (uac_auth_f != NULL) {
      DBG("UAC Auth enabled for new DSM session.\n");
      AmSessionEventHandler* h = uac_auth_f->getHandler(s);
      if (h != NULL )
	s->addHandler(h);
    } else {
      ERROR("uac_auth interface not accessible. "
	    "Load uac_auth for authenticated dialout.\n");
    }		
  }

  return s;
}
Пример #2
0
// outgoing call
AmSession* DSMFactory::onInvite(const AmSipRequest& req, const string& app_name,
				AmArg& session_params) 
{

  string start_diag;

  if (app_name == MOD_NAME) {
    if (OutboundStartDiag.empty()) {
      ERROR("no outbound calls allowed\n");
      throw AmSession::Exception(488, "Not Acceptable Here");
    }
  } else {
    start_diag = app_name;
  }

  UACAuthCred* cred = NULL;
  map<string, string> vars;
  // Creds
  if (session_params.getType() == AmArg::AObject) {
    AmObject* cred_obj = session_params.asObject();
    if (cred_obj)
      cred = dynamic_cast<UACAuthCred*>(cred_obj);
  } else if (session_params.getType() == AmArg::Array) {
    DBG("session params is array - size %zd\n", session_params.size());
    // Creds
    cred = AmUACAuth::unpackCredentials(session_params.get(0));
    // Creds + vars
    if (session_params.size()>1 && 
	session_params.get(1).getType() == AmArg::Struct) {
      AmArg2DSMStrMap(session_params.get(1), vars);
    }
  } else if (session_params.getType() == AmArg::Struct) {
    // vars
    AmArg2DSMStrMap(session_params, vars);
  }

  DSMScriptConfig call_config;
  ScriptConfigs_mut.lock();
  map<string, DSMScriptConfig>::iterator sc=ScriptConfigs.find(start_diag);
  if (sc == ScriptConfigs.end())
    call_config = MainScriptConfig;
  else 
    call_config = sc->second;

  DSMCall* s = new DSMCall(call_config, &prompts, *call_config.diags, start_diag, cred); 

  ScriptConfigs_mut.unlock();

  prepareSession(s);  

  addVariables(s, "config.", call_config.config_vars);
  if (!vars.empty())
    addVariables(s, "", vars);

  if (call_config.SetParamVariables) 
    addParams(s, req.hdrs); 

  if (NULL == cred) {
    DBG("outgoing DSM call will not be authenticated.\n");
  } else {
    AmUACAuth::enable(s);
  }

  return s;
}
Пример #3
0
AmSession* DSMFactory::onInvite(const AmSipRequest& req)
{
  string start_diag;
  map<string, string> vars;

  if (req.cmd == MOD_NAME) {
    if (InboundStartDiag.empty()) {
      ERROR("no inbound calls allowed\n");
      throw AmSession::Exception(488, "Not Acceptable Here");
    }
    if (InboundStartDiag=="$(mon_select)") {
#ifdef USE_MONITORING

      if (NULL == MONITORING_GLOBAL_INTERFACE) {
	ERROR("using $(mon_select) but monitoring not loaded\n");
	throw AmSession::Exception(488, "Not Acceptable Here");
      }

      AmArg di_args, ret;
      if (MonSelectCaller != MonSelect_NONE) {
	AmUriParser from_parser;
	if (MonSelectCaller == MonSelect_FROM)
	  from_parser.uri = req.from_uri;
	else {
	  size_t end;
	  string pai = getHeader(req.hdrs, SIP_HDR_P_ASSERTED_IDENTITY);
	  if (!from_parser.parse_contact(pai, 0, end)) {
	    ERROR("Failed to parse "SIP_HDR_P_ASSERTED_IDENTITY " '%s'\n",
		  pai.c_str());
	    throw AmSession::Exception(488, "Not Acceptable Here");
	  }
	}

	if (!from_parser.parse_uri()) {
	  DBG("failed to parse caller uri '%s'\n", from_parser.uri.c_str());
	  throw AmSession::Exception(488, "Not Acceptable Here");
	}
	
	AmArg caller_filter;
	caller_filter.push("caller");
	caller_filter.push(from_parser.uri_user);
	DBG(" && looking for caller=='%s'\n", from_parser.uri_user.c_str());
	di_args.push(caller_filter);
      }


      if (MonSelectCallee != MonSelect_NONE) {
	AmArg callee_filter;
	callee_filter.push("callee");
	if (MonSelectCallee == MonSelect_RURI)
	  callee_filter.push(req.user);
	else {
	  AmUriParser to_parser;
	  size_t end;
	  if (!to_parser.parse_contact(req.to, 0, end)) {
	    ERROR("Failed to parse To '%s'\n", req.to.c_str());
	    throw AmSession::Exception(488, "Not Acceptable Here");
	  }
	  if (!to_parser.parse_uri()) {
	    DBG("failed to parse callee uri '%s'\n", to_parser.uri.c_str());
	    throw AmSession::Exception(488, "Not Acceptable Here");
	  }
	  callee_filter.push(to_parser.uri_user);
	}
	  
	DBG(" && looking for callee=='%s'\n", req.user.c_str());
	di_args.push(callee_filter);	
      }
      MONITORING_GLOBAL_INTERFACE->invoke("listByFilter",di_args,ret);
      
      if ((ret.getType()!=AmArg::Array)||
	  !ret.size()) {
	INFO("call info not found. caller uri %s, r-uri %s\n", 
	     req.from_uri.c_str(), req.r_uri.c_str());
	throw AmSession::Exception(488, "Not Acceptable Here");
      }

      AmArg sess_id, sess_params;
      if (ret.size()>1) {
	DBG("multiple call info found - picking the first one\n");
      }
      const char* session_id = ret.get(0).asCStr();
      sess_id.push(session_id);
      MONITORING_GLOBAL_INTERFACE->invoke("get",sess_id,sess_params);
      
      if ((sess_params.getType()!=AmArg::Array)||
	  !sess_params.size() ||
	  sess_params.get(0).getType() != AmArg::Struct) {
	INFO("call parameters not found. caller uri %s, r-uri %s, id %s\n", 
	     req.from_uri.c_str(), req.r_uri.c_str(), ret.get(0).asCStr());
	throw AmSession::Exception(488, "Not Acceptable Here");
      }

      AmArg& sess_dict = sess_params.get(0);
      if (sess_dict.hasMember("app")) {
	start_diag = sess_dict["app"].asCStr();
	DBG("selected application '%s' for session\n", start_diag.c_str());
      } else {
	ERROR("selected session params don't contain 'app'\n");
	throw AmSession::Exception(488, "Not Acceptable Here");
      }
      AmArg2DSMStrMap(sess_dict["appParams"], vars);
      vars["mon_session_record"] = session_id;
	
#else
      ERROR("using $(mon_select) for dsm application, "
	    "but compiled without monitoring support!\n");
      throw AmSession::Exception(488, "Not Acceptable Here");
#endif
    } else {
      start_diag = InboundStartDiag;
    }
  } else {
    start_diag = req.cmd;
  }

  // determine run configuration for script
  DSMScriptConfig call_config;
  ScriptConfigs_mut.lock();
  map<string, DSMScriptConfig>::iterator sc=ScriptConfigs.find(start_diag);
  if (sc == ScriptConfigs.end()) 
    call_config = MainScriptConfig;
  else 
    call_config = sc->second;

  DSMCall* s = new DSMCall(call_config, &prompts, *call_config.diags, start_diag, NULL);

  ScriptConfigs_mut.unlock();

  prepareSession(s);
  addVariables(s, "config.", call_config.config_vars);

  if (call_config.SetParamVariables) 
    addParams(s, req.hdrs);

  if (!vars.empty())
    addVariables(s, "", vars);

  return s;
}
Пример #4
0
void DSMFactory::runMonitorAppSelect(const AmSipRequest& req, string& start_diag, 
				     map<string, string>& vars) {
#define FALLBACK_OR_EXCEPTION(code, reason)				\
  if (MonSelectFallback.empty()) {					\
    throw AmSession::Exception(code, reason);				\
  } else {								\
    DBG("falling back to '%s'\n", MonSelectFallback.c_str());		\
    start_diag = MonSelectFallback;					\
    return;								\
  }

#ifdef USE_MONITORING
      if (NULL == MONITORING_GLOBAL_INTERFACE) {
	ERROR("using $(mon_select) but monitoring not loaded\n");
	FALLBACK_OR_EXCEPTION(500, "Internal Server Error");
      }

      AmArg di_args, ret;
      if (MonSelectCaller != MonSelect_NONE) {
	AmUriParser from_parser;
	if (MonSelectCaller == MonSelect_FROM)
	  from_parser.uri = req.from_uri;
	else {
	  size_t end;
	  string pai = getHeader(req.hdrs, SIP_HDR_P_ASSERTED_IDENTITY, true);
	  if (!from_parser.parse_contact(pai, 0, end)) {
	    WARN("Failed to parse " SIP_HDR_P_ASSERTED_IDENTITY " '%s'\n",
		  pai.c_str());
	    FALLBACK_OR_EXCEPTION(500, "Internal Server Error");
	  }
	}

	if (!from_parser.parse_uri()) {
	  DBG("failed to parse caller uri '%s'\n", from_parser.uri.c_str());
	  FALLBACK_OR_EXCEPTION(500, "Internal Server Error");
	}
	
	AmArg caller_filter;
	caller_filter.push("caller");
	caller_filter.push(from_parser.uri_user);
	DBG(" && looking for caller=='%s'\n", from_parser.uri_user.c_str());
	di_args.push(caller_filter);
      }


      if (MonSelectCallee != MonSelect_NONE) {
	AmArg callee_filter;
	callee_filter.push("callee");
	if (MonSelectCallee == MonSelect_RURI)
	  callee_filter.push(req.user);
	else {
	  AmUriParser to_parser;
	  size_t end;
	  if (!to_parser.parse_contact(req.to, 0, end)) {
	    ERROR("Failed to parse To '%s'\n", req.to.c_str());
	    FALLBACK_OR_EXCEPTION(500, "Internal Server Error");
	  }
	  if (!to_parser.parse_uri()) {
	    DBG("failed to parse callee uri '%s'\n", to_parser.uri.c_str());
	    FALLBACK_OR_EXCEPTION(500, "Internal Server Error");
	  }
	  callee_filter.push(to_parser.uri_user);
	}
	  
	DBG(" && looking for callee=='%s'\n", req.user.c_str());
	di_args.push(callee_filter);
      }
      // apply additional filters
      if (MonSelectFilters.size()) {
	string app_params = getHeader(req.hdrs, PARAM_HDR);
	for (vector<string>::iterator it = 
	       MonSelectFilters.begin(); it != MonSelectFilters.end(); it++) {
	  AmArg filter;
	  filter.push(*it); // avp name
	  string app_param_val = get_header_keyvalue(app_params, *it);
	  filter.push(app_param_val);
	  di_args.push(filter);
	  DBG(" && looking for %s=='%s'\n", it->c_str(), app_param_val.c_str());
	}
      }

      MONITORING_GLOBAL_INTERFACE->invoke("listByFilter",di_args,ret);
      
      if ((ret.getType()!=AmArg::Array)||
	  !ret.size()) {
	DBG("call info not found. caller uri %s, r-uri %s\n", 
	     req.from_uri.c_str(), req.r_uri.c_str());
	FALLBACK_OR_EXCEPTION(500, "Internal Server Error");
      }

      AmArg sess_id, sess_params;
      if (ret.size()>1) {
	DBG("multiple call info found - picking the first one\n");
      }
      const char* session_id = ret.get(0).asCStr();
      sess_id.push(session_id);
      MONITORING_GLOBAL_INTERFACE->invoke("get",sess_id,sess_params);
      
      if ((sess_params.getType()!=AmArg::Array)||
	  !sess_params.size() ||
	  sess_params.get(0).getType() != AmArg::Struct) {
	INFO("call parameters not found. caller uri %s, r-uri %s, id %s\n", 
	     req.from_uri.c_str(), req.r_uri.c_str(), ret.get(0).asCStr());
	FALLBACK_OR_EXCEPTION(500, "Internal Server Error");
      }

      AmArg& sess_dict = sess_params.get(0);
      if (sess_dict.hasMember("app")) {
	start_diag = sess_dict["app"].asCStr();
	DBG("selected application '%s' for session\n", start_diag.c_str());
      } else {
	ERROR("selected session params don't contain 'app'\n");
	FALLBACK_OR_EXCEPTION(500, "Internal Server Error");
      }
      AmArg2DSMStrMap(sess_dict["appParams"], vars);
      vars["mon_session_record"] = session_id;
	
#else
      ERROR("using $(mon_select) for dsm application, "
	    "but compiled without monitoring support!\n");
      throw AmSession::Exception(500, "Internal Server Error");
#endif

#undef FALLBACK_OR_EXCEPTION
}