1 /*
2 belle-sip - SIP (RFC3261) library.
3 Copyright (C) 2010 Belledonne Communications SARL
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (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, see <http://www.gnu.org/licenses/>.
17 */
18
19
20
21 #include "belle-sip/headers.h"
22 #include "belle-sip/parameters.h"
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdarg.h>
26 #include "grammars/belle_sip_messageLexer.h"
27 #include "grammars/belle_sip_messageParser.h"
28
29 #include "belle_sip_internal.h"
30 #include "listeningpoint_internal.h"
31
32 /************************
33 * header
34 ***********************/
35
36 GET_SET_STRING(belle_sip_header,name);
37 #define PROTO_SIP 0x1
38 #define PROTO_HTTP 0x1<<1
39 typedef belle_sip_header_t* (*header_parse_func)(const char*) ;
40 struct header_name_func_pair {
41 int protocol;
42 const char* name;
43 header_parse_func func;
44 };
45 static struct header_name_func_pair header_table[] = {
46 {PROTO_SIP, "m", (header_parse_func)belle_sip_header_contact_parse}
47 ,{PROTO_SIP, BELLE_SIP_CONTACT, (header_parse_func)belle_sip_header_contact_parse}
48 ,{PROTO_SIP, "f", (header_parse_func)belle_sip_header_from_parse}
49 ,{PROTO_SIP, BELLE_SIP_FROM, (header_parse_func)belle_sip_header_from_parse}
50 ,{PROTO_SIP, "t", (header_parse_func)belle_sip_header_to_parse}
51 ,{PROTO_SIP, BELLE_SIP_TO, (header_parse_func)belle_sip_header_to_parse}
52 ,{PROTO_SIP, "d", (header_parse_func)belle_sip_header_diversion_parse}
53 ,{PROTO_SIP, BELLE_SIP_DIVERSION, (header_parse_func)belle_sip_header_diversion_parse}
54 ,{PROTO_SIP, "i", (header_parse_func)belle_sip_header_call_id_parse}
55 ,{PROTO_SIP, BELLE_SIP_CALL_ID, (header_parse_func)belle_sip_header_call_id_parse}
56 ,{PROTO_SIP, "l", (header_parse_func)belle_sip_header_content_length_parse}
57 ,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_CONTENT_LENGTH, (header_parse_func)belle_sip_header_content_length_parse}
58 ,{PROTO_SIP, "c", (header_parse_func)belle_sip_header_content_type_parse}
59 ,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_CONTENT_TYPE, (header_parse_func)belle_sip_header_content_type_parse}
60 ,{PROTO_SIP, BELLE_SIP_CSEQ, (header_parse_func)belle_sip_header_cseq_parse}
61 ,{PROTO_SIP, BELLE_SIP_ROUTE, (header_parse_func)belle_sip_header_route_parse}
62 ,{PROTO_SIP, BELLE_SIP_RECORD_ROUTE, (header_parse_func)belle_sip_header_record_route_parse}
63 ,{PROTO_SIP, "v", (header_parse_func)belle_sip_header_via_parse}
64 ,{PROTO_SIP, BELLE_SIP_VIA, (header_parse_func)belle_sip_header_via_parse}
65 ,{PROTO_SIP, BELLE_SIP_AUTHORIZATION, (header_parse_func)belle_sip_header_authorization_parse}
66 ,{PROTO_SIP, BELLE_SIP_PROXY_AUTHORIZATION, (header_parse_func)belle_sip_header_proxy_authorization_parse}
67 ,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_WWW_AUTHENTICATE, (header_parse_func)belle_sip_header_www_authenticate_parse}
68 ,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_PROXY_AUTHENTICATE, (header_parse_func)belle_sip_header_proxy_authenticate_parse}
69 ,{PROTO_SIP, BELLE_SIP_MAX_FORWARDS, (header_parse_func)belle_sip_header_max_forwards_parse}
70 ,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_USER_AGENT, (header_parse_func)belle_sip_header_user_agent_parse}
71 ,{PROTO_SIP, BELLE_SIP_EXPIRES, (header_parse_func)belle_sip_header_expires_parse}
72 ,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_ALLOW, (header_parse_func)belle_sip_header_allow_parse}
73 ,{PROTO_SIP, BELLE_SIP_SUBSCRIPTION_STATE, (header_parse_func)belle_sip_header_subscription_state_parse}
74 ,{PROTO_SIP, BELLE_SIP_SERVICE_ROUTE, (header_parse_func)belle_sip_header_service_route_parse}
75 ,{PROTO_SIP, BELLE_SIP_REFER_TO, (header_parse_func)belle_sip_header_refer_to_parse}
76 ,{PROTO_SIP, BELLE_SIP_REFERRED_BY, (header_parse_func)belle_sip_header_referred_by_parse}
77 ,{PROTO_SIP, BELLE_SIP_REPLACES, (header_parse_func)belle_sip_header_replaces_parse}
78 ,{PROTO_SIP, BELLE_SIP_DATE, (header_parse_func)belle_sip_header_date_parse}
79 ,{PROTO_SIP, BELLE_SIP_P_PREFERRED_IDENTITY, (header_parse_func)belle_sip_header_p_preferred_identity_parse}
80 ,{PROTO_SIP, BELLE_SIP_PRIVACY, (header_parse_func)belle_sip_header_privacy_parse}
81 ,{PROTO_SIP, BELLE_SIP_EVENT, (header_parse_func)belle_sip_header_event_parse}
82 ,{PROTO_SIP, BELLE_SIP_SUPPORTED, (header_parse_func)belle_sip_header_supported_parse}
83 ,{PROTO_SIP, "k", (header_parse_func)belle_sip_header_supported_parse}
84 ,{PROTO_SIP, BELLE_SIP_CONTENT_DISPOSITION, (header_parse_func)belle_sip_header_content_disposition_parse}
85 ,{PROTO_SIP, BELLE_SIP_ACCEPT, (header_parse_func)belle_sip_header_accept_parse}
86 ,{PROTO_SIP, BELLE_SIP_REASON, (header_parse_func)belle_sip_header_reason_parse}
87 ,{PROTO_SIP, BELLE_SIP_AUTHENTICATION_INFO, (header_parse_func)belle_sip_header_authentication_info_parse}
88 };
89
belle_header_create(const char * name,const char * value,int protocol)90 static belle_sip_header_t* belle_header_create(const char* name,const char* value,int protocol) {
91 size_t i;
92 belle_sip_header_t* ret;
93 size_t elements =sizeof(header_table)/sizeof(struct header_name_func_pair);
94
95 if (!name || name[0]=='\0') {
96 belle_sip_error("Cannot create header without name");
97 return NULL;
98 }
99
100 for(i=0;i<elements;i++) {
101 if ((header_table[i].protocol & protocol) && strcasecmp(header_table[i].name,name)==0) {
102 char* raw = belle_sip_strdup_printf("%s:%s",name,value);
103 ret=header_table[i].func(raw);
104 belle_sip_free(raw);
105 return ret;
106 }
107 }
108 /*not a known header*/
109 return BELLE_SIP_HEADER(belle_sip_header_extension_create(name,value));
110
111 }
belle_sip_header_create(const char * name,const char * value)112 belle_sip_header_t* belle_sip_header_create(const char* name, const char* value) {
113 return belle_header_create(name,value,PROTO_SIP);
114 }
115
belle_http_header_create(const char * name,const char * value)116 belle_sip_header_t* belle_http_header_create (const char* name,const char* value) {
117 return belle_header_create(name,value,PROTO_HTTP);
118 }
119
belle_sip_header_init(belle_sip_header_t * header)120 void belle_sip_header_init(belle_sip_header_t *header) {
121
122 }
123
belle_sip_header_clone(belle_sip_header_t * header,const belle_sip_header_t * orig)124 static void belle_sip_header_clone(belle_sip_header_t *header, const belle_sip_header_t *orig){
125 CLONE_STRING(belle_sip_header,name,header,orig)
126 if (belle_sip_header_get_next(orig)) {
127 belle_sip_header_set_next(header,BELLE_SIP_HEADER(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_get_next(orig))))) ;
128 }
129 }
130
belle_sip_header_destroy(belle_sip_header_t * header)131 static void belle_sip_header_destroy(belle_sip_header_t *header){
132 if (header->name) belle_sip_free(header->name);
133 if (header->unparsed_value) belle_sip_free(header->unparsed_value);
134 if (header->next) belle_sip_object_unref(BELLE_SIP_OBJECT(header->next));
135 }
136
belle_sip_header_set_next(belle_sip_header_t * header,belle_sip_header_t * next)137 void belle_sip_header_set_next(belle_sip_header_t* header,belle_sip_header_t* next) {
138 if (next) belle_sip_object_ref(next);
139 if (header->next) belle_sip_object_unref(header->next);
140 header->next = next;
141 }
142
belle_sip_header_get_next(const belle_sip_header_t * header)143 belle_sip_header_t* belle_sip_header_get_next(const belle_sip_header_t* header) {
144 return header->next;
145 }
146
belle_sip_header_get_unparsed_value(belle_sip_header_t * obj)147 const char *belle_sip_header_get_unparsed_value(belle_sip_header_t* obj){
148 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(obj,belle_sip_header_extension_t)) {
149 return belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(obj));
150 } else {
151 char *tmp=belle_sip_object_to_string(obj);
152 char *ret;
153 char *end;
154 if (obj->unparsed_value){
155 belle_sip_free(obj->unparsed_value);
156 obj->unparsed_value=NULL;
157 }
158 obj->unparsed_value=tmp;
159 ret=tmp;
160 ret+=strlen(obj->name)+1; /* name + semicolon*/
161 for(;*ret==' ';ret++){};/*skip spaces*/
162 return ret;
163 }
164 }
165
belle_sip_header_marshal(belle_sip_header_t * header,char * buff,size_t buff_size,size_t * offset)166 belle_sip_error_code belle_sip_header_marshal(belle_sip_header_t* header, char* buff, size_t buff_size, size_t *offset) {
167 if (header->name) {
168 return belle_sip_snprintf(buff,buff_size,offset,"%s: ",header->name);
169 } else {
170 belle_sip_warning("no header name found");
171 return BELLE_SIP_OK;
172 }
173 }
174
175 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_header_t);
176
177 BELLE_SIP_INSTANCIATE_VPTR(belle_sip_header_t,belle_sip_object_t,belle_sip_header_destroy,belle_sip_header_clone,belle_sip_header_marshal,TRUE);
178
179 BELLE_SIP_PARSE(header)
180
181
182 /************************
183 * header_address
184 ***********************/
185 struct _belle_sip_header_address {
186 belle_sip_parameters_t base;
187 char* displayname;
188 belle_sip_uri_t* uri;
189 belle_generic_uri_t* absolute_uri;
190 };
191
belle_sip_header_address_init(belle_sip_header_address_t * object)192 static void belle_sip_header_address_init(belle_sip_header_address_t* object){
193 belle_sip_parameters_init((belle_sip_parameters_t*)object); /*super*/
194 }
195
belle_sip_header_address_destroy(belle_sip_header_address_t * address)196 static void belle_sip_header_address_destroy(belle_sip_header_address_t* address) {
197 if (address->displayname) belle_sip_free(address->displayname);
198 if (address->uri) belle_sip_object_unref(address->uri);
199 if (address->absolute_uri) belle_sip_object_unref(address->absolute_uri);
200 }
201
belle_sip_header_address_clone(belle_sip_header_address_t * addr,const belle_sip_header_address_t * orig)202 static void belle_sip_header_address_clone(belle_sip_header_address_t *addr, const belle_sip_header_address_t *orig){
203 CLONE_STRING(belle_sip_header_address,displayname,addr,orig)
204 if (belle_sip_header_address_get_uri(orig)) {
205 belle_sip_header_address_set_uri(addr,BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_address_get_uri(orig)))));
206 }
207 if (belle_sip_header_address_get_absolute_uri(orig)) {
208 belle_sip_header_address_set_absolute_uri(addr,BELLE_GENERIC_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_address_get_absolute_uri(orig)))));
209 }
210 }
211
_belle_sip_header_address_marshal(belle_sip_header_address_t * header,char * buff,size_t buff_size,size_t * offset,int force_angle_quote)212 static belle_sip_error_code _belle_sip_header_address_marshal(belle_sip_header_address_t* header, char* buff, size_t buff_size, size_t *offset, int force_angle_quote) {
213 belle_sip_error_code error=BELLE_SIP_OK;
214 /*1 display name*/
215 if (header->displayname) {
216 char* escaped_display_name = belle_sip_display_name_to_backslashed_escaped_string(header->displayname);
217 error=belle_sip_snprintf(buff,buff_size,offset,"\"%s\" ",escaped_display_name);
218 belle_sip_free(escaped_display_name);
219 if (error!=BELLE_SIP_OK) return error;
220 }
221 if (header->uri || header->absolute_uri) {
222 /*cases where < is required*/
223 if (force_angle_quote
224 || header->displayname
225 || header->absolute_uri
226 || belle_sip_parameters_get_parameter_names((belle_sip_parameters_t*)header->uri)
227 || belle_sip_uri_get_header_names(header->uri)
228 || belle_sip_parameters_get_parameter_names(&header->base)) {
229 error=belle_sip_snprintf(buff,buff_size,offset,"%s","<");
230 if (error!=BELLE_SIP_OK) return error;
231 }
232 if (header->uri) {
233 error=belle_sip_uri_marshal(header->uri,buff,buff_size,offset);
234 } else {
235 error=belle_generic_uri_marshal(header->absolute_uri,buff,buff_size,offset);
236 }
237 if (error!=BELLE_SIP_OK) return error;
238 if (force_angle_quote
239 || header->displayname
240 || header->absolute_uri
241 || belle_sip_parameters_get_parameter_names((belle_sip_parameters_t*)header->uri)
242 || belle_sip_uri_get_header_names(header->uri)
243 || belle_sip_parameters_get_parameter_names(&header->base)) {
244 error=belle_sip_snprintf(buff,buff_size,offset,"%s",">");
245 if (error!=BELLE_SIP_OK) return error;
246 }
247 }
248 error=belle_sip_parameters_marshal(&header->base,buff,buff_size,offset);
249 if (error!=BELLE_SIP_OK) return error;
250 return error;
251 }
252
belle_sip_header_address_marshal(belle_sip_header_address_t * header,char * buff,size_t buff_size,size_t * offset)253 belle_sip_error_code belle_sip_header_address_marshal(belle_sip_header_address_t* header, char* buff, size_t buff_size, size_t *offset){
254 return _belle_sip_header_address_marshal(header, buff, buff_size, offset, FALSE);
255 }
256
257 BELLE_SIP_NEW_HEADER(header_address,parameters,"header_address")
258 BELLE_SIP_PARSE(header_address)
259 GET_SET_STRING(belle_sip_header_address,displayname);
260
belle_sip_header_address_set_quoted_displayname(belle_sip_header_address_t * address,const char * value)261 void belle_sip_header_address_set_quoted_displayname(belle_sip_header_address_t* address,const char* value) {
262 if (address->displayname != NULL) belle_sip_free(address->displayname);
263 if (strlen(value)>2)
264 address->displayname=_belle_sip_str_dup_and_unquote_string(value);
265 else
266 address->displayname=NULL;
267 }
268
belle_sip_header_address_get_uri(const belle_sip_header_address_t * address)269 belle_sip_uri_t* belle_sip_header_address_get_uri(const belle_sip_header_address_t* address) {
270 return address->uri;
271 }
272
belle_sip_header_address_set_uri(belle_sip_header_address_t * address,belle_sip_uri_t * uri)273 void belle_sip_header_address_set_uri(belle_sip_header_address_t* address, belle_sip_uri_t* uri) {
274 if (uri) belle_sip_object_ref(uri);
275 if (address->uri){
276 belle_sip_object_unref(address->uri);
277 }
278 address->uri=uri;
279 if (address->absolute_uri && uri) {
280 belle_sip_warning("sip absolute uri [%p] already set for header_address [%p], cleaning it",address->absolute_uri, address);
281 belle_sip_header_address_set_absolute_uri(address,NULL);
282 }
283 }
284
belle_sip_header_address_get_absolute_uri(const belle_sip_header_address_t * address)285 belle_generic_uri_t* belle_sip_header_address_get_absolute_uri(const belle_sip_header_address_t* address) {
286 return address->absolute_uri;
287 }
288
belle_sip_header_address_set_absolute_uri(belle_sip_header_address_t * address,belle_generic_uri_t * absolute_uri)289 void belle_sip_header_address_set_absolute_uri(belle_sip_header_address_t* address, belle_generic_uri_t* absolute_uri) {
290 belle_sip_object_ref(absolute_uri);
291 if (address->absolute_uri){
292 belle_sip_object_unref(address->absolute_uri);
293 }
294 address->absolute_uri=absolute_uri;
295 if (address->uri && absolute_uri) {
296 belle_sip_warning("sip uri [%p] already set for header_address [%p], cleaning it",address->uri, address);
297 belle_sip_header_address_set_uri(address,NULL);
298 }
299 }
300
belle_sip_header_address_create(const char * display,belle_sip_uri_t * uri)301 belle_sip_header_address_t* belle_sip_header_address_create(const char* display, belle_sip_uri_t* uri) {
302 belle_sip_header_address_t* address = belle_sip_header_address_new();
303 belle_sip_header_address_set_displayname(address,display);
304 belle_sip_header_address_set_uri(address,uri);
305 return address;
306 }
307
belle_sip_header_address_create2(const char * display,belle_generic_uri_t * uri)308 belle_sip_header_address_t* belle_sip_header_address_create2(const char* display, belle_generic_uri_t* uri) {
309 belle_sip_header_address_t* address = belle_sip_header_address_new();
310 belle_sip_header_address_set_displayname(address,display);
311 belle_sip_header_address_set_absolute_uri(address,uri);
312 return address;
313 }
314
315 /*fast header address implemenation*/
316 typedef belle_sip_header_address_t belle_sip_fast_header_address_t;
317 #define belle_sip_fast_header_address_parse belle_sip_header_address_fast_parse
318 BELLE_SIP_PARSE(fast_header_address)
319
320
321
322 /******************************
323 * Extension header inherits from header
324 *
325 ******************************/
326 struct _belle_sip_header_allow {
327 belle_sip_header_t header;
328 const char* method;
329 };
belle_sip_header_allow_clone(belle_sip_header_allow_t * allow,const belle_sip_header_allow_t * orig)330 static void belle_sip_header_allow_clone(belle_sip_header_allow_t *allow, const belle_sip_header_allow_t *orig){
331 CLONE_STRING(belle_sip_header_allow,method,allow,orig)
332 }
belle_sip_header_allow_destroy(belle_sip_header_allow_t * allow)333 static void belle_sip_header_allow_destroy(belle_sip_header_allow_t* allow) {
334 if (allow->method) belle_sip_free((void*)allow->method);
335 }
336
337
belle_sip_header_allow_marshal(belle_sip_header_allow_t * allow,char * buff,size_t buff_size,size_t * offset)338 belle_sip_error_code belle_sip_header_allow_marshal(belle_sip_header_allow_t* allow, char* buff, size_t buff_size, size_t *offset) {
339 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(allow), buff, buff_size, offset);
340 if (error!=BELLE_SIP_OK) return error;
341 error=belle_sip_snprintf(buff,buff_size,offset,"%s",allow->method);
342 if (error!=BELLE_SIP_OK) return error;
343 return error;
344 }
345
346 BELLE_SIP_NEW_HEADER(header_allow,header,"Allow")
BELLE_SIP_PARSE(header_allow)347 BELLE_SIP_PARSE(header_allow)
348 belle_sip_header_allow_t* belle_sip_header_allow_create (const char* methods) {
349 belle_sip_header_allow_t* allow = belle_sip_header_allow_new();
350 belle_sip_header_allow_set_method(allow,methods);
351 return allow;
352 }
353 GET_SET_STRING(belle_sip_header_allow,method);
354
355
356
357 /************************
358 * header_contact
359 ***********************/
360 struct _belle_sip_header_contact {
361 belle_sip_header_address_t address;
362 unsigned char wildcard;
363 unsigned char automatic;
364 unsigned char unknown;
365 unsigned char pad[1];
366 };
367
belle_sip_header_contact_destroy(belle_sip_header_contact_t * contact)368 void belle_sip_header_contact_destroy(belle_sip_header_contact_t* contact) {
369 }
370
belle_sip_header_contact_clone(belle_sip_header_contact_t * contact,const belle_sip_header_contact_t * orig)371 void belle_sip_header_contact_clone(belle_sip_header_contact_t *contact, const belle_sip_header_contact_t *orig){
372 contact->wildcard=orig->wildcard;
373 contact->automatic=orig->automatic;
374 }
375
belle_sip_header_contact_marshal(belle_sip_header_contact_t * contact,char * buff,size_t buff_size,size_t * offset)376 belle_sip_error_code belle_sip_header_contact_marshal(belle_sip_header_contact_t* contact, char* buff, size_t buff_size, size_t *offset) {
377 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(contact), buff, buff_size, offset);
378 if (error!=BELLE_SIP_OK) return error;
379 if (contact->wildcard) {
380 error=belle_sip_snprintf(buff,buff_size,offset,"%s","*");
381 } else {
382 error=belle_sip_header_address_marshal(&contact->address, buff, buff_size, offset);
383 }
384 return error;
385 }
386
BELLE_SIP_NEW_HEADER(header_contact,header_address,BELLE_SIP_CONTACT)387 BELLE_SIP_NEW_HEADER(header_contact,header_address,BELLE_SIP_CONTACT)
388 BELLE_SIP_PARSE(header_contact)
389 belle_sip_header_contact_t* belle_sip_header_contact_create (const belle_sip_header_address_t* contact) {
390 belle_sip_header_contact_t* header = belle_sip_header_contact_new();
391 _belle_sip_object_copy(BELLE_SIP_OBJECT(header),BELLE_SIP_OBJECT(contact));
392 belle_sip_header_set_next(BELLE_SIP_HEADER(header),NULL); /*make sure only one header is kept*/
393 belle_sip_header_set_name(BELLE_SIP_HEADER(header),BELLE_SIP_CONTACT); /*restaure header name*/
394 return header;
395 }
396 GET_SET_INT_PARAM_PRIVATE(belle_sip_header_contact,expires,int,_)
397 GET_SET_INT_PARAM_PRIVATE(belle_sip_header_contact,q,float,_);
398 GET_SET_BOOL(belle_sip_header_contact,wildcard,is);
399
400
belle_sip_header_contact_set_expires(belle_sip_header_contact_t * contact,int expires)401 int belle_sip_header_contact_set_expires(belle_sip_header_contact_t* contact, int expires) {
402 if (expires < 0 ) {
403 belle_sip_error("bad expires value [%i] for contact",expires);
404 return -1;
405 }
406 _belle_sip_header_contact_set_expires(contact,expires);
407 return 0;
408 }
belle_sip_header_contact_set_qvalue(belle_sip_header_contact_t * contact,float qValue)409 int belle_sip_header_contact_set_qvalue(belle_sip_header_contact_t* contact, float qValue) {
410 if (qValue != -1 && qValue < 0 && qValue >1) {
411 belle_sip_error("bad q value [%f] for contact",qValue);
412 return -1;
413 }
414 _belle_sip_header_contact_set_q(contact,qValue);
415 return 0;
416 }
belle_sip_header_contact_get_qvalue(const belle_sip_header_contact_t * contact)417 float belle_sip_header_contact_get_qvalue(const belle_sip_header_contact_t* contact) {
418 return belle_sip_header_contact_get_q(contact);
419 }
belle_sip_header_contact_equals(const belle_sip_header_contact_t * a,const belle_sip_header_contact_t * b)420 unsigned int belle_sip_header_contact_equals(const belle_sip_header_contact_t* a,const belle_sip_header_contact_t* b) {
421 if (!a | !b) return 0;
422 return belle_sip_uri_equals(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(a))
423 ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(b)));
424 }
belle_sip_header_contact_not_equals(const belle_sip_header_contact_t * a,const belle_sip_header_contact_t * b)425 unsigned int belle_sip_header_contact_not_equals(const belle_sip_header_contact_t* a,const belle_sip_header_contact_t* b) {
426 return !belle_sip_header_contact_equals(a,b);
427 }
428
belle_sip_header_contact_set_automatic(belle_sip_header_contact_t * a,int enabled)429 void belle_sip_header_contact_set_automatic(belle_sip_header_contact_t *a, int enabled){
430 a->automatic=enabled;
431 }
432
belle_sip_header_contact_get_automatic(const belle_sip_header_contact_t * a)433 int belle_sip_header_contact_get_automatic(const belle_sip_header_contact_t *a){
434 return a->automatic;
435 }
436
belle_sip_header_contact_set_unknown(belle_sip_header_contact_t * a,int value)437 void belle_sip_header_contact_set_unknown(belle_sip_header_contact_t *a, int value){
438 a->unknown=value;
439 }
440
belle_sip_header_contact_is_unknown(const belle_sip_header_contact_t * a)441 int belle_sip_header_contact_is_unknown(const belle_sip_header_contact_t *a){
442 return a->unknown;
443 }
444 /**************************
445 * From header object inherent from header_address
446 ****************************
447 */
448 #define BELLE_SIP_FROM_LIKE_MARSHAL(header,force_angle_quote) \
449 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(header), buff, buff_size, offset);\
450 if (error!=BELLE_SIP_OK) return error;\
451 error=_belle_sip_header_address_marshal(&header->address, buff, buff_size, offset, force_angle_quote); \
452 if (error!=BELLE_SIP_OK) return error;\
453 return error;
454
455 struct _belle_sip_header_from {
456 belle_sip_header_address_t address;
457 };
458
belle_sip_header_from_destroy(belle_sip_header_from_t * from)459 static void belle_sip_header_from_destroy(belle_sip_header_from_t* from) {
460 }
461
belle_sip_header_from_clone(belle_sip_header_from_t * from,const belle_sip_header_from_t * cloned)462 static void belle_sip_header_from_clone(belle_sip_header_from_t* from, const belle_sip_header_from_t* cloned) {
463 }
464
belle_sip_header_from_marshal(belle_sip_header_from_t * from,char * buff,size_t buff_size,size_t * offset)465 belle_sip_error_code belle_sip_header_from_marshal(belle_sip_header_from_t* from, char* buff, size_t buff_size, size_t *offset) {
466 BELLE_SIP_FROM_LIKE_MARSHAL(from,FALSE);
467 }
468
belle_sip_header_from_create2(const char * uri,const char * tag)469 belle_sip_header_from_t* belle_sip_header_from_create2(const char *uri, const char *tag){
470 belle_sip_header_address_t* address = belle_sip_header_address_parse(uri);
471 if (address) {
472 belle_sip_header_from_t* from = belle_sip_header_from_create(address,tag);
473 belle_sip_object_unref(address);
474 return from;
475 } else
476 return NULL;
477 }
belle_sip_header_from_create(const belle_sip_header_address_t * address,const char * tag)478 belle_sip_header_from_t* belle_sip_header_from_create(const belle_sip_header_address_t* address, const char *tag) {
479 belle_sip_header_from_t* header= belle_sip_header_from_new();
480 belle_sip_uri_t* uri;
481 _belle_sip_object_copy((belle_sip_object_t*)header,(belle_sip_object_t*)address);
482 /*clear unwanted uri components*/
483 if ((uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)))) {
484 belle_sip_parameters_t* params=BELLE_SIP_PARAMETERS(uri);
485 belle_sip_parameters_remove_parameter(params,"lr");
486 belle_sip_parameters_remove_parameter(params,"ttl");
487 belle_sip_parameters_remove_parameter(params,"method");
488 belle_sip_parameters_remove_parameter(params,"maddr");
489 belle_sip_parameters_remove_parameter(params,"transport");
490 belle_sip_uri_set_port(uri,0);
491 belle_sip_uri_headers_clean(uri);
492 }
493 belle_sip_header_set_next(BELLE_SIP_HEADER(header),NULL); /*make sure only one header is kept*/
494 belle_sip_header_set_name(BELLE_SIP_HEADER(header),BELLE_SIP_FROM); /*restore header name*/
495 if (tag) belle_sip_header_from_set_tag(header,tag);
496 return header;
497 }
498 BELLE_SIP_NEW_HEADER(header_from,header_address,BELLE_SIP_FROM)
499 BELLE_SIP_PARSE(header_from)
500 GET_SET_STRING_PARAM2(belle_sip_header_from,tag,raw_tag);
501
belle_sip_header_from_set_random_tag(belle_sip_header_from_t * obj)502 void belle_sip_header_from_set_random_tag(belle_sip_header_from_t *obj){
503 char tmp[BELLE_SIP_TAG_LENGTH];
504 belle_sip_header_from_set_raw_tag(obj,belle_sip_random_token(tmp,sizeof(tmp)));
505 }
506
belle_sip_header_from_set_tag(belle_sip_header_from_t * obj,const char * tag)507 void belle_sip_header_from_set_tag(belle_sip_header_from_t *obj, const char *tag){
508 if (tag==BELLE_SIP_RANDOM_TAG) belle_sip_header_from_set_random_tag(obj);
509 else belle_sip_header_from_set_raw_tag(obj,tag);
510 }
511
belle_sip_header_from_get_tag(const belle_sip_header_from_t * obj)512 const char *belle_sip_header_from_get_tag(const belle_sip_header_from_t *obj){
513 return belle_sip_header_from_get_raw_tag(obj);
514 }
515
516 /**************************
517 * To header object inherits from header_address
518 ****************************
519 */
520 struct _belle_sip_header_to {
521 belle_sip_header_address_t address;
522 };
523
belle_sip_header_to_destroy(belle_sip_header_to_t * to)524 static void belle_sip_header_to_destroy(belle_sip_header_to_t* to) {
525 }
526
belle_sip_header_to_clone(belle_sip_header_to_t * contact,const belle_sip_header_to_t * orig)527 void belle_sip_header_to_clone(belle_sip_header_to_t *contact, const belle_sip_header_to_t *orig){
528 }
529
belle_sip_header_to_marshal(belle_sip_header_to_t * to,char * buff,size_t buff_size,size_t * offset)530 belle_sip_error_code belle_sip_header_to_marshal(belle_sip_header_to_t* to, char* buff, size_t buff_size, size_t *offset) {
531 BELLE_SIP_FROM_LIKE_MARSHAL(to,FALSE)
532 }
533
534 BELLE_SIP_NEW_HEADER(header_to,header_address,BELLE_SIP_TO)
535 BELLE_SIP_PARSE(header_to)
536 GET_SET_STRING_PARAM2(belle_sip_header_to,tag,raw_tag);
537
belle_sip_header_to_create2(const char * uri,const char * tag)538 belle_sip_header_to_t* belle_sip_header_to_create2(const char *uri, const char *tag){
539 belle_sip_header_address_t* address = belle_sip_header_address_parse(uri);
540 if (address) {
541 belle_sip_header_to_t* to = belle_sip_header_to_create(address,tag);
542 belle_sip_object_unref(address);
543 return to;
544 } else
545 return NULL;
546 }
belle_sip_header_to_create(const belle_sip_header_address_t * address,const char * tag)547 belle_sip_header_to_t* belle_sip_header_to_create(const belle_sip_header_address_t* address, const char *tag) {
548 belle_sip_header_to_t* header= belle_sip_header_to_new();
549 belle_sip_uri_t* uri;
550 _belle_sip_object_copy((belle_sip_object_t*)header,(belle_sip_object_t*)address);
551 /*clear unwanted uri components*/
552 if ((uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)))) {
553 belle_sip_parameters_t* params=BELLE_SIP_PARAMETERS(uri);
554 belle_sip_parameters_remove_parameter(params,"lr");
555 belle_sip_parameters_remove_parameter(params,"ttl");
556 belle_sip_parameters_remove_parameter(params,"method");
557 belle_sip_parameters_remove_parameter(params,"maddr");
558 belle_sip_parameters_remove_parameter(params,"transport");
559 belle_sip_uri_set_port(uri,0);
560 belle_sip_uri_headers_clean(uri);
561 }
562 belle_sip_header_set_next(BELLE_SIP_HEADER(header),NULL); /*make sure only one header is kept*/
563 belle_sip_header_set_name(BELLE_SIP_HEADER(header),BELLE_SIP_TO); /*restaure header name*/
564 if (tag) belle_sip_header_to_set_tag(header,tag);
565 return header;
566 }
belle_sip_header_to_set_random_tag(belle_sip_header_to_t * obj)567 void belle_sip_header_to_set_random_tag(belle_sip_header_to_t *obj){
568 char tmp[8];
569 /*not less than 32bit */
570 belle_sip_header_to_set_tag(obj,belle_sip_random_token(tmp,sizeof(tmp)));
571 }
572
belle_sip_header_to_set_tag(belle_sip_header_to_t * obj,const char * tag)573 void belle_sip_header_to_set_tag(belle_sip_header_to_t *obj, const char *tag){
574 if (tag==BELLE_SIP_RANDOM_TAG) belle_sip_header_to_set_random_tag(obj);
575 else belle_sip_header_to_set_raw_tag(obj,tag);
576 }
577
belle_sip_header_to_get_tag(const belle_sip_header_to_t * obj)578 const char *belle_sip_header_to_get_tag(const belle_sip_header_to_t *obj){
579 return belle_sip_header_to_get_raw_tag(obj);
580 }
581
582 /**************************
583 * Diversion header object inherits from header_address
584 ****************************
585 */
586 struct _belle_sip_header_diversion {
587 belle_sip_header_address_t address;
588 };
589
belle_sip_header_diversion_destroy(belle_sip_header_diversion_t * diversion)590 static void belle_sip_header_diversion_destroy(belle_sip_header_diversion_t* diversion) {
591 }
592
belle_sip_header_diversion_clone(belle_sip_header_diversion_t * contact,const belle_sip_header_diversion_t * orig)593 void belle_sip_header_diversion_clone(belle_sip_header_diversion_t *contact, const belle_sip_header_diversion_t *orig){
594 }
595
belle_sip_header_diversion_marshal(belle_sip_header_diversion_t * diversion,char * buff,size_t buff_size,size_t * offset)596 belle_sip_error_code belle_sip_header_diversion_marshal(belle_sip_header_diversion_t* diversion, char* buff, size_t buff_size, size_t *offset) {
597 BELLE_SIP_FROM_LIKE_MARSHAL(diversion,FALSE)
598 }
599
600 BELLE_SIP_NEW_HEADER(header_diversion,header_address,BELLE_SIP_DIVERSION)
601 BELLE_SIP_PARSE(header_diversion)
602 GET_SET_STRING_PARAM2(belle_sip_header_diversion,tag,raw_tag);
603
belle_sip_header_diversion_create2(const char * uri,const char * tag)604 belle_sip_header_diversion_t* belle_sip_header_diversion_create2(const char *uri, const char *tag){
605 belle_sip_header_address_t* address = belle_sip_header_address_parse(uri);
606 if (address) {
607 belle_sip_header_diversion_t* diversion = belle_sip_header_diversion_create(address,tag);
608 belle_sip_object_unref(address);
609 return diversion;
610 } else
611 return NULL;
612 }
belle_sip_header_diversion_create(const belle_sip_header_address_t * address,const char * tag)613 belle_sip_header_diversion_t* belle_sip_header_diversion_create(const belle_sip_header_address_t* address, const char *tag) {
614 belle_sip_header_diversion_t* header= belle_sip_header_diversion_new();
615 belle_sip_uri_t* uri;
616 _belle_sip_object_copy((belle_sip_object_t*)header,(belle_sip_object_t*)address);
617 /*clear unwanted uri components*/
618 if ((uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)))) {
619 belle_sip_parameters_t* params=BELLE_SIP_PARAMETERS(uri);
620 belle_sip_parameters_remove_parameter(params,"lr");
621 belle_sip_parameters_remove_parameter(params,"ttl");
622 belle_sip_parameters_remove_parameter(params,"method");
623 belle_sip_parameters_remove_parameter(params,"maddr");
624 belle_sip_parameters_remove_parameter(params,"transport");
625 belle_sip_uri_set_port(uri,0);
626 belle_sip_uri_headers_clean(uri);
627 }
628 belle_sip_header_set_name(BELLE_SIP_HEADER(header),BELLE_SIP_DIVERSION); /*restaure header name*/
629 if (tag) belle_sip_header_diversion_set_tag(header,tag);
630 return header;
631 }
belle_sip_header_diversion_set_random_tag(belle_sip_header_diversion_t * obj)632 void belle_sip_header_diversion_set_random_tag(belle_sip_header_diversion_t *obj){
633 char tmp[8];
634 /*not less than 32bit */
635 belle_sip_header_diversion_set_tag(obj,belle_sip_random_token(tmp,sizeof(tmp)));
636 }
637
belle_sip_header_diversion_set_tag(belle_sip_header_diversion_t * obj,const char * tag)638 void belle_sip_header_diversion_set_tag(belle_sip_header_diversion_t *obj, const char *tag){
639 if (tag==BELLE_SIP_RANDOM_TAG) belle_sip_header_diversion_set_random_tag(obj);
640 else belle_sip_header_diversion_set_raw_tag(obj,tag);
641 }
642
belle_sip_header_diversion_get_tag(const belle_sip_header_diversion_t * obj)643 const char *belle_sip_header_diversion_get_tag(const belle_sip_header_diversion_t *obj){
644 return belle_sip_header_diversion_get_raw_tag(obj);
645 }
646
647
648 /******************************
649 * User-Agent header inherits from header
650 *
651 ******************************/
652 struct _belle_sip_header_user_agent {
653 belle_sip_header_t header;
654 belle_sip_list_t* products;
655 };
656
belle_sip_header_user_agent_destroy(belle_sip_header_user_agent_t * user_agent)657 static void belle_sip_header_user_agent_destroy(belle_sip_header_user_agent_t* user_agent) {
658 belle_sip_header_user_agent_set_products(user_agent,NULL);
659 }
660
belle_sip_header_user_agent_clone(belle_sip_header_user_agent_t * user_agent,const belle_sip_header_user_agent_t * orig)661 static void belle_sip_header_user_agent_clone(belle_sip_header_user_agent_t* user_agent, const belle_sip_header_user_agent_t* orig){
662 belle_sip_list_t* list=orig->products;
663 for(;list!=NULL;list=list->next){
664 belle_sip_header_user_agent_add_product(user_agent,(const char *)list->data);
665 }
666 }
667
belle_sip_header_user_agent_marshal(belle_sip_header_user_agent_t * user_agent,char * buff,size_t buff_size,size_t * offset)668 belle_sip_error_code belle_sip_header_user_agent_marshal(belle_sip_header_user_agent_t* user_agent, char* buff, size_t buff_size, size_t *offset) {
669 belle_sip_error_code error=BELLE_SIP_OK;
670 belle_sip_list_t* list = user_agent->products;
671 error=belle_sip_header_marshal(BELLE_SIP_HEADER(user_agent), buff, buff_size, offset);
672 if (error!=BELLE_SIP_OK) return error;
673 for(;list!=NULL;list=list->next){
674 error=belle_sip_snprintf(buff,buff_size,offset,list==user_agent->products ? "%s" : " %s",(const char *)list->data);
675 if (error!=BELLE_SIP_OK) return error;
676 }
677 return error;
678 }
679
680 BELLE_SIP_NEW_HEADER(header_user_agent,header,"User-Agent")
BELLE_SIP_PARSE(header_user_agent)681 BELLE_SIP_PARSE(header_user_agent)
682 belle_sip_list_t* belle_sip_header_user_agent_get_products(const belle_sip_header_user_agent_t* user_agent) {
683 return user_agent->products;
684 }
belle_sip_header_user_agent_set_products(belle_sip_header_user_agent_t * user_agent,belle_sip_list_t * products)685 void belle_sip_header_user_agent_set_products(belle_sip_header_user_agent_t* user_agent,belle_sip_list_t* products) {
686 belle_sip_list_t* list;
687 if (user_agent->products) {
688 for (list=user_agent->products;list !=NULL; list=list->next) {
689 belle_sip_free((void*)list->data);
690
691 }
692 belle_sip_list_free(user_agent->products);
693 }
694 user_agent->products=products;
695 }
belle_sip_header_user_agent_add_product(belle_sip_header_user_agent_t * user_agent,const char * product)696 void belle_sip_header_user_agent_add_product(belle_sip_header_user_agent_t* user_agent,const char* product) {
697 user_agent->products = belle_sip_list_append(user_agent->products ,belle_sip_strdup(product));
698 }
699
belle_sip_header_user_agent_get_products_as_string(const belle_sip_header_user_agent_t * user_agent,char * value,unsigned int value_size)700 int belle_sip_header_user_agent_get_products_as_string(const belle_sip_header_user_agent_t* user_agent,char* value,unsigned int value_size) {
701 size_t result = 0;
702 belle_sip_error_code error=BELLE_SIP_OK;
703 belle_sip_list_t* list = user_agent->products;
704
705 for(;list!=NULL;list=list->next){
706 error=belle_sip_snprintf(value,value_size,&result,"%s ",(const char *)list->data);
707 if (error!=BELLE_SIP_OK) return -1;
708 }
709 if (result>0) value[result-1]='\0'; /*remove last space */
710
711 return (int)result-1;
712 }
713
714 /**************************
715 * Via header object inherits from parameters
716 ****************************
717 */
718 struct _belle_sip_header_via {
719 belle_sip_parameters_t params_list;
720 char* protocol;
721 char* transport;
722 char* host;
723 int port;
724 char* received;
725 };
726
belle_sip_header_via_destroy(belle_sip_header_via_t * via)727 static void belle_sip_header_via_destroy(belle_sip_header_via_t* via) {
728 if (via->protocol) belle_sip_free(via->protocol);
729 if (via->transport) belle_sip_free(via->transport);
730 if (via->host) belle_sip_free(via->host);
731 DESTROY_STRING(via,received)
732 }
733
belle_sip_header_via_clone(belle_sip_header_via_t * via,const belle_sip_header_via_t * orig)734 static void belle_sip_header_via_clone(belle_sip_header_via_t* via, const belle_sip_header_via_t*orig){
735 CLONE_STRING(belle_sip_header_via,protocol,via,orig)
736 CLONE_STRING(belle_sip_header_via,transport,via,orig)
737 CLONE_STRING(belle_sip_header_via,host,via,orig)
738 CLONE_STRING(belle_sip_header_via,received,via,orig)
739 via->port=orig->port;
740 }
741
belle_sip_header_via_marshal(belle_sip_header_via_t * via,char * buff,size_t buff_size,size_t * offset)742 belle_sip_error_code belle_sip_header_via_marshal(belle_sip_header_via_t* via, char* buff, size_t buff_size, size_t *offset) {
743 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(via), buff, buff_size, offset);
744 if (error!=BELLE_SIP_OK) return error;
745 error=belle_sip_snprintf(buff,buff_size,offset,"%s/%s",via->protocol,via->transport);
746 if (error!=BELLE_SIP_OK) return error;
747
748 if (via->host) {
749 if (strchr(via->host,':')) { /*ipv6*/
750 error=belle_sip_snprintf(buff,buff_size,offset," [%s]",via->host);
751 } else {
752 error=belle_sip_snprintf(buff,buff_size,offset," %s",via->host);
753 }
754 if (error!=BELLE_SIP_OK) return error;
755 } else {
756 belle_sip_warning("no host found in this via");
757 }
758
759 if (via->port > 0) {
760 error=belle_sip_snprintf(buff,buff_size,offset,":%i",via->port);
761 if (error!=BELLE_SIP_OK) return error;
762 }
763 if (via->received) {
764 error=belle_sip_snprintf(buff,buff_size,offset,";received=%s",via->received);
765 if (error!=BELLE_SIP_OK) return error;
766 }
767
768 error=belle_sip_parameters_marshal(&via->params_list, buff, buff_size, offset);
769 if (error!=BELLE_SIP_OK) return error;
770
771 return error;
772 }
773
belle_sip_header_via_create(const char * host,int port,const char * transport,const char * branch)774 belle_sip_header_via_t* belle_sip_header_via_create(const char *host, int port, const char *transport, const char *branch){
775 belle_sip_header_via_t *via=belle_sip_header_via_new();
776 via->host=belle_sip_strdup(host);
777 via->port=port;
778 via->transport=belle_sip_strdup(transport);
779 via->protocol=belle_sip_strdup("SIP/2.0");
780 belle_sip_header_via_set_branch(via,branch);
781 return via;
782 }
783
784 BELLE_SIP_NEW_HEADER(header_via,parameters,BELLE_SIP_VIA)
785 BELLE_SIP_PARSE(header_via)
786 GET_SET_STRING(belle_sip_header_via,protocol);
787 GET_SET_STRING(belle_sip_header_via,transport);
788 GET_SET_STRING(belle_sip_header_via,host);
789 GET_SET_STRING(belle_sip_header_via,received);
790 GET_SET_INT_PRIVATE(belle_sip_header_via,port,int,_);
791
792 GET_SET_STRING_PARAM(belle_sip_header_via,branch);
793 GET_SET_STRING_PARAM(belle_sip_header_via,maddr);
794
795
GET_SET_INT_PARAM_PRIVATE(belle_sip_header_via,rport,int,_)796 GET_SET_INT_PARAM_PRIVATE(belle_sip_header_via,rport,int,_)
797 GET_SET_INT_PARAM_PRIVATE(belle_sip_header_via,ttl,int,_)
798
799 int belle_sip_header_via_set_rport (belle_sip_header_via_t* obj,int value) {
800 if (value == -1) {
801 belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(obj),"rport",NULL);
802 return 0;
803 }
804 if (value>0 && value<65536) {
805 _belle_sip_header_via_set_rport(obj,value);
806 return 0;
807 } else {
808 belle_sip_error("bad rport value [%i] for via",value);
809 return -1;
810 }
811 }
belle_sip_header_via_set_ttl(belle_sip_header_via_t * obj,int value)812 int belle_sip_header_via_set_ttl (belle_sip_header_via_t* obj,int value) {
813 if (value ==-1 || (value>0 && value<=255)) {
814 _belle_sip_header_via_set_ttl(obj,value);
815 return 0;
816 } else {
817 belle_sip_error("bad ttl value [%i] for via",value);
818 return -1;
819 }
820 }
821
belle_sip_header_via_set_port(belle_sip_header_via_t * obj,int value)822 int belle_sip_header_via_set_port (belle_sip_header_via_t* obj,int value) {
823 if (value ==-1 || (value>0 && value<65536)) {
824 _belle_sip_header_via_set_port(obj,value);
825 return 0;
826 } else {
827 belle_sip_error("bad port value [%i] for via",value);
828 return -1;
829 }
830 }
831
belle_sip_header_via_get_listening_port(const belle_sip_header_via_t * via)832 int belle_sip_header_via_get_listening_port(const belle_sip_header_via_t *via){
833 int ret=belle_sip_header_via_get_port(via);
834 if (ret==0) ret=belle_sip_listening_point_get_well_known_port(via->transport);
835 return ret;
836 }
837
belle_sip_header_via_get_transport_lowercase(const belle_sip_header_via_t * via)838 const char* belle_sip_header_via_get_transport_lowercase(const belle_sip_header_via_t* via) {
839 if (strcasecmp("udp",via->transport)==0) return "udp";
840 else if (strcasecmp("tcp",via->transport)==0) return "tcp";
841 else if (strcasecmp("tls",via->transport)==0) return "tls";
842 else if (strcasecmp("dtls",via->transport)==0) return "dtls";
843 else {
844 belle_sip_warning("Cannot convert [%s] to lower case",via->transport);
845 return via->transport;
846 }
847 }
848 /**************************
849 * call_id header object inherits from object
850 ****************************
851 */
852 struct _belle_sip_header_call_id {
853 belle_sip_header_t header;
854 const char* call_id;
855 };
856
belle_sip_header_call_id_destroy(belle_sip_header_call_id_t * call_id)857 static void belle_sip_header_call_id_destroy(belle_sip_header_call_id_t* call_id) {
858 if (call_id->call_id) belle_sip_free((void*)call_id->call_id);
859 }
860
belle_sip_header_call_id_clone(belle_sip_header_call_id_t * call_id,const belle_sip_header_call_id_t * orig)861 static void belle_sip_header_call_id_clone(belle_sip_header_call_id_t* call_id,const belle_sip_header_call_id_t *orig){
862 CLONE_STRING(belle_sip_header_call_id,call_id,call_id,orig);
863 }
864
belle_sip_header_call_id_marshal(belle_sip_header_call_id_t * call_id,char * buff,size_t buff_size,size_t * offset)865 belle_sip_error_code belle_sip_header_call_id_marshal(belle_sip_header_call_id_t* call_id, char* buff, size_t buff_size, size_t *offset) {
866 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(call_id), buff, buff_size, offset);
867 if (error!=BELLE_SIP_OK) return error;
868 error=belle_sip_snprintf(buff,buff_size,offset,"%s",call_id->call_id);
869 if (error!=BELLE_SIP_OK) return error;
870 return error;
871 }
872
belle_sip_header_call_id_equals(const belle_sip_header_call_id_t * a,const belle_sip_header_call_id_t * b)873 unsigned int belle_sip_header_call_id_equals(const belle_sip_header_call_id_t* a,const belle_sip_header_call_id_t* b) {
874 return strcasecmp(a->call_id,b->call_id) == 0;
875 }
876 BELLE_SIP_NEW_HEADER(header_call_id,header,BELLE_SIP_CALL_ID)
877 BELLE_SIP_PARSE(header_call_id)
878 GET_SET_STRING(belle_sip_header_call_id,call_id);
879 /**************************
880 * cseq header object inherent from object
881 ****************************
882 */
883 struct _belle_sip_header_cseq {
884 belle_sip_header_t header;
885 char* method;
886 unsigned int seq_number;
887 };
888
belle_sip_header_cseq_destroy(belle_sip_header_cseq_t * cseq)889 static void belle_sip_header_cseq_destroy(belle_sip_header_cseq_t* cseq) {
890 if (cseq->method) belle_sip_free(cseq->method);
891 }
892
belle_sip_header_cseq_clone(belle_sip_header_cseq_t * cseq,const belle_sip_header_cseq_t * orig)893 static void belle_sip_header_cseq_clone(belle_sip_header_cseq_t* cseq, const belle_sip_header_cseq_t *orig) {
894 CLONE_STRING(belle_sip_header_cseq,method,cseq,orig)
895 cseq->seq_number=orig->seq_number;
896 }
897
belle_sip_header_cseq_marshal(belle_sip_header_cseq_t * cseq,char * buff,size_t buff_size,size_t * offset)898 belle_sip_error_code belle_sip_header_cseq_marshal(belle_sip_header_cseq_t* cseq, char* buff, size_t buff_size, size_t *offset) {
899 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(cseq), buff,buff_size, offset);
900 if (error!=BELLE_SIP_OK) return error;
901 error=belle_sip_snprintf(buff,buff_size,offset,"%i %s",cseq->seq_number,cseq->method);
902 if (error!=BELLE_SIP_OK) return error;
903 return error;
904 }
905
belle_sip_header_cseq_create(unsigned int number,const char * method)906 belle_sip_header_cseq_t * belle_sip_header_cseq_create(unsigned int number, const char *method){
907 belle_sip_header_cseq_t *cseq=belle_sip_header_cseq_new();
908 belle_sip_header_cseq_set_method(cseq,method);
909 cseq->seq_number=number;
910 return cseq;
911 }
912 BELLE_SIP_NEW_HEADER(header_cseq,header,BELLE_SIP_CSEQ)
913 BELLE_SIP_PARSE(header_cseq)
914 GET_SET_STRING(belle_sip_header_cseq,method);
915 GET_SET_INT(belle_sip_header_cseq,seq_number,unsigned int)
916 /**************************
917 * content type header object inherent from parameters
918 ****************************
919 */
920 struct _belle_sip_header_content_type {
921 belle_sip_parameters_t params_list;
922 const char* type;
923 const char* subtype;
924 };
925
belle_sip_header_content_type_destroy(belle_sip_header_content_type_t * content_type)926 static void belle_sip_header_content_type_destroy(belle_sip_header_content_type_t* content_type) {
927 if (content_type->type) belle_sip_free((void*)content_type->type);
928 if (content_type->subtype) belle_sip_free((void*)content_type->subtype);
929 }
930
belle_sip_header_content_type_clone(belle_sip_header_content_type_t * content_type,const belle_sip_header_content_type_t * orig)931 static void belle_sip_header_content_type_clone(belle_sip_header_content_type_t* content_type, const belle_sip_header_content_type_t* orig){
932 CLONE_STRING(belle_sip_header_content_type,type,content_type,orig);
933 CLONE_STRING(belle_sip_header_content_type,subtype,content_type,orig);
934 }
935
belle_sip_header_content_type_marshal(belle_sip_header_content_type_t * content_type,char * buff,size_t buff_size,size_t * offset)936 belle_sip_error_code belle_sip_header_content_type_marshal(belle_sip_header_content_type_t* content_type, char* buff, size_t buff_size, size_t *offset) {
937 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(content_type), buff, buff_size, offset);
938 if (error!=BELLE_SIP_OK) return error;
939 error=belle_sip_snprintf(buff,buff_size,offset,"%s/%s",content_type->type, content_type->subtype);
940 if (error!=BELLE_SIP_OK) return error;
941 error=belle_sip_parameters_marshal(&content_type->params_list, buff, buff_size, offset);
942 if (error!=BELLE_SIP_OK) return error;
943 return error;
944 }
945
BELLE_SIP_NEW_HEADER(header_content_type,parameters,BELLE_SIP_CONTENT_TYPE)946 BELLE_SIP_NEW_HEADER(header_content_type,parameters,BELLE_SIP_CONTENT_TYPE)
947 BELLE_SIP_PARSE(header_content_type)
948 belle_sip_header_content_type_t* belle_sip_header_content_type_create (const char* type,const char* sub_type) {
949 belle_sip_header_content_type_t* header = belle_sip_header_content_type_new();
950 belle_sip_header_content_type_set_type(header,type);
951 belle_sip_header_content_type_set_subtype(header,sub_type);
952 return header;
953 }
954 GET_SET_STRING(belle_sip_header_content_type,type);
955 GET_SET_STRING(belle_sip_header_content_type,subtype);
956 /**************************
957 * Route header object inherent from header_address
958 ****************************
959 */
960 struct _belle_sip_header_route {
961 belle_sip_header_address_t address;
962 };
963
belle_sip_header_route_destroy(belle_sip_header_route_t * route)964 static void belle_sip_header_route_destroy(belle_sip_header_route_t* route) {
965 }
966
belle_sip_header_route_clone(belle_sip_header_route_t * route,const belle_sip_header_route_t * orig)967 static void belle_sip_header_route_clone(belle_sip_header_route_t* route, const belle_sip_header_route_t* orig) {
968 }
969
belle_sip_header_route_marshal(belle_sip_header_route_t * route,char * buff,size_t buff_size,size_t * offset)970 belle_sip_error_code belle_sip_header_route_marshal(belle_sip_header_route_t* route, char* buff, size_t buff_size, size_t *offset) {
971 BELLE_SIP_FROM_LIKE_MARSHAL(route,TRUE)
972 }
973
BELLE_SIP_NEW_HEADER(header_route,header_address,BELLE_SIP_ROUTE)974 BELLE_SIP_NEW_HEADER(header_route,header_address,BELLE_SIP_ROUTE)
975 BELLE_SIP_PARSE(header_route)
976 belle_sip_header_route_t* belle_sip_header_route_create(const belle_sip_header_address_t* route) {
977 belle_sip_header_route_t* header= belle_sip_header_route_new();
978 _belle_sip_object_copy((belle_sip_object_t*)header,(belle_sip_object_t*)route);
979 belle_sip_header_set_next(BELLE_SIP_HEADER(header),NULL); /*make sure only one header is kept*/
980 belle_sip_header_set_name(BELLE_SIP_HEADER(header),BELLE_SIP_ROUTE); /*restore header name*/
981 return header;
982 }
983 /**************************
984 * Record route header object inherent from header_address
985 ****************************
986 */
987 struct _belle_sip_header_record_route {
988 belle_sip_header_address_t address;
989 unsigned char auto_outgoing;
990 unsigned char pad[3];
991 };
992
belle_sip_header_record_route_destroy(belle_sip_header_record_route_t * record_route)993 static void belle_sip_header_record_route_destroy(belle_sip_header_record_route_t* record_route) {
994 }
995
belle_sip_header_record_route_clone(belle_sip_header_record_route_t * record_route,const belle_sip_header_record_route_t * orig)996 static void belle_sip_header_record_route_clone(belle_sip_header_record_route_t* record_route,
997 const belle_sip_header_record_route_t* orig ) {
998 }
999
belle_sip_header_record_route_marshal(belle_sip_header_record_route_t * record_route,char * buff,size_t buff_size,size_t * offset)1000 belle_sip_error_code belle_sip_header_record_route_marshal(belle_sip_header_record_route_t* record_route, char* buff, size_t buff_size, size_t *offset) {
1001 BELLE_SIP_FROM_LIKE_MARSHAL(record_route,TRUE)
1002 }
1003
belle_sip_header_record_route_new_auto_outgoing()1004 belle_sip_header_record_route_t *belle_sip_header_record_route_new_auto_outgoing() {
1005 belle_sip_header_record_route_t *rr = belle_sip_header_record_route_new();
1006 rr->auto_outgoing = TRUE;
1007 return rr;
1008 }
1009
belle_sip_header_record_route_get_auto_outgoing(const belle_sip_header_record_route_t * a)1010 unsigned char belle_sip_header_record_route_get_auto_outgoing(const belle_sip_header_record_route_t *a) {
1011 return a->auto_outgoing;
1012 }
1013
1014 BELLE_SIP_NEW_HEADER(header_record_route,header_address,BELLE_SIP_RECORD_ROUTE)
1015 BELLE_SIP_PARSE(header_record_route)
1016 /**************************
1017 * Service route header object inherent from header_address
1018 ****************************
1019 */
1020 struct _belle_sip_header_service_route {
1021 belle_sip_header_address_t address;
1022 };
1023
belle_sip_header_service_route_destroy(belle_sip_header_service_route_t * service_route)1024 static void belle_sip_header_service_route_destroy(belle_sip_header_service_route_t* service_route) {
1025 }
1026
belle_sip_header_service_route_clone(belle_sip_header_service_route_t * service_route,const belle_sip_header_service_route_t * orig)1027 static void belle_sip_header_service_route_clone(belle_sip_header_service_route_t* service_route,
1028 const belle_sip_header_service_route_t* orig ) {
1029 }
1030
belle_sip_header_service_route_marshal(belle_sip_header_service_route_t * service_route,char * buff,size_t buff_size,size_t * offset)1031 belle_sip_error_code belle_sip_header_service_route_marshal(belle_sip_header_service_route_t* service_route, char* buff, size_t buff_size, size_t *offset) {
1032 BELLE_SIP_FROM_LIKE_MARSHAL(service_route,TRUE)
1033 }
1034
1035 BELLE_SIP_NEW_HEADER(header_service_route,header_address,BELLE_SIP_SERVICE_ROUTE)
1036 BELLE_SIP_PARSE(header_service_route)
1037 /**************************
1038 * content length header object inherent from object
1039 ****************************
1040 */
1041 struct _belle_sip_header_content_length {
1042 belle_sip_header_t header;
1043 size_t content_length;
1044 };
1045
belle_sip_header_content_length_destroy(belle_sip_header_content_length_t * content_length)1046 static void belle_sip_header_content_length_destroy(belle_sip_header_content_length_t* content_length) {
1047 }
1048
belle_sip_header_content_length_clone(belle_sip_header_content_length_t * content_length,const belle_sip_header_content_length_t * orig)1049 static void belle_sip_header_content_length_clone(belle_sip_header_content_length_t* content_length,
1050 const belle_sip_header_content_length_t *orig ) {
1051 content_length->content_length=orig->content_length;
1052 }
1053
belle_sip_header_content_length_marshal(belle_sip_header_content_length_t * content_length,char * buff,size_t buff_size,size_t * offset)1054 belle_sip_error_code belle_sip_header_content_length_marshal(belle_sip_header_content_length_t* content_length, char* buff, size_t buff_size, size_t *offset) {
1055 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(content_length), buff, buff_size, offset);
1056 if (error!=BELLE_SIP_OK) return error;
1057 error=belle_sip_snprintf(buff,buff_size,offset,FORMAT_SIZE_T,content_length->content_length);
1058 if (error!=BELLE_SIP_OK) return error;
1059 return error;
1060 }
1061
BELLE_SIP_NEW_HEADER(header_content_length,header,BELLE_SIP_CONTENT_LENGTH)1062 BELLE_SIP_NEW_HEADER(header_content_length,header,BELLE_SIP_CONTENT_LENGTH)
1063 BELLE_SIP_PARSE(header_content_length)
1064 GET_SET_INT(belle_sip_header_content_length,content_length,size_t)
1065 belle_sip_header_content_length_t* belle_sip_header_content_length_create (size_t content_length) {
1066 belle_sip_header_content_length_t* obj;
1067 obj = belle_sip_header_content_length_new();
1068 belle_sip_header_content_length_set_content_length(obj,content_length);
1069 return obj;
1070 }
1071 /**************************
1072 * Expires header object inherent from header
1073 ****************************
1074 */
1075 struct _belle_sip_header_expires {
1076 belle_sip_header_t header;
1077 int expires;
1078 };
1079
belle_sip_header_expires_destroy(belle_sip_header_expires_t * expires)1080 static void belle_sip_header_expires_destroy(belle_sip_header_expires_t* expires) {
1081 }
1082
belle_sip_header_expires_clone(belle_sip_header_expires_t * expires,const belle_sip_header_expires_t * orig)1083 static void belle_sip_header_expires_clone(belle_sip_header_expires_t* expires,
1084 const belle_sip_header_expires_t *orig ) {
1085 expires->expires=orig->expires;
1086 }
1087
belle_sip_header_expires_marshal(belle_sip_header_expires_t * expires,char * buff,size_t buff_size,size_t * offset)1088 belle_sip_error_code belle_sip_header_expires_marshal(belle_sip_header_expires_t* expires, char* buff, size_t buff_size, size_t *offset) {
1089 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(expires), buff, buff_size, offset);
1090 if (error!=BELLE_SIP_OK) return error;
1091 error=belle_sip_snprintf(buff,buff_size,offset,"%i",expires->expires);
1092 if (error!=BELLE_SIP_OK) return error;
1093 return error;
1094 }
1095
BELLE_SIP_NEW_HEADER(header_expires,header,BELLE_SIP_EXPIRES)1096 BELLE_SIP_NEW_HEADER(header_expires,header,BELLE_SIP_EXPIRES)
1097 BELLE_SIP_PARSE(header_expires)
1098 GET_SET_INT(belle_sip_header_expires,expires,int)
1099 belle_sip_header_expires_t* belle_sip_header_expires_create(int expires) {
1100 belle_sip_header_expires_t* obj = belle_sip_header_expires_new();
1101 belle_sip_header_expires_set_expires(obj,expires);
1102 return obj;
1103 }
1104 /******************************
1105 * Extension header hinerite from header
1106 *
1107 ******************************/
1108 struct _belle_sip_header_extension {
1109 belle_sip_header_t header;
1110 const char* value;
1111 };
1112
belle_sip_header_extension_destroy(belle_sip_header_extension_t * extension)1113 static void belle_sip_header_extension_destroy(belle_sip_header_extension_t* extension) {
1114 if (extension->value) belle_sip_free((void*)extension->value);
1115 }
1116
belle_sip_header_extension_clone(belle_sip_header_extension_t * extension,const belle_sip_header_extension_t * orig)1117 static void belle_sip_header_extension_clone(belle_sip_header_extension_t* extension, const belle_sip_header_extension_t* orig){
1118 CLONE_STRING(belle_sip_header_extension,value,extension,orig)
1119 }
1120
belle_sip_header_extension_marshal(belle_sip_header_extension_t * extension,char * buff,size_t buff_size,size_t * offset)1121 belle_sip_error_code belle_sip_header_extension_marshal(belle_sip_header_extension_t* extension, char* buff, size_t buff_size, size_t *offset) {
1122 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(extension), buff, buff_size, offset);
1123 if (error!=BELLE_SIP_OK) return error;
1124 if (extension->value) error=belle_sip_snprintf(buff,buff_size,offset,"%s",extension->value);
1125 if (error!=BELLE_SIP_OK) return error;
1126 return error;
1127 }
1128
BELLE_SIP_NEW_HEADER(header_extension,header,NULL)1129 BELLE_SIP_NEW_HEADER(header_extension,header,NULL)
1130
1131 belle_sip_header_extension_t* belle_sip_header_extension_create (const char* name,const char* value) {
1132 belle_sip_header_extension_t* ext = belle_sip_header_extension_new();
1133 belle_sip_header_set_name(BELLE_SIP_HEADER(ext),name);
1134 belle_sip_header_extension_set_value(ext,value);
1135 return ext;
1136
1137 }
1138
1139 GET_SET_STRING(belle_sip_header_extension,value);
1140 /**************************
1141 *Authorization header object inherent from parameters
1142 ****************************
1143 */
1144 #define AUTH_BASE \
1145 belle_sip_parameters_t params_list; \
1146 const char* scheme; \
1147 const char* realm; \
1148 const char* nonce; \
1149 const char* algorithm; \
1150 const char* opaque;
1151
1152
1153
1154
1155 #define AUTH_BASE_DESTROY(obj) \
1156 if (obj->scheme) belle_sip_free((void*)obj->scheme);\
1157 if (obj->realm) belle_sip_free((void*)obj->realm);\
1158 if (obj->nonce) belle_sip_free((void*)obj->nonce);\
1159 if (obj->algorithm) belle_sip_free((void*)obj->algorithm);\
1160 if (obj->opaque) belle_sip_free((void*)obj->opaque);\
1161
1162 /*if (obj->params_list) FIXME free list*/
1163
1164 #define AUTH_BASE_CLONE(object_type,dest,src) \
1165 CLONE_STRING(object_type,scheme,dest,src)\
1166 CLONE_STRING(object_type,realm,dest,src)\
1167 CLONE_STRING(object_type,nonce,dest,src)\
1168 CLONE_STRING(object_type,algorithm,dest,src)\
1169 CLONE_STRING(object_type,opaque,dest,src) \
1170
1171
1172 #define AUTH_BASE_MARSHAL(header) \
1173 char* border=" ";\
1174 const belle_sip_list_t* list;\
1175 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(header), buff, buff_size, offset);\
1176 if (error!=BELLE_SIP_OK) return error;\
1177 list=belle_sip_parameters_get_parameters(&header->params_list);\
1178 if (header->scheme) { \
1179 error=belle_sip_snprintf(buff,buff_size,offset," %s",header->scheme);\
1180 if (error!=BELLE_SIP_OK) return error;\
1181 } else { \
1182 belle_sip_error("missing mandatory scheme"); \
1183 } \
1184 for(;list!=NULL;list=list->next){\
1185 belle_sip_param_pair_t* container = list->data;\
1186 error=belle_sip_snprintf(buff,buff_size,offset,"%s%s=%s",border, container->name,container->value);\
1187 if (error!=BELLE_SIP_OK) return error;\
1188 border=", ";\
1189 }\
1190 if (header->realm) {\
1191 error=belle_sip_snprintf(buff,buff_size,offset,"%srealm=\"%s\"",border,header->realm);\
1192 if (error!=BELLE_SIP_OK) return error;\
1193 border=", ";\
1194 }\
1195 if (header->nonce) {\
1196 error=belle_sip_snprintf(buff,buff_size,offset,"%snonce=\"%s\"",border,header->nonce);\
1197 if (error!=BELLE_SIP_OK) return error;\
1198 border=", ";\
1199 }\
1200 if (header->algorithm) {\
1201 const char* format;\
1202 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(header,belle_http_header_authorization_t)) {\
1203 format="%salgorithm=\"%s\"";\
1204 } else {\
1205 format="%salgorithm=%s";\
1206 }\
1207 error=belle_sip_snprintf(buff,buff_size,offset,format,border,header->algorithm);\
1208 if (error!=BELLE_SIP_OK) return error;\
1209 border=", ";\
1210 }\
1211 if (header->opaque) {\
1212 error=belle_sip_snprintf(buff,buff_size,offset,"%sopaque=\"%s\"",border,header->opaque);\
1213 if (error!=BELLE_SIP_OK) return error;\
1214 border=", ";\
1215 }
1216
1217 struct _belle_sip_header_authorization {
1218 AUTH_BASE
1219 const char* username;
1220 belle_sip_uri_t* uri;
1221 const char* response;
1222 const char* cnonce;
1223 int nonce_count;
1224 const char* qop;
1225 };
1226
1227
belle_sip_header_authorization_destroy(belle_sip_header_authorization_t * authorization)1228 static void belle_sip_header_authorization_destroy(belle_sip_header_authorization_t* authorization) {
1229 if (authorization->username) belle_sip_free((void*)authorization->username);
1230 if (authorization->uri) {
1231 belle_sip_object_unref(authorization->uri);
1232 }
1233 if (authorization->cnonce) belle_sip_free((void*)authorization->cnonce);
1234 AUTH_BASE_DESTROY(authorization)
1235 DESTROY_STRING(authorization,response);
1236 DESTROY_STRING(authorization,qop);
1237 }
1238
belle_sip_header_authorization_clone(belle_sip_header_authorization_t * authorization,const belle_sip_header_authorization_t * orig)1239 static void belle_sip_header_authorization_clone(belle_sip_header_authorization_t* authorization,
1240 const belle_sip_header_authorization_t *orig ) {
1241 AUTH_BASE_CLONE(belle_sip_header_authorization,authorization,orig)
1242 CLONE_STRING(belle_sip_header_authorization,username,authorization,orig)
1243 if (belle_sip_header_authorization_get_uri(orig)) {
1244 belle_sip_header_authorization_set_uri(authorization,BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_authorization_get_uri(orig)))));
1245 }
1246 CLONE_STRING(belle_sip_header_authorization,response,authorization,orig)
1247 CLONE_STRING(belle_sip_header_authorization,cnonce,authorization,orig)
1248 authorization->nonce_count=orig->nonce_count;
1249 CLONE_STRING(belle_sip_header_authorization,qop,authorization,orig)
1250 }
belle_sip_header_authorization_init(belle_sip_header_authorization_t * authorization)1251 static void belle_sip_header_authorization_init(belle_sip_header_authorization_t* authorization) {
1252 }
1253
belle_sip_header_authorization_get_uri(const belle_sip_header_authorization_t * authorization)1254 belle_sip_uri_t* belle_sip_header_authorization_get_uri(const belle_sip_header_authorization_t* authorization) {
1255 return authorization->uri;
1256 }
1257
belle_sip_header_authorization_set_uri(belle_sip_header_authorization_t * authorization,belle_sip_uri_t * uri)1258 void belle_sip_header_authorization_set_uri(belle_sip_header_authorization_t* authorization, belle_sip_uri_t* uri) {
1259 if (uri) belle_sip_object_ref(uri);
1260 if (authorization->uri) {
1261 belle_sip_object_unref(BELLE_SIP_OBJECT(authorization->uri));
1262 }
1263 authorization->uri=uri;
1264 }
1265
belle_sip_header_authorization_marshal(belle_sip_header_authorization_t * authorization,char * buff,size_t buff_size,size_t * offset)1266 belle_sip_error_code belle_sip_header_authorization_marshal(belle_sip_header_authorization_t* authorization, char* buff, size_t buff_size, size_t *offset) {
1267 char nonce_count[10];
1268 AUTH_BASE_MARSHAL(authorization)
1269 if (authorization->username) {
1270 error=belle_sip_snprintf(buff,buff_size,offset,"%susername=\"%s\"",border,authorization->username);
1271 if (error!=BELLE_SIP_OK) return error;
1272 border=", ";
1273 }
1274 if (authorization->uri) {
1275 error=belle_sip_snprintf(buff,buff_size,offset,"%s uri=\"",border);
1276 if (error!=BELLE_SIP_OK) return error;
1277 border=", ";
1278 error=belle_sip_uri_marshal(authorization->uri,buff,buff_size,offset);
1279 if (error!=BELLE_SIP_OK) return error;
1280 error=belle_sip_snprintf(buff,buff_size,offset,"%s","\"");
1281 if (error!=BELLE_SIP_OK) return error;
1282 }
1283
1284 if (authorization->response) {
1285 error=belle_sip_snprintf(buff,buff_size,offset,"%sresponse=\"%s\"",border,authorization->response);
1286 if (error!=BELLE_SIP_OK) return error;
1287 border=", ";
1288 }
1289 if (authorization->cnonce) {
1290 error=belle_sip_snprintf(buff,buff_size,offset,"%scnonce=\"%s\"",border,authorization->cnonce);
1291 if (error!=BELLE_SIP_OK) return error;
1292 border=", ";
1293 }
1294 if (authorization->nonce_count>0) {
1295 belle_sip_header_authorization_get_nonce_count_as_string(authorization,nonce_count);
1296 error=belle_sip_snprintf(buff,buff_size,offset,"%snc=%s",border,nonce_count);
1297 if (error!=BELLE_SIP_OK) return error;
1298 border=", ";
1299 }
1300 if (authorization->qop) {
1301 const char* format;
1302 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(authorization,belle_http_header_authorization_t)) {
1303 format="%sqop=\"%s\"";
1304 } else {
1305 format="%sqop=%s";
1306 }
1307 error=belle_sip_snprintf(buff,buff_size,offset,format,border,authorization->qop);
1308 if (error!=BELLE_SIP_OK) return error;
1309 }
1310 return error;
1311 }
1312
1313 BELLE_SIP_NEW_HEADER(header_authorization,parameters,BELLE_SIP_AUTHORIZATION)
1314 BELLE_SIP_PARSE(header_authorization)
1315 GET_SET_STRING(belle_sip_header_authorization,scheme);
1316 GET_SET_STRING(belle_sip_header_authorization,username);
1317 GET_SET_STRING(belle_sip_header_authorization,realm);
1318 GET_SET_STRING(belle_sip_header_authorization,nonce);
1319 GET_SET_STRING(belle_sip_header_authorization,response);
1320 GET_SET_STRING(belle_sip_header_authorization,algorithm);
1321 GET_SET_STRING(belle_sip_header_authorization,cnonce);
1322 GET_SET_STRING(belle_sip_header_authorization,opaque);
1323 GET_SET_STRING(belle_sip_header_authorization,qop);
GET_SET_INT(belle_sip_header_authorization,nonce_count,int)1324 GET_SET_INT(belle_sip_header_authorization,nonce_count,int)
1325
1326 int belle_sip_header_authorization_get_nonce_count_as_string(const belle_sip_header_authorization_t* authorization,char nounce_count[9]) {
1327 nounce_count[0]='\0';
1328 if (authorization->nonce_count>0) {
1329 snprintf(nounce_count,9,"%08x",authorization->nonce_count);
1330 return 0;
1331 } else {
1332 return -1;
1333 }
1334 }
1335
1336 /**************************
1337 *Proxy-Authorization header object inherent from parameters
1338 ****************************
1339 */
1340 struct _belle_sip_header_proxy_authorization {
1341 belle_sip_header_authorization_t authorization;
1342 };
1343
1344
belle_sip_header_proxy_authorization_destroy(belle_sip_header_proxy_authorization_t * proxy_authorization)1345 static void belle_sip_header_proxy_authorization_destroy(belle_sip_header_proxy_authorization_t* proxy_authorization) {
1346
1347 }
1348
belle_sip_header_proxy_authorization_clone(belle_sip_header_proxy_authorization_t * proxy_authorization,const belle_sip_header_proxy_authorization_t * orig)1349 static void belle_sip_header_proxy_authorization_clone(belle_sip_header_proxy_authorization_t* proxy_authorization,
1350 const belle_sip_header_proxy_authorization_t *orig ) {
1351 }
1352
belle_sip_header_proxy_authorization_marshal(belle_sip_header_proxy_authorization_t * proxy_authorization,char * buff,size_t buff_size,size_t * offset)1353 belle_sip_error_code belle_sip_header_proxy_authorization_marshal(belle_sip_header_proxy_authorization_t* proxy_authorization, char* buff, size_t buff_size, size_t *offset) {
1354 return belle_sip_header_authorization_marshal(&proxy_authorization->authorization,buff,buff_size,offset);
1355 }
1356
1357 BELLE_SIP_NEW_HEADER(header_proxy_authorization,header_authorization,BELLE_SIP_PROXY_AUTHORIZATION)
1358 BELLE_SIP_PARSE(header_proxy_authorization)
1359 /**************************
1360 *HTTP Authorization header object inherent from Authorization
1361 ****************************
1362 */
1363 struct _belle_http_header_authorization {
1364 belle_sip_header_authorization_t authorization;
1365 belle_generic_uri_t* uri;
1366 };
1367
belle_http_header_authorization_init(belle_http_header_authorization_t * authorization)1368 static void belle_http_header_authorization_init(belle_http_header_authorization_t* authorization) {
1369 belle_sip_header_set_name(BELLE_SIP_HEADER(authorization),BELLE_HTTP_AUTHORIZATION);
1370 }
belle_http_header_authorization_destroy(belle_http_header_authorization_t * authorization)1371 static void belle_http_header_authorization_destroy(belle_http_header_authorization_t* authorization) {
1372 if (authorization->uri) {
1373 belle_sip_object_unref(authorization->uri);
1374 }
1375 }
1376
belle_http_header_authorization_clone(belle_http_header_authorization_t * authorization,const belle_http_header_authorization_t * orig)1377 static void belle_http_header_authorization_clone(belle_http_header_authorization_t* authorization,
1378 const belle_http_header_authorization_t *orig ) {
1379 if (belle_http_header_authorization_get_uri(orig)) {
1380 belle_http_header_authorization_set_uri(authorization,BELLE_GENERIC_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_http_header_authorization_get_uri(orig)))));
1381 }
1382 }
1383
belle_http_header_authorization_marshal(belle_http_header_authorization_t * authorization,char * buff,size_t buff_size,size_t * offset)1384 belle_sip_error_code belle_http_header_authorization_marshal(belle_http_header_authorization_t* authorization, char* buff, size_t buff_size, size_t *offset) {
1385 belle_sip_error_code error=BELLE_SIP_OK;
1386
1387 /*first make sure there is no sip uri*/
1388 if (belle_sip_header_authorization_get_uri(BELLE_SIP_HEADER_AUTHORIZATION(authorization))) {
1389 belle_sip_error ("Cannot marshal http_header_authorization because a sip uri is set. Use belle_http_authorization_set uri instead of belle_sip_header_authorization_set_uri");
1390 return BELLE_SIP_NOT_IMPLEMENTED;
1391 }
1392 belle_sip_header_authorization_marshal(BELLE_SIP_HEADER_AUTHORIZATION(authorization),buff,buff_size,offset);
1393 if (authorization->uri) {
1394 error=belle_sip_snprintf(buff,buff_size,offset,", uri=\"");
1395 if (error!=BELLE_SIP_OK) return error;
1396 error=belle_generic_uri_marshal(authorization->uri,buff,buff_size,offset);
1397 if (error!=BELLE_SIP_OK) return error;
1398 error=belle_sip_snprintf(buff,buff_size,offset,"%s","\"");
1399 if (error!=BELLE_SIP_OK) return error;
1400 }
1401 return error;
1402 }
1403
BELLE_NEW(belle_http_header_authorization,belle_sip_header_authorization)1404 BELLE_NEW(belle_http_header_authorization,belle_sip_header_authorization)
1405 belle_generic_uri_t* belle_http_header_authorization_get_uri(const belle_http_header_authorization_t* authorization) {
1406 return authorization->uri;
1407 }
belle_http_header_authorization_set_uri(belle_http_header_authorization_t * authorization,belle_generic_uri_t * uri)1408 void belle_http_header_authorization_set_uri( belle_http_header_authorization_t* authorization,belle_generic_uri_t* uri) {
1409 if (authorization->uri) belle_sip_object_unref(authorization->uri);
1410 if (uri) belle_sip_object_ref(uri);
1411 authorization->uri=uri;
1412 }
1413
1414 /**************************
1415 *WWW-Authenticate header object inherent from parameters
1416 ****************************
1417 */
1418 struct _belle_sip_header_www_authenticate {
1419 AUTH_BASE
1420 const char* domain;
1421 int stale;
1422 belle_sip_list_t* qop;
1423 };
1424
1425
belle_sip_header_www_authenticate_destroy(belle_sip_header_www_authenticate_t * www_authenticate)1426 static void belle_sip_header_www_authenticate_destroy(belle_sip_header_www_authenticate_t* www_authenticate) {
1427 AUTH_BASE_DESTROY(www_authenticate)
1428 if (www_authenticate->domain) belle_sip_free((void*)www_authenticate->domain);
1429 if (www_authenticate->qop) belle_sip_list_free_with_data(www_authenticate->qop,belle_sip_free);
1430 }
belle_sip_header_www_authenticate_init(belle_sip_header_www_authenticate_t * www_authenticate)1431 void belle_sip_header_www_authenticate_init(belle_sip_header_www_authenticate_t* www_authenticate) {
1432 www_authenticate->stale=-1;
1433 }
belle_sip_header_www_authenticate_clone(belle_sip_header_www_authenticate_t * www_authenticate,const belle_sip_header_www_authenticate_t * orig)1434 static void belle_sip_header_www_authenticate_clone(belle_sip_header_www_authenticate_t* www_authenticate,
1435 const belle_sip_header_www_authenticate_t *orig ) {
1436 AUTH_BASE_CLONE(belle_sip_header_www_authenticate,www_authenticate,orig)
1437 CLONE_STRING(belle_sip_header_www_authenticate,domain,www_authenticate,orig)
1438 www_authenticate->stale=orig->stale;
1439 www_authenticate->qop=belle_sip_list_copy_with_data(orig->qop,(void* (*)(void*))belle_sip_strdup);
1440 }
1441
belle_sip_header_www_authenticate_marshal(belle_sip_header_www_authenticate_t * www_authenticate,char * buff,size_t buff_size,size_t * offset)1442 belle_sip_error_code belle_sip_header_www_authenticate_marshal(belle_sip_header_www_authenticate_t* www_authenticate, char* buff, size_t buff_size, size_t *offset) {
1443 belle_sip_list_t* qops=www_authenticate->qop;
1444 AUTH_BASE_MARSHAL(www_authenticate)
1445 if (www_authenticate->domain) {
1446 error=belle_sip_snprintf(buff,buff_size,offset,"%sdomain=\"%s\"",border,www_authenticate->domain);
1447 if (error!=BELLE_SIP_OK) return error;
1448 border=", ";
1449 }
1450 if (www_authenticate->stale>=0) {
1451 error=belle_sip_snprintf(buff,buff_size,offset,"%sstale=%s",border,www_authenticate->stale?"true":"false");
1452 if (error!=BELLE_SIP_OK) return error;
1453 }
1454 if (qops!=NULL && qops->data!=NULL) {
1455 error=belle_sip_snprintf(buff,buff_size,offset,"%sqop=\"",border);
1456 if (error!=BELLE_SIP_OK) return error;
1457 border="";
1458 for(;qops!=NULL;qops=qops->next){
1459 error=belle_sip_snprintf(buff,buff_size,offset,"%s%s",border, (const char*)qops->data);
1460 if (error!=BELLE_SIP_OK) return error;
1461 border=",";
1462 }\
1463 error=belle_sip_snprintf(buff,buff_size,offset,"\"");
1464 if (error!=BELLE_SIP_OK) return error;
1465 border=", ";
1466 }
1467 return error;
1468 }
1469
1470 #define SET_ADD_STRING_LIST(header,name) \
1471 void header##_set_##name(header##_t* obj, belle_sip_list_t* value) {\
1472 if (obj->name) {\
1473 belle_sip_list_free_with_data(obj->name,belle_sip_free);\
1474 } \
1475 obj->name=value;\
1476 }\
1477 void header##_add_##name(header##_t* obj, const char* value) {\
1478 obj->name=belle_sip_list_append(obj->name,strdup(value));\
1479 }
1480
1481 BELLE_SIP_NEW_HEADER_INIT(header_www_authenticate,parameters,BELLE_SIP_WWW_AUTHENTICATE,header_www_authenticate)
1482 BELLE_SIP_PARSE(header_www_authenticate)
1483 GET_SET_STRING(belle_sip_header_www_authenticate,scheme);
1484 GET_SET_STRING(belle_sip_header_www_authenticate,realm);
1485 GET_SET_STRING(belle_sip_header_www_authenticate,nonce);
1486 GET_SET_STRING(belle_sip_header_www_authenticate,algorithm);
1487 GET_SET_STRING(belle_sip_header_www_authenticate,opaque);
1488 /*GET_SET_STRING(belle_sip_header_www_authenticate,qop);*/
SET_ADD_STRING_LIST(belle_sip_header_www_authenticate,qop)1489 SET_ADD_STRING_LIST(belle_sip_header_www_authenticate,qop)
1490 GET_SET_STRING(belle_sip_header_www_authenticate,domain)
1491 GET_SET_BOOL(belle_sip_header_www_authenticate,stale,is)
1492 belle_sip_list_t* belle_sip_header_www_authenticate_get_qop(const belle_sip_header_www_authenticate_t* www_authetication) {
1493 return www_authetication->qop;
1494 }
belle_sip_header_www_authenticate_get_qop_first(const belle_sip_header_www_authenticate_t * www_authetication)1495 const char* belle_sip_header_www_authenticate_get_qop_first(const belle_sip_header_www_authenticate_t* www_authetication) {
1496 return www_authetication->qop?(const char*)www_authetication->qop->data:NULL;
1497 }
1498
1499 /**************************
1500 *Proxy-authenticate header object inherent from www_authenticate
1501 ****************************
1502 */
1503 struct _belle_sip_header_proxy_authenticate {
1504 belle_sip_header_www_authenticate_t www_authenticate;
1505 };
1506
1507
belle_sip_header_proxy_authenticate_destroy(belle_sip_header_proxy_authenticate_t * proxy_authenticate)1508 static void belle_sip_header_proxy_authenticate_destroy(belle_sip_header_proxy_authenticate_t* proxy_authenticate) {
1509 }
1510
belle_sip_header_proxy_authenticate_clone(belle_sip_header_proxy_authenticate_t * proxy_authenticate,const belle_sip_header_proxy_authenticate_t * orig)1511 static void belle_sip_header_proxy_authenticate_clone(belle_sip_header_proxy_authenticate_t* proxy_authenticate,
1512 const belle_sip_header_proxy_authenticate_t *orig ) {
1513 }
1514
belle_sip_header_proxy_authenticate_marshal(belle_sip_header_proxy_authenticate_t * proxy_authenticate,char * buff,size_t buff_size,size_t * offset)1515 belle_sip_error_code belle_sip_header_proxy_authenticate_marshal(belle_sip_header_proxy_authenticate_t* proxy_authenticate, char* buff, size_t buff_size, size_t *offset) {
1516 return belle_sip_header_www_authenticate_marshal(&proxy_authenticate->www_authenticate,buff,buff_size,offset);
1517 }
1518
1519 BELLE_SIP_NEW_HEADER(header_proxy_authenticate,header_www_authenticate,BELLE_SIP_PROXY_AUTHENTICATE)
1520 BELLE_SIP_PARSE(header_proxy_authenticate)
1521
1522 /**************************
1523 * max forwards header object inherent from header
1524 ****************************
1525 */
1526 struct _belle_sip_header_max_forwards {
1527 belle_sip_header_t header;
1528 int max_forwards;
1529 };
1530
belle_sip_header_max_forwards_destroy(belle_sip_header_max_forwards_t * max_forwards)1531 static void belle_sip_header_max_forwards_destroy(belle_sip_header_max_forwards_t* max_forwards) {
1532 }
1533
belle_sip_header_max_forwards_clone(belle_sip_header_max_forwards_t * max_forwards,const belle_sip_header_max_forwards_t * orig)1534 static void belle_sip_header_max_forwards_clone(belle_sip_header_max_forwards_t* max_forwards,
1535 const belle_sip_header_max_forwards_t *orig ) {
1536 max_forwards->max_forwards=orig->max_forwards;
1537 }
1538
belle_sip_header_max_forwards_marshal(belle_sip_header_max_forwards_t * max_forwards,char * buff,size_t buff_size,size_t * offset)1539 belle_sip_error_code belle_sip_header_max_forwards_marshal(belle_sip_header_max_forwards_t* max_forwards, char* buff, size_t buff_size, size_t *offset) {
1540 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(max_forwards), buff, buff_size, offset);
1541 if (error!=BELLE_SIP_OK) return error;
1542 error=belle_sip_snprintf(buff,buff_size,offset,"%i",max_forwards->max_forwards);
1543 if (error!=BELLE_SIP_OK) return error;
1544 return error;
1545 }
1546
1547 BELLE_SIP_NEW_HEADER(header_max_forwards,header,"Max-Forwards")
BELLE_SIP_PARSE(header_max_forwards)1548 BELLE_SIP_PARSE(header_max_forwards)
1549 GET_SET_INT(belle_sip_header_max_forwards,max_forwards,int)
1550 int belle_sip_header_max_forwards_decrement_max_forwards(belle_sip_header_max_forwards_t* max_forwards) {
1551 return max_forwards->max_forwards--;
1552 }
belle_sip_header_max_forwards_create(int value)1553 belle_sip_header_max_forwards_t* belle_sip_header_max_forwards_create(int value) {
1554 belle_sip_header_max_forwards_t* max_forwards=belle_sip_header_max_forwards_new();
1555 max_forwards->max_forwards=value;
1556 return max_forwards;
1557 }
1558
1559 /**************************
1560 * Subscription state header object inherent from parameters
1561 ****************************
1562 */
1563 struct _belle_sip_header_subscription_state {
1564 belle_sip_parameters_t parameters;
1565 const char* state;
1566 };
1567
belle_sip_header_subscription_state_destroy(belle_sip_header_subscription_state_t * subscription_state)1568 static void belle_sip_header_subscription_state_destroy(belle_sip_header_subscription_state_t* subscription_state) {
1569 DESTROY_STRING(subscription_state,state);
1570 }
1571
belle_sip_header_subscription_state_clone(belle_sip_header_subscription_state_t * subscription_state,const belle_sip_header_subscription_state_t * orig)1572 static void belle_sip_header_subscription_state_clone(belle_sip_header_subscription_state_t* subscription_state,
1573 const belle_sip_header_subscription_state_t *orig ) {
1574 CLONE_STRING(belle_sip_header_subscription_state,state,subscription_state,orig)
1575 }
1576
belle_sip_header_subscription_state_marshal(belle_sip_header_subscription_state_t * subscription_state,char * buff,size_t buff_size,size_t * offset)1577 belle_sip_error_code belle_sip_header_subscription_state_marshal(belle_sip_header_subscription_state_t* subscription_state, char* buff, size_t buff_size, size_t *offset) {
1578 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(subscription_state), buff, buff_size, offset);
1579 if (error!=BELLE_SIP_OK) return error;
1580 error=belle_sip_snprintf(buff,buff_size,offset,"%s",subscription_state->state);
1581 if (error!=BELLE_SIP_OK) return error;
1582 error=belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(subscription_state), buff, buff_size, offset);
1583 if (error!=BELLE_SIP_OK) return error;
1584 return error;
1585 }
1586
1587 BELLE_SIP_NEW_HEADER(header_subscription_state,parameters,BELLE_SIP_SUBSCRIPTION_STATE)
1588 BELLE_SIP_PARSE(header_subscription_state)
1589 GET_SET_STRING(belle_sip_header_subscription_state,state);
1590 GET_SET_STRING_PARAM(belle_sip_header_subscription_state,reason);
1591 GET_SET_INT_PARAM2(belle_sip_header_subscription_state,retry-after,int,retry_after);
GET_SET_INT_PARAM(belle_sip_header_subscription_state,expires,int)1592 GET_SET_INT_PARAM(belle_sip_header_subscription_state,expires,int)
1593 belle_sip_header_subscription_state_t* belle_sip_header_subscription_state_create (const char* subscription_state,int expires) {
1594 belle_sip_header_subscription_state_t* sub_state=belle_sip_header_subscription_state_new();
1595 belle_sip_header_subscription_state_set_state(sub_state,subscription_state);
1596 belle_sip_header_subscription_state_set_expires(sub_state,expires);
1597 return sub_state;
1598 }
1599
1600
1601 #define HEADER_TO_LIKE_IMPL(name,header_name) \
1602 struct _belle_sip_header_##name { \
1603 belle_sip_header_address_t address; \
1604 }; \
1605 \
1606 static void belle_sip_header_##name##_destroy(belle_sip_header_##name##_t * obj) { \
1607 } \
1608 void belle_sip_header_##name##_clone(belle_sip_header_##name##_t *contact, const belle_sip_header_##name##_t *orig){ }\
1609 belle_sip_error_code belle_sip_header_##name##_marshal(belle_sip_header_##name##_t* name, char* buff, size_t buff_size, size_t *offset) {\
1610 BELLE_SIP_FROM_LIKE_MARSHAL(name,FALSE)\
1611 }\
1612 BELLE_SIP_NEW_HEADER(header_##name,header_address,header_name)\
1613 BELLE_SIP_PARSE(header_##name)\
1614 belle_sip_header_##name##_t* belle_sip_header_##name##_create(const belle_sip_header_address_t* address) { \
1615 belle_sip_header_##name##_t* header= belle_sip_header_##name##_new();\
1616 _belle_sip_object_copy((belle_sip_object_t*)header,(belle_sip_object_t*)address);\
1617 belle_sip_header_set_next(BELLE_SIP_HEADER(header),NULL); /*make sure only one header is kept*/\
1618 belle_sip_header_set_name(BELLE_SIP_HEADER(header),header_name); \
1619 return header;\
1620 }
1621
1622 /**************************
1623 * Refer-To header object inherits from header_address
1624 ****************************
1625 */
1626 HEADER_TO_LIKE_IMPL(refer_to,BELLE_SIP_REFER_TO)
1627
1628 /**************************
1629 * Referred-By header object inherits from header_address
1630 ****************************
1631 */
1632 HEADER_TO_LIKE_IMPL(referred_by,BELLE_SIP_REFERRED_BY)
1633
1634 /**************************
1635 * Replaces state header object inherent from parameters
1636 ****************************
1637 */
1638 struct _belle_sip_header_replaces {
1639 belle_sip_parameters_t parameters;
1640 char* call_id;
1641 };
1642
belle_sip_header_replaces_destroy(belle_sip_header_replaces_t * replaces)1643 static void belle_sip_header_replaces_destroy(belle_sip_header_replaces_t* replaces) {
1644 DESTROY_STRING(replaces,call_id);
1645 }
1646
belle_sip_header_replaces_clone(belle_sip_header_replaces_t * replaces,const belle_sip_header_replaces_t * orig)1647 static void belle_sip_header_replaces_clone(belle_sip_header_replaces_t* replaces,
1648 const belle_sip_header_replaces_t *orig ) {
1649 CLONE_STRING(belle_sip_header_replaces,call_id,replaces,orig)
1650 }
1651
belle_sip_header_replaces_marshal(belle_sip_header_replaces_t * replaces,char * buff,size_t buff_size,size_t * offset)1652 belle_sip_error_code belle_sip_header_replaces_marshal(belle_sip_header_replaces_t* replaces, char* buff, size_t buff_size, size_t *offset) {
1653 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(replaces), buff, buff_size, offset);
1654 if (error!=BELLE_SIP_OK) return error;
1655 error=belle_sip_snprintf(buff,buff_size,offset,"%s",replaces->call_id);
1656 if (error!=BELLE_SIP_OK) return error;
1657 error=belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(replaces), buff, buff_size, offset);
1658 if (error!=BELLE_SIP_OK) return error;
1659 return error;
1660 }
1661
1662 BELLE_SIP_NEW_HEADER(header_replaces,parameters,BELLE_SIP_REPLACES)
1663 BELLE_SIP_PARSE(header_replaces)
1664
1665 GET_SET_STRING(belle_sip_header_replaces,call_id);
1666 GET_SET_STRING_PARAM2(belle_sip_header_replaces,to-tag,to_tag);
1667 GET_SET_STRING_PARAM2(belle_sip_header_replaces,from-tag,from_tag);
1668
escaped_to_ascii(const char * a,char * b,size_t n)1669 static void escaped_to_ascii(const char*a,char*b,size_t n) {
1670 size_t index_a=0,index_b=0;
1671
1672 while (a[index_a]!='\0'&& index_a<n)
1673 index_a+=belle_sip_get_char(a+index_a,b+index_b++);
1674 }
1675
1676 #define REPLACES_PREF_OFFSET (strlen(BELLE_SIP_REPLACES)+2)
belle_sip_header_replaces_create2(const char * escaped_replace)1677 belle_sip_header_replaces_t* belle_sip_header_replaces_create2(const char* escaped_replace) {
1678 belle_sip_header_replaces_t* replaces;
1679 size_t len=strlen(escaped_replace);
1680 char* out=belle_sip_malloc0(REPLACES_PREF_OFFSET+len+1);
1681 strcpy(out,BELLE_SIP_REPLACES ": ");
1682 escaped_to_ascii(escaped_replace,out+REPLACES_PREF_OFFSET,len);
1683 /*now we can parse*/
1684 replaces= belle_sip_header_replaces_parse(out);
1685 belle_sip_free(out);
1686 return replaces;
1687 }
1688
belle_sip_header_replaces_value_to_escaped_string(const belle_sip_header_replaces_t * replaces)1689 char* belle_sip_header_replaces_value_to_escaped_string(const belle_sip_header_replaces_t* replaces) {
1690 char buff[BELLE_SIP_MAX_TO_STRING_SIZE];
1691 size_t buff_size=sizeof(buff);
1692 size_t offset=0;
1693 belle_sip_error_code error=BELLE_SIP_OK;
1694 /*first, marshall callid/from/to tags*/
1695 error=belle_sip_snprintf(buff,buff_size,&offset,"%s",replaces->call_id);
1696 if (error!=BELLE_SIP_OK) return NULL;
1697 error=belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(replaces), buff, buff_size, &offset);
1698 if (error!=BELLE_SIP_OK) return NULL;
1699 buff[offset]='\0';
1700 return strdup(buff);
1701 }
1702
belle_sip_header_replaces_create(const char * call_id,const char * from_tag,const char * to_tag)1703 belle_sip_header_replaces_t* belle_sip_header_replaces_create(const char* call_id,const char* from_tag,const char* to_tag) {
1704 belle_sip_header_replaces_t* replaces=belle_sip_header_replaces_new();
1705 belle_sip_header_replaces_set_call_id(replaces,call_id);
1706 belle_sip_header_replaces_set_from_tag(replaces,from_tag);
1707 belle_sip_header_replaces_set_to_tag(replaces,to_tag);
1708 return replaces;
1709 }
1710
1711 struct belle_sip_header_date{
1712 belle_sip_header_t base;
1713 char *date;
1714 };
1715
belle_sip_header_date_destroy(belle_sip_header_date_t * obj)1716 static void belle_sip_header_date_destroy(belle_sip_header_date_t* obj) {
1717 DESTROY_STRING(obj,date);
1718 }
1719
belle_sip_header_date_clone(belle_sip_header_date_t * obj,const belle_sip_header_date_t * orig)1720 static void belle_sip_header_date_clone(belle_sip_header_date_t* obj,
1721 const belle_sip_header_date_t *orig ) {
1722 CLONE_STRING(belle_sip_header_date,date,obj,orig);
1723 }
1724
belle_sip_header_date_marshal(belle_sip_header_date_t * obj,char * buff,size_t buff_size,size_t * offset)1725 belle_sip_error_code belle_sip_header_date_marshal(belle_sip_header_date_t* obj, char* buff, size_t buff_size, size_t *offset) {
1726 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(obj), buff, buff_size, offset);
1727 if (error!=BELLE_SIP_OK) return error;
1728 error=belle_sip_snprintf(buff,buff_size,offset,"%s",obj->date);
1729 if (error!=BELLE_SIP_OK) return error;
1730 return error;
1731 }
1732
BELLE_SIP_NEW_HEADER(header_date,header,BELLE_SIP_DATE)1733 BELLE_SIP_NEW_HEADER(header_date,header,BELLE_SIP_DATE)
1734 BELLE_SIP_PARSE(header_date)
1735
1736 BELLESIP_EXPORT belle_sip_header_date_t* belle_sip_header_date_create_from_time(const time_t *utc_time){
1737 belle_sip_header_date_t *obj=belle_sip_header_date_new();
1738 belle_sip_header_date_set_time(obj,utc_time);
1739 return obj;
1740 }
1741
1742 static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
1743 static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
1744
belle_sip_header_date_get_time(belle_sip_header_date_t * obj)1745 BELLESIP_EXPORT time_t belle_sip_header_date_get_time(belle_sip_header_date_t *obj){
1746 struct tm ret ={0};
1747 char tmp1[16] ={0};
1748 char tmp2[16] ={0};
1749 int i,j;
1750 time_t seconds;
1751
1752
1753 /* time headers are in GMT as spec says */
1754 sscanf(obj->date,"%3c,%d %16s %d %d:%d:%d",tmp1,&ret.tm_mday,tmp2,
1755 &ret.tm_year,&ret.tm_hour,&ret.tm_min,&ret.tm_sec);
1756 ret.tm_year-=1900;
1757 for(i=0;i<7;i++) {
1758 if(strcmp(tmp1,days[i])==0) {
1759 ret.tm_wday=i;
1760 for(j=0;j<12;j++) {
1761 if(strcmp(tmp2,months[j])==0) {
1762 ret.tm_mon=j;
1763 goto success;
1764 }
1765 }
1766 }
1767 }
1768 belle_sip_warning("Failed to parse date %s",obj->date);
1769 return (time_t)-1;
1770 success:
1771 ret.tm_isdst=0;
1772 seconds = timegm(&ret);
1773 if (seconds==(time_t)-1){
1774 belle_sip_error("timegm() failed: %s",strerror(errno));
1775 return (time_t)-1;
1776 }
1777 return seconds;
1778 }
1779
belle_sip_header_date_set_time(belle_sip_header_date_t * obj,const time_t * utc_time)1780 BELLESIP_EXPORT void belle_sip_header_date_set_time(belle_sip_header_date_t *obj, const time_t *utc_time){
1781
1782 struct tm *ret;
1783 #ifndef _WIN32
1784 struct tm gmt;
1785 ret=gmtime_r(utc_time,&gmt);
1786 #else
1787 ret=gmtime(utc_time);
1788 #endif
1789 /*cannot use strftime because it is locale dependant*/
1790 if (obj->date){
1791 belle_sip_free(obj->date);
1792 }
1793 /*SIP-date = rfc1123-date
1794 rfc1123-date = wkday "," SP date1 SP time SP "GMT"
1795 date1 = 2DIGIT SP month SP 4DIGIT
1796 ; day month year (e.g., 02 Jun 1982)
1797 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
1798 ; 00:00:00 - 23:59:59
1799 wkday = "Mon" / "Tue" / "Wed"
1800 / "Thu" / "Fri" / "Sat" / "Sun"
1801 month = "Jan" / "Feb" / "Mar" / "Apr"
1802 / "May" / "Jun" / "Jul" / "Aug"
1803 / "Sep" / "Oct" / "Nov" / "Dec"
1804 */
1805 obj->date=belle_sip_strdup_printf("%s, %02i %s %04i %02i:%02i:%02i GMT",
1806 days[ret->tm_wday],ret->tm_mday,months[ret->tm_mon],1900+ret->tm_year,ret->tm_hour,ret->tm_min,ret->tm_sec);
1807 }
1808
1809 GET_SET_STRING(belle_sip_header_date,date);
1810
1811 /************************
1812 * header_p_prefered_identity
1813 ***********************/
1814 struct _belle_sip_header_p_preferred_identity {
1815 belle_sip_header_address_t address;
1816 };
1817
belle_sip_header_p_preferred_identity_destroy(belle_sip_header_p_preferred_identity_t * p_preferred_identity)1818 void belle_sip_header_p_preferred_identity_destroy(belle_sip_header_p_preferred_identity_t* p_preferred_identity) {
1819 }
1820
belle_sip_header_p_preferred_identity_clone(belle_sip_header_p_preferred_identity_t * p_preferred_identity,const belle_sip_header_p_preferred_identity_t * orig)1821 void belle_sip_header_p_preferred_identity_clone(belle_sip_header_p_preferred_identity_t *p_preferred_identity, const belle_sip_header_p_preferred_identity_t *orig){
1822
1823 }
belle_sip_header_p_preferred_identity_marshal(belle_sip_header_p_preferred_identity_t * p_preferred_identity,char * buff,size_t buff_size,size_t * offset)1824 belle_sip_error_code belle_sip_header_p_preferred_identity_marshal(belle_sip_header_p_preferred_identity_t* p_preferred_identity, char* buff, size_t buff_size, size_t *offset) {
1825 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(p_preferred_identity), buff, buff_size, offset);
1826 if (error!=BELLE_SIP_OK) return error;
1827 error=belle_sip_header_address_marshal(&p_preferred_identity->address, buff, buff_size, offset);
1828 if (error!=BELLE_SIP_OK) return error;
1829 return error;
1830 }
BELLE_SIP_NEW_HEADER(header_p_preferred_identity,header_address,BELLE_SIP_P_PREFERRED_IDENTITY)1831 BELLE_SIP_NEW_HEADER(header_p_preferred_identity,header_address,BELLE_SIP_P_PREFERRED_IDENTITY)
1832 BELLE_SIP_PARSE(header_p_preferred_identity)
1833 belle_sip_header_p_preferred_identity_t* belle_sip_header_p_preferred_identity_create (const belle_sip_header_address_t* p_preferred_identity) {
1834 belle_sip_header_p_preferred_identity_t* header = belle_sip_header_p_preferred_identity_new();
1835 _belle_sip_object_copy(BELLE_SIP_OBJECT(header),BELLE_SIP_OBJECT(p_preferred_identity));
1836 belle_sip_header_set_next(BELLE_SIP_HEADER(header),NULL); /*make sure only one header is kept*/
1837 belle_sip_header_set_name(BELLE_SIP_HEADER(header),BELLE_SIP_P_PREFERRED_IDENTITY); /*restaure header name*/
1838 return header;
1839 }
1840
1841 #define PRIVACY_LIKE_HEADER(header_name, string_name,separator) \
1842 struct _belle_sip_header_##header_name { \
1843 belle_sip_header_t header;\
1844 belle_sip_list_t* header_name;\
1845 }; \
1846 \
1847 static void belle_sip_header_##header_name##_destroy(belle_sip_header_##header_name##_t* p) {\
1848 belle_sip_header_##header_name##_set_##header_name(p,NULL);\
1849 }\
1850 \
1851 static void belle_sip_header_##header_name##_clone(belle_sip_header_##header_name##_t* p, const belle_sip_header_##header_name##_t* orig){\
1852 belle_sip_list_t* list=orig->header_name;\
1853 for(;list!=NULL;list=list->next){\
1854 belle_sip_header_##header_name##_add_##header_name(p,(const char *)list->data);\
1855 }\
1856 }\
1857 \
1858 belle_sip_error_code belle_sip_header_##header_name##_marshal(belle_sip_header_##header_name##_t* p, char* buff, size_t buff_size, size_t *offset) {\
1859 belle_sip_error_code error=BELLE_SIP_OK;\
1860 belle_sip_list_t* list = p->header_name;\
1861 error=belle_sip_header_marshal(BELLE_SIP_HEADER(p), buff, buff_size, offset);\
1862 if (error!=BELLE_SIP_OK) return error;\
1863 for(;list!=NULL;list=list->next){\
1864 error=belle_sip_snprintf(buff,buff_size,offset,list==p->header_name ? "%s" : separator" %s",(const char *)list->data);\
1865 if (error!=BELLE_SIP_OK) return error;\
1866 }\
1867 return error;\
1868 }\
1869 \
1870 BELLE_SIP_NEW_HEADER(header_##header_name,header,string_name)\
1871 BELLE_SIP_PARSE(header_##header_name)\
1872 belle_sip_list_t* belle_sip_header_##header_name##_get_##header_name(const belle_sip_header_##header_name##_t* p) {\
1873 return p->header_name;\
1874 }\
1875 SET_ADD_STRING_LIST(belle_sip_header_##header_name,header_name)\
1876 \
1877 belle_sip_header_##header_name##_t* belle_sip_header_##header_name##_create(const char* header_name) {\
1878 belle_sip_header_##header_name##_t* header=belle_sip_header_##header_name##_new();\
1879 belle_sip_header_##header_name##_add_##header_name(header,header_name);\
1880 return header;\
1881 }
1882
1883
1884 /******************************
1885 * Privacy header inherits from header
1886 *
1887 ******************************/
1888 PRIVACY_LIKE_HEADER(privacy,BELLE_SIP_PRIVACY,";")
1889 /**************************
1890 * Event header object inherent from parameters
1891 ****************************
1892 */
1893 struct _belle_sip_header_event {
1894 belle_sip_parameters_t parameters;
1895 const char* package_name;
1896 };
1897
belle_sip_header_event_destroy(belle_sip_header_event_t * event)1898 static void belle_sip_header_event_destroy(belle_sip_header_event_t* event) {
1899 DESTROY_STRING(event,package_name);
1900 }
1901
belle_sip_header_event_clone(belle_sip_header_event_t * event,const belle_sip_header_event_t * orig)1902 static void belle_sip_header_event_clone(belle_sip_header_event_t* event, const belle_sip_header_event_t *orig ) {
1903 CLONE_STRING(belle_sip_header_event,package_name,event,orig)
1904 }
1905
belle_sip_header_event_marshal(belle_sip_header_event_t * event,char * buff,size_t buff_size,size_t * offset)1906 belle_sip_error_code belle_sip_header_event_marshal(belle_sip_header_event_t* event, char* buff, size_t buff_size, size_t *offset) {
1907 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(event), buff, buff_size, offset);
1908 if (error!=BELLE_SIP_OK) return error;
1909 error=belle_sip_snprintf(buff,buff_size,offset,"%s",event->package_name);
1910 if (error!=BELLE_SIP_OK) return error;
1911 error=belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(event), buff, buff_size, offset);
1912 if (error!=BELLE_SIP_OK) return error;
1913 return error;
1914 }
1915
1916 BELLE_SIP_NEW_HEADER(header_event,parameters,BELLE_SIP_EVENT)
1917 BELLE_SIP_PARSE(header_event)
1918 GET_SET_STRING(belle_sip_header_event,package_name);
1919 GET_SET_STRING_PARAM(belle_sip_header_event,id);
1920
belle_sip_header_event_create(const char * package_name)1921 belle_sip_header_event_t* belle_sip_header_event_create (const char* package_name) {
1922 belle_sip_header_event_t* event=belle_sip_header_event_new();
1923 belle_sip_header_event_set_package_name(event,package_name);
1924 return event;
1925 }
1926
1927 /******************************
1928 * Supported header inherits from header
1929 *
1930 ******************************/
1931 PRIVACY_LIKE_HEADER(supported,BELLE_SIP_SUPPORTED,",")
1932
1933 /******************************
1934 * Content-Disposition header inherits from header
1935 *
1936 ******************************/
1937 struct _belle_sip_header_content_disposition {
1938 belle_sip_parameters_t parameters;
1939 const char* content_disposition;
1940 };
1941
belle_sip_header_content_disposition_destroy(belle_sip_header_content_disposition_t * content_disposition)1942 static void belle_sip_header_content_disposition_destroy(belle_sip_header_content_disposition_t* content_disposition) {
1943 DESTROY_STRING(content_disposition,content_disposition);
1944 }
1945
belle_sip_header_content_disposition_clone(belle_sip_header_content_disposition_t * content_disposition,const belle_sip_header_content_disposition_t * orig)1946 static void belle_sip_header_content_disposition_clone(belle_sip_header_content_disposition_t* content_disposition,
1947 const belle_sip_header_content_disposition_t *orig ) {
1948 CLONE_STRING(belle_sip_header_content_disposition,content_disposition,content_disposition,orig)
1949 }
1950
belle_sip_header_content_disposition_marshal(belle_sip_header_content_disposition_t * content_disposition,char * buff,size_t buff_size,size_t * offset)1951 belle_sip_error_code belle_sip_header_content_disposition_marshal(belle_sip_header_content_disposition_t* content_disposition, char* buff, size_t buff_size, size_t *offset) {
1952 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(content_disposition), buff, buff_size, offset);
1953 if (error!=BELLE_SIP_OK) return error;
1954 error=belle_sip_snprintf(buff,buff_size,offset,"%s",content_disposition->content_disposition);
1955 if (error!=BELLE_SIP_OK) return error;
1956 error=belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(content_disposition), buff, buff_size, offset);
1957 if (error!=BELLE_SIP_OK) return error;
1958 return error;
1959 }
1960
1961 BELLE_SIP_NEW_HEADER(header_content_disposition,parameters,BELLE_SIP_CONTENT_DISPOSITION)
1962 BELLE_SIP_PARSE(header_content_disposition)
1963 GET_SET_STRING(belle_sip_header_content_disposition,content_disposition);
1964
belle_sip_header_content_disposition_create(const char * value)1965 belle_sip_header_content_disposition_t* belle_sip_header_content_disposition_create (const char* value) {
1966 belle_sip_header_content_disposition_t* header=belle_sip_header_content_disposition_new();
1967 belle_sip_header_content_disposition_set_content_disposition(header,value);
1968 return header;
1969 }
1970
1971
1972 /******************************
1973 * Accept header inherits from parameters
1974 *
1975 ******************************/
1976
1977 struct _belle_sip_header_accept {
1978 belle_sip_parameters_t params_list;
1979 const char* type;
1980 const char* subtype;
1981 };
1982
belle_sip_header_accept_destroy(belle_sip_header_accept_t * accept)1983 static void belle_sip_header_accept_destroy(belle_sip_header_accept_t* accept) {
1984 if (accept->type) belle_sip_free((void*)accept->type);
1985 if (accept->subtype) belle_sip_free((void*)accept->subtype);
1986 }
1987
belle_sip_header_accept_clone(belle_sip_header_accept_t * accept,const belle_sip_header_accept_t * orig)1988 static void belle_sip_header_accept_clone(belle_sip_header_accept_t* accept, const belle_sip_header_accept_t* orig){
1989 CLONE_STRING(belle_sip_header_accept,type,accept,orig);
1990 CLONE_STRING(belle_sip_header_accept,subtype,accept,orig);
1991 }
1992
belle_sip_header_accept_marshal(belle_sip_header_accept_t * accept,char * buff,size_t buff_size,size_t * offset)1993 belle_sip_error_code belle_sip_header_accept_marshal(belle_sip_header_accept_t* accept, char* buff, size_t buff_size, size_t *offset) {
1994 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(accept), buff, buff_size, offset);
1995 if (error!=BELLE_SIP_OK) return error;
1996 error=belle_sip_snprintf(buff,buff_size,offset,"%s/%s",accept->type, accept->subtype);
1997 if (error!=BELLE_SIP_OK) return error;
1998 error=belle_sip_parameters_marshal(&accept->params_list, buff, buff_size, offset);
1999 if (error!=BELLE_SIP_OK) return error;
2000 return error;
2001 }
2002
BELLE_SIP_NEW_HEADER(header_accept,parameters,BELLE_SIP_ACCEPT)2003 BELLE_SIP_NEW_HEADER(header_accept,parameters,BELLE_SIP_ACCEPT)
2004 BELLE_SIP_PARSE(header_accept)
2005 belle_sip_header_accept_t* belle_sip_header_accept_create (const char* type,const char* sub_type) {
2006 belle_sip_header_accept_t* header = belle_sip_header_accept_new();
2007 belle_sip_header_accept_set_type(header,type);
2008 belle_sip_header_accept_set_subtype(header,sub_type);
2009 return header;
2010 }
2011 GET_SET_STRING(belle_sip_header_accept,type);
2012 GET_SET_STRING(belle_sip_header_accept,subtype);
2013
2014 /******************************
2015 * Reason header object inherent from parameters
2016 *
2017 ******************************/
2018 struct _belle_sip_header_reason {
2019 belle_sip_parameters_t params_list;
2020 const char* protocol;
2021 const char* unquoted_text;
2022 };
2023
belle_sip_header_reason_destroy(belle_sip_header_reason_t * reason)2024 static void belle_sip_header_reason_destroy(belle_sip_header_reason_t* reason) {
2025 DESTROY_STRING(reason,protocol);
2026 DESTROY_STRING(reason,unquoted_text);
2027 }
2028
belle_sip_header_reason_clone(belle_sip_header_reason_t * reason,const belle_sip_header_reason_t * orig)2029 static void belle_sip_header_reason_clone(belle_sip_header_reason_t* reason, const belle_sip_header_reason_t* orig){
2030 CLONE_STRING(belle_sip_header_reason,protocol,reason,orig)
2031 }
2032
belle_sip_header_reason_marshal(belle_sip_header_reason_t * reason,char * buff,size_t buff_size,size_t * offset)2033 belle_sip_error_code belle_sip_header_reason_marshal(belle_sip_header_reason_t* reason, char* buff, size_t buff_size, size_t *offset) {
2034 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(reason), buff, buff_size, offset);
2035 if (error!=BELLE_SIP_OK) return error;
2036 error=belle_sip_snprintf(buff,buff_size,offset,"%s ",reason->protocol);
2037 if (error!=BELLE_SIP_OK) return error;
2038 error=belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(reason), buff, buff_size, offset);
2039 if (error!=BELLE_SIP_OK) return error;
2040 if (reason->unquoted_text)
2041 error=belle_sip_snprintf(buff,buff_size,offset,"; text=\"%s\"",reason->unquoted_text);
2042 return error;
2043 }
2044
2045 GET_SET_STRING(belle_sip_header_reason,unquoted_text);
2046
belle_sip_header_reason_set_text(belle_sip_header_reason_t * reason,const char * text)2047 void belle_sip_header_reason_set_text(belle_sip_header_reason_t* reason,const char* text) {
2048 belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(reason),"text"); /*just in case*/
2049 belle_sip_header_reason_set_unquoted_text((belle_sip_header_reason_t*)reason, text);
2050 }
belle_sip_header_reason_get_text(const belle_sip_header_reason_t * reason)2051 BELLESIP_EXPORT const char* belle_sip_header_reason_get_text(const belle_sip_header_reason_t* reason) {
2052 if (!reason->unquoted_text) {
2053 /*try from params*/
2054 const char * quoted = belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(reason), "text");
2055 if (quoted) {
2056 char* unquoted = _belle_sip_str_dup_and_unquote_string(quoted);
2057 belle_sip_header_reason_set_unquoted_text((belle_sip_header_reason_t*)reason, unquoted); /*change internal param, ,even if reason is const*/
2058 belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(reason),"text");
2059 belle_sip_free(unquoted);
2060 }
2061
2062 }
2063 return reason->unquoted_text;
2064 }
2065
2066 GET_SET_STRING(belle_sip_header_reason,protocol);
2067
2068 GET_SET_INT_PARAM(belle_sip_header_reason,cause,int);
2069 BELLE_SIP_PARSE(header_reason)
2070 BELLE_SIP_NEW_HEADER(header_reason,parameters,BELLE_SIP_REASON)
2071
2072 /******************************
2073 * AuthenticationInfo header hinerite from header
2074 *
2075 ******************************/
2076
2077 struct _belle_sip_header_authentication_info {
2078 belle_sip_header_t header;
2079 const char* rsp_auth;
2080 const char* cnonce;
2081 int nonce_count;
2082 const char* qop;
2083 const char* next_nonce;
2084 };
belle_sip_header_authentication_info_destroy(belle_sip_header_authentication_info_t * authentication_info)2085 static void belle_sip_header_authentication_info_destroy(belle_sip_header_authentication_info_t* authentication_info) {
2086 DESTROY_STRING(authentication_info,rsp_auth);
2087 DESTROY_STRING(authentication_info,cnonce);
2088 DESTROY_STRING(authentication_info,qop);
2089 DESTROY_STRING(authentication_info,next_nonce);
2090
2091 }
2092
belle_sip_header_authentication_info_clone(belle_sip_header_authentication_info_t * authentication_info,const belle_sip_header_authentication_info_t * orig)2093 static void belle_sip_header_authentication_info_clone( belle_sip_header_authentication_info_t* authentication_info
2094 , const belle_sip_header_authentication_info_t* orig){
2095 CLONE_STRING(belle_sip_header_authentication_info,rsp_auth,authentication_info,orig)
2096 CLONE_STRING(belle_sip_header_authentication_info,cnonce,authentication_info,orig)
2097 CLONE_STRING(belle_sip_header_authentication_info,qop,authentication_info,orig)
2098 CLONE_STRING(belle_sip_header_authentication_info,next_nonce,authentication_info,orig)
2099 }
2100
belle_sip_header_authentication_info_marshal(belle_sip_header_authentication_info_t * authentication_info,char * buff,size_t buff_size,size_t * offset)2101 belle_sip_error_code belle_sip_header_authentication_info_marshal(belle_sip_header_authentication_info_t* authentication_info, char* buff, size_t buff_size, size_t *offset) {
2102 char* border="";
2103 belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(authentication_info), buff, buff_size, offset);
2104 if (error!=BELLE_SIP_OK) return error;
2105
2106 if (authentication_info->rsp_auth) {
2107 error=belle_sip_snprintf(buff,buff_size,offset,"%srspauth=\"%s\"", border,authentication_info->rsp_auth);
2108 border=", ";
2109 }
2110 if (error!=BELLE_SIP_OK) return error;
2111
2112 if (authentication_info->cnonce) {
2113 error=belle_sip_snprintf(buff,buff_size,offset,"%scnonce=\"%s\"", border, authentication_info->cnonce);
2114 border=", ";
2115 }
2116 if (error!=BELLE_SIP_OK) return error;
2117
2118 if (authentication_info->nonce_count >= 0) {
2119 error=belle_sip_snprintf(buff,buff_size,offset,"%snc=%08x", border, authentication_info->nonce_count);
2120 border=", ";
2121 }
2122 if (error!=BELLE_SIP_OK) return error;
2123
2124 if (authentication_info->qop) {
2125 error=belle_sip_snprintf(buff,buff_size,offset,"%sqop=%s", border, authentication_info->qop);
2126 border=", ";
2127 }
2128 if (error!=BELLE_SIP_OK) return error;
2129
2130 if (authentication_info->next_nonce) {
2131 error=belle_sip_snprintf(buff,buff_size,offset,"%snextnonce=\"%s\"", border, authentication_info->next_nonce);
2132 }
2133 return error;
2134
2135
2136 }
belle_sip_header_authentication_info_init(belle_sip_header_authentication_info_t * header_authentication)2137 void belle_sip_header_authentication_info_init(belle_sip_header_authentication_info_t* header_authentication) {
2138 header_authentication->nonce_count=-1;
2139 }
2140 BELLE_SIP_NEW_HEADER_INIT(header_authentication_info,header,BELLE_SIP_AUTHENTICATION_INFO,header_authentication_info)
2141 BELLE_SIP_PARSE(header_authentication_info)
2142 GET_SET_STRING(belle_sip_header_authentication_info,rsp_auth);
2143 GET_SET_STRING(belle_sip_header_authentication_info,qop);
2144 GET_SET_STRING(belle_sip_header_authentication_info,next_nonce);
2145 GET_SET_STRING(belle_sip_header_authentication_info,cnonce);
2146 GET_SET_INT(belle_sip_header_authentication_info,nonce_count,int);
2147