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