mirror of
https://github.com/open5gs/open5gs.git
synced 2026-05-05 15:24:14 +00:00
417 lines
12 KiB
OpenEdge ABL
417 lines
12 KiB
OpenEdge ABL
/*********************************************************************************************************
|
|
* 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;
|
|
}
|
|
}
|
|
|