blob: 41c9be8537d0ba087544357dd633c454bfd78cce [file] [log] [blame]
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@freediameter.net> *
* *
* Copyright (c) 2013, WIDE Project and NICT *
* All rights reserved. *
* *
* Redistribution and use of this software in source and binary forms, with or without modification, are *
* permitted provided that the following conditions are met: *
* *
* * Redistributions of source code must retain the above *
* copyright notice, this list of conditions and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other *
* materials provided with the distribution. *
* *
* * Neither the name of the WIDE Project or NICT nor the *
* names of its contributors may be used to endorse or *
* promote products derived from this software without *
* specific prior written permission of WIDE Project and *
* NICT. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*********************************************************************************************************/
/* Do not include this directly, use dbg_interactive.i instead */
/****** DICTIONARY *********/
struct dictionary {
};
%extend dictionary {
dictionary() {
struct dictionary * r = NULL;
int ret = fd_dict_init(&r);
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return NULL;
}
return r;
}
~dictionary() {
struct dictionary *d = self;
int ret = fd_dict_fini(&d);
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
}
return;
}
void dump() {
char * buf = NULL;
size_t len;
printf("%s", fd_dict_dump(&buf, &len, NULL, $self));
free(buf);
}
PyObject * vendors_list() {
uint32_t *list = NULL, *li;
PyObject * ret;
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
ret = PyList_New(0);
list = fd_dict_get_vendorid_list($self);
for (li = list; *li != 0; li++) {
PyList_Append(ret, PyInt_FromLong((long)*li));
}
free(list);
SWIG_PYTHON_THREAD_END_BLOCK;
return ret;
}
struct dict_object * new_obj(enum dict_object_type type, void * data, struct dict_object * parent = NULL) {
struct dict_object * obj = NULL;
int ret = fd_dict_new($self, type, data, parent, &obj);
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return NULL;
}
return obj;
}
struct dict_object * search(enum dict_object_type type, int criteria, int what_by_val) {
struct dict_object * obj = NULL;
int ret = fd_dict_search ( $self, type, criteria, &what_by_val, &obj, ENOENT );
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return NULL;
}
return obj;
}
struct dict_object * search(enum dict_object_type type, int criteria, char * what_by_string) {
struct dict_object * obj = NULL;
int ret = fd_dict_search ( $self, type, criteria, what_by_string, &obj, ENOENT );
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return NULL;
}
return obj;
}
struct dict_object * search(enum dict_object_type type, int criteria, void * what) {
struct dict_object * obj = NULL;
int ret = fd_dict_search ( $self, type, criteria, what, &obj, ENOENT );
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return NULL;
}
return obj;
}
struct dict_object * error_cmd() {
struct dict_object * obj = NULL;
int ret = fd_dict_get_error_cmd ( $self, &obj );
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return NULL;
}
return obj;
}
}
%nodefaultctor dict_object;
struct dict_object {
};
%extend dict_object {
void dump() {
char * buf = NULL;
size_t len;
printf("%s", fd_dict_dump_object(&buf, &len, NULL, $self));
free(buf);
}
enum dict_object_type gettype() {
enum dict_object_type t;
int ret = fd_dict_gettype ( $self, &t);
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return 0;
}
return t;
}
struct dictionary * getdict() {
struct dictionary *d;
int ret = fd_dict_getdict ( $self, &d );
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return NULL;
}
return d;
}
/* Since casting the pointer requires intelligence, we do it here instead of giving it to SWIG */
PyObject * getval() {
/* first, get the type */
enum dict_object_type t;
int ret = fd_dict_gettype ( $self, &t);
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
return NULL;
}
switch (t) {
%define %GETVAL_CASE(TYPE,STRUCT)
case TYPE: {
PyObject * v = NULL;
struct STRUCT * data = NULL;
data = malloc(sizeof(struct STRUCT));
if (!data) {
DI_ERROR_MALLOC;
return NULL;
}
ret = fd_dict_getval($self, data);
if (ret != 0) {
DI_ERROR(ret, NULL, NULL);
free(data);
return NULL;
}
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
v = SWIG_NewPointerObj((void *)data, SWIGTYPE_p_##STRUCT, SWIG_POINTER_OWN );
Py_XINCREF(v);
SWIG_PYTHON_THREAD_END_BLOCK;
return v;
} break
%enddef
%GETVAL_CASE( DICT_VENDOR, dict_vendor_data );
%GETVAL_CASE( DICT_APPLICATION, dict_application_data );
%GETVAL_CASE( DICT_TYPE, dict_type_data );
%GETVAL_CASE( DICT_ENUMVAL, dict_enumval_data );
%GETVAL_CASE( DICT_AVP, dict_avp_data );
%GETVAL_CASE( DICT_COMMAND, dict_cmd_data );
%GETVAL_CASE( DICT_RULE, dict_rule_data );
default:
DI_ERROR(EINVAL, PyExc_SystemError, "Internal error: Got invalid object type");
}
return NULL;
}
}
/* The following wrapper leaks memory each time an union avp_value is assigned an octet string.
TODO: fix this leak by better understanding SWIG...
-- the alternative is to uncomment the "free" statements below, but then it is easy to
create a segmentation fault by assigning first an integer, then an octetstring.
*/
%extend avp_value {
/* The following hack in the proxy file allows assigning the octet string directly like this:
avp_value.os = "blabla"
*/
%pythoncode
{
__swig_setmethods__["os"] = _fDpy.avp_value_os_set
if _newclass:os = _swig_property(_fDpy.avp_value_os_get, _fDpy.avp_value_os_set)
}
void os_set(char *STRING, size_t LENGTH) {
/* free($self->os.data); -- do not free, in case the previous value was not an OS */
$self->os.data = malloc(LENGTH);
if (!$self->os.data) {
DI_ERROR_MALLOC;
return;
}
memcpy($self->os.data, STRING, LENGTH);
$self->os.len = LENGTH;
}
void os_set(avp_value_os * os) {
/* free($self->os.data); -- do not free, in case the previous value was not an OS */
$self->os.data = malloc(os->len);
if (!$self->os.data) {
DI_ERROR_MALLOC;
return;
}
memcpy($self->os.data, os->data, os->len);
$self->os.len = os->len;
}
};
%extend avp_value_os {
void dump() {
%#define LEN_MAX 20
int i, n=LEN_MAX;
if ($self->len < LEN_MAX)
n = $self->len;
fd_log_debug("l:%u, v:[", $self->len);
for (i=0; i < n; i++)
fd_log_debug("%02.2X", $self->data[i]);
fd_log_debug("] '%.*s%s'", n, $self->data, n == LEN_MAX ? "..." : "");
}
%cstring_output_allocate_size(char ** outbuffer, size_t * outlen, free(*$1));
void as_str ( char ** outbuffer, size_t * outlen ) {
char * b;
if (!$self->len) {
*outlen = 0;
*outbuffer = NULL;
return;
}
b = malloc($self->len);
if (!b) {
DI_ERROR_MALLOC;
return;
}
memcpy(b, $self->data, $self->len);
*outlen = $self->len;
*outbuffer = b;
}
}
/* Allow constructors with parameters for the dict_*_data */
%extend dict_vendor_data {
dict_vendor_data(uint32_t id = 0, char * name = NULL) {
struct dict_vendor_data * d = (struct dict_vendor_data *)calloc(1, sizeof(struct dict_vendor_data));
if (!d) {
DI_ERROR_MALLOC;
return NULL;
}
d->vendor_id = id;
if (name) {
d->vendor_name = strdup(name);
if (!d->vendor_name) {
DI_ERROR_MALLOC;
free(d);
return NULL;
}
}
return d;
}
}
%extend dict_application_data {
dict_application_data(uint32_t id = 0, char * name = NULL) {
struct dict_application_data * d = (struct dict_application_data *)calloc(1, sizeof(struct dict_application_data));
if (!d) {
DI_ERROR_MALLOC;
return NULL;
}
d->application_id = id;
if (name) {
d->application_name = strdup(name);
if (!d->application_name) {
DI_ERROR_MALLOC;
free(d);
return NULL;
}
}
return d;
}
}
%extend dict_type_data {
dict_type_data(enum dict_avp_basetype base = 0, char * name = NULL) {
struct dict_type_data * d = (struct dict_type_data *)calloc(1, sizeof(struct dict_type_data));
if (!d) {
DI_ERROR_MALLOC;
return NULL;
}
d->type_base = base;
if (name) {
d->type_name = strdup(name);
if (!d->type_name) {
DI_ERROR_MALLOC;
free(d);
return NULL;
}
}
return d;
}
}
%extend dict_enumval_data {
dict_enumval_data(char * name = NULL, uint32_t v = 0) {
struct dict_enumval_data * d = (struct dict_enumval_data *)calloc(1, sizeof(struct dict_enumval_data));
if (!d) {
DI_ERROR_MALLOC;
return NULL;
}
if (name) {
d->enum_name = strdup(name);
if (!d->enum_name) {
DI_ERROR_MALLOC;
free(d);
return NULL;
}
}
d->enum_value.u32 = v;
return d;
}
}
%extend dict_avp_data {
dict_avp_data(uint32_t code = 0, char * name = NULL, enum dict_avp_basetype basetype = 0, uint32_t vendor = 0, int mandatory=0) {
struct dict_avp_data * d = (struct dict_avp_data *)calloc(1, sizeof(struct dict_avp_data));
if (!d) {
DI_ERROR_MALLOC;
return NULL;
}
if (name) {
d->avp_name = strdup(name);
if (!d->avp_name) {
DI_ERROR_MALLOC;
free(d);
return NULL;
}
}
d->avp_code = code;
d->avp_basetype = basetype;
d->avp_vendor = vendor;
if (vendor) {
d->avp_flag_val |= AVP_FLAG_VENDOR;
d->avp_flag_mask |= AVP_FLAG_VENDOR;
}
d->avp_flag_mask |= AVP_FLAG_MANDATORY;
if (mandatory)
d->avp_flag_val |= AVP_FLAG_MANDATORY;
return d;
}
}
%extend dict_cmd_data {
dict_cmd_data(uint32_t code = 0, char * name = NULL, int request = 1) {
struct dict_cmd_data * d = (struct dict_cmd_data *)calloc(1, sizeof(struct dict_cmd_data));
if (!d) {
DI_ERROR_MALLOC;
return NULL;
}
if (name) {
d->cmd_name = strdup(name);
if (!d->cmd_name) {
DI_ERROR_MALLOC;
free(d);
return NULL;
}
}
d->cmd_code = code;
d->cmd_flag_mask = CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE;
d->cmd_flag_val = CMD_FLAG_PROXIABLE | ( request ? CMD_FLAG_REQUEST : 0 );
return d;
}
}
%extend dict_rule_data {
dict_rule_data(struct dict_object *avp = NULL, enum rule_position pos = 0, int min = -1, int max = -1 ) {
struct dict_rule_data * d = (struct dict_rule_data *)calloc(1, sizeof(struct dict_rule_data));
if (!d) {
DI_ERROR_MALLOC;
return NULL;
}
d->rule_avp = avp;
d->rule_position = pos;
d->rule_order = 1;
d->rule_min = min;
d->rule_max = max;
return d;
}
}