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