blob: 41c9be8537d0ba087544357dd633c454bfd78cce [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*********************************************************************************************************
2* Software License Agreement (BSD License) *
3* Author: Sebastien Decugis <sdecugis@freediameter.net> *
4* *
5* Copyright (c) 2013, WIDE Project and NICT *
6* All rights reserved. *
7* *
8* Redistribution and use of this software in source and binary forms, with or without modification, are *
9* permitted provided that the following conditions are met: *
10* *
11* * Redistributions of source code must retain the above *
12* copyright notice, this list of conditions and the *
13* following disclaimer. *
14* *
15* * Redistributions in binary form must reproduce the above *
16* copyright notice, this list of conditions and the *
17* following disclaimer in the documentation and/or other *
18* materials provided with the distribution. *
19* *
20* * Neither the name of the WIDE Project or NICT nor the *
21* names of its contributors may be used to endorse or *
22* promote products derived from this software without *
23* specific prior written permission of WIDE Project and *
24* NICT. *
25* *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34*********************************************************************************************************/
35
36/* Do not include this directly, use dbg_interactive.i instead */
37
38/****** DICTIONARY *********/
39
40struct dictionary {
41};
42
43%extend dictionary {
44 dictionary() {
45 struct dictionary * r = NULL;
46 int ret = fd_dict_init(&r);
47 if (ret != 0) {
48 DI_ERROR(ret, NULL, NULL);
49 return NULL;
50 }
51 return r;
52 }
53 ~dictionary() {
54 struct dictionary *d = self;
55 int ret = fd_dict_fini(&d);
56 if (ret != 0) {
57 DI_ERROR(ret, NULL, NULL);
58 }
59 return;
60 }
61 void dump() {
62 char * buf = NULL;
63 size_t len;
64 printf("%s", fd_dict_dump(&buf, &len, NULL, $self));
65 free(buf);
66 }
67 PyObject * vendors_list() {
68 uint32_t *list = NULL, *li;
69 PyObject * ret;
70 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
71 ret = PyList_New(0);
72 list = fd_dict_get_vendorid_list($self);
73 for (li = list; *li != 0; li++) {
74 PyList_Append(ret, PyInt_FromLong((long)*li));
75 }
76 free(list);
77 SWIG_PYTHON_THREAD_END_BLOCK;
78 return ret;
79 }
80 struct dict_object * new_obj(enum dict_object_type type, void * data, struct dict_object * parent = NULL) {
81 struct dict_object * obj = NULL;
82 int ret = fd_dict_new($self, type, data, parent, &obj);
83 if (ret != 0) {
84 DI_ERROR(ret, NULL, NULL);
85 return NULL;
86 }
87 return obj;
88 }
89 struct dict_object * search(enum dict_object_type type, int criteria, int what_by_val) {
90 struct dict_object * obj = NULL;
91 int ret = fd_dict_search ( $self, type, criteria, &what_by_val, &obj, ENOENT );
92 if (ret != 0) {
93 DI_ERROR(ret, NULL, NULL);
94 return NULL;
95 }
96 return obj;
97 }
98 struct dict_object * search(enum dict_object_type type, int criteria, char * what_by_string) {
99 struct dict_object * obj = NULL;
100 int ret = fd_dict_search ( $self, type, criteria, what_by_string, &obj, ENOENT );
101 if (ret != 0) {
102 DI_ERROR(ret, NULL, NULL);
103 return NULL;
104 }
105 return obj;
106 }
107 struct dict_object * search(enum dict_object_type type, int criteria, void * what) {
108 struct dict_object * obj = NULL;
109 int ret = fd_dict_search ( $self, type, criteria, what, &obj, ENOENT );
110 if (ret != 0) {
111 DI_ERROR(ret, NULL, NULL);
112 return NULL;
113 }
114 return obj;
115 }
116 struct dict_object * error_cmd() {
117 struct dict_object * obj = NULL;
118 int ret = fd_dict_get_error_cmd ( $self, &obj );
119 if (ret != 0) {
120 DI_ERROR(ret, NULL, NULL);
121 return NULL;
122 }
123 return obj;
124 }
125}
126
127%nodefaultctor dict_object;
128struct dict_object {
129};
130
131%extend dict_object {
132 void dump() {
133 char * buf = NULL;
134 size_t len;
135 printf("%s", fd_dict_dump_object(&buf, &len, NULL, $self));
136 free(buf);
137 }
138 enum dict_object_type gettype() {
139 enum dict_object_type t;
140 int ret = fd_dict_gettype ( $self, &t);
141 if (ret != 0) {
142 DI_ERROR(ret, NULL, NULL);
143 return 0;
144 }
145 return t;
146 }
147 struct dictionary * getdict() {
148 struct dictionary *d;
149 int ret = fd_dict_getdict ( $self, &d );
150 if (ret != 0) {
151 DI_ERROR(ret, NULL, NULL);
152 return NULL;
153 }
154 return d;
155 }
156 /* Since casting the pointer requires intelligence, we do it here instead of giving it to SWIG */
157 PyObject * getval() {
158 /* first, get the type */
159 enum dict_object_type t;
160 int ret = fd_dict_gettype ( $self, &t);
161 if (ret != 0) {
162 DI_ERROR(ret, NULL, NULL);
163 return NULL;
164 }
165 switch (t) {
166%define %GETVAL_CASE(TYPE,STRUCT)
167 case TYPE: {
168 PyObject * v = NULL;
169 struct STRUCT * data = NULL;
170 data = malloc(sizeof(struct STRUCT));
171 if (!data) {
172 DI_ERROR_MALLOC;
173 return NULL;
174 }
175 ret = fd_dict_getval($self, data);
176 if (ret != 0) {
177 DI_ERROR(ret, NULL, NULL);
178 free(data);
179 return NULL;
180 }
181 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
182 v = SWIG_NewPointerObj((void *)data, SWIGTYPE_p_##STRUCT, SWIG_POINTER_OWN );
183 Py_XINCREF(v);
184 SWIG_PYTHON_THREAD_END_BLOCK;
185 return v;
186 } break
187%enddef
188 %GETVAL_CASE( DICT_VENDOR, dict_vendor_data );
189 %GETVAL_CASE( DICT_APPLICATION, dict_application_data );
190 %GETVAL_CASE( DICT_TYPE, dict_type_data );
191 %GETVAL_CASE( DICT_ENUMVAL, dict_enumval_data );
192 %GETVAL_CASE( DICT_AVP, dict_avp_data );
193 %GETVAL_CASE( DICT_COMMAND, dict_cmd_data );
194 %GETVAL_CASE( DICT_RULE, dict_rule_data );
195 default:
196 DI_ERROR(EINVAL, PyExc_SystemError, "Internal error: Got invalid object type");
197 }
198 return NULL;
199 }
200}
201
202
203/* The following wrapper leaks memory each time an union avp_value is assigned an octet string.
204 TODO: fix this leak by better understanding SWIG...
205 -- the alternative is to uncomment the "free" statements below, but then it is easy to
206 create a segmentation fault by assigning first an integer, then an octetstring.
207 */
208%extend avp_value {
209 /* The following hack in the proxy file allows assigning the octet string directly like this:
210 avp_value.os = "blabla"
211 */
212 %pythoncode
213 {
214 __swig_setmethods__["os"] = _fDpy.avp_value_os_set
215 if _newclass:os = _swig_property(_fDpy.avp_value_os_get, _fDpy.avp_value_os_set)
216 }
217 void os_set(char *STRING, size_t LENGTH) {
218 /* free($self->os.data); -- do not free, in case the previous value was not an OS */
219 $self->os.data = malloc(LENGTH);
220 if (!$self->os.data) {
221 DI_ERROR_MALLOC;
222 return;
223 }
224 memcpy($self->os.data, STRING, LENGTH);
225 $self->os.len = LENGTH;
226 }
227 void os_set(avp_value_os * os) {
228 /* free($self->os.data); -- do not free, in case the previous value was not an OS */
229 $self->os.data = malloc(os->len);
230 if (!$self->os.data) {
231 DI_ERROR_MALLOC;
232 return;
233 }
234 memcpy($self->os.data, os->data, os->len);
235 $self->os.len = os->len;
236 }
237};
238
239%extend avp_value_os {
240 void dump() {
241 %#define LEN_MAX 20
242 int i, n=LEN_MAX;
243 if ($self->len < LEN_MAX)
244 n = $self->len;
245 fd_log_debug("l:%u, v:[", $self->len);
246 for (i=0; i < n; i++)
247 fd_log_debug("%02.2X", $self->data[i]);
248 fd_log_debug("] '%.*s%s'", n, $self->data, n == LEN_MAX ? "..." : "");
249 }
250 %cstring_output_allocate_size(char ** outbuffer, size_t * outlen, free(*$1));
251 void as_str ( char ** outbuffer, size_t * outlen ) {
252 char * b;
253 if (!$self->len) {
254 *outlen = 0;
255 *outbuffer = NULL;
256 return;
257 }
258 b = malloc($self->len);
259 if (!b) {
260 DI_ERROR_MALLOC;
261 return;
262 }
263 memcpy(b, $self->data, $self->len);
264 *outlen = $self->len;
265 *outbuffer = b;
266 }
267}
268
269
270/* Allow constructors with parameters for the dict_*_data */
271%extend dict_vendor_data {
272 dict_vendor_data(uint32_t id = 0, char * name = NULL) {
273 struct dict_vendor_data * d = (struct dict_vendor_data *)calloc(1, sizeof(struct dict_vendor_data));
274 if (!d) {
275 DI_ERROR_MALLOC;
276 return NULL;
277 }
278 d->vendor_id = id;
279 if (name) {
280 d->vendor_name = strdup(name);
281 if (!d->vendor_name) {
282 DI_ERROR_MALLOC;
283 free(d);
284 return NULL;
285 }
286 }
287 return d;
288 }
289}
290
291%extend dict_application_data {
292 dict_application_data(uint32_t id = 0, char * name = NULL) {
293 struct dict_application_data * d = (struct dict_application_data *)calloc(1, sizeof(struct dict_application_data));
294 if (!d) {
295 DI_ERROR_MALLOC;
296 return NULL;
297 }
298 d->application_id = id;
299 if (name) {
300 d->application_name = strdup(name);
301 if (!d->application_name) {
302 DI_ERROR_MALLOC;
303 free(d);
304 return NULL;
305 }
306 }
307 return d;
308 }
309}
310
311%extend dict_type_data {
312 dict_type_data(enum dict_avp_basetype base = 0, char * name = NULL) {
313 struct dict_type_data * d = (struct dict_type_data *)calloc(1, sizeof(struct dict_type_data));
314 if (!d) {
315 DI_ERROR_MALLOC;
316 return NULL;
317 }
318 d->type_base = base;
319 if (name) {
320 d->type_name = strdup(name);
321 if (!d->type_name) {
322 DI_ERROR_MALLOC;
323 free(d);
324 return NULL;
325 }
326 }
327 return d;
328 }
329}
330
331%extend dict_enumval_data {
332 dict_enumval_data(char * name = NULL, uint32_t v = 0) {
333 struct dict_enumval_data * d = (struct dict_enumval_data *)calloc(1, sizeof(struct dict_enumval_data));
334 if (!d) {
335 DI_ERROR_MALLOC;
336 return NULL;
337 }
338 if (name) {
339 d->enum_name = strdup(name);
340 if (!d->enum_name) {
341 DI_ERROR_MALLOC;
342 free(d);
343 return NULL;
344 }
345 }
346 d->enum_value.u32 = v;
347 return d;
348 }
349}
350
351%extend dict_avp_data {
352 dict_avp_data(uint32_t code = 0, char * name = NULL, enum dict_avp_basetype basetype = 0, uint32_t vendor = 0, int mandatory=0) {
353 struct dict_avp_data * d = (struct dict_avp_data *)calloc(1, sizeof(struct dict_avp_data));
354 if (!d) {
355 DI_ERROR_MALLOC;
356 return NULL;
357 }
358 if (name) {
359 d->avp_name = strdup(name);
360 if (!d->avp_name) {
361 DI_ERROR_MALLOC;
362 free(d);
363 return NULL;
364 }
365 }
366 d->avp_code = code;
367 d->avp_basetype = basetype;
368 d->avp_vendor = vendor;
369 if (vendor) {
370 d->avp_flag_val |= AVP_FLAG_VENDOR;
371 d->avp_flag_mask |= AVP_FLAG_VENDOR;
372 }
373 d->avp_flag_mask |= AVP_FLAG_MANDATORY;
374 if (mandatory)
375 d->avp_flag_val |= AVP_FLAG_MANDATORY;
376 return d;
377 }
378}
379
380%extend dict_cmd_data {
381 dict_cmd_data(uint32_t code = 0, char * name = NULL, int request = 1) {
382 struct dict_cmd_data * d = (struct dict_cmd_data *)calloc(1, sizeof(struct dict_cmd_data));
383 if (!d) {
384 DI_ERROR_MALLOC;
385 return NULL;
386 }
387 if (name) {
388 d->cmd_name = strdup(name);
389 if (!d->cmd_name) {
390 DI_ERROR_MALLOC;
391 free(d);
392 return NULL;
393 }
394 }
395 d->cmd_code = code;
396 d->cmd_flag_mask = CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE;
397 d->cmd_flag_val = CMD_FLAG_PROXIABLE | ( request ? CMD_FLAG_REQUEST : 0 );
398 return d;
399 }
400}
401
402%extend dict_rule_data {
403 dict_rule_data(struct dict_object *avp = NULL, enum rule_position pos = 0, int min = -1, int max = -1 ) {
404 struct dict_rule_data * d = (struct dict_rule_data *)calloc(1, sizeof(struct dict_rule_data));
405 if (!d) {
406 DI_ERROR_MALLOC;
407 return NULL;
408 }
409 d->rule_avp = avp;
410 d->rule_position = pos;
411 d->rule_order = 1;
412 d->rule_min = min;
413 d->rule_max = max;
414 return d;
415 }
416}
417