1 /*
2  * Copyright (C) 2007 iptego GmbH
3  *
4  * This file is part of SEMS, a free SIP media server.
5  *
6  * SEMS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * For a license to use the sems software under conditions
12  * other than those described here, or to purchase support for this
13  * software, please contact iptel.org by e-mail at the following addresses:
14  *    info@iptel.org
15  *
16  * SEMS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25 
26 #include "AmPromptCollection.h"
27 #include "AmUtils.h"
28 #include "log.h"
29 
AmPromptCollection()30 AmPromptCollection::AmPromptCollection()
31 {
32 }
33 
~AmPromptCollection()34 AmPromptCollection::~AmPromptCollection()
35 {
36   // clean up
37   for (std::map<std::string, AudioFileEntry*>::iterator it=
38 	 store.begin(); it != store.end();it++)
39     delete it->second;
40 }
41 
configureModule(AmConfigReader & cfg,std::vector<std::pair<std::string,std::string>> & announcements,const char * mod_name)42 int AmPromptCollection::configureModule(AmConfigReader& cfg,
43 					std::vector<std::pair<std::string, std::string> >& announcements,
44 					const char* mod_name) {
45   int res = 0;
46   for (std::vector<std::pair<std::string, std::string> >::iterator it=
47 	 announcements.begin(); it != announcements.end(); it++) {
48     string fname = cfg.getParameter(it->first, "");
49     if (fname.empty()){
50       WARN("using default file '%s' for '%s' prompt in '%s' module\n",
51 	   it->second.c_str(), it->first.c_str(), mod_name);
52       fname = it->second;
53     }
54 
55     if (0 != setPrompt(it->first, fname, mod_name))
56       res = -1;
57   }
58 
59   return res;
60 }
61 
setPrompt(const std::string & name,const std::string & filename,const char * mod_name)62 int AmPromptCollection::setPrompt(const std::string& name,
63 				  const std::string& filename,
64 				  const char* mod_name) {
65   if (!file_exists(filename)) {
66     ERROR("'%s' prompt for module %s does not exist at '%s'.\n",
67 	  name.c_str(), mod_name, filename.c_str());
68     return -1;
69   }
70 
71   AudioFileEntry* af = new AudioFileEntry();
72   if (af->load(filename)) {
73     ERROR("Could not load '%s' prompt for module %s at '%s'.\n",
74 	  name.c_str(), mod_name, filename.c_str());
75     delete af;
76     return -1;
77   }
78   DBG("adding prompt '%s' to prompt collection.\n",
79       name.c_str());
80   store[name]=af;
81   return 0;
82 }
83 
84 
85 
AudioFileEntry()86 AudioFileEntry::AudioFileEntry()
87   : isopen(false)
88 {
89 }
90 
~AudioFileEntry()91 AudioFileEntry::~AudioFileEntry() {
92 }
93 
load(const std::string & filename)94 int AudioFileEntry::load(const std::string& filename) {
95   int res = cache.load(filename);
96   isopen = !res;
97   return res;
98 }
99 
getAudio()100 AmCachedAudioFile* AudioFileEntry::getAudio(){
101   if (!isopen)
102     return NULL;
103   return new AmCachedAudioFile(&cache);
104 }
105 
hasPrompt(const string & name)106 bool AmPromptCollection::hasPrompt(const string& name) {
107   string s = name;
108   std::map<std::string, AudioFileEntry*>::iterator it=store.begin();
109 
110   while (it != store.end()) {
111     if (!strcmp(it->first.c_str(), s.c_str()))
112       break;
113     it++;
114   }
115   return it != store.end();
116 
117 }
118 
addToPlaylist(const std::string & name,long sess_id,AmPlaylist & list,bool front,bool loop)119 int AmPromptCollection::addToPlaylist(const std::string& name, long sess_id,
120 				      AmPlaylist& list, bool front,
121 				      bool loop) {
122   string s = name;
123   std::map<std::string, AudioFileEntry*>::iterator it=store.begin();
124 
125   while (it != store.end()) {
126     if (!strcmp(it->first.c_str(), s.c_str()))
127       break;
128     it++;
129   }
130   if (it == store.end()) {
131     WARN("'%s' prompt not found!\n", name.c_str());
132     return -1;
133   }
134 
135   DBG("adding '%s' prompt to playlist at the %s'\n", it->first.c_str(),
136       front ? "front":"back");
137 
138   AmCachedAudioFile* af = it->second->getAudio();
139   if (NULL == af) {
140     return -2;
141   }
142 
143   if (loop)
144     af->loop.set(true);
145 
146   if (front)
147     list.addToPlayListFront(new AmPlaylistItem(af,NULL));
148   else
149     list.addToPlaylist(new AmPlaylistItem(af,NULL));
150 
151   items_mut.lock();
152   items[sess_id].push_back(af);
153   items_mut.unlock();
154 
155   return 0;
156 }
157 
158 
cleanup(long sess_id)159 void AmPromptCollection::cleanup(long sess_id) {
160   items_mut.lock();
161   for (std::vector<AmCachedAudioFile*>::iterator it =
162 	 items[sess_id].begin(); it!=items[sess_id].end(); it++)
163     delete *it;
164   items.erase(sess_id);
165   items_mut.unlock();
166 }
167