1 /*
2  * Copyright (C) 2002-2003 Fhg Fokus
3  * Copyright (C) 2006 iptego GmbH
4  *
5  * This file is part of SEMS, a free SIP media server.
6  *
7  * SEMS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version. This program is released under
11  * the GPL with the additional exemption that compiling, linking,
12  * and/or using OpenSSL is allowed.
13  *
14  * For a license to use the SEMS software under conditions
15  * other than those described here, or to purchase support for this
16  * software, please contact iptel.org by e-mail at the following addresses:
17  *    info@iptel.org
18  *
19  * SEMS is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  */
28 /** @file AmPlugIn.h */
29 #ifndef _AmPlugIn_h_
30 #define _AmPlugIn_h_
31 
32 #include "AmThread.h"
33 
34 #include <string>
35 #include <map>
36 #include <vector>
37 #include <set>
38 #include <list>
39 using std::string;
40 using std::vector;
41 using std::list;
42 
43 class AmPluginFactory;
44 class AmSessionFactory;
45 class AmSessionEventHandlerFactory;
46 class AmDynInvokeFactory;
47 class AmLoggingFacility;
48 class AmSipRequest;
49 struct SdpPayload;
50 
51 struct amci_exports_t;
52 struct amci_codec_t;
53 struct amci_payload_t;
54 struct amci_inoutfmt_t;
55 struct amci_subtype_t;
56 
57 /** Interface that a payload provider needs to implement */
58 class AmPayloadProvider {
59  public:
60   AmPayloadProvider() { }
61   virtual ~AmPayloadProvider() { }
62 
63   /**
64    * Payload lookup function.
65    * @param payload_id Payload ID.
66    * @return NULL if failed .
67    */
68   virtual amci_payload_t*  payload(int payload_id) const = 0;
69 
70   /**
71    * Payload lookup function by name & rate
72    * @param name Payload ID.
73    * @return -1 if failed, else the internal payload id.
74    */
75   virtual int getDynPayload(const string& name, int rate, int encoding_param) const = 0;
76 
77   /**
78    * List all the payloads available for a media type
79    */
80   virtual void getPayloads(vector<SdpPayload>& pl_vec) const = 0;
81 };
82 
83 /**
84  * \brief Container for loaded Plug-ins.
85  */
86 class AmPlugIn : public AmPayloadProvider
87 {
88  private:
89   static AmPlugIn* _instance;
90 
91   std::set<string>                  rtld_global_plugins;
92   vector<void*> dlls;
93 
94   std::map<int,amci_codec_t*>       codecs;
95   std::map<int,amci_payload_t*>     payloads;
96   std::multimap<int,int>            payload_order;
97   std::map<string,amci_inoutfmt_t*> file_formats;
98 
99   std::map<string,AmSessionFactory*>             name2app;
100   AmMutex name2app_mut;
101 
102   std::map<string,AmSessionEventHandlerFactory*> name2seh;
103   std::map<string,AmPluginFactory*>              name2base;
104   std::map<string,AmDynInvokeFactory*>           name2di;
105   std::map<string,AmLoggingFacility*>            name2logfac;
106 
107   std::map<string,AmPluginFactory*>             module_objects;
108 
109   //AmCtrlInterfaceFactory *ctrlIface;
110 
111   int dynamic_pl; // range: 96->127, see RFC 1890
112   std::set<string> excluded_payloads;  // don't load these payloads (named)
113 
114   AmPlugIn();
115   virtual ~AmPlugIn();
116 
117   /** @return -1 if failed, else 0. */
118   int loadPlugIn(const string& file, const string& plugin_name, vector<AmPluginFactory*>& plugins);
119 
120   int loadAudioPlugIn(amci_exports_t* exports);
121   int loadAppPlugIn(AmPluginFactory* cb);
122   int loadSehPlugIn(AmPluginFactory* cb);
123   int loadBasePlugIn(AmPluginFactory* cb);
124   int loadDiPlugIn(AmPluginFactory* cb);
125   int loadLogFacPlugIn(AmPluginFactory* f);
126 
127   int initLoggingModules();
128  public:
129 
130   int addCodec(amci_codec_t* c);
131   int addPayload(amci_payload_t* p);
132   int addFileFormat(amci_inoutfmt_t* f);
133 
134   void set_load_rtld_global(const string& plugin_name);
135 
136   static AmPlugIn* instance();
137   static void dispose();
138 
139   void init();
140 
141   /**
142    * Loads all plug-ins from the directory given as parameter.
143    * @return -1 if failed, else 0.
144    */
145   int load(const string& directory, const string& plugins);
146 
147   /** register logging plugins to receive logging messages */
148   void registerLoggingPlugins();
149 
150   /**
151    * Payload lookup function.
152    * @param payload_id Payload ID.
153    * @return NULL if failed .
154    */
155   amci_payload_t*  payload(int payload_id) const;
156 
157   /**
158    * Payload lookup function by name & rate
159    * @param name Payload ID.
160    * @return -1 if failed, else the internal payload id.
161    */
162   int getDynPayload(const string& name, int rate, int encoding_param) const;
163 
164   /** return 0, or -1 in case of error. */
165   void getPayloads(vector<SdpPayload>& pl_vec) const;
166 
167   /** @return the suported payloads. */
168 
169   /** @return the order of payloads. */
170 
171   /**
172    * File format lookup according to the
173    * format name and/or file extension.
174    * @param fmt_name Format name.
175    * @param ext File extension.
176    * @return NULL if failed.
177    */
178   amci_inoutfmt_t* fileFormat(const string& fmt_name, const string& ext = "");
179 
180   /**
181    * File format's subtype lookup function.
182    * @param iofmt The file format.
183    * @param subtype Subtype ID (see plug-in declaration for values).
184    * @return NULL if failed.
185    */
186   amci_subtype_t*  subtype(amci_inoutfmt_t* iofmt, int subtype);
187 
188   /**
189    * File subtype lookup function.
190    * @param subtype_name The subtype's name (e.g. Pcm16).
191    * @return NULL if failed.
192    */
193   amci_subtype_t* subtype(amci_inoutfmt_t* iofmt, const string& subtype_name);
194 
195   /**
196    * Codec lookup function.
197    * @param id Codec ID (see amci/codecs.h).
198    * @return NULL if failed.
199    */
200   amci_codec_t*    codec(int id);
201 
202   /**
203    * get codec format parameters
204    * @param id Codec ID (see amci/codecs.h).
205    * @param is_offer for an offer?
206    * @param fmt_params_in input parameters for an answer
207    * @return fmt parameters for SDP (offer or answer)
208    */
209   string getSdpFormatParameters(int codec_id, bool is_offer, const string& fmt_params_in);
210 
211 
212 
213   /**
214    * Application lookup function
215    * @param app_name application name
216    * @return NULL if failed (-> application not found).
217    */
218   AmSessionFactory* getFactory4App(const string& app_name);
219 
220   /** @return true if this record has been inserted. */
221   bool registerFactory4App(const string& app_name, AmSessionFactory* f);
222 
223   /** register a factory for applications
224       @return true on success
225    */
226   static bool registerApplication(const string& app_name, AmSessionFactory* f);
227 
228   /** register a SIP Event Handler module
229       note: unprotected, use only at server startup (onLoad)
230       @return true on success
231    */
232   static bool registerSIPEventHandler(const string& seh_name,
233 				      AmSessionEventHandlerFactory* f);
234   /** register a DI Interface module
235       note: unprotected, use only at server startup (onLoad)
236       @return true on success
237    */
238   static bool registerDIInterface(const string& di_name, AmDynInvokeFactory* f);
239 
240   /** register a logging facility
241       note: unprotected, use only at server startup (onLoad)
242       @return true on success
243    */
244   static bool registerLoggingFacility(const string& lf_name, AmLoggingFacility* f);
245 
246   /**
247    * Find the proper SessionFactory
248    * for the given request.
249    */
250   AmSessionFactory* findSessionFactory(const AmSipRequest& req, string& app_name);
251 
252   /**
253    * Session event handler lookup function
254    * @param name application name
255    * @return NULL if failed (-> handler not found).
256    */
257   AmSessionEventHandlerFactory* getFactory4Seh(const string& name);
258 
259   /**
260    * Dynamic invokation component
261    */
262   AmDynInvokeFactory* getFactory4Di(const string& name);
263 
264   /**
265    * logging facility lookup function
266    * @param name application name
267    * @return NULL if failed (-> handler not found).
268    */
269   AmLoggingFacility* getFactory4LogFaclty(const string& name);
270 
271 };
272 
273 #endif
274