Merge kamailio modules into sip-router master branch
[sip-router] / modules / carrierroute / cr_fixup.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2007-2008 1&1 Internet AG
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License 
19  * along with this program; if not, write to the Free Software 
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /**
24  * \file cr_fixup.c
25  * \brief Fixup functions.
26  * \ingroup carrierroute
27  * - Module; \ref carrierroute
28  */
29
30 #include "../../mod_fix.h"
31 #include "../../mem/mem.h"
32 #include "cr_fixup.h"
33 #include "carrierroute.h"
34 #include "cr_map.h"
35 #include "cr_domain.h"
36 #include "prime_hash.h"
37 #include "cr_data.h"
38
39
40 /**
41  * The fixup funcions will use the initial mapping.
42  * If the mapping changes afterwards (eg. due to cr_reload_routes),
43  * the names used in the routing script will not be mapped
44  * to the correct IDs!
45  * @param name carrier name
46  * @return carrier id
47  */
48 static int carrier_name_2_id(const str *name) {
49         int id;
50         struct route_data_t * rd;
51         
52         do {
53                 rd = get_data();
54         } while (rd == NULL);
55
56         id = map_name2id(rd->carrier_map, rd->carrier_num, name);
57         
58         release_data(rd);
59
60         return id;
61 }
62
63
64 /**
65  * The fixup funcions will use the initial mapping.
66  * If the mapping changes afterwards (eg. due to cr_reload_routes),
67  * the names used in the routing script will not be mapped
68  * to the correct IDs!
69  * @param name domain name
70  * @return domain id 
71  */
72 static int domain_name_2_id(const str *name) {
73         int id;
74         struct route_data_t * rd;
75
76         do {
77                 rd = get_data();
78         } while (rd == NULL);
79         
80         id = map_name2id(rd->domain_map, rd->domain_num, name);
81         
82         release_data(rd);
83
84         return id;
85 }
86
87
88 /**
89  * Fixes the hash source to enum values
90  *
91  * @param my_hash_source the hash source as string
92  *
93  * @return the enum value on success, -1 on failure
94  */
95 static enum hash_source hash_fixup(const char * my_hash_source) {
96         if (strcasecmp("call_id", my_hash_source) == 0) {
97                 return shs_call_id;
98         } else if (strcasecmp("from_uri", my_hash_source) == 0) {
99                 return shs_from_uri;
100         } else if (strcasecmp("from_user", my_hash_source) == 0) {
101                 return shs_from_user;
102         } else if (strcasecmp("to_uri", my_hash_source) == 0) {
103                 return shs_to_uri;
104         } else if (strcasecmp("to_user", my_hash_source) == 0) {
105                 return shs_to_user;
106         } else {
107                 return shs_error;
108         }
109 }
110
111
112 /**
113  * Fixes the module functions' parameters if it is a carrier.
114  * supports name string and PVs.
115  *
116  * @param param the parameter
117  *
118  * @return 0 on success, -1 on failure
119  */
120 static int carrier_fixup(void ** param) {
121         int id;
122
123         if (fixup_spve_null(param, 1) !=0) {
124                 LM_ERR("could not fixup parameter");
125                 return -1;
126         }
127
128         if (((gparam_p)(*param))->type == GPARAM_TYPE_STR) {
129                 /* This is a name string, convert to a int */
130                 ((gparam_p)(*param))->type=GPARAM_TYPE_INT;
131                 /* get carrier id */
132                 if ((id = carrier_name_2_id(&((gparam_p)(*param))->v.str)) < 0) {
133                         LM_ERR("could not find carrier name '%.*s' in map\n", ((gparam_p)(*param))->v.str.len, ((gparam_p)(*param))->v.str.s);
134                         pkg_free(*param);
135                         return -1;
136                 }
137                 ((gparam_p)(*param))->v.i = id;
138         }
139         return 0;
140 }
141
142
143 /**
144  * Fixes the module functions' parameters if it is a domain.
145  * supports name string, and PVs.
146  *
147  * @param param the parameter
148  *
149  * @return 0 on success, -1 on failure
150  */
151 static int domain_fixup(void ** param) {
152         int id;
153
154         if (fixup_spve_null(param, 1) !=0) {
155                 LM_ERR("could not fixup parameter");
156                 return -1;
157         }
158
159         if (((gparam_p)(*param))->type == GPARAM_TYPE_STR) {
160                 /* This is a name string, convert to a int */
161                 ((gparam_p)(*param))->type=GPARAM_TYPE_INT;
162                 /* get domain id */
163                 if ((id = domain_name_2_id(&(((gparam_p)(*param))->v.str))) < 0) {
164                         LM_ERR("could not find domain name '%.*s' in map\n", ((gparam_p)(*param))->v.str.len, ((gparam_p)(*param))->v.str.s);
165                         pkg_free(*param);
166                         return -1;
167                 }
168                 ((gparam_p)(*param))->v.i = id;
169         }
170         return 0;
171 }
172
173
174 /**
175  * Fixes the module functions' parameters in case of AVP names.
176  *
177  * @param param the parameter
178  *
179  * @return 0 on success, -1 on failure
180  */
181 static int avp_name_fixup(void ** param) {
182
183         if (fixup_spve_null(param, 1) !=0) {
184                 LM_ERR("could not fixup parameter");
185                 return -1;
186         }
187         if (((gparam_p)(*param))->v.pve->spec.type == PVT_AVP &&
188                         ((gparam_p)(*param))->v.pve->spec.pvp.pvn.u.isname.name.s.len == 0 &&
189                         ((gparam_p)(*param))->v.pve->spec.pvp.pvn.u.isname.name.s.s == 0) {
190                 LM_ERR("malformed or non AVP type definition\n");
191                 return -1;
192         }
193         return 0;
194 }
195
196
197 /**
198  * Fixes the module functions' parameters, i.e. it maps
199  * the routing domain names to numbers for faster access
200  * at runtime
201  *
202  * @param param the parameter
203  * @param param_no the number of the parameter
204  *
205  * @return 0 on success, -1 on failure
206  */
207 int cr_route_fixup(void ** param, int param_no) {
208         enum hash_source my_hash_source;
209
210         if (param_no == 1) {
211                 /* carrier */
212                 if (carrier_fixup(param) < 0) {
213                         LM_ERR("cannot fixup parameter %d\n", param_no);
214                         return -1;
215                 }
216         }
217         else if (param_no == 2) {
218                 /* domain */
219                 if (domain_fixup(param) < 0) {
220                         LM_ERR("cannot fixup parameter %d\n", param_no);
221                         return -1;
222                 }
223         }
224         else if ((param_no == 3) || (param_no == 4)){
225                 /* prefix matching, rewrite user */
226                 if (fixup_spve_null(param, 1) != 0) {
227                         LM_ERR("cannot fixup parameter %d\n", param_no);
228                         return -1;
229                 }
230         }
231         else if (param_no == 5) {
232                 /* hash source */
233                 if ((my_hash_source = hash_fixup((char *)*param)) == shs_error) {
234                         LM_ERR("invalid hash source\n");
235                         return -1;
236                 }
237                 pkg_free(*param);
238                 *param = (void *)my_hash_source;
239         }
240         else if (param_no == 6) {
241                 /* destination avp name */
242                 if (avp_name_fixup(param) < 0) {
243                         LM_ERR("cannot fixup parameter %d\n", param_no);
244                         return -1;
245                 }
246         }
247
248         return 0;
249 }
250
251
252 /**
253  * fixes the module functions' parameters, i.e. it maps
254  * the routing domain names to numbers for faster access
255  * at runtime
256  *
257  * @param param the parameter
258  * @param param_no the number of the parameter
259  *
260  * @return 0 on success, -1 on failure
261  */
262 int cr_load_next_domain_fixup(void ** param, int param_no) {
263         if (param_no == 1) {
264                 /* carrier */
265                 if (carrier_fixup(param) < 0) {
266                         LM_ERR("cannot fixup parameter %d\n", param_no);
267                         return -1;
268                 }
269         }
270         else if (param_no == 2) {
271                 /* domain */
272                 if (domain_fixup(param) < 0) {
273                         LM_ERR("cannot fixup parameter %d\n", param_no);
274                         return -1;
275                 }
276         }
277         else if ((param_no == 3) || (param_no == 4) || (param_no == 5)) {
278                 /* prefix matching, host, reply code */
279                 if (fixup_spve_null(param, 1) != 0) {
280                         LM_ERR("cannot fixup parameter %d\n", param_no);
281                         return -1;
282                 }
283         }
284         else if (param_no == 6) {
285                 /* destination avp name */
286                 if (avp_name_fixup(param) < 0) {
287                         LM_ERR("cannot fixup parameter %d\n", param_no);
288                         return -1;
289                 }
290         }
291
292         return 0;
293 }
294
295
296 /**
297  * Fixes the module functions' parameters.
298  *
299  * @param param the parameter
300  * @param param_no the number of the parameter
301  *
302  * @return 0 on success, -1 on failure
303  */
304 int cr_load_user_carrier_fixup(void ** param, int param_no) {
305         if (mode == CARRIERROUTE_MODE_FILE) {
306                 LM_ERR("command cr_user_rewrite_uri can't be used in file mode\n");
307                 return -1;
308         }
309
310         if ((param_no == 1) || (param_no == 2)) {
311                 /* user, domain */
312                 if (fixup_spve_null(param, 1) != 0) {
313                         LM_ERR("cannot fixup parameter %d\n", param_no);
314                         return -1;
315                 }
316         }
317         else if (param_no == 3) {
318                 /* destination avp name */
319                 if (avp_name_fixup(param) < 0) {
320                         LM_ERR("cannot fixup parameter %d\n", param_no);
321                         return -1;
322                 }
323         }
324
325         return 0;
326 }