示例#1
0
/** get the value of key @param short_name or @param name or from the list param_hdr*/
string get_header_keyvalue(const string& param_hdr, const string& short_name, const string& name) {
    string res = get_header_keyvalue(param_hdr, short_name);
    if (res.length())
        return res;

    return get_header_keyvalue(param_hdr, name);
}
示例#2
0
AmSession* CallTimerFactory::onInvite(const AmSipRequest& req)
{
  DBG(" *** creating new call timer session ***\n");
  AmDynInvoke* user_timer = user_timer_fact->getInstance();
  if(!user_timer) {
    ERROR("could not get a user timer reference\n");
     throw AmSession::Exception(500,"could not get a user timer reference");
  }

  string app_param = getHeader(req.hdrs, PARAM_HDR);

  unsigned int call_time = CallTimerFactory::DefaultCallTimer;

  if (CallTimerFactory::UseAppParam) {
    if (!app_param.length()) {
      INFO("call_time: no call timer parameters found. "
	   "Using default value of %d seconds\n", 
	   CallTimerFactory::DefaultCallTimer);
    } else {
      string call_time_s = get_header_keyvalue(app_param,"t", "Timer");
      
      if (str2i(call_time_s, call_time)) {
	WARN("Error decoding call time value '%s'. Using default time of %d\n",
	     call_time_s.c_str(), call_time);
      } 
    }
  }

  DBG("using call timer %d seconds\n", call_time);

  return new CallTimerDialog(user_timer, call_time);
}
示例#3
0
/** get the value of key @param name from \ref PARAM_HDR header in hdrs */
string get_session_param(const string& hdrs, const string& name) {
    string iptel_app_param = getHeader(hdrs, PARAM_HDR);
    if (!iptel_app_param.length()) {
        //      DBG("call parameters header PARAM_HDR not found "
        // 	 "(need to configure ser's tw_append?).\n");
        return "";
    }

    return get_header_keyvalue(iptel_app_param, name);
}
void EarlyAnnounceDialog::process(AmEvent* event)
{

  AmAudioEvent* audio_event = dynamic_cast<AmAudioEvent*>(event);
  if(audio_event && 
     (audio_event->event_id == AmAudioEvent::cleared))
    {
      DBG("AmAudioEvent::cleared\n");
      unsigned int code_i = 404;
      string reason = "Not Found";

      string iptel_app_param = getHeader(localreq.hdrs, PARAM_HDR);
      if (iptel_app_param.length()) {
	string code = get_header_keyvalue(iptel_app_param,"Final-Reply-Code");
	if (code.length() && str2i(code, code_i)) {
	  ERROR("while parsing Final-Reply-Code parameter\n");
	}
	reason = get_header_keyvalue(iptel_app_param,"Final-Reply-Reason");
      } else {
	string code = getHeader(localreq.hdrs,"P-Final-Reply-Code");
	if (code.length() && str2i(code, code_i)) {
	  ERROR("while parsing P-Final-Reply-Code\n");
	}
	string h_reason =  getHeader(localreq.hdrs,"P-Final-Reply-Reason");
	if (h_reason.length()) {
	  INFO("Use of P-Final-Reply-Code/P-Final-Reply-Reason is deprecated. ");
	  INFO("Use '%s: Final-Reply-Code=<code>;"
	       "Final-Reply-Reason=<rs>' instead.\n",PARAM_HDR);
	  reason = h_reason;
	}
      }

      DBG("Replying with code %d %s\n", code_i, reason.c_str());
      dlg.reply(localreq, code_i, reason);
	
      setStopped();
	
      return;
    }

  AmSession::process(event);
}
示例#5
0
void ConferenceDialog::onSipRequest(const AmSipRequest& req)
{
  AmSession::onSipRequest(req);
  if((dlg.getStatus() >= AmSipDialog::Connected) ||
     (req.method != "REFER"))
    return;

  std::swap(dlg.local_party,dlg.remote_party);
  dlg.remote_tag = "";

  // get route set and next hop
  string iptel_app_param = getHeader(req.hdrs, PARAM_HDR);
  if (iptel_app_param.length()) {
    dlg.setRoute(get_header_keyvalue(iptel_app_param,"Transfer-RR"));
    dlg.next_hop = get_header_keyvalue(iptel_app_param,"Transfer-NH");
  } else {
    INFO("Use of P-Transfer-RR/P-Transfer-NH is deprecated. "
	 "Use '%s: Transfer-RR=<rr>;Transfer-NH=<nh>' instead.\n",PARAM_HDR);

    dlg.setRoute(getHeader(req.hdrs,"P-Transfer-RR"));
    dlg.next_hop = getHeader(req.hdrs,"P-Transfer-NH");
  }

  DBG("ConferenceDialog::onSipRequest: local_party = %s\n",dlg.local_party.c_str());
  DBG("ConferenceDialog::onSipRequest: local_tag = %s\n",dlg.local_tag.c_str());
  DBG("ConferenceDialog::onSipRequest: remote_party = %s\n",dlg.remote_party.c_str());
  DBG("ConferenceDialog::onSipRequest: remote_tag = %s\n",dlg.remote_tag.c_str());

  string body;
  int local_port = rtp_str.getLocalPort();
  sdp.genRequest(AmConfig::LocalIP,local_port,body);
  dlg.sendRequest("INVITE","application/sdp",body,"");

  transfer_req.reset(new AmSipRequest(req));

  return;
}
AmSession* EarlyAnnounceFactory::onInvite(const AmSipRequest& req)
{

#ifdef USE_MYSQL

    string iptel_app_param = getHeader(req.hdrs, PARAM_HDR);
    string language = get_header_keyvalue(iptel_app_param,"Language");
    string announce_file = "";

    if (language.empty()) language = DefaultLanguage;

    get_announce_msg(AnnounceApplication, AnnounceMessage, req.user,
		     req.domain, "", &announce_file);
    if (!announce_file.empty()) goto end;
    get_announce_msg(AnnounceApplication, AnnounceMessage, "", req.domain,
		     language, &announce_file);
    if (!announce_file.empty()) goto end;
    get_announce_msg(AnnounceApplication, AnnounceMessage, "", "", language,
		     &announce_file);

#else

  string announce_path = AnnouncePath;
  string announce_file = announce_path + req.domain 
    + "/" + req.user + ".wav";

  DBG("trying '%s'\n",announce_file.c_str());
  if(file_exists(announce_file))
    goto end;

  announce_file = announce_path + req.user + ".wav";
  DBG("trying '%s'\n",announce_file.c_str());
  if(file_exists(announce_file))
    goto end;

  announce_file = AnnouncePath + AnnounceFile;

#endif

 end:
  return new EarlyAnnounceDialog(announce_file);
}
示例#7
0
void ConferenceDialog::onSessionStart(const AmSipRequest& req)
{
  int i, len;
  string lonely_user_file;

  string app_param_hdr = getHeader(req.hdrs, PARAM_HDR);
  if (app_param_hdr.length()) {
    from_header = get_header_keyvalue(app_param_hdr, "Dialout-From");
    extra_headers = get_header_keyvalue(app_param_hdr, "Dialout-Extra");
    dialout_suffix = get_header_keyvalue(app_param_hdr, "Dialout-Suffix");      
    language = get_header_keyvalue(app_param_hdr, "Language");      
  } else {
    from_header = getHeader(req.hdrs, "P-Dialout-From");
    extra_headers = getHeader(req.hdrs, "P-Dialout-Extra");
    dialout_suffix = getHeader(req.hdrs, "P-Dialout-Suffix");
    if (from_header.length() || extra_headers.length() 
	|| dialout_suffix.length()) {
      DBG("Warning: P-Dialout- style headers are deprecated."
	  " Please use P-App-Param header instead.\n");
    }
    language = getHeader(req.hdrs, "P-Language");
    if (language.length()) {
      DBG("Warning: P-Language header is deprecated."
	  " Please use P-App-Param header instead.\n");
    }
  }

  len = extra_headers.length();
  for (i = 0; i < len; i++) {
    if (extra_headers[i] == '|') extra_headers[i] = '\n';
  }
  if (extra_headers[len - 1] != '\n') {
      extra_headers += '\n';
  }

  if (dialout_suffix.length() == 0) {
    if (!ConferenceFactory::DialoutSuffix.empty()) {
      dialout_suffix = ConferenceFactory::DialoutSuffix;
    } else {
      dialout_suffix = "";
    }
  }
    
  allow_dialout = dialout_suffix.length() > 0;

  if (!language.empty()) {

#ifdef USE_MYSQL
    /* Get domain/language specific lonely user file from MySQL */
    if (get_audio_file(LONELY_USER_MSG, req.domain, language,
		       lonely_user_file) &&
	!lonely_user_file.empty()) {
      ConferenceFactory::LonelyUserFile = lonely_user_file;
    } else {
      if (get_audio_file(LONELY_USER_MSG, "", language,
			 lonely_user_file) &&
	  !lonely_user_file.empty()) {
	ConferenceFactory::LonelyUserFile = lonely_user_file;
      }
    }
#else
    /* Get domain/language specific lonely user file from file system */
    lonely_user_file = ConferenceFactory::AudioPath + "/lonely_user_msg/" +
      req.domain + "/" + "default_" + language + ".wav";
    if(file_exists(lonely_user_file)) {
      ConferenceFactory::LonelyUserFile = lonely_user_file;
    } else {
      lonely_user_file = ConferenceFactory::AudioPath +
	"/lonely_user_msg/default_" + language + ".wav";
      if(file_exists(lonely_user_file)) {
	ConferenceFactory::LonelyUserFile = lonely_user_file;
      }
    }
#endif
  }

  DBG("Using LonelyUserFile <%s>\n",
      ConferenceFactory::LonelyUserFile.c_str());
	
  setupAudio();
}
void EarlyAnnounceDialog::process(AmEvent* event)
{

  AmAudioEvent* audio_event = dynamic_cast<AmAudioEvent*>(event);
  if(audio_event && 
     (audio_event->event_id == AmAudioEvent::cleared)) {
      DBG("AmAudioEvent::cleared\n");

      bool continue_b2b = false;
      if (EarlyAnnounceFactory::ContinueB2B == 
	  EarlyAnnounceFactory::Always) {
	continue_b2b = true;
      } else if (EarlyAnnounceFactory::ContinueB2B == 
		 EarlyAnnounceFactory::AppParam) {
	string iptel_app_param = getHeader(invite_req.hdrs, PARAM_HDR);
	if (iptel_app_param.length()) {
	  continue_b2b = get_header_keyvalue(iptel_app_param,"B2B")=="yes";
	} else {
	  continue_b2b = getHeader(invite_req.hdrs,"P-B2B")=="yes";
	}
      }
      DBG("determined: continue_b2b = %s\n", continue_b2b?"true":"false");

      if (!continue_b2b) {
	unsigned int code_i = 404;
	string reason = "Not Found";
	
	string iptel_app_param = getHeader(invite_req.hdrs, PARAM_HDR);
	if (iptel_app_param.length()) {
	  string code = get_header_keyvalue(iptel_app_param,"Final-Reply-Code");
	  if (code.length() && str2i(code, code_i)) {
	    ERROR("while parsing Final-Reply-Code parameter\n");
	  }
	  reason = get_header_keyvalue(iptel_app_param,"Final-Reply-Reason");
	  if (!reason.length())
	    reason = "Not Found";
	} else {
	  string code = getHeader(invite_req.hdrs,"P-Final-Reply-Code");
	  if (code.length() && str2i(code, code_i)) {
	    ERROR("while parsing P-Final-Reply-Code\n");
	  }
	  string h_reason =  getHeader(invite_req.hdrs,"P-Final-Reply-Reason");
	  if (h_reason.length()) {
	    INFO("Use of P-Final-Reply-Code/P-Final-Reply-Reason is deprecated. ");
	    INFO("Use '%s: Final-Reply-Code=<code>;"
		 "Final-Reply-Reason=<rs>' instead.\n",PARAM_HDR);
	    reason = h_reason;
	  }
	}

	DBG("Replying with code %d %s\n", code_i, reason.c_str());
	dlg.reply(invite_req, code_i, reason);
	
	setStopped();
      } else {
	set_sip_relay_only(true);
	recvd_req.insert(std::make_pair(invite_req.cseq,invite_req));
	
	relayEvent(new B2BSipRequestEvent(invite_req,true));
      }
	
      return;
    }

  AmB2BCallerSession::process(event);
}
AmSession* AnswerMachineFactory::onInvite(const AmSipRequest& req)
{
  string language;
  string email;
  string domain;
  string user;
  string sender;
  string typ;

  int vm_mode = MODE_VOICEMAIL; 

  string iptel_app_param = getHeader(req.hdrs, PARAM_HDR);

  if (!iptel_app_param.length()) {
    throw AmSession::Exception(500, "voicemail: parameters not found");
  }

  language = get_header_keyvalue(iptel_app_param, "lng", "Language");
  email = get_header_keyvalue(iptel_app_param, "eml", "Email-Address");

  string mode = get_header_keyvalue(iptel_app_param,"mod", "Mode");
  if (!mode.empty()) {
    if (mode == "box")
      vm_mode = MODE_BOX;
    else if (mode == "both")
      vm_mode = MODE_BOTH;
    else if (mode == "ann")
      vm_mode = MODE_ANN;
  }

  if (((vm_mode == MODE_BOTH) || (vm_mode == MODE_VOICEMAIL)) &&
      (email.find('@') == string::npos)) {
    ERROR("no @ found in email address '%s' from params '%s'\n",
	  email.c_str(), iptel_app_param.c_str());
    throw AmSession::Exception(500, "voicemail: no email address");
  }

  user = get_header_keyvalue(iptel_app_param,"usr", "User");
  if (!user.length())
    user = req.user;
  
  sender = get_header_keyvalue(iptel_app_param, "snd", "Sender");
  if (!sender.length()) 
    sender = req.from;  
  
  domain = get_header_keyvalue(iptel_app_param, "dom", "Domain");
  if (!domain.length())
    domain = req.domain;

  typ = get_header_keyvalue(iptel_app_param, "typ", "Type");
  if (!typ.length())
    typ = DEFAULT_TYPE;

  // checks
  if (user.empty()) 
    throw AmSession::Exception(500, "voicemail: user missing");

  if (sender.empty()) 
    throw AmSession::Exception(500, "voicemail: sender missing");

  if (((vm_mode == MODE_BOX) || (vm_mode == MODE_BOTH))
      && (NULL == MessageStorage)) {
    throw AmSession::Exception(500, "voicemail: no message storage available");
  }
    

  DBG("voicemail invocation parameters: \n");
  DBG(" Mode:     <%s> \n", mode.c_str());
  DBG(" Email:    <%s> \n", email.c_str());
  DBG(" User:     <%s> \n", user.c_str());
  DBG(" Sender:   <%s> \n", sender.c_str());
  DBG(" Domain:   <%s> \n", domain.c_str());
  DBG(" Language: <%s> \n", language.c_str());
  DBG(" Type:     <%s> \n", typ.c_str());

  FILE* greeting_fp = NULL;
  if (TryPersonalGreeting)
    greeting_fp = getMsgStoreGreeting(typ, user, domain);

#ifdef USE_MYSQL

  string announce_file;

  if (get_audio_file(GREETING_MSG, domain, req.user, "",
                    &announce_file) && !announce_file.empty())
    goto announce_found;

  if (!language.empty()) {
    if (get_audio_file(GREETING_MSG, domain, "", language,
                      &announce_file) && !announce_file.empty())
      goto announce_found;
  } else {
    if (get_audio_file(GREETING_MSG, domain, "", "",
                      &announce_file) && !announce_file.empty())
      goto announce_found;
  }

  if (!language.empty())
    if (get_audio_file(GREETING_MSG, "", "", language,
                      &announce_file) && !announce_file.empty())
      goto announce_found;

  get_audio_file(GREETING_MSG, "", "", "", &announce_file);

#else

  string announce_file = add2path(AnnouncePath,2, 
				  domain.c_str(), (user + ".wav").c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,3, 
			     domain.c_str(), language.c_str(), DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }

  announce_file = add2path(AnnouncePath,2, 
			   domain.c_str(), DefaultAnnounce.c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,2, 
			     language.c_str(),  DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }
	
  announce_file = add2path(AnnouncePath,1, DefaultAnnounce.c_str());
  if (!file_exists(announce_file)) 
    announce_file = "";

#endif

 announce_found:
  if(announce_file.empty())
    throw AmSession::Exception(500,"voicemail: no greeting file found");

  // VBOX mode does not need email template
  if ((vm_mode == MODE_BOX) || (vm_mode == MODE_ANN))
    return new AnswerMachineDialog(user, sender, domain,
				   email, announce_file, greeting_fp,
				   vm_mode, NULL);
				    
  if(email.empty())
    throw AmSession::Exception(404,"missing email address");

  map<string,EmailTemplate>::iterator tmpl_it;
  if (!language.empty()) {
    tmpl_it = email_tmpl.find(domain + "_" + language);
    if(tmpl_it == email_tmpl.end()) {
      tmpl_it = email_tmpl.find(domain);
      if(tmpl_it == email_tmpl.end()) {
	tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL + "_"
				  + language);
	if(tmpl_it == email_tmpl.end())
	  tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
      }
    }
  } else {
    tmpl_it = email_tmpl.find(domain);
    if(tmpl_it == email_tmpl.end())
      tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
  }
    
  if(tmpl_it == email_tmpl.end()){
    ERROR("Voicemail: unable to find an email template.\n");
    return 0;
  }
  return new AnswerMachineDialog(user, sender, domain,
				 email, announce_file, greeting_fp,
				 vm_mode, &tmpl_it->second);
}
示例#10
0
AmSession* AnswerMachineFactory::onInvite(const AmSipRequest& req, const string& app_name,
					  const map<string,string>& app_params)
{
  string language;
  string email;
  string domain;
  string user;
  string sender;
  string typ;
  string uid; // user ID
  string did; // domain ID
  string mode;
  string iptel_app_param;

  EmailTmplDict template_variables;

  int vm_mode = DefaultVMMode; 

  if(SimpleMode) {
    email = EmailAddress;
    uid = user = req.user;
    //did = domain = req.domain;
    did = domain = "default";
    sender = req.from;
    typ = DEFAULT_TYPE;
  }
  else {
  
    iptel_app_param = getHeader(req.hdrs, PARAM_HDR, true);
    mode = get_header_keyvalue(iptel_app_param,"mod", "Mode");
    
    if (!EmailAddress.length()) {
      
      if (!iptel_app_param.length()) {
	throw AmSession::Exception(500, "voicemail: parameters not found");
      }
      
      language = get_header_keyvalue(iptel_app_param, "lng", "Language");
      email = get_header_keyvalue(iptel_app_param, "eml", "Email-Address");
      
      if (!mode.empty()) {
	if (mode == "box")
	  vm_mode = MODE_BOX;
	else if (mode == "both")
	  vm_mode = MODE_BOTH;
	else if (mode == "ann")
	  vm_mode = MODE_ANN;
      }
    } else {
      // overrides email address
      //vm_mode = MODE_VOICEMAIL;
      email = EmailAddress;
    }
    
    if (((vm_mode == MODE_BOTH) || (vm_mode == MODE_VOICEMAIL)) &&
	(email.find('@') == string::npos)) {
      ERROR("no @ found in email address '%s' from params '%s'\n",
	    email.c_str(), iptel_app_param.c_str());
      throw AmSession::Exception(500, "voicemail: no email address");
    }
    
    user = get_header_keyvalue(iptel_app_param,"usr", "User");
    if (!user.length())
      user = req.user;
    
    sender = get_header_keyvalue(iptel_app_param, "snd", "Sender");
    if (!sender.length()) 
      sender = req.from;  
    
    domain = get_header_keyvalue(iptel_app_param, "dom", "Domain");
    if (!domain.length())
      domain = req.domain;
    
    typ = get_header_keyvalue(iptel_app_param, "typ", "Type");
    if (!typ.length())
      typ = DEFAULT_TYPE;
    
    uid = get_header_keyvalue(iptel_app_param, "uid", "UserID");
    if (uid.empty())
      uid=user;
    
    did = get_header_keyvalue(iptel_app_param, "did", "DomainID");
    if (did.empty())
      did=domain;
  }
    
  // checks
  if (uid.empty()) 
    throw AmSession::Exception(500, "voicemail: user missing");
  
  if (sender.empty()) 
    throw AmSession::Exception(500, "voicemail: sender missing");
  
  if (((vm_mode == MODE_BOX) || (vm_mode == MODE_BOTH))
      && (NULL == MessageStorage)) {
    throw AmSession::Exception(500, "voicemail: no message storage available");
  }
  
  
  DBG("voicemail invocation parameters: \n");
  DBG(" Mode:     <%s> \n", mode.c_str());
  DBG(" Email:    <%s> \n", email.c_str());
  DBG(" User:     <%s> \n", user.c_str());
  DBG(" Sender:   <%s> \n", sender.c_str());
  DBG(" Domain:   <%s> \n", domain.c_str());
  DBG(" Language: <%s> \n", language.c_str());
  DBG(" Type:     <%s> \n", typ.c_str());
  DBG(" UID:      <%s> \n", uid.c_str());
  DBG(" DID:      <%s> \n", did.c_str());
  
  FILE* greeting_fp = NULL;
  if (TryPersonalGreeting)
    greeting_fp = getMsgStoreGreeting(typ, uid, did);

#ifdef USE_MYSQL

  string announce_file;

  if (get_audio_file(GREETING_MSG, domain, req.user, "",
                    announce_file) && !announce_file.empty())
    goto announce_found;

  if (!language.empty()) {
    if (get_audio_file(GREETING_MSG, domain, "", language,
                      announce_file) && !announce_file.empty())
      goto announce_found;
  } else {
    if (get_audio_file(GREETING_MSG, domain, "", "",
                      announce_file) && !announce_file.empty())
      goto announce_found;
  }

  if (!language.empty())
    if (get_audio_file(GREETING_MSG, "", "", language,
                      announce_file) && !announce_file.empty())
      goto announce_found;

  get_audio_file(GREETING_MSG, "", "", "", announce_file);

#else

  string announce_file = add2path(AnnouncePath,2, 
				  did.c_str(), (uid + ".wav").c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,3, 
			     did.c_str(), language.c_str(), DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }

  announce_file = add2path(AnnouncePath,2, 
			   did.c_str(), DefaultAnnounce.c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,2, 
			     language.c_str(),  DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }
	
  announce_file = add2path(AnnouncePath,1, DefaultAnnounce.c_str());
  if (!file_exists(announce_file)) 
    announce_file = "";

#endif

 announce_found:
  if(announce_file.empty())
    throw AmSession::Exception(500,"voicemail: no greeting file found");

  if(!SimpleMode) {

    // a little inefficient this way - but get_header_keyvalue supports escaping
    for (vector<string>::iterator it=
	   MailHeaderVariables.begin(); it != MailHeaderVariables.end(); it++) {
      template_variables[*it] = get_header_keyvalue(iptel_app_param, *it);
    }
  }

  // VBOX mode does not need email template
  if ((vm_mode == MODE_BOX) || (vm_mode == MODE_ANN))
    return new AnswerMachineDialog(user, sender, domain,
				   email, announce_file, uid, did, 
				   greeting_fp, vm_mode, 
				   template_variables, NULL);

  if(email.empty())
    throw AmSession::Exception(404,"missing email address");

  map<string,EmailTemplate>::iterator tmpl_it;
  if (!language.empty()) {
    tmpl_it = email_tmpl.find(did + "_" + language);
    if(tmpl_it == email_tmpl.end()) {
      tmpl_it = email_tmpl.find(did);
      if(tmpl_it == email_tmpl.end()) {
	tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL + "_"
				  + language);
	if(tmpl_it == email_tmpl.end())
	  tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
      }
    }
  } else {
    tmpl_it = email_tmpl.find(did);
    if(tmpl_it == email_tmpl.end())
      tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
  }
    
  if(tmpl_it == email_tmpl.end()){
    ERROR("Voicemail: unable to find an email template.\n");
    return 0;
  }
  return new AnswerMachineDialog(user, sender, domain,
				 email, announce_file, 
				 uid, did,
				 greeting_fp,
				 vm_mode, template_variables,
				 &tmpl_it->second);
}
示例#11
0
AmSession* AnswerMachineFactory::onInvite(const AmSipRequest& req)
{
  string language;
  string email;

  string iptel_app_param = getHeader(req.hdrs, PARAM_HDR);

  if (!EmailAddress.length()) {
    if (iptel_app_param.length()) {
      language = get_header_keyvalue(iptel_app_param,"Language");
      email = get_header_keyvalue(iptel_app_param,"Email-Address");
    } else {      
      email = getHeader(req.hdrs,"P-Email-Address");
      language = getHeader(req.hdrs,"P-Language"); // local user's language
      
      if (email.length()) {
	INFO("Use of P-Email-Address/P-Language is deprecated. \n");
	INFO("Use '%s: Email-Address=<addr>;"
	     "Language=<lang>' instead.\n",PARAM_HDR);
      }
    }
  } else {
    email = EmailAddress;
  }

  DBG("email address for user '%s': <%s> \n",
      req.user.c_str(),email.c_str());
  DBG("language: <%s> \n", language.c_str());

#ifdef USE_MYSQL

  string announce_file;

  if (get_audio_file(GREETING_MSG, req.domain, req.user, "",
		     &announce_file) && !announce_file.empty())
    goto announce_found;

  if (!language.empty()) {
    if (get_audio_file(GREETING_MSG, req.domain, "", language,
		       &announce_file) && !announce_file.empty())
      goto announce_found;
  } else {
    if (get_audio_file(GREETING_MSG, req.domain, "", "",
		       &announce_file) && !announce_file.empty())
      goto announce_found;
  }
    
  if (!language.empty())
    if (get_audio_file(GREETING_MSG, "", "", language,
		       &announce_file) && !announce_file.empty())
      goto announce_found;
    
  get_audio_file(GREETING_MSG, "", "", "", &announce_file);
    
#else

  string announce_file = add2path(AnnouncePath,2, req.domain.c_str(), (req.user + ".wav").c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,3, req.domain.c_str(), language.c_str(), DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }

  announce_file = add2path(AnnouncePath,2, req.domain.c_str(), DefaultAnnounce.c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,2, language.c_str(),  DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }
	
  announce_file = add2path(AnnouncePath,1, DefaultAnnounce.c_str());
  if (!file_exists(announce_file)) 
    announce_file = "";

#endif

 announce_found:
  if(announce_file.empty())
    throw AmSession::Exception(500,"voicemail: no greeting file found");

  if(email.empty())
    throw AmSession::Exception(404,"missing email address");

  map<string,EmailTemplate>::iterator tmpl_it;
  if (!language.empty()) {
    tmpl_it = email_tmpl.find(req.domain + "_" + language);
    if(tmpl_it == email_tmpl.end()) {
      tmpl_it = email_tmpl.find(req.domain);
      if(tmpl_it == email_tmpl.end()) {
	tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL + "_"
				  + language);
	if(tmpl_it == email_tmpl.end())
	  tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
      }
    }
  } else {
    tmpl_it = email_tmpl.find(req.domain);
    if(tmpl_it == email_tmpl.end())
      tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
  }
	    
  if(tmpl_it == email_tmpl.end()){
    ERROR("Voicemail: unable to find an email template.\n");
    return 0;
  }

  return new AnswerMachineDialog(email,announce_file,
				 &tmpl_it->second);
}
string replaceParameters(const string& s,
			 const char* r_type,
			 const AmSipRequest& req,
			 const string& app_param,
			 AmUriParser& ruri_parser, AmUriParser& from_parser,
			 AmUriParser& to_parser) {
  string res;
  bool is_replaced = false;
  size_t p = 0;
  bool is_escaped = false;

  // char last_char=' ';
  
  while (p<s.length()) {
    size_t skip_chars = 1;

    if (is_escaped) {
      switch (s[p]) {
      case 'r': res += '\r'; break;
      case 'n': res += '\n'; break;
      case 't': res += '\t'; break;
      default: res += s[p]; break;
      }
      is_escaped = false;
    } else { // not escaped
      if (s[p]=='\\') {
	if (p==s.length()-1) {
	  res += '\\'; // add single \ at the end
	} else {
	  is_escaped = true;
	  is_replaced = true;
	}
      } else if ((s[p]=='$') && (s.length() >= p+1)) {
	is_replaced = true;
	p++;
	switch (s[p]) {
	case 'f': { // from
	  if ((s.length() == p+1) || (s[p+1] == '.')) {
	    res += req.from;
	    break;
	  }

	  if (s[p+1]=='t') { // $ft - from tag
	    res += req.from_tag;
	    break;
	  }

	  if (from_parser.uri.empty()) {
	    size_t end;
	    if (!from_parser.parse_contact(req.from, 0, end)) {
	      WARN("Error parsing From URI '%s'\n", req.from.c_str());
	      break;
	    }
	    from_parser.dump();
	  }

	  replaceParsedParam(s, p, from_parser, res);

	}; break;

	case 't': { // to
	  if ((s.length() == p+1) || (s[p+1] == '.')) {
	    res += req.to;
	    break;
	  }

	  if (to_parser.uri.empty()) {
	    size_t end;
	    if (!to_parser.parse_contact(req.to, 0, end)) {
	      WARN("Error parsing To URI '%s'\n", req.to.c_str());
	      break;
	    }
	  }

	  replaceParsedParam(s, p, to_parser, res);

	}; break;

	case 'r': { // r-uri
	  if ((s.length() == p+1) || (s[p+1] == '.')) {
	    res += req.r_uri;
	    break;
	  }

	  if (ruri_parser.uri.empty()) {
	    ruri_parser.uri = req.r_uri;
	    if (!ruri_parser.parse_uri()) {
	      WARN("Error parsing R-URI '%s'\n", req.r_uri.c_str());
	      break;
	    }
	  }
	  replaceParsedParam(s, p, ruri_parser, res);
	}; break;

	case 'c': { // call-id
	  if ((s.length() == p+1) || (s[p+1] == 'i')) {
	    res += req.callid;
	    break;
	  }
	  WARN("unknown replacement $c%c\n", s[p+1]);
	}; break;

	case 's': { // source (remote)
	  if (s.length() < p+1) {
	    WARN("unknown replacement $s\n");
	    break;
	  }

	  if (s[p+1] == 'i') { // $si source IP address
	    res += req.remote_ip.c_str();
	    break;
	  } else if (s[p+1] == 'p') { // $sp source port
	    res += int2str(req.remote_port);
	    break;
	  }

	  WARN("unknown replacement $s%c\n", s[p+1]);
	}; break;

	case 'R': { // received (local)
	  if (s.length() < p+1) {
	    WARN("unknown replacement $R\n");
	    break;
	  }

	  if (s[p+1] == 'i') { // $Ri received IP address
	    res += req.local_ip.c_str();
	    break;
	  } else if (s[p+1] == 'p') { // $Rp received port
	    res += int2str(req.local_port);
	    break;
	  } else if (s[p+1] == 'f') { // $Rf received interface id
	    res += int2str(req.local_if);
	  } else if (s[p+1] == 'n') { // $Rn received interface name
	    if ((req.local_if >= 0) && req.local_if < AmConfig::Ifs.size()) {
	      res += AmConfig::Ifs[req.local_if].name;
	    }
	  } else if (s[p+1] == 'I') { // $RI received interface public IP
	    if ((req.local_if >= 0) && req.local_if < AmConfig::Ifs.size()) {
	      res += AmConfig::Ifs[req.local_if].PublicIP;
	    }
	  }
	  WARN("unknown replacement $R%c\n", s[p+1]);
	}; break;


#define case_HDR(pv_char, pv_name, hdr_name)				\
	  case pv_char: {						\
	    AmUriParser uri_parser;					\
	    string m_uri = getHeader(req.hdrs, hdr_name);		\
	    if ((s.length() == p+1) || (s[p+1] == '.')) {		\
	      res += m_uri;						\
	      break;							\
	    }								\
	    size_t end;							\
	    if (!uri_parser.parse_contact(m_uri, 0, end)) {		\
	      WARN("Error parsing " pv_name " URI '%s'\n", m_uri.c_str()); \
	      break;							\
	    }								\
	    if (s[p+1] == 'i') {					\
	      res+=uri_parser.uri_user+"@"+uri_parser.uri_host;		\
	      if (!uri_parser.uri_port.empty())				\
		res+=":"+uri_parser.uri_port;				\
	    } else {							\
	      replaceParsedParam(s, p, uri_parser, res);		\
	    }								\
	  }; break;

	  case_HDR('a', "PAI", SIP_HDR_P_ASSERTED_IDENTITY);  // P-Asserted-Identity
	  case_HDR('p', "PPI", SIP_HDR_P_PREFERRED_IDENTITY); // P-Preferred-Identity

	case 'P': { // app-params
	  if (s[p+1] != '(') {
	    WARN("Error parsing P param replacement (missing '(')\n");
	    break;
	  }
	  if (s.length()<p+3) {
	    WARN("Error parsing P param replacement (short string)\n");
	    break;
	  }

	  size_t skip_p = p+2;
	  for (;skip_p<s.length() && s[skip_p] != ')';skip_p++) { }
	  if (skip_p==s.length()) {
	    WARN("Error parsing P param replacement (unclosed brackets)\n");
	    break;
	  }
	  string param_name = s.substr(p+2, skip_p-p-2);
	  // DBG("param_name = '%s' (skip-p - p = %d)\n", param_name.c_str(), skip_p-p);
	  res += get_header_keyvalue(app_param, param_name);
	  skip_chars = skip_p-p;
	} break;

	case 'H': { // header
	  size_t name_offset = 2;
	  if (s[p+1] != '(') {
	    if (s[p+2] != '(') {
	      WARN("Error parsing H header replacement (missing '(')\n");
	      break;
	    }
	    name_offset = 3;
	  }
	  if (s.length()<name_offset+1) {
	    WARN("Error parsing H header replacement (short string)\n");
	    break;
	  }

	  size_t skip_p = p+name_offset;
	  for (;skip_p<s.length() && s[skip_p] != ')';skip_p++) { }
	  if (skip_p==s.length()) {
	    WARN("Error parsing H header replacement (unclosed brackets)\n");
	    break;
	  }
	  string hdr_name = s.substr(p+name_offset, skip_p-p-name_offset);
	  // DBG("param_name = '%s' (skip-p - p = %d)\n", param_name.c_str(), skip_p-p);
	  if (name_offset == 2) {
	    // full header
	    res += getHeader(req.hdrs, hdr_name);
	  } else {
	    // parse URI and use component
	    AmUriParser uri_parser;
	    string m_uri = getHeader(req.hdrs, hdr_name);
	    if ((s[p+1] == '.')) {
	      res += m_uri;
	      break;
	    }

	    size_t end;
	    if (!uri_parser.parse_contact(m_uri, 0, end)) {
	      WARN("Error parsing header %s URI '%s'\n",
		   hdr_name.c_str(), m_uri.c_str());
	      break;
	    }
	    replaceParsedParam(s, p, uri_parser, res);
	  }
	  skip_chars = skip_p-p;
	} break;

	case 'M': { // regex map
	  if (s[p+1] != '(') {
	    WARN("Error parsing $M regex map replacement (missing '(')\n");
	    break;
	  }
	  if (s.length()<p+3) {
	    WARN("Error parsing $M regex map replacement (short string)\n");
	    break;
	  }

	  size_t skip_p = p+2;
	  skip_p = skip_to_end_of_brackets(s, skip_p);

	  if (skip_p==s.length()) {
	    WARN("Error parsing $M regex map replacement (unclosed brackets)\n");
	    skip_chars = skip_p-p;
	    break;
	  }

	  string map_str = s.substr(p+2, skip_p-p-2);
	  size_t spos = map_str.rfind("=>");
	  if (spos == string::npos) {
	    skip_chars = skip_p-p;
	    WARN("Error parsing $M regex map replacement: no => found in '%s'\n",
		 map_str.c_str());
	    break;
	  }

	  string map_val = map_str.substr(0, spos);
	  string map_val_replaced = replaceParameters(map_val, r_type, req, app_param,
						      ruri_parser, from_parser, to_parser);
	  string mapping_name = map_str.substr(spos+2);

	  string map_res; 
	  if (SBCFactory::regex_mappings.
	      mapRegex(mapping_name, map_val_replaced.c_str(), map_res)) {
	    DBG("matched regex mapping '%s' (orig '%s) in '%s'\n",
		map_val_replaced.c_str(), map_val.c_str(), mapping_name.c_str());
	    res+=map_res;
	  } else {
	    DBG("no match in regex mapping '%s' (orig '%s') in '%s'\n",
		map_val_replaced.c_str(), map_val.c_str(), mapping_name.c_str());
	  }
 
	  skip_chars = skip_p-p;
	} break;

	case '_': { // modify
	  if (s.length()<p+4) { // $_O()
	    WARN("Error parsing $_ modifier replacement (short string)\n");
	    break;
	  }

	  char operation = s[p+1];
	  if (operation != 'U' && operation != 'l'
	      && operation != 's' && operation != '5') {
	    WARN("Error parsing $_%c string modifier: unknown operator '%c'\n",
		 operation, operation);
	  }

	  if (s[p+2] != '(') {
	    WARN("Error parsing $U upcase replacement (missing '(')\n");
	    break;
	  }

	  size_t skip_p = p+3;
	  skip_p = skip_to_end_of_brackets(s, skip_p);

	  if (skip_p==s.length()) {
	    WARN("Error parsing $_ modifier (unclosed brackets)\n");
	    skip_chars = skip_p-p;
	    break;
	  }

	  string br_str = s.substr(p+3, skip_p-p-3);
	  string br_str_replaced = replaceParameters(br_str, "$_*(...)",
						     req, app_param,
						     ruri_parser, from_parser, to_parser);
	  br_str = br_str_replaced;
	  switch(operation) {
	  case 'u': // uppercase
	    transform(br_str_replaced.begin(), br_str_replaced.end(),
		      br_str_replaced.begin(), ::toupper); break;
	  case 'l': // lowercase
	    transform(br_str_replaced.begin(), br_str_replaced.end(),
		      br_str_replaced.begin(), ::tolower); break;

	  case 's': // size (string length)
	    br_str_replaced = int2str((unsigned int)br_str.length());
	    break;

	  case '5': // md5
	    br_str_replaced = calculateMD5(br_str);
	    break;

	  default: break;
	  }
	  DBG("applied operator '%c': '%s' => '%s'\n", operation,
	      br_str.c_str(), br_str_replaced.c_str());
	  res+=br_str_replaced;

	  skip_chars = skip_p-p;
	} break;

	default: {
	  WARN("unknown replace pattern $%c%c\n",
	       s[p], s[p+1]);
	}; break;
	};

	p+=skip_chars; // skip $.X
      } else {
	res += s[p];
      }
    } // end not escaped

    p++;
  }

  if (is_replaced) {
    DBG("%s pattern replace: '%s' -> '%s'\n", r_type, s.c_str(), res.c_str());
  }
  return res;
}
示例#13
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
}