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 #include "belle-sip/belle-sip.h"
19 #include "belle-sip/parameters.h"
20 #include "belle_sip_internal.h"
21 #include "belle-sip/headers.h"
22 
belle_sip_parameters_init(belle_sip_parameters_t * obj)23 void belle_sip_parameters_init(belle_sip_parameters_t *obj){
24 }
25 
belle_sip_parameters_clean(belle_sip_parameters_t * params)26 void belle_sip_parameters_clean(belle_sip_parameters_t* params) {
27 	if (params->param_list) belle_sip_list_free_with_data (params->param_list, (void (*)(void*))belle_sip_param_pair_destroy);
28 	if (params->paramnames_list) belle_sip_list_free(params->paramnames_list);
29 	params->paramnames_list=NULL;
30 	params->param_list=NULL;
31 }
32 
belle_sip_parameters_destroy(belle_sip_parameters_t * params)33 static void belle_sip_parameters_destroy(belle_sip_parameters_t* params) {
34 	belle_sip_parameters_clean(params);
35 }
36 
belle_sip_parameters_copy_parameters_from(belle_sip_parameters_t * params,const belle_sip_parameters_t * orig)37 void belle_sip_parameters_copy_parameters_from(belle_sip_parameters_t *params, const belle_sip_parameters_t *orig){
38 	belle_sip_list_t* list=orig->param_list;
39 	for(;list!=NULL;list=list->next){
40 		belle_sip_param_pair_t* container = (belle_sip_param_pair_t* )(list->data);
41 		belle_sip_parameters_set_parameter( params,container->name,container->value);
42 	}
43 }
44 
belle_sip_parameters_clone(belle_sip_parameters_t * params,const belle_sip_parameters_t * orig)45 static void belle_sip_parameters_clone(belle_sip_parameters_t *params, const belle_sip_parameters_t *orig){
46 	belle_sip_parameters_copy_parameters_from(params,orig);
47 }
48 
49 
belle_sip_parameters_marshal(const belle_sip_parameters_t * params,char * buff,size_t buff_size,size_t * offset)50 belle_sip_error_code belle_sip_parameters_marshal(const belle_sip_parameters_t* params, char* buff, size_t buff_size, size_t *offset) {
51 	belle_sip_list_t* list=params->param_list;
52 	belle_sip_error_code error=BELLE_SIP_OK;
53 	for(;list!=NULL;list=list->next){
54 		belle_sip_param_pair_t* container = (belle_sip_param_pair_t* )(list->data);
55 		if (container->value) {
56 			error=belle_sip_snprintf(buff,buff_size,offset,";%s=%s", container->name, container->value);
57 		} else {
58 			error=belle_sip_snprintf(buff,buff_size,offset,";%s", container->name);
59 		}
60 		if (error!=BELLE_SIP_OK) return error;
61 	}
62 	return error;
63 }
64 BELLE_SIP_NEW_HEADER(parameters,header,"parameters")
belle_sip_parameters_get_parameters(const belle_sip_parameters_t * obj)65 const belle_sip_list_t *belle_sip_parameters_get_parameters(const belle_sip_parameters_t* obj) {
66 	return obj->param_list;
67 }
68 
belle_sip_parameters_get_parameter_base(const belle_sip_parameters_t * params,const char * name,belle_sip_compare_func func)69 const char* belle_sip_parameters_get_parameter_base(const belle_sip_parameters_t* params,const char* name,belle_sip_compare_func func) {
70 	belle_sip_list_t *  lResult = belle_sip_list_find_custom(params->param_list, func, name);
71 	if (lResult) {
72 		return ((belle_sip_param_pair_t*)(lResult->data))->value;
73 	}
74 	else {
75 		return NULL;
76 	}
77 }
belle_sip_parameters_get_parameter(const belle_sip_parameters_t * params,const char * name)78 const char* belle_sip_parameters_get_parameter(const belle_sip_parameters_t* params,const char* name) {
79 	return belle_sip_parameters_get_parameter_base(params,name,(belle_sip_compare_func)belle_sip_param_pair_comp_func);
80 }
belle_sip_parameters_get_case_parameter(const belle_sip_parameters_t * params,const char * name)81 const char* belle_sip_parameters_get_case_parameter(const belle_sip_parameters_t* params,const char* name) {
82 	return belle_sip_parameters_get_parameter_base(params,name,(belle_sip_compare_func)belle_sip_param_pair_case_comp_func);
83 }
84 
belle_sip_parameters_has_parameter(const belle_sip_parameters_t * params,const char * name)85 unsigned int belle_sip_parameters_has_parameter(const belle_sip_parameters_t* params,const char* name) {
86 	return belle_sip_list_find_custom(params->param_list, (belle_sip_compare_func)belle_sip_param_pair_comp_func, name) != NULL;
87 }
88 
belle_sip_parameters_set_parameter(belle_sip_parameters_t * params,const char * name,const char * value)89 void belle_sip_parameters_set_parameter(belle_sip_parameters_t* params,const char* name,const char* value) {
90 	/*1 check if present*/
91 	belle_sip_param_pair_t* lNewpair;
92 	belle_sip_list_t *  lResult = belle_sip_list_find_custom(params->paramnames_list, (belle_sip_compare_func)strcmp, name);
93 	/* first remove from header names list*/
94 	if (lResult) {
95 		params->paramnames_list=belle_sip_list_delete_link(params->paramnames_list,lResult);
96 	}
97 	/* next from header list*/
98 	lResult = belle_sip_list_find_custom(params->param_list, (belle_sip_compare_func)belle_sip_param_pair_comp_func, name);
99 	if (lResult) {
100 		belle_sip_param_pair_destroy(lResult->data);
101 		params->param_list=belle_sip_list_delete_link(params->param_list,lResult);
102 	}
103 	/* 2 insert*/
104 	lNewpair = belle_sip_param_pair_new(name,value);
105 	params->param_list=belle_sip_list_append(params->param_list,lNewpair);
106 	params->paramnames_list=belle_sip_list_append(params->paramnames_list,lNewpair->name);
107 }
108 
belle_sip_parameters_set(belle_sip_parameters_t * parameters,const char * params)109 void belle_sip_parameters_set(belle_sip_parameters_t *parameters, const char* params){
110 	belle_sip_parameters_clean(parameters);
111 	if (params && *params!='\0'){
112 		char *tmp=belle_sip_strdup(params);
113 		char *end_of_param;
114 		char *current=tmp;
115 		char *equal;
116 		char *next;
117 
118 		do{
119 			end_of_param=strchr(current,';');
120 			equal=strchr(current,'=');
121 			if (!end_of_param) {
122 				end_of_param=current+strlen(current);
123 				next=end_of_param;
124 			}else{
125 				*end_of_param='\0';
126 				next=end_of_param+1;
127 			}
128 			if (equal && equal<end_of_param){
129 				*equal='\0';
130 				belle_sip_parameters_set_parameter(parameters,current,equal+1);
131 			}else{
132 				belle_sip_parameters_set_parameter(parameters,current,NULL);
133 			}
134 			current=next;
135 		}while(*current!='\0');
136 		belle_sip_free(tmp);
137 	}
138 }
139 
belle_sip_parameters_get_parameter_names(const belle_sip_parameters_t * params)140 const belle_sip_list_t*	belle_sip_parameters_get_parameter_names(const belle_sip_parameters_t* params) {
141 	return params?params->paramnames_list:NULL;
142 }
143 
belle_sip_parameters_remove_parameter(belle_sip_parameters_t * params,const char * name)144 void belle_sip_parameters_remove_parameter(belle_sip_parameters_t* params,const char* name) {
145 	/*1 check if present*/
146 	belle_sip_list_t *  lResult = belle_sip_list_find_custom(params->paramnames_list, (belle_sip_compare_func)strcmp, name);
147 	/* first remove from header names list*/
148 	if (lResult) {
149 		params->paramnames_list=belle_sip_list_delete_link(params->paramnames_list,lResult);
150 		/*next remove node*/
151 		lResult = belle_sip_list_find_custom(params->param_list, (belle_sip_compare_func)belle_sip_param_pair_comp_func, name);
152 		if (lResult) {
153 			belle_sip_param_pair_destroy(lResult->data);
154 			params->param_list=belle_sip_list_delete_link(params->param_list,lResult);
155 		}
156 	}
157 }
158 
159