1 /*
2 linphone
3 Copyright (C) 2010-2014 Belledonne Communications SARL
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/core.h"
21 #include "private.h"
22 
23 
24 
linphone_content_set_sal_body_handler(LinphoneContent * content,SalBodyHandler * body_handler)25 static void linphone_content_set_sal_body_handler(LinphoneContent *content, SalBodyHandler *body_handler) {
26 	if (content->body_handler != NULL) {
27 		sal_body_handler_unref(content->body_handler);
28 		content->body_handler = NULL;
29 	}
30 	content->body_handler = sal_body_handler_ref(body_handler);
31 }
32 
linphone_content_new_with_body_handler(SalBodyHandler * body_handler)33 static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) {
34 	LinphoneContent *content = belle_sip_object_new(LinphoneContent);
35 	belle_sip_object_ref(content);
36 	content->owned_fields = TRUE;
37 	content->cryptoContext = NULL; /* this field is managed externally by encryption/decryption functions so be careful to initialise it to NULL */
38 	if (body_handler == NULL) {
39 		linphone_content_set_sal_body_handler(content, sal_body_handler_new());
40 	} else {
41 		linphone_content_set_sal_body_handler(content, body_handler);
42 	}
43 	return content;
44 }
45 
linphone_content_destroy(LinphoneContent * content)46 static void linphone_content_destroy(LinphoneContent *content) {
47 	if (content->owned_fields == TRUE) {
48 		if (content->body_handler) sal_body_handler_unref(content->body_handler);
49 		if (content->name) belle_sip_free(content->name);
50 		if (content->key) belle_sip_free(content->key);
51 		/* note : crypto context is allocated/destroyed by the encryption function */
52 	}
53 }
54 
linphone_content_clone(LinphoneContent * obj,const LinphoneContent * ref)55 static void linphone_content_clone(LinphoneContent *obj, const LinphoneContent *ref) {
56 	obj->owned_fields = TRUE;
57 	linphone_content_set_sal_body_handler(obj, sal_body_handler_new());
58 	if ((linphone_content_get_type(ref) != NULL) || (linphone_content_get_subtype(ref) != NULL)) {
59 		linphone_content_set_type(obj, linphone_content_get_type(ref));
60 		linphone_content_set_subtype(obj, linphone_content_get_subtype(ref));
61 	}
62 	if (linphone_content_get_encoding(ref) != NULL) {
63 		linphone_content_set_encoding(obj, linphone_content_get_encoding(ref));
64 	}
65 	linphone_content_set_name(obj, linphone_content_get_name(ref));
66 	linphone_content_set_key(obj, linphone_content_get_key(ref), linphone_content_get_key_size(ref));
67 	if (linphone_content_get_buffer(ref) != NULL) {
68 		linphone_content_set_buffer(obj, linphone_content_get_buffer(ref), linphone_content_get_size(ref));
69 	} else {
70 		linphone_content_set_size(obj, linphone_content_get_size(ref));
71 	}
72 }
73 
74 
75 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneContent);
76 
77 BELLE_SIP_INSTANCIATE_VPTR(LinphoneContent, belle_sip_object_t,
78 	(belle_sip_object_destroy_t)linphone_content_destroy,
79 	(belle_sip_object_clone_t)linphone_content_clone,
80 	NULL, // marshal
81 	TRUE
82 );
83 
84 
linphone_core_create_content(LinphoneCore * lc)85 LinphoneContent * linphone_core_create_content(LinphoneCore *lc) {
86 	return linphone_content_new();
87 }
88 
linphone_content_ref(LinphoneContent * content)89 LinphoneContent * linphone_content_ref(LinphoneContent *content) {
90 	belle_sip_object_ref(content);
91 	return content;
92 }
93 
linphone_content_unref(LinphoneContent * content)94 void linphone_content_unref(LinphoneContent *content) {
95 	belle_sip_object_unref(content);
96 }
97 
linphone_content_get_user_data(const LinphoneContent * content)98 void *linphone_content_get_user_data(const LinphoneContent *content) {
99 	return content->user_data;
100 }
101 
linphone_content_set_user_data(LinphoneContent * content,void * ud)102 void linphone_content_set_user_data(LinphoneContent *content, void *ud) {
103 	content->user_data = ud;
104 }
105 
linphone_content_get_type(const LinphoneContent * content)106 const char * linphone_content_get_type(const LinphoneContent *content) {
107 	return sal_body_handler_get_type(content->body_handler);
108 }
109 
linphone_content_set_type(LinphoneContent * content,const char * type)110 void linphone_content_set_type(LinphoneContent *content, const char *type) {
111 	sal_body_handler_set_type(content->body_handler, type);
112 }
113 
linphone_content_get_subtype(const LinphoneContent * content)114 const char * linphone_content_get_subtype(const LinphoneContent *content) {
115 	return sal_body_handler_get_subtype(content->body_handler);
116 }
117 
linphone_content_set_subtype(LinphoneContent * content,const char * subtype)118 void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) {
119 	sal_body_handler_set_subtype(content->body_handler, subtype);
120 }
121 
linphone_content_get_buffer(const LinphoneContent * content)122 void * linphone_content_get_buffer(const LinphoneContent *content) {
123 	return sal_body_handler_get_data(content->body_handler);
124 }
125 
linphone_content_set_buffer(LinphoneContent * content,const void * buffer,size_t size)126 void linphone_content_set_buffer(LinphoneContent *content, const void *buffer, size_t size) {
127 	void *data;
128 	sal_body_handler_set_size(content->body_handler, size);
129 	data = belle_sip_malloc(size + 1);
130 	memcpy(data, buffer, size);
131 	((char *)data)[size] = '\0';
132 	sal_body_handler_set_data(content->body_handler, data);
133 }
134 
linphone_content_get_string_buffer(const LinphoneContent * content)135 const char * linphone_content_get_string_buffer(const LinphoneContent *content) {
136 	return (const char *)linphone_content_get_buffer(content);
137 }
138 
linphone_content_set_string_buffer(LinphoneContent * content,const char * buffer)139 void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) {
140 	sal_body_handler_set_size(content->body_handler, strlen(buffer));
141 	sal_body_handler_set_data(content->body_handler, belle_sip_strdup(buffer));
142 }
143 
linphone_content_get_size(const LinphoneContent * content)144 size_t linphone_content_get_size(const LinphoneContent *content) {
145 	return sal_body_handler_get_size(content->body_handler);
146 }
147 
linphone_content_set_size(LinphoneContent * content,size_t size)148 void linphone_content_set_size(LinphoneContent *content, size_t size) {
149 	sal_body_handler_set_size(content->body_handler, size);
150 }
151 
linphone_content_get_encoding(const LinphoneContent * content)152 const char * linphone_content_get_encoding(const LinphoneContent *content) {
153 	return sal_body_handler_get_encoding(content->body_handler);
154 }
155 
linphone_content_set_encoding(LinphoneContent * content,const char * encoding)156 void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) {
157 	sal_body_handler_set_encoding(content->body_handler, encoding);
158 }
159 
linphone_content_get_name(const LinphoneContent * content)160 const char * linphone_content_get_name(const LinphoneContent *content) {
161 	return content->name;
162 }
163 
linphone_content_set_name(LinphoneContent * content,const char * name)164 void linphone_content_set_name(LinphoneContent *content, const char *name) {
165 	if (content->name != NULL) {
166 		belle_sip_free(content->name);
167 		content->name = NULL;
168 	}
169 	if (name != NULL) {
170 		content->name = belle_sip_strdup(name);
171 	}
172 }
173 
linphone_content_get_key_size(const LinphoneContent * content)174 size_t linphone_content_get_key_size(const LinphoneContent *content) {
175 	return content->keyLength;
176 }
177 
linphone_content_get_key(const LinphoneContent * content)178 const char * linphone_content_get_key(const LinphoneContent *content) {
179 	return content->key;
180 }
181 
linphone_content_set_key(LinphoneContent * content,const char * key,const size_t keyLength)182 void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) {
183 	if (content->key != NULL) {
184 		belle_sip_free(content->key);
185 		content->key = NULL;
186 	}
187 	if (key != NULL) {
188 		content->key = belle_sip_malloc(keyLength + 1);
189 		memcpy(content->key, key, keyLength);
190 		content->key[keyLength] = '\0';
191 		content->keyLength = keyLength;
192 	}
193 }
194 
195 /* crypto context is managed(allocated/freed) by the encryption function, so provide the address of field in the private structure */
linphone_content_get_cryptoContext_address(LinphoneContent * content)196 void ** linphone_content_get_cryptoContext_address(LinphoneContent *content) {
197 	return &(content->cryptoContext);
198 }
199 
linphone_content_is_multipart(const LinphoneContent * content)200 bool_t linphone_content_is_multipart(const LinphoneContent *content) {
201 	return sal_body_handler_is_multipart(content->body_handler);
202 }
203 
linphone_content_get_part(const LinphoneContent * content,int idx)204 LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) {
205 	SalBodyHandler *part_body_handler;
206 	if (!linphone_content_is_multipart(content)) return NULL;
207 	part_body_handler = sal_body_handler_get_part(content->body_handler, idx);
208 	return linphone_content_from_sal_body_handler(part_body_handler);
209 }
210 
linphone_content_find_part_by_header(const LinphoneContent * content,const char * header_name,const char * header_value)211 LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) {
212 	SalBodyHandler *part_body_handler;
213 	if (!linphone_content_is_multipart(content)) return NULL;
214 	part_body_handler = sal_body_handler_find_part_by_header(content->body_handler, header_name, header_value);
215 	return linphone_content_from_sal_body_handler(part_body_handler);
216 }
217 
linphone_content_get_custom_header(const LinphoneContent * content,const char * header_name)218 const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) {
219 	return sal_body_handler_get_header(content->body_handler, header_name);
220 }
221 
222 
linphone_content_new(void)223 LinphoneContent * linphone_content_new(void) {
224 	return linphone_content_new_with_body_handler(NULL);
225 }
226 
linphone_content_copy(const LinphoneContent * ref)227 LinphoneContent * linphone_content_copy(const LinphoneContent *ref) {
228 	return (LinphoneContent *)belle_sip_object_ref(belle_sip_object_clone(BELLE_SIP_OBJECT(ref)));
229 }
230 
linphone_content_from_sal_body_handler(SalBodyHandler * body_handler)231 LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_handler) {
232 	if (body_handler) {
233 		return linphone_content_new_with_body_handler(body_handler);
234 	}
235 	return NULL;
236 }
237 
sal_body_handler_from_content(const LinphoneContent * content)238 SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) {
239 	if (content == NULL) return NULL;
240 	return content->body_handler;
241 }
242