Navigation


Changeset 635:134e4fb9eef5 in freeDiameter


Ignore:
Timestamp:
Dec 14, 2010, 5:34:46 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Continued work on python interface

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • doc/dbg_interactive.py.sample

    r627 r635  
    8787############# Dictionary ############
    8888
    89 # Create a dedicated dictionary for our tests
     89##### Create a dedicated dictionary for our tests
    9090d = dictionary()
    9191d.dump()
     
    124124
    125125c.enum_name = "A_BUFFER_CONSTANT"
    126 osval = avp_value_os("This is a very long AVP value that we prefer to represent as a constant")
    127 c.enum_value.os = osval
     126c.enum_value.os = "This is a very long AVP value that we prefer to represent as a constant"
    128127c.enum_value.os.dump()
     128fd_dict_new(d, DICT_ENUMVAL, c, my_type_os)
     129del c
     130
     131# AVP
     132a = dict_avp_data()
     133a.avp_code = 234
     134a.avp_name = "my integer avp"
     135a.avp_flag_mask = AVP_FLAG_MANDATORY
     136a.avp_basetype = AVP_TYPE_INTEGER32
     137r, my_avp_int = fd_dict_new(d, DICT_AVP, a, my_type_int)
     138
     139a.avp_vendor = 123
     140a.avp_name = "my OS avp"
     141a.avp_flag_mask = AVP_FLAG_MANDATORY + AVP_FLAG_VENDOR
     142a.avp_flag_val = AVP_FLAG_VENDOR
     143a.avp_basetype = AVP_TYPE_OCTETSTRING
     144r, my_avp_os = fd_dict_new(d, DICT_AVP, a, my_type_os)
     145del a
     146
     147# Command
     148c = dict_cmd_data()
     149c.cmd_code = 345
     150c.cmd_name = "My-Python-Request"
     151c.cmd_flag_mask = CMD_FLAG_REQUEST + CMD_FLAG_PROXIABLE
     152c.cmd_flag_val = CMD_FLAG_REQUEST + CMD_FLAG_PROXIABLE
     153r, my_req = fd_dict_new(d, DICT_COMMAND, c, my_appl)
     154c.cmd_name = "My-Python-Answer"
     155c.cmd_flag_val = CMD_FLAG_PROXIABLE
     156r, my_ans = fd_dict_new(d, DICT_COMMAND, c, my_appl)
     157del c
     158
     159# Rule
     160rd = dict_rule_data()
     161rd.rule_avp = my_avp_int
     162rd.rule_position = RULE_REQUIRED
     163rd.rule_min = -1
     164rd.rule_max = -1
     165r, my_rule1 = fd_dict_new(d, DICT_RULE, rd, my_req)
     166r, my_rule2 = fd_dict_new(d, DICT_RULE, rd, my_ans)
     167rd.rule_avp = my_avp_os
     168r, my_rule3 = fd_dict_new(d, DICT_RULE, rd, my_req)
     169r, my_rule4 = fd_dict_new(d, DICT_RULE, rd, my_ans)
     170del rd
     171
     172d.dump()
    129173del d
    130174
    131 c = dict_enumval_data()
    132 c.enum_value.os = "coucou"
    133 c.enum_value.os.dump()
    134 
     175
     176####### Now play with the "real" dictionary
    135177
    136178gdict = cvar.fd_g_config.cnf_dict
    137 r, obj = fd_dict_search ( gdict, DICT_APPLICATION, APPLICATION_BY_ID, 3, -1 )
     179
     180r, appl = fd_dict_search ( gdict, DICT_APPLICATION, APPLICATION_BY_ID, 3, -1 )
    138181obj.dump()
    139 r, obj = fd_dict_search( gdict, DICT_AVP, AVP_BY_NAME, "Origin-Host", -1)
     182r, avp = fd_dict_search( gdict, DICT_AVP, AVP_BY_NAME, "Origin-Host", -1)
    140183obj.dump()
    141 
    142 t = new_dict_object_type_ptr()
    143 fd_dict_gettype(obj, t)
    144 dict_object_type_ptr_dump(t)
    145 delete_dict_object_type_ptr(t)
    146 objdata = new_dict_application_data()
    147 fd_dict_getval(obj, objdata)
    148 dict_application_data_application_name_get(objdata)
    149 delete_dict_application_data(objdata)
    150 
    151 vd = new_dict_vendor_data()
    152 dict_vendor_data_vendor_id_set(vd, 123)
    153 dict_vendor_data_vendor_name_set(vd, "my test vendor")
    154 pobj = new_dict_object_pptr()
    155 fd_dict_new ( gdict, DICT_VENDOR, vd, None, pobj)
    156 delete_dict_vendor_data(vd)
    157 obj = dict_object_pptr_value(pobj)
    158 delete_dict_object_pptr(pobj)
    159 fd_dict_dump_object(obj)
    160 
    161 
    162 # Sessions
    163 pmyhdl = new_session_handler_pptr()
    164 fd_sess_handler_create_internal(pmyhdl, None)
    165 ### Have to work on this one, a cleanup handler is actually required.
    166 ### How to define the handler in python ?
    167 myhdl = session_handler_pptr_value(pmyhdl)
    168 delete_session_handler_pptr(pmyhdl)
    169 
    170 psess = new_session_pptr()
    171 fd_sess_new (psess, fd_config_cnf_diamid_get(cvar.fd_g_config), "dbg_interactive", 0)
    172 sess = session_pptr_value(psess)
    173 fd_sess_dump(0, sess)
    174 fd_sess_destroy(psess)
    175 delete_session_pptr(psess)
    176 
     184r, errcmd = fd_dict_get_error_cmd( gdict )
     185
     186data = dict_avp_data()
     187fd_dict_getval(avp, data)
     188print data.avp_code
     189del data
     190
     191r, t = fd_dict_gettype(appl)
     192del t
     193
     194r, dict = fd_dict_getdict(avp)
     195del dict
     196
     197
     198
     199############# Sessions ############
     200
     201# handler
     202def my_cleanup(state,sid):
     203    print "Cleaning up python state for session:", sid
     204    print "Received state:", state
     205
     206hdl = session_handler(my_cleanup)
     207hdl.dump()
     208del hdl
     209
     210hdl = session_handler(my_cleanup)
     211
     212
     213# Session
     214s1 = session()
     215s1.getsid()
     216s2 = session("this.is.a.full.session.id")
     217r,s3,isnew = fd_sess_fromsid("this.is.a.full.session.id")
     218s4 = session("host.id", "opt.part")
     219
     220s4.settimeout(30) # the python wrapper takes a number of seconds as parameter for simplicity
     221s4.dump()
     222
     223
     224# state
     225mystate = [ 34, "clah", [ 32, 12 ] ]
     226
     227s4.store(hdl, mystate)
     228
     229
     230
     231## TODO : debug the following (segfault)
     232
     233def my_cleanup(state,sid):
     234    print "Cleaning up python state for session:", sid
     235    print "Received state:", state
     236
     237hdl = session_handler(my_cleanup)
     238s4 = session("host.id", "opt.part")
     239mystate = [ 34, "clah", [ 32, 12 ] ]
     240s4.store(hdl, mystate)
     241del hdl
     242
     243
     244
     245
     246
     247
     248
     249
     250######################### old stuff (need update) ######################
    177251
    178252# Routing data
  • extensions/dbg_interactive/dbg_interactive.i

    r625 r635  
    5151%include <typemaps.i>
    5252
    53 /* Some functions are not available through the wrapper */
     53/* Some functions are not available through the wrapper, or accessed differently */
    5454%ignore fd_lib_init;
    5555%ignore fd_lib_fini;
     56%ignore fd_dict_init;
     57%ignore fd_dict_fini;
     58%ignore fd_sess_handler_create_internal;
     59%ignore fd_sess_handler_destroy;
     60%ignore fd_sess_new;
     61%ignore fd_sess_getsid;
     62%ignore fd_sess_destroy;
     63%ignore fd_sess_reclaim;
     64%ignore fd_sess_state_store_internal;
     65%ignore fd_sess_state_retrieve_internal;
     66
    5667
    5768/* Inline functions seems to give problems to SWIG -- just remove the inline definition */
     
    8091}
    8192%apply SWIGTYPE ** OUTPUT { struct dict_object ** ref };
     93%apply SWIGTYPE ** OUTPUT { struct dict_object ** obj };
    8294%apply SWIGTYPE ** OUTPUT { struct dict_object ** result };
    83 
    84 
     95%apply SWIGTYPE ** OUTPUT { struct dictionary  ** dict }; /* this is for fd_dict_getdict, not fd_dict_init (use constructor) */
     96%apply int * OUTPUT { enum dict_object_type * type };
     97%apply (char *STRING, size_t LENGTH) { (char * sid, size_t len) };
     98%apply SWIGTYPE ** OUTPUT { struct session ** session };
     99%apply int * OUTPUT { int * new };
    85100
    86101/*********************************************************
     
    211226%}
    212227
     228/* The following wrapper leaks memory each time an union avp_value is assigned an octet string.
     229 TODO: fix this leak by better understanding SWIG...
     230   -- the alternative is to uncomment the "free" statements bellow, but then it is easy to
     231   create a segmentation fault by assigning first an integer, then an octetstring.
     232 */
     233%extend avp_value {
     234        /* The following hack in the proxy file allows assigning the octet string directly like this:
     235        avp_value.os = "blabla"
     236        */
     237        %pythoncode
     238        {
     239    __swig_setmethods__["os"] = _fDpy.avp_value_os_set
     240    if _newclass:os = _swig_property(_fDpy.avp_value_os_get, _fDpy.avp_value_os_set)
     241        }
     242        void os_set(char *STRING, size_t LENGTH) {
     243                /* free($self->os.data);  -- do not free, in case the previous value was not an OS */
     244                $self->os.data = malloc(LENGTH);
     245                if (!$self->os.data) {
     246                        fd_log_debug("Out of memory!\n");
     247                        PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     248                        return;
     249                }
     250                memcpy($self->os.data, STRING, LENGTH);
     251                $self->os.len = LENGTH;
     252        }
     253        void os_set(avp_value_os * os) {
     254                /* free($self->os.data);  -- do not free, in case the previous value was not an OS */
     255                $self->os.data = malloc(os->len);
     256                if (!$self->os.data) {
     257                        fd_log_debug("Out of memory!\n");
     258                        PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     259                        return;
     260                }
     261                memcpy($self->os.data, os->data, os->len);
     262                $self->os.len = os->len;
     263        }
     264};
    213265
    214266%extend avp_value_os {
    215         ~avp_value_os() {
    216                 if (self)
    217                         free(self->data);
    218         }
    219267        void dump() {
    220268                if ($self) {
     
    231279}
    232280
    233 %extend avp_value {
    234         void os_set(char *STRING, size_t LENGTH) {
    235                 free($self->os.data);
    236                 $self->os.data = malloc(LENGTH);
    237                 if (!$self->os.data) {
    238                         fd_log_debug("Out of memory!\n");
    239                         PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     281/****** SESSIONS *********/
     282
     283%{
     284/* At the moment, only 1 callback is supported... */
     285static PyObject * py_cleanup_cb = NULL;
     286static void call_the_python_cleanup_callback(session_state * state, char * sid) {
     287        PyObject *result;
     288        if (!py_cleanup_cb)
     289                return;
     290       
     291        /* Call the function */
     292        result = PyEval_CallFunction(py_cleanup_cb, "(Os)", state, sid);
     293       
     294        Py_XDECREF(result);
     295        return;
     296}
     297%}
     298
     299struct session_handler {
     300};
     301
     302%extend session_handler {
     303        session_handler() {
     304                fd_log_debug("Error: a cleanup callback parameter is required.\n");
     305                PyErr_SetString(PyExc_SyntaxError,"Error: a cleanup callback parameter is required.\n");
     306                return NULL;
     307        }
     308        session_handler(PyObject * PyCleanupCb) {
     309                struct session_handler * hdl = NULL;
     310                int ret;
     311                if (py_cleanup_cb) {
     312                        fd_log_debug("dbg_interactive supports only 1 session handler in python at the moment\n");
     313                        PyErr_SetString(PyExc_SyntaxError,"dbg_interactive supports only 1 session handler in python at the moment\n");
     314                        return NULL;
     315                }
     316                if (!PyCallable_Check(PyCleanupCb)) {
     317                        PyErr_SetString(PyExc_TypeError, "Need a callable object!");
     318                        return NULL;
     319                }
     320                py_cleanup_cb = PyCleanupCb;
     321                Py_XINCREF(py_cleanup_cb);
     322               
     323                ret = fd_sess_handler_create_internal ( &hdl, call_the_python_cleanup_callback );
     324                if (ret != 0) {
     325                        fd_log_debug("Error: %s\n", strerror(ret));
     326                        PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     327                        return NULL;
     328                }
     329                return hdl;
     330        }
     331        ~session_handler() {
     332                if (self) {
     333                        struct session_handler * hdl = self;
     334                        int ret = fd_sess_handler_destroy(&hdl);
     335                        if (ret != 0) {
     336                                fd_log_debug("Error: %s\n", strerror(ret));
     337                        }
    240338                        return;
    241339                }
    242                 memcpy($self->os.data, STRING, LENGTH);
    243                 $self->os.len = LENGTH;
    244         }
    245         void os_set(avp_value_os * os) {
    246                 free($self->os.data);
    247                 $self->os.data = malloc(os->len);
    248                 if (!$self->os.data) {
    249                         fd_log_debug("Out of memory!\n");
    250                         PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     340        }
     341        void dump() {
     342                if ($self) {
     343                        fd_sess_dump_hdl(0, $self);
     344                }
     345        }
     346}
     347
     348struct session {
     349};
     350
     351%extend session {
     352        /* The first two versions create a new session string. The third one allow to use an existing string. */
     353        session() {
     354                int ret;
     355                struct session * s = NULL;
     356                ret = fd_sess_new(&s, fd_g_config->cnf_diamid, "dbg_interactive", sizeof("dbg_interactive"));
     357                if (ret != 0) {
     358                        fd_log_debug("Error: %s\n", strerror(ret));
     359                        PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     360                        return NULL;
     361                }
     362                return s;
     363        }
     364        session(char * diamid, char * STRING, size_t LENGTH) {
     365                int ret;
     366                struct session * s = NULL;
     367                ret = fd_sess_new(&s, diamid, STRING, LENGTH);
     368                if (ret != 0) {
     369                        fd_log_debug("Error: %s\n", strerror(ret));
     370                        PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     371                        return NULL;
     372                }
     373                return s;
     374        }
     375        session(char * STRING, size_t LENGTH) {
     376                int ret, n;
     377                struct session * s = NULL;
     378                ret = fd_sess_fromsid(STRING, LENGTH, &s, &n);
     379                if (ret != 0) {
     380                        fd_log_debug("Error: %s\n", strerror(ret));
     381                        PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     382                        return NULL;
     383                }
     384                /* When defining n as OUTPUT parameter, we get something strange... Use fd_sess_fromsid if you need it */
     385                if (n) {
     386                        fd_log_debug("A new session has been created\n");
     387                } else {
     388                        fd_log_debug("A session with same id already existed\n");
     389                }
     390                return s;
     391        }
     392        ~session() {
     393                if (self) {
     394                        struct session * s = self;
     395                        int ret = fd_sess_reclaim(&s);
     396                        if (ret != 0) {
     397                                fd_log_debug("Error: %s\n", strerror(ret));
     398                        }
    251399                        return;
    252400                }
    253                 memcpy($self->os.data, os->data, os->len);
    254                 $self->os.len = os->len;
    255         }
    256 };
     401        }
     402        char * getsid() {
     403                int ret;
     404                char * sid = NULL;
     405                if (!$self)
     406                        return NULL;
     407                ret = fd_sess_getsid( $self, &sid);
     408                if (ret != 0) {
     409                        fd_log_debug("Error: %s\n", strerror(ret));
     410                        PyErr_SetString(PyExc_MemoryError,"Problem...");
     411                        return NULL;
     412                }
     413                return sid;
     414        }
     415        void settimeout(long seconds) {
     416                struct timespec timeout;
     417                int ret;
     418                clock_gettime(CLOCK_REALTIME, &timeout);
     419                timeout.tv_sec += seconds;
     420                ret = fd_sess_settimeout( $self, &timeout );
     421                if (ret != 0) {
     422                        fd_log_debug("Error: %s\n", strerror(ret));
     423                        PyErr_SetString(PyExc_MemoryError,"Problem...");
     424                }
     425        }
     426        void dump() {
     427                if ($self) {
     428                        fd_sess_dump(0, $self);
     429                }
     430        }
     431        void store(struct session_handler * handler, PyObject * state) {
     432                int ret;
     433                void * store = state;
     434                Py_INCREF(state);
     435                ret = fd_sess_state_store_internal(handler, $self, (void *) &store);
     436                if (ret != 0) {
     437                        fd_log_debug("Error: %s\n", strerror(ret));
     438                        PyErr_SetString(PyExc_MemoryError,"Problem...");
     439                }
     440        }
     441        PyObject *  retrieve(struct session_handler * handler) {
     442                int ret;
     443                PyObject * state = NULL;
     444                ret = fd_sess_state_retrieve_internal(handler, $self, (void *) &state);
     445                if (ret != 0) {
     446                        fd_log_debug("Error: %s\n", strerror(ret));
     447                        PyErr_SetString(PyExc_MemoryError,"Problem...");
     448                }
     449                if (state == NULL) {
     450                        return Py_None;
     451                }
     452                Py_DECREF(state);
     453                return state;
     454        }
     455}       
     456
     457
     458
     459/****** MESSAGES *********/
     460
    257461
    258462%cstring_output_allocate_size(char ** swig_buffer, size_t * swig_len, free(*$1))
Note: See TracChangeset for help on using the changeset viewer.