Exemple #1
0
int main(int argc, char* argv[])
{
	const char* login_config = "appid = 5392db98, work_dir =   .  ";
	const char* param = "rst=plain,rse=gb2312,sub=asr,ssm=1,aue=speex,auf=audio/L16;rate=16000,ent=sms16k";//注意sub=asr
	const char* grammar = NULL;
	int ret = 0 ;
	char key = 0 ;
	const char* asrfile = get_audio_file();
	ret = MSPLogin(NULL, NULL, login_config);
	if ( ret != MSP_SUCCESS )
	{
		printf("MSPLogin failed , Error code %d.\n",ret);
		return 0 ;
	}
	grammar = get_grammar( "gm_continuous_digit.abnf" );
	if(ret != MSP_SUCCESS)
	{
		printf("getExID with errorCode: %d \n", ret);
		return 0;
	}
	ret = run_asr(asrfile, param, grammar);
	if(ret != MSP_SUCCESS)
	{
		printf("run_asr with errorCode: %d \n", ret);
		return 0;
	}
	release_grammar(&grammar);
	MSPLogout();
	return 0;
}
Exemple #2
0
int main(int argc, char* argv[])
{
	const char* login_config = "appid = 55dbb5fb,work_dir =   .  ";
	const char* param = "rst=plain,rse=utf8,sub=asr,aue=speex-wb,auf=audio/L16;rate=16000,ent=sms16k";    //注意sub=asr,16k音频aue=speex-wb,8k音频识别aue=speex,
	int ret = 0 ;
	char key = 0 ;
	int grammar_flag = 0;//0:不上传词表;1:上传词表
	const char* asrfile = get_audio_file();//选择
	ret = MSPLogin(NULL, NULL, login_config);
	if ( ret != MSP_SUCCESS )
	{
		printf("MSPLogin failed , Error code %d.\n",ret);
		return 0 ;
	}
	memset(GrammarID, 0, sizeof(GrammarID));
	ret = get_grammar_id(grammar_flag);
	if(ret != MSP_SUCCESS)
	{
		printf("get_grammar_id with errorCode: %d \n", ret);
		return 0 ;
	}
 	ret = run_asr(asrfile, param);
	if(ret != MSP_SUCCESS)
	{
		printf("run_asr with errorCode: %d \n", ret);
		return 0;
	}
	MSPLogout();
	return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
	const char* grammar = NULL;
	const char* asrfile = get_audio_file();
	int ret = MSP_SUCCESS;
	//appid 请勿随意改动
	ret = QISRInit("appid=52d8f781");
	if(ret != MSP_SUCCESS)
	{
		printf("QISRInit with errorCode: %d \n", ret);
		return 0;
	}

	grammar = get_grammar( "gm_continuous_digit.abnf" );
	if(ret != MSP_SUCCESS)
	{
		printf("getExID with errorCode: %d \n", ret);
		return 0;
	}

	ret = run_asr(grammar , asrfile);
	release_grammar(&grammar);
	
	QISRFini();
	char key = _getch();
	return 0;
}
void AnswerMachineDialog::onSessionStart(const AmSipRequest& req)
{
  // disable DTMF detection - don't use DTMF here
  setDtmfDetectionEnabled(false);

#ifdef USE_MYSQL
  string beep_file;
  if (!get_audio_file(BEEP_SOUND, "", "", "", &beep_file) ||
      beep_file.empty())
    throw string("AnswerMachine: could not find beep file\n");
  if (a_greeting.open(announce_file.c_str(),AmAudioFile::Read) ||
      a_beep.open(beep_file,AmAudioFile::Read))
    throw string("AnswerMachine: could not open greeting or beep file\n");
#else
  if (a_greeting.open(announce_file.c_str(),AmAudioFile::Read) ||
      a_beep.open(add2path(AnswerMachineFactory::AnnouncePath,1, "beep.wav"),AmAudioFile::Read))
    throw string("AnswerMachine: could not open annoucement files\n");
#endif

  msg_filename = "/tmp/" + getLocalTag() + "."
    + AnswerMachineFactory::RecFileExt;
    
  if(a_msg.open(msg_filename,AmAudioFile::Write,true))
    throw string("AnswerMachine: couldn't open ") + 
      msg_filename + string(" for writing");

  //a_msg.setRecordTime(AnswerMachineFactory::MaxRecordTime*1000);
    
  playlist.addToPlaylist(new AmPlaylistItem(&a_greeting,NULL));
  playlist.addToPlaylist(new AmPlaylistItem(&a_beep,NULL));
  //playlist.addToPlaylist(new AmPlaylistItem(NULL,&a_msg));

  setInOut(&playlist,&playlist);

  request2dict(req);
}
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();
}
int ConferenceFactory::onLoad()
{
  AmConfigReader cfg;
  if(cfg.loadFile(AmConfig::ModConfigPath + string(APP_NAME)+ ".conf"))
    return -1;

  // get application specific global parameters
  configureModule(cfg);

#ifdef USE_MYSQL

  /* Get default audio from MySQL */

  string mysql_server, mysql_user, mysql_passwd, mysql_db;

  mysql_server = cfg.getParameter("mysql_server");
  if (mysql_server.empty()) {
    mysql_server = "localhost";
  }

  mysql_user = cfg.getParameter("mysql_user");
  if (mysql_user.empty()) {
    ERROR("conference.conf parameter 'mysql_user' is missing.\n");
    return -1;
  }

  mysql_passwd = cfg.getParameter("mysql_passwd");
  if (mysql_passwd.empty()) {
    ERROR("conference.conf parameter 'mysql_passwd' is missing.\n");
    return -1;
  }

  mysql_db = cfg.getParameter("mysql_db");
  if (mysql_db.empty()) {
    mysql_db = "sems";
  }

  try {

#ifdef VERSION2
    Connection.set_option(Connection.opt_reconnect, true);
#else
    Connection.set_option(new mysqlpp::ReconnectOption(true));
#endif
    Connection.connect(mysql_db.c_str(), mysql_server.c_str(),
		       mysql_user.c_str(), mysql_passwd.c_str());
    if (!Connection) {
      ERROR("Database connection failed: %s\n", Connection.error());
      return -1;
    }
  }

  catch (const mysqlpp::BadOption& er) {
    ERROR("MySQL++ set_option error: %s\n", er.what());
    return -1;
  }

  catch (const mysqlpp::Exception& er) {
    // Catch-all for any MySQL++ exceptions
    ERROR("MySQL++ error: %s\n", er.what());
    return -1;
  }

  if (!get_audio_file(LONELY_USER_MSG, "", "", LonelyUserFile)) {
    return -1;
  }

  if (LonelyUserFile.empty()) {
    ERROR("default announce 'first_participant_msg'\n");
    ERROR("for module conference does not exist.\n");
    return -1;
  }

  if (!get_audio_file(JOIN_SOUND, "", "", JoinSound)) {
    return -1;
  }

  if (!get_audio_file(DROP_SOUND, "", "", DropSound)) {
    return -1;
  }

#else 

  /* Get default audio from file system */

  AudioPath = cfg.getParameter("audio_path", ANNOUNCE_PATH);

  LonelyUserFile = cfg.getParameter("default_announce");
  if (LonelyUserFile.empty()) {
    LonelyUserFile = AudioPath + "/" ANNOUNCE_FILE;
  } else {
    if (LonelyUserFile[0] != '/') {
      LonelyUserFile = AudioPath + "/" + LonelyUserFile;
    }
  }
  if(!file_exists(LonelyUserFile)){
    ERROR("default announce '%s' \n",LonelyUserFile.c_str());
    ERROR("for module conference does not exist.\n");
    return -1;
  }

  JoinSound = cfg.getParameter("join_sound");
  if (!JoinSound.empty()) {
    if (JoinSound[0] != '/') {
      JoinSound = AudioPath + "/" + JoinSound;
    }
  }

  DropSound = cfg.getParameter("drop_sound");
  if (!DropSound.empty()) {
    if (DropSound[0] != '/') {
      DropSound = AudioPath + "/" + DropSound;
    }
  }

#endif
	
  DialoutSuffix = cfg.getParameter("dialout_suffix");
  if(DialoutSuffix.empty()){
    WARN("No dialout_suffix has been configured in the conference plug-in:\n");
    WARN("\t -> dial out will not be available unless P-Dialout-Suffix\n");
    WARN("\t -> header parameter is passed to conference plug-in\n");
  }
    
  string playout_type = cfg.getParameter("playout_type");
  if (playout_type == "simple") {
    m_PlayoutType = SIMPLE_PLAYOUT;
    DBG("Using simple (fifo) buffer as playout technique.\n");
  } else 	if (playout_type == "adaptive_jb") {
    m_PlayoutType = JB_PLAYOUT;
    DBG("Using adaptive jitter buffer as playout technique.\n");
  } else {
    DBG("Using adaptive playout buffer as playout technique.\n");
  }

  MaxParticipants = 0;
  string max_participants = cfg.getParameter("max_participants");
  if (max_participants.length() && str2i(max_participants, MaxParticipants)) {
    ERROR("while parsing max_participants parameter\n"); 
  }

  UseRFC4240Rooms = cfg.getParameter("use_rfc4240_rooms")=="yes";
  DBG("%ssing RFC4240 room naming.\n", UseRFC4240Rooms?"U":"Not u");

  return 0;
}
void AnswerMachineDialog::onSessionStart(const AmSipRequest& req)
{
  // disable DTMF detection - don't use DTMF here
  setDtmfDetectionEnabled(false);

  // announcement mode - no receiving needed
  if (MODE_ANN == vm_mode)
    setReceiving(false);

#ifdef USE_MYSQL
  string beep_file;
  if (!get_audio_file(BEEP_SOUND, "", "", "", &beep_file) ||
      beep_file.empty())
    throw string("AnswerMachine: could not find beep file\n");

  if (announce_fp) {
    rewind(announce_fp);
    if (a_greeting.fpopen(DEFAULT_TYPE"."DEFAULT_AUDIO_EXT, 
			  AmAudioFile::Read, announce_fp) ||
	a_beep.open(beep_file,AmAudioFile::Read)) {
      if (a_greeting.open(announce_file.c_str(),AmAudioFile::Read) ||
	a_beep.open(beep_file,AmAudioFile::Read))
      throw string("AnswerMachine: could not open greeting or beep file\n");
    }
  } else {
    if (a_greeting.open(announce_file.c_str(),AmAudioFile::Read) ||
	a_beep.open(beep_file,AmAudioFile::Read))
      throw string("AnswerMachine: could not open greeting or beep file\n");
  }
#else
  if (announce_fp) {
    if (a_greeting.fpopen(DEFAULT_TYPE"."DEFAULT_AUDIO_EXT, 
			  AmAudioFile::Read, announce_fp) ||
	a_beep.open(add2path(AnswerMachineFactory::AnnouncePath,1, "beep.wav"),
		    AmAudioFile::Read))
      throw string("AnswerMachine: could not open annoucement files\n");
  } else {
    if (a_greeting.open(announce_file.c_str(),AmAudioFile::Read) ||
	a_beep.open(add2path(AnswerMachineFactory::AnnouncePath,1, "beep.wav"),
		    AmAudioFile::Read))
      throw string("AnswerMachine: could not open annoucement files\n");
  }
#endif

  msg_filename = "/tmp/" + getLocalTag() + "."
    + AnswerMachineFactory::RecFileExt;
    
  if (vm_mode != MODE_ANN) {
    if(a_msg.open(msg_filename,AmAudioFile::Write,true))
      throw string("AnswerMachine: couldn't open ") + 
	msg_filename + string(" for writing");
  }

  //a_msg.setRecordTime(AnswerMachineFactory::MaxRecordTime*1000);
    
  playlist.addToPlaylist(new AmPlaylistItem(&a_greeting,NULL));
  if (vm_mode != MODE_ANN) 
    playlist.addToPlaylist(new AmPlaylistItem(&a_beep,NULL));
  //playlist.addToPlaylist(new AmPlaylistItem(NULL,&a_msg));

  setInOut(&playlist,&playlist);

  char now[15];
  sprintf(now, "%d", (int) time(NULL));
  email_dict["ts"] = now;

}
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);
}
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);
}
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);
}