Initial commit
Change-Id: I6a4444e3c193dae437cd7929f4c39aba7b749efa
diff --git a/extensions/dbg_interactive/dictionary.i b/extensions/dbg_interactive/dictionary.i
new file mode 100644
index 0000000..41c9be8
--- /dev/null
+++ b/extensions/dbg_interactive/dictionary.i
@@ -0,0 +1,417 @@
+/*********************************************************************************************************
+* 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;
+ }
+}
+