1 /*
2 linphone
3 Copyright (C) 2016 Belledonne Communications <info@belledonne-communications.com>
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 */
19 
20 #include "linphone/factory.h"
21 #include "private.h"
22 
23 #ifndef PACKAGE_SOUND_DIR
24 #define PACKAGE_SOUND_DIR "."
25 #endif
26 #ifndef PACKAGE_RING_DIR
27 #define PACKAGE_RING_DIR "."
28 #endif
29 
30 #ifndef PACKAGE_DATA_DIR
31 #define PACKAGE_DATA_DIR "."
32 #endif
33 
34 extern LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata);
35 extern LinphoneAddress *_linphone_address_new(const char *addr);
36 
37 typedef belle_sip_object_t_vptr_t LinphoneFactory_vptr_t;
38 
39 struct _LinphoneFactory {
40 	belle_sip_object_t base;
41 
42 	bctbx_list_t *supported_video_definitions;
43 
44 	/*these are the directories set by the application*/
45 	char *top_resources_dir;
46 	char *data_resources_dir;
47 	char *sound_resources_dir;
48 	char *ring_resources_dir;
49 	char *image_resources_dir;
50 	char *msplugins_dir;
51 
52 	/*these are the cached result computed from directories set by the application*/
53 	char *cached_data_resources_dir;
54 	char *cached_sound_resources_dir;
55 	char *cached_ring_resources_dir;
56 	char *cached_image_resources_dir;
57 	char *cached_msplugins_dir;
58 	LinphoneErrorInfo* ei;
59 };
60 
linphone_factory_uninit(LinphoneFactory * obj)61 static void linphone_factory_uninit(LinphoneFactory *obj){
62 	bctbx_list_free_with_data(obj->supported_video_definitions, (bctbx_list_free_func)linphone_video_definition_unref);
63 
64 	STRING_RESET(obj->top_resources_dir);
65 	STRING_RESET(obj->data_resources_dir);
66 	STRING_RESET(obj->sound_resources_dir);
67 	STRING_RESET(obj->ring_resources_dir);
68 	STRING_RESET(obj->image_resources_dir);
69 	STRING_RESET(obj->msplugins_dir);
70 
71 	STRING_RESET(obj->cached_data_resources_dir);
72 	STRING_RESET(obj->cached_sound_resources_dir);
73 	STRING_RESET(obj->cached_ring_resources_dir);
74 	STRING_RESET(obj->cached_image_resources_dir);
75 	STRING_RESET(obj->cached_msplugins_dir);
76 }
77 
78 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFactory);
79 BELLE_SIP_INSTANCIATE_VPTR(LinphoneFactory, belle_sip_object_t,
80 	linphone_factory_uninit, // destroy
81 	NULL, // clone
82 	NULL, // Marshall
83 	FALSE
84 );
85 
86 static LinphoneFactory *_factory = NULL;
87 
_linphone_factory_destroying_cb(void)88 static void _linphone_factory_destroying_cb(void) {
89 	if (_factory != NULL) {
90 		belle_sip_object_unref(_factory);
91 		_factory = NULL;
92 	}
93 }
94 
95 #define ADD_SUPPORTED_VIDEO_DEFINITION(factory, width, height, name) \
96 	(factory)->supported_video_definitions = bctbx_list_append((factory)->supported_video_definitions, \
97 		linphone_video_definition_ref(linphone_video_definition_new(width, height, name)))
98 
initialize_supported_video_definitions(LinphoneFactory * factory)99 static void initialize_supported_video_definitions(LinphoneFactory *factory) {
100 #if !defined(__ANDROID__) && !TARGET_OS_IPHONE
101 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_1080P_W, MS_VIDEO_SIZE_1080P_H, "1080p");
102 #endif
103 #if !defined(__ANDROID__) && !TARGET_OS_MAC /*limit to most common sizes because mac video API cannot list supported resolutions*/
104 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_UXGA_W, MS_VIDEO_SIZE_UXGA_H, "uxga");
105 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_SXGA_MINUS_W, MS_VIDEO_SIZE_SXGA_MINUS_H, "sxga-");
106 #endif
107 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_720P_W, MS_VIDEO_SIZE_720P_H, "720p");
108 #if !defined(__ANDROID__) && !TARGET_OS_MAC
109 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_XGA_W, MS_VIDEO_SIZE_XGA_H, "xga");
110 #endif
111 #if !defined(__ANDROID__) && !TARGET_OS_IPHONE
112 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_SVGA_W, MS_VIDEO_SIZE_SVGA_H, "svga");
113 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H, "4cif");
114 #endif
115 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H, "vga");
116 #if TARGET_OS_IPHONE
117 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_IOS_MEDIUM_H, MS_VIDEO_SIZE_IOS_MEDIUM_W, "ios-medium");
118 #endif
119 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H, "cif");
120 #if !TARGET_OS_MAC || TARGET_OS_IPHONE /* OS_MAC is 1 for iPhone, but we need QVGA */
121 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H, "qvga");
122 #endif
123 	ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H, "qcif");
124 }
125 
linphone_factory_new(void)126 static LinphoneFactory *linphone_factory_new(void){
127 	LinphoneFactory *factory = belle_sip_object_new(LinphoneFactory);
128 	factory->top_resources_dir = bctbx_strdup(PACKAGE_DATA_DIR);
129 	initialize_supported_video_definitions(factory);
130 	return factory;
131 }
132 
133 
linphone_factory_get(void)134 LinphoneFactory *linphone_factory_get(void) {
135 	if (_factory == NULL) {
136 		_factory = linphone_factory_new();
137 		atexit(_linphone_factory_destroying_cb);
138 	}
139 	return _factory;
140 }
141 
linphone_factory_clean(void)142 void linphone_factory_clean(void){
143 	if (_factory){
144 		belle_sip_object_unref(_factory);
145 		_factory = NULL;
146 	}
147 }
148 
linphone_factory_create_core(const LinphoneFactory * factory,LinphoneCoreCbs * cbs,const char * config_path,const char * factory_config_path)149 LinphoneCore *linphone_factory_create_core(const LinphoneFactory *factory, LinphoneCoreCbs *cbs,
150 		const char *config_path, const char *factory_config_path) {
151 	LpConfig *config = lp_config_new_with_factory(config_path, factory_config_path);
152 	LinphoneCore *lc = _linphone_core_new_with_config(cbs, config, NULL);
153 	lp_config_unref(config);
154 	return lc;
155 }
156 
linphone_factory_create_core_with_config(const LinphoneFactory * factory,LinphoneCoreCbs * cbs,LinphoneConfig * config)157 LinphoneCore *linphone_factory_create_core_with_config(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, LinphoneConfig *config) {
158 	return _linphone_core_new_with_config(cbs, config, NULL);
159 }
160 
linphone_factory_create_core_cbs(const LinphoneFactory * factory)161 LinphoneCoreCbs *linphone_factory_create_core_cbs(const LinphoneFactory *factory) {
162 	return _linphone_core_cbs_new();
163 }
164 
linphone_factory_create_address(const LinphoneFactory * factory,const char * addr)165 LinphoneAddress *linphone_factory_create_address(const LinphoneFactory *factory, const char *addr) {
166 	return _linphone_address_new(addr);
167 }
168 
linphone_factory_create_auth_info(const LinphoneFactory * factory,const char * username,const char * userid,const char * passwd,const char * ha1,const char * realm,const char * domain)169 LinphoneAuthInfo *linphone_factory_create_auth_info(const LinphoneFactory *factory, const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm, const char *domain) {
170 	return linphone_auth_info_new(username, userid, passwd, ha1, realm, domain);
171 }
172 
linphone_factory_create_call_cbs(const LinphoneFactory * factory)173 LinphoneCallCbs * linphone_factory_create_call_cbs(const LinphoneFactory *factory) {
174 	return _linphone_call_cbs_new();
175 }
176 
linphone_factory_create_vcard(LinphoneFactory * factory)177 LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory) {
178 	return _linphone_vcard_new();
179 }
180 
linphone_factory_create_video_definition(const LinphoneFactory * factory,unsigned int width,unsigned int height)181 LinphoneVideoDefinition * linphone_factory_create_video_definition(const LinphoneFactory *factory, unsigned int width, unsigned int height) {
182 	return linphone_video_definition_ref(linphone_video_definition_new(width, height, NULL));
183 }
184 
linphone_factory_create_video_definition_from_name(const LinphoneFactory * factory,const char * name)185 LinphoneVideoDefinition * linphone_factory_create_video_definition_from_name(const LinphoneFactory *factory, const char *name) {
186 	unsigned int width = 0;
187 	unsigned int height = 0;
188 	LinphoneVideoDefinition *vdef = linphone_factory_find_supported_video_definition_by_name(factory, name);
189 	if (vdef != NULL) return vdef;
190 	if (sscanf(name, "%ux%u", &width, &height) == 2) {
191 		return linphone_video_definition_new(width, height, NULL);
192 	}
193 	return linphone_video_definition_new(0, 0, NULL);
194 }
195 
linphone_factory_get_supported_video_definitions(const LinphoneFactory * factory)196 const bctbx_list_t * linphone_factory_get_supported_video_definitions(const LinphoneFactory *factory) {
197 	return factory->supported_video_definitions;
198 }
199 
linphone_factory_find_supported_video_definition(const LinphoneFactory * factory,unsigned int width,unsigned int height)200 LinphoneVideoDefinition * linphone_factory_find_supported_video_definition(const LinphoneFactory *factory, unsigned int width, unsigned int height) {
201 	const bctbx_list_t *item;
202 	const bctbx_list_t *supported = linphone_factory_get_supported_video_definitions(factory);
203 	LinphoneVideoDefinition *searched_vdef = linphone_video_definition_new(width, height, NULL);
204 
205 	for (item = supported; item != NULL; item = bctbx_list_next(item)) {
206 		LinphoneVideoDefinition *svdef = (LinphoneVideoDefinition *)bctbx_list_get_data(item);
207 		if (linphone_video_definition_equals(svdef, searched_vdef)) {
208 			linphone_video_definition_unref(searched_vdef);
209 			return linphone_video_definition_clone(svdef);
210 		}
211 	}
212 
213 	return searched_vdef;
214 }
215 
linphone_factory_find_supported_video_definition_by_name(const LinphoneFactory * factory,const char * name)216 LinphoneVideoDefinition * linphone_factory_find_supported_video_definition_by_name(const LinphoneFactory *factory, const char *name) {
217 	const bctbx_list_t *item;
218 	const bctbx_list_t *supported = linphone_factory_get_supported_video_definitions(factory);
219 
220 	for (item = supported; item != NULL; item = bctbx_list_next(item)) {
221 		LinphoneVideoDefinition *svdef = (LinphoneVideoDefinition *)bctbx_list_get_data(item);
222 		if (strcmp(linphone_video_definition_get_name(svdef), name) == 0) {
223 			return linphone_video_definition_clone(svdef);
224 		}
225 	}
226 	return NULL;
227 }
228 
linphone_factory_get_top_resources_dir(const LinphoneFactory * factory)229 const char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory) {
230 	return factory->top_resources_dir;
231 }
232 
linphone_factory_set_top_resources_dir(LinphoneFactory * factory,const char * path)233 void linphone_factory_set_top_resources_dir(LinphoneFactory *factory, const char *path) {
234 	STRING_SET(factory->top_resources_dir, path);
235 }
236 
linphone_factory_get_data_resources_dir(LinphoneFactory * factory)237 const char * linphone_factory_get_data_resources_dir(LinphoneFactory *factory) {
238 	if (factory->data_resources_dir) return factory->data_resources_dir;
239 	if (factory->top_resources_dir){
240 		STRING_TRANSFER(factory->cached_data_resources_dir, bctbx_strdup_printf("%s/linphone", factory->top_resources_dir));
241 	}else{
242 		STRING_TRANSFER(factory->cached_data_resources_dir, bctbx_strdup_printf("%s/linphone", PACKAGE_DATA_DIR));
243 	}
244 	return factory->cached_data_resources_dir;
245 }
246 
linphone_factory_set_data_resources_dir(LinphoneFactory * factory,const char * path)247 void linphone_factory_set_data_resources_dir(LinphoneFactory *factory, const char *path) {
248 	STRING_SET(factory->data_resources_dir, path);
249 }
250 
linphone_factory_get_sound_resources_dir(LinphoneFactory * factory)251 const char * linphone_factory_get_sound_resources_dir(LinphoneFactory *factory) {
252 	if (factory->sound_resources_dir) return factory->sound_resources_dir;
253 	if (factory->top_resources_dir){
254 		STRING_TRANSFER(factory->cached_sound_resources_dir, bctbx_strdup_printf("%s/sounds/linphone", factory->top_resources_dir));
255 		return factory->cached_sound_resources_dir;
256 	}
257 	return PACKAGE_SOUND_DIR;
258 }
259 
linphone_factory_set_sound_resources_dir(LinphoneFactory * factory,const char * path)260 void linphone_factory_set_sound_resources_dir(LinphoneFactory *factory, const char *path) {
261 	STRING_SET(factory->sound_resources_dir, path);
262 }
263 
linphone_factory_get_ring_resources_dir(LinphoneFactory * factory)264 const char * linphone_factory_get_ring_resources_dir(LinphoneFactory *factory) {
265 	if (factory->ring_resources_dir) return factory->ring_resources_dir;
266 	if (factory->sound_resources_dir){
267 		STRING_TRANSFER(factory->cached_ring_resources_dir, bctbx_strdup_printf("%s/rings", factory->sound_resources_dir));
268 		return factory->cached_ring_resources_dir;
269 	}
270 	if (factory->top_resources_dir) {
271 		STRING_TRANSFER(factory->cached_ring_resources_dir, bctbx_strdup_printf("%s/sounds/linphone/rings", factory->top_resources_dir));
272 		return factory->cached_ring_resources_dir;
273 	}
274 	return PACKAGE_RING_DIR;
275 }
276 
linphone_factory_set_ring_resources_dir(LinphoneFactory * factory,const char * path)277 void linphone_factory_set_ring_resources_dir(LinphoneFactory *factory, const char *path) {
278 	STRING_SET(factory->ring_resources_dir, path);
279 }
280 
linphone_factory_get_image_resources_dir(LinphoneFactory * factory)281 const char * linphone_factory_get_image_resources_dir(LinphoneFactory *factory) {
282 	if (factory->image_resources_dir) return factory->image_resources_dir;
283 	if (factory->top_resources_dir) {
284 		STRING_TRANSFER(factory->cached_image_resources_dir, bctbx_strdup_printf("%s/images", factory->top_resources_dir));
285 	}else{
286 		STRING_TRANSFER(factory->cached_image_resources_dir, bctbx_strdup_printf("%s/images", PACKAGE_DATA_DIR));
287 	}
288 	return factory->cached_image_resources_dir;
289 }
290 
linphone_factory_set_image_resources_dir(LinphoneFactory * factory,const char * path)291 void linphone_factory_set_image_resources_dir(LinphoneFactory *factory, const char *path) {
292 	STRING_SET(factory->image_resources_dir, path);
293 }
294 
linphone_factory_get_msplugins_dir(LinphoneFactory * factory)295 const char * linphone_factory_get_msplugins_dir(LinphoneFactory *factory) {
296 	return factory->msplugins_dir;
297 }
298 
linphone_factory_set_msplugins_dir(LinphoneFactory * factory,const char * path)299 void linphone_factory_set_msplugins_dir(LinphoneFactory *factory, const char *path) {
300 	STRING_SET(factory->msplugins_dir, path);
301 }
302 
linphone_factory_create_error_info(LinphoneFactory * factory)303 LinphoneErrorInfo *linphone_factory_create_error_info(LinphoneFactory *factory){
304 
305 	return linphone_error_info_new();
306 
307 }
308 
linphone_factory_create_range(LinphoneFactory * factory)309 LinphoneRange *linphone_factory_create_range(LinphoneFactory *factory) {
310 	return linphone_range_new();
311 }
312 
linphone_factory_create_transports(LinphoneFactory * factory)313 LinphoneTransports *linphone_factory_create_transports(LinphoneFactory *factory) {
314 	return linphone_transports_new();
315 }
316 
linphone_factory_create_video_activation_policy(LinphoneFactory * factory)317 LinphoneVideoActivationPolicy *linphone_factory_create_video_activation_policy(LinphoneFactory *factory) {
318 	return linphone_video_activation_policy_new();
319 }