Navigation


Changeset 640:237cf6339546 in freeDiameter for extensions/dbg_interactive


Ignore:
Timestamp:
Dec 20, 2010, 7:36:40 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

dbg_interactive almost complete

Location:
extensions/dbg_interactive
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • extensions/dbg_interactive/CMakeLists.txt

    r637 r640  
    2626        queues.i
    2727        peers.i
     28        events.i
     29        endpoints.i
    2830        )
    2931SET_SOURCE_FILES_PROPERTIES(dbg_interactive.i PROPERTIES SWIG_MODULE_NAME fDpy)
  • extensions/dbg_interactive/dbg_interactive.i

    r638 r640  
    6868static int wrapper_errno;
    6969static PyObject* wrapper_errno_py;
    70 static char * wrapper_error_txt; /* if NULL, use strerror(errno) */
     70static const char * wrapper_error_txt; /* if NULL, use strerror(errno) */
    7171#define DI_ERROR(code, pycode, str) {   \
    7272        fd_log_debug("[dbg_interactive] ERROR: %s: %s\n", __PRETTY_FUNCTION__, str ? str : strerror(code)); \
     
    8888        /* Now, test for error */
    8989        if (wrapper_errno) {
    90                 char * str = wrapper_error_txt ? wrapper_error_txt : strerror(wrapper_errno);
     90                const char * str = wrapper_error_txt ? wrapper_error_txt : strerror(wrapper_errno);
    9191                PyObject * exc = wrapper_errno_py;
    9292                if (!exc) {
     
    109109 ***********************************/
    110110
    111 %apply (char *STRING, size_t LENGTH) { ( char * string, size_t len ) }; /* fd_hash */
     111%apply (char *STRING, size_t LENGTH) { ( char * string, size_t len ) };
    112112
    113113/* Generic typemap for functions that create something */
     
    119119}
    120120
     121/* Typemap to return a boolean value as output parameter */
     122%typemap(in, numinputs=0,noblock=1) int * BOOL_OUT (int temp) {
     123        $1 = &temp;
     124}
     125%typemap(argout,noblock=1) int * BOOL_OUT {
     126        PyObject * r;
     127        if (*$1)
     128                r = Py_True;
     129        else
     130                r = Py_False;
     131        Py_XINCREF(r);
     132        %append_output(r);
     133}
     134
    121135/* To allow passing callback functions defined in python */
    122136%typemap(in) PyObject *PyCb {
    123         if (!PyCallable_Check($input)) {
    124                 PyErr_SetString(PyExc_TypeError, "Need a callable object!");
    125                 SWIG_fail;
     137        if (!$input || ($input == Py_None)) {
     138                $1 = NULL;
     139        } else {
     140                if (!PyCallable_Check($input)) {
     141                        PyErr_SetString(PyExc_TypeError, "Need a callable object!");
     142                        SWIG_fail;
     143                }
     144                $1 = $input;
    126145        }
    127         $1 = $input;
    128146}
    129147
    130 
     148%{
    131149/* Forward declaration for the peers module */
    132 %{
    133150static void fd_add_cb(struct peer_info *peer, void *data);
    134151%}
     152
     153/* Overwrite declaration to apply typemaps */
     154int fd_sess_fromsid ( char * STRING, size_t LENGTH, struct session ** OUTPUT, int * BOOL_OUT);
     155
    135156
    136157/*********************************************************
     
    155176
    156177%include "peers.i"
     178%include "events.i"
     179%include "endpoints.i"
  • extensions/dbg_interactive/lists.i

    r637 r640  
    7171        }
    7272        /* Test for emptyness */
    73         int isempty() {
    74                 return FD_IS_LIST_EMPTY($self);
     73        PyObject * isempty() {
     74                PyObject * ret;
     75                if (FD_IS_LIST_EMPTY($self))
     76                        ret = Py_True;
     77                else
     78                        ret = Py_False;
     79                Py_XINCREF(ret);
     80                return ret;
    7581        }
    7682        /* Concatenate two lists */
  • extensions/dbg_interactive/messages.i

    r638 r640  
    293293       
    294294        /* Is routable? */
    295         int is_routable() {
    296                 return fd_msg_is_routable($self);
     295        PyObject * is_routable() {
     296                PyObject * r;
     297                if (fd_msg_is_routable($self))
     298                        r = Py_True;
     299                else
     300                        r = Py_False;
     301                Py_XINCREF(r);
     302                return r;
    297303        }
    298304       
  • extensions/dbg_interactive/peers.i

    r638 r640  
    6767
    6868%extend peer_info {
     69        peer_info () {
     70                struct peer_info *np = (struct peer_info *)calloc(1, sizeof(struct peer_info));
     71                if (!np) {
     72                        DI_ERROR_MALLOC;
     73                        return NULL;
     74                }
     75               
     76                fd_list_init(&np->pi_endpoints, NULL);
     77               
     78                return np;
     79        }
     80
    6981        /* Wrapper around fd_peer_add to allow calling the python callback */
     82        %delobject add;
    7083        void add(PyObject * PyCb=NULL) {
    7184                int ret;
     
    8194                }
    8295        }
    83 
    84         /* Add an endpoint */
    85         void add_endpoint(char * endpoint) {
    86                 fd_log_debug("What is the best way in python to pass an endpoint? (ip + port)");
    87         }
    88 
    89 }
     96}
     97
     98%inline %{
     99static struct peer_hdr * peer_search(char *diamid) {
     100        struct peer_hdr *r = NULL;
     101        int ret = fd_peer_getbyid( diamid, &r );
     102        if (ret) {
     103                DI_ERROR(ret, NULL, NULL);
     104                return NULL;
     105        }
     106        return r;
     107}
     108%}
     109
     110%{
     111static PyObject * validate_cb_py = NULL;
     112static PyObject * validate_cb2_py = NULL;
     113
     114/* C wrapper that calls validate_cb2_py */
     115int call_the_python_validate_callback2(struct peer_info * info) {
     116        PyObject *PyInfo;
     117        PyObject *result = NULL;
     118        int ret = 0;
     119       
     120        if (!validate_cb2_py) {
     121                fd_log_debug("Internal error: missing the callback2!\n");
     122                return ENOTSUP;
     123        }
     124       
     125        SWIG_PYTHON_THREAD_BEGIN_BLOCK;
     126        /* Convert the arguments */
     127        PyInfo  = SWIG_NewPointerObj((void *)info,     SWIGTYPE_p_peer_info,     0 );
     128       
     129        /* Call the function */
     130        result = PyEval_CallFunction(validate_cb2_py, "(O)", PyInfo);
     131       
     132        /* The result is an integer */
     133        if ((result == NULL) || !SWIG_IsOK(SWIG_AsVal_int(result, &ret))) {
     134                fd_log_debug("Error: The Python callback did not return an integer.\n");
     135                ret = EINVAL;
     136                goto out;
     137        }
     138       
     139out:   
     140        Py_XDECREF(result);
     141        SWIG_PYTHON_THREAD_END_BLOCK;
     142        return ret;
     143}
     144
     145/* C wrapper that calls validate_cb_py */
     146int call_the_python_validate_callback(struct peer_info * info, int * auth, int (**cb2)(struct peer_info *)) {
     147        PyObject *PyInfo;
     148        PyObject *result = NULL;
     149        int ret = 0;
     150       
     151        if (!validate_cb_py) {
     152                fd_log_debug("Internal error: missing the callback!\n");
     153                return ENOTSUP;
     154        }
     155       
     156        SWIG_PYTHON_THREAD_BEGIN_BLOCK;
     157        /* Convert the arguments */
     158        PyInfo  = SWIG_NewPointerObj((void *)info,     SWIGTYPE_p_peer_info,     0 );
     159       
     160        /* Call the function */
     161        result = PyEval_CallFunction(validate_cb_py, "(O)", PyInfo);
     162       
     163        /* The result is supposedly -1, 1, or a cb2 */
     164        if (result == NULL) {
     165                fd_log_debug("Error: The Python callback did not return a value.\n");
     166                ret = EINVAL;
     167                goto out;
     168        }
     169       
     170        if (PyCallable_Check(result)) {
     171                if (cb2) {
     172                        if (validate_cb2_py && (validate_cb2_py != result)) {
     173                                fd_log_debug("Only 1 register callback2 is supported currently\n");
     174                                ret = ENOTSUP;
     175                                goto out;
     176                        }
     177                        validate_cb2_py = result;
     178                        *cb2 = call_the_python_validate_callback2;
     179                        *auth = 1;
     180                        goto out_nodec;
     181                } else {
     182                        *auth = 1;
     183                        goto out; /* ignore the callback since it won't be used */
     184                }
     185        } else { /* In this case, the return value must be -1, 0, or 1 */
     186                if (!SWIG_IsOK(SWIG_AsVal_int(result, auth))) {
     187                        fd_log_debug("Error: Cannot convert the return value to integer.\n");
     188                        ret = EINVAL;
     189                        goto out;
     190                }
     191        }
     192       
     193out:   
     194        Py_XDECREF(result);
     195out_nodec:     
     196        SWIG_PYTHON_THREAD_END_BLOCK;
     197        TRACE_DEBUG(FULL, "ret=%d, *auth=%d, cb2=%p, *cb2=%p", ret, *auth, cb2, cb2 ? *cb2 : NULL);
     198        return ret;
     199}
     200
     201%}
     202
     203%inline %{
     204static void peer_validate_register(PyObject * PyCb) {
     205        int ret ;
     206       
     207        if (!PyCb) {
     208                DI_ERROR(EINVAL, NULL, "The callback must be provided");
     209                return;
     210        }
     211       
     212        if (validate_cb_py) {
     213                if (PyCb != validate_cb_py) {
     214                        DI_ERROR(ENOTSUP, PyExc_RuntimeError, "Only 1 register callback is supported currently");
     215                        return;
     216                }
     217        } else {
     218                validate_cb_py = PyCb;
     219                Py_XINCREF(PyCb);
     220        }
     221       
     222        ret = fd_peer_validate_register ( call_the_python_validate_callback );
     223        if (ret) {
     224                DI_ERROR(ret, NULL, NULL);
     225        }
     226}
     227%}
  • extensions/dbg_interactive/queues.i

    r638 r640  
    7777       
    7878        /* Post an item */
    79         void post(PyObject * item) {
    80                 int ret;
    81                 PyObject * i = item;
    82                
    83                 Py_XINCREF(i);
    84                 ret = fd_fifo_post($self, &i);
     79        void post(PyObject * item, char * type = NULL) {
     80                int ret;
     81                if (type) {
     82                        void * real_obj = NULL;
     83                        swig_type_info * desttype = NULL;
     84                        desttype = SWIG_TypeQuery(type);
     85                        if (!desttype) {
     86                                DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
     87                                return;
     88                        }
     89                        /* Now, get the "real" value under the shadow umbrella */
     90                        ret = SWIG_ConvertPtr(item, &real_obj, desttype, SWIG_POINTER_DISOWN );
     91                        if (!SWIG_IsOK(ret)) {
     92                                DI_ERROR(EINVAL, SWIG_ErrorType(ret), "Unable to convert the item to given type");
     93                                return;
     94                        }
     95                        ret = fd_fifo_post($self, &real_obj);
     96                } else {
     97                        PyObject * i = item;
     98                        Py_XINCREF(i);
     99                        ret = fd_fifo_post($self, &i);
     100                }
    85101                if (ret != 0) {
    86102                        DI_ERROR(ret, NULL, NULL);
     
    89105       
    90106        /* Get (blocking) */
    91         PyObject * get() {
     107        PyObject * get(char * type = NULL) {
    92108                int ret;
    93109                PyObject * i = NULL;
    94                
    95                 ret = fd_fifo_get($self, &i);
    96                 if (ret != 0) {
    97                         DI_ERROR(ret, NULL, NULL);
    98                 }
    99                
    100                 return i;
     110                void * obj = NULL;
     111                swig_type_info * desttype = NULL;
     112                if (type) {
     113                        desttype = SWIG_TypeQuery(type);
     114                        if (!desttype) {
     115                                DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
     116                                return NULL;
     117                        }
     118                }
     119               
     120                ret = fd_fifo_get($self, &obj);
     121                if (ret != 0) {
     122                        DI_ERROR(ret, NULL, NULL);
     123                }
     124               
     125                if (type) {
     126                        return SWIG_NewPointerObj(obj, desttype, 0 );
     127                } else {
     128                        i = obj;
     129                        return i;
     130                }
    101131        }
    102132       
    103133        /* TryGet (non-blocking, returns None on empty queue) */
    104         PyObject * tryget() {
     134        PyObject * tryget(char * type = NULL) {
    105135                int ret;
    106136                PyObject * i = NULL;
    107                
    108                 ret = fd_fifo_tryget($self, &i);
     137                void * obj = NULL;
     138                swig_type_info * desttype = NULL;
     139                if (type) {
     140                        desttype = SWIG_TypeQuery(type);
     141                        if (!desttype) {
     142                                DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
     143                                return NULL;
     144                        }
     145                }
     146               
     147                ret = fd_fifo_tryget($self, &obj);
    109148                if (ret == EWOULDBLOCK) {
    110149                        Py_XINCREF(Py_None);
     
    115154                }
    116155               
    117                 return i;
     156                if (type) {
     157                        return SWIG_NewPointerObj(obj, desttype, 0 );
     158                } else {
     159                        i = obj;
     160                        return i;
     161                }
    118162        }
    119163       
    120164        /* TimedGet (blocking for a while) */
    121         PyObject * timedget(long seconds) {
     165        PyObject * timedget(long seconds, char * type = NULL) {
    122166                int ret;
    123167                PyObject * i = NULL;
    124168                struct timespec ts;
     169                void * obj = NULL;
     170                swig_type_info * desttype = NULL;
     171                if (type) {
     172                        desttype = SWIG_TypeQuery(type);
     173                        if (!desttype) {
     174                                DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
     175                                return NULL;
     176                        }
     177                }
    125178               
    126179                clock_gettime(CLOCK_REALTIME, &ts);
    127180                ts.tv_sec += seconds;
    128181               
    129                 ret = fd_fifo_timedget($self, &i, &ts);
     182                ret = fd_fifo_timedget($self, &obj, &ts);
    130183                if (ret == ETIMEDOUT) {
    131184                        Py_XINCREF(Py_None);
     
    136189                }
    137190               
    138                 return i;
     191                if (type) {
     192                        return SWIG_NewPointerObj(obj, desttype, 0 );
     193                } else {
     194                        i = obj;
     195                        return i;
     196                }
    139197        }
    140198       
  • extensions/dbg_interactive/routing.i

    r637 r640  
    7777}
    7878
     79
     80
    7981%extend rtd_candidate {
    8082        void dump() {
     
    8688}
    8789
     90
     91%{
     92/* call it (will be called from a different thread than the interpreter, when message arrives) */
     93static int call_the_python_rt_fwd_callback(void * pycb, struct msg **msg) {
     94        PyObject *PyMsg;
     95        PyObject *cb, *result = NULL;
     96        int ret = 0;
     97       
     98        if (!pycb) {
     99                fd_log_debug("Internal error: missing the callback!\n");
     100                return ENOTSUP;
     101        }
     102        cb = pycb;
     103       
     104        SWIG_PYTHON_THREAD_BEGIN_BLOCK;
     105        /* Convert the arguments */
     106        PyMsg  = SWIG_NewPointerObj((void *)*msg,     SWIGTYPE_p_msg,     0 );
     107       
     108        /* Call the function */
     109        result = PyEval_CallFunction(cb, "(O)", PyMsg);
     110       
     111        /* The result is supposedly composed of: [ ret, *msg ] */
     112        if ((result == NULL) || (!PyList_Check(result)) || (PyList_Size(result) != 2)) {
     113                fd_log_debug("Error: The Python callback did not return [ ret, msg ].\n");
     114                ret = EINVAL;
     115                goto out;
     116        }
     117       
     118        /* Convert the return values */
     119        if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 0), &ret))) {
     120                fd_log_debug("Error: Cannot convert the first return value to integer.\n");
     121                ret = EINVAL;
     122                goto out;
     123        }
     124        if (ret) {
     125                TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)\n", ret, strerror(ret));
     126                goto out;
     127        }
     128       
     129        if (!SWIG_IsOK(SWIG_ConvertPtr(PyList_GetItem(result, 1), (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) {
     130                fd_log_debug("Error: Cannot convert the second return value to message.\n");
     131                ret = EINVAL;
     132                goto out;
     133        }
     134       
     135out:   
     136        Py_XDECREF(result);
     137       
     138        SWIG_PYTHON_THREAD_END_BLOCK;
     139        return ret;
     140}
     141%}
     142
     143
     144struct fd_rt_fwd_hdl {
     145};
     146
     147%extend fd_rt_fwd_hdl{
     148        fd_rt_fwd_hdl(PyObject * PyCb, enum fd_rt_fwd_dir dir) {
     149                struct fd_rt_fwd_hdl * r = NULL;
     150                int ret;
     151               
     152                Py_XINCREF(PyCb);
     153
     154                ret = fd_rt_fwd_register( call_the_python_rt_fwd_callback, PyCb, dir, &r );
     155                if (ret != 0) {
     156                        DI_ERROR(ret, NULL, NULL);
     157                        return NULL;
     158                }
     159                return r;
     160        }
     161       
     162        ~fd_rt_fwd_hdl() {
     163                PyObject * func;
     164                int ret = fd_rt_fwd_unregister ( $self, (void *) &func );
     165                if (ret != 0) {
     166                        DI_ERROR(ret, NULL, NULL);
     167                        return;
     168                }
     169                Py_XDECREF(func);
     170                return;
     171        }
     172}
     173
     174
     175%{
     176/* call it (will be called from a different thread than the interpreter, when message arrives) */
     177static int call_the_python_rt_out_callback(void * pycb, struct msg *msg, struct fd_list * candidates) {
     178        PyObject *PyMsg, *PyCands;
     179        PyObject *cb, *result = NULL;
     180        int ret = 0;
     181       
     182        if (!pycb) {
     183                fd_log_debug("Internal error: missing the callback!\n");
     184                return ENOTSUP;
     185        }
     186        cb = pycb;
     187       
     188        SWIG_PYTHON_THREAD_BEGIN_BLOCK;
     189        /* Convert the arguments */
     190        PyMsg   = SWIG_NewPointerObj((void *)msg,        SWIGTYPE_p_msg,     0 );
     191        PyCands = SWIG_NewPointerObj((void *)candidates, SWIGTYPE_p_fd_list, 0 );
     192       
     193        /* Call the function */
     194        result = PyEval_CallFunction(cb, "(OO)", PyMsg, PyCands);
     195       
     196        /* The result is supposedly composed of: [ ret, *msg ] */
     197        if (result == NULL){
     198                fd_log_debug("Error: The Python callback raised an exception.\n");
     199                ret = EINVAL;
     200                goto out;
     201        }
     202       
     203        /* Convert the return values */
     204        if (!SWIG_IsOK(SWIG_AsVal_int(result, &ret))) {
     205                fd_log_debug("Error: Cannot convert the return value to integer.\n");
     206                ret = EINVAL;
     207                goto out;
     208        }
     209out:   
     210        Py_XDECREF(result);
     211       
     212        SWIG_PYTHON_THREAD_END_BLOCK;
     213        return ret;
     214}
     215%}
     216
     217
     218struct fd_rt_out_hdl {
     219};
     220
     221%extend fd_rt_out_hdl{
     222        fd_rt_out_hdl(PyObject * PyCb, int priority = 0) {
     223                struct fd_rt_out_hdl * r = NULL;
     224                int ret;
     225               
     226                Py_XINCREF(PyCb);
     227
     228                ret = fd_rt_out_register( call_the_python_rt_out_callback, PyCb, priority, &r );
     229                if (ret != 0) {
     230                        DI_ERROR(ret, NULL, NULL);
     231                        return NULL;
     232                }
     233                return r;
     234        }
     235       
     236        ~fd_rt_out_hdl() {
     237                PyObject * func;
     238                int ret = fd_rt_out_unregister ( $self, (void *) &func );
     239                if (ret != 0) {
     240                        DI_ERROR(ret, NULL, NULL);
     241                        return;
     242                }
     243                Py_XDECREF(func);
     244                return;
     245        }
     246}
     247
Note: See TracChangeset for help on using the changeset viewer.