Changeset 638:9448cba86673 in freeDiameter for extensions/dbg_interactive
- Timestamp:
- Dec 17, 2010, 6:41:19 PM (13 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- extensions/dbg_interactive
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/dbg_interactive/dbg_interactive.i
r637 r638 129 129 130 130 131 /* Forward declaration for the peers module */ 132 %{ 133 static void fd_add_cb(struct peer_info *peer, void *data); 134 %} 135 131 136 /********************************************************* 132 137 Now, create wrappers for (almost) all objects from fD API -
extensions/dbg_interactive/dictionary.i
r637 r638 242 242 fd_log_debug("] '%.*s%s'\n", n, $self->data, n == LEN_MAX ? "..." : ""); 243 243 } 244 } 244 %cstring_output_allocate_size(char ** outbuffer, size_t * outlen, free(*$1)); 245 void as_str ( char ** outbuffer, size_t * outlen ) { 246 char * b; 247 if (!$self->len) { 248 *outlen = 0; 249 *outbuffer = NULL; 250 return; 251 } 252 b = malloc($self->len); 253 if (!b) { 254 DI_ERROR_MALLOC; 255 return; 256 } 257 memcpy(b, $self->data, $self->len); 258 *outlen = $self->len; 259 *outbuffer = b; 260 } 261 } 262 263 264 /* Allow constructors with parameters for the dict_*_data */ 265 %extend dict_vendor_data { 266 dict_vendor_data(uint32_t id = 0, char * name = NULL) { 267 struct dict_vendor_data * d = (struct dict_vendor_data *)calloc(1, sizeof(struct dict_vendor_data)); 268 if (!d) { 269 DI_ERROR_MALLOC; 270 return NULL; 271 } 272 d->vendor_id = id; 273 if (name) { 274 d->vendor_name = strdup(name); 275 if (!d->vendor_name) { 276 DI_ERROR_MALLOC; 277 free(d); 278 return NULL; 279 } 280 } 281 return d; 282 } 283 } 284 285 %extend dict_application_data { 286 dict_application_data(uint32_t id = 0, char * name = NULL) { 287 struct dict_application_data * d = (struct dict_application_data *)calloc(1, sizeof(struct dict_application_data)); 288 if (!d) { 289 DI_ERROR_MALLOC; 290 return NULL; 291 } 292 d->application_id = id; 293 if (name) { 294 d->application_name = strdup(name); 295 if (!d->application_name) { 296 DI_ERROR_MALLOC; 297 free(d); 298 return NULL; 299 } 300 } 301 return d; 302 } 303 } 304 305 %extend dict_type_data { 306 dict_type_data(enum dict_avp_basetype base = 0, char * name = NULL) { 307 struct dict_type_data * d = (struct dict_type_data *)calloc(1, sizeof(struct dict_type_data)); 308 if (!d) { 309 DI_ERROR_MALLOC; 310 return NULL; 311 } 312 d->type_base = base; 313 if (name) { 314 d->type_name = strdup(name); 315 if (!d->type_name) { 316 DI_ERROR_MALLOC; 317 free(d); 318 return NULL; 319 } 320 } 321 return d; 322 } 323 } 324 325 %extend dict_enumval_data { 326 dict_enumval_data(char * name = NULL, uint32_t v = 0) { 327 struct dict_enumval_data * d = (struct dict_enumval_data *)calloc(1, sizeof(struct dict_enumval_data)); 328 if (!d) { 329 DI_ERROR_MALLOC; 330 return NULL; 331 } 332 if (name) { 333 d->enum_name = strdup(name); 334 if (!d->enum_name) { 335 DI_ERROR_MALLOC; 336 free(d); 337 return NULL; 338 } 339 } 340 d->enum_value.u32 = v; 341 return d; 342 } 343 } 344 345 %extend dict_avp_data { 346 dict_avp_data(uint32_t code = 0, char * name = NULL, enum dict_avp_basetype basetype = 0, uint32_t vendor = 0, int mandatory=0) { 347 struct dict_avp_data * d = (struct dict_avp_data *)calloc(1, sizeof(struct dict_avp_data)); 348 if (!d) { 349 DI_ERROR_MALLOC; 350 return NULL; 351 } 352 if (name) { 353 d->avp_name = strdup(name); 354 if (!d->avp_name) { 355 DI_ERROR_MALLOC; 356 free(d); 357 return NULL; 358 } 359 } 360 d->avp_code = code; 361 d->avp_basetype = basetype; 362 d->avp_vendor = vendor; 363 if (vendor) { 364 d->avp_flag_val |= AVP_FLAG_VENDOR; 365 d->avp_flag_mask |= AVP_FLAG_VENDOR; 366 } 367 d->avp_flag_mask |= AVP_FLAG_MANDATORY; 368 if (mandatory) 369 d->avp_flag_val |= AVP_FLAG_MANDATORY; 370 return d; 371 } 372 } 373 374 %extend dict_cmd_data { 375 dict_cmd_data(uint32_t code = 0, char * name = NULL, int request = 1) { 376 struct dict_cmd_data * d = (struct dict_cmd_data *)calloc(1, sizeof(struct dict_cmd_data)); 377 if (!d) { 378 DI_ERROR_MALLOC; 379 return NULL; 380 } 381 if (name) { 382 d->cmd_name = strdup(name); 383 if (!d->cmd_name) { 384 DI_ERROR_MALLOC; 385 free(d); 386 return NULL; 387 } 388 } 389 d->cmd_code = code; 390 d->cmd_flag_mask = CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE; 391 d->cmd_flag_val = CMD_FLAG_PROXIABLE | ( request ? CMD_FLAG_REQUEST : 0 ); 392 return d; 393 } 394 } 395 396 %extend dict_rule_data { 397 dict_rule_data(struct dict_object *avp = NULL, enum rule_position pos = 0, int min = -1, int max = -1 ) { 398 struct dict_rule_data * d = (struct dict_rule_data *)calloc(1, sizeof(struct dict_rule_data)); 399 if (!d) { 400 DI_ERROR_MALLOC; 401 return NULL; 402 } 403 d->rule_avp = avp; 404 d->rule_position = pos; 405 d->rule_order = 1; 406 d->rule_min = min; 407 d->rule_max = max; 408 return d; 409 } 410 } 411 -
extensions/dbg_interactive/dispatch.i
r637 r638 36 36 /* Do not include this directly, use dbg_interactive.i instead */ 37 37 38 /****** DISPATCH *********/ 39 40 41 %{ 42 /* store the python callback function here */ 43 static PyObject * py_dispatch_cb = NULL; 44 static int py_dispatch_cb_n = 0; 45 /* call it (will be called from a different thread than the interpreter, when message arrives) */ 46 static int call_the_python_dispatch_callback(struct msg **msg, struct avp *avp, struct session *session, enum disp_action *action) { 47 PyObject *PyMsg, *PyAvp, *PySess; 48 PyObject *result = NULL; 49 int ret = 0; 50 51 if (!py_dispatch_cb) 52 return ENOTSUP; 53 54 SWIG_PYTHON_THREAD_BEGIN_BLOCK; 55 /* Convert the arguments */ 56 PyMsg = SWIG_NewPointerObj((void *)*msg, SWIGTYPE_p_msg, 0 ); 57 PyAvp = SWIG_NewPointerObj((void *) avp, SWIGTYPE_p_avp, 0 ); 58 PySess = SWIG_NewPointerObj((void *) session, SWIGTYPE_p_session, 0 ); 59 60 /* Call the function */ 61 result = PyEval_CallFunction(py_dispatch_cb, "(OOO)", PyMsg, PyAvp, PySess); 62 63 /* The result is supposedly composed of: [ ret, *msg, *action ] */ 64 if ((result == NULL) || (!PyList_Check(result)) || (PyList_Size(result) != 3)) { 65 fd_log_debug("Error: The Python callback did not return [ ret, msg, action ].\n"); 66 ret = EINVAL; 67 goto out; 68 } 69 70 /* Convert the return values */ 71 if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 0), &ret))) { 72 fd_log_debug("Error: Cannot convert the first return value to integer.\n"); 73 ret = EINVAL; 74 goto out; 75 } 76 if (ret) { 77 TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)\n", ret, strerror(ret)); 78 goto out; 79 } 80 81 if (!SWIG_IsOK(SWIG_ConvertPtr(PyList_GetItem(result, 1), (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) { 82 fd_log_debug("Error: Cannot convert the second return value to message.\n"); 83 ret = EINVAL; 84 goto out; 85 } 86 87 if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 2), (int *)action))) { 88 fd_log_debug("Error: Cannot convert the third return value to integer.\n"); 89 ret = EINVAL; 90 goto out; 91 } 92 93 TRACE_DEBUG(FULL, "Python callback return: *action = %d\n", *action); 94 out: 95 Py_XDECREF(result); 96 97 SWIG_PYTHON_THREAD_END_BLOCK; 98 return ret; 99 } 100 %} 101 102 struct disp_hdl { 103 }; 104 105 %nodefaultctor disp_hdl; 106 %extend disp_hdl { 107 disp_hdl(PyObject * PyCb, enum disp_how how, struct disp_when * when) { 108 struct disp_hdl * hdl = NULL; 109 int ret; 110 if (py_dispatch_cb && (py_dispatch_cb != PyCb)) { 111 DI_ERROR(EINVAL, PyExc_SyntaxError, "Only one dispatch callback is supported at the moment in this extension\n."); 112 return NULL; 113 } 114 py_dispatch_cb = PyCb; 115 py_dispatch_cb_n += 1; 116 Py_XINCREF(py_dispatch_cb); 117 118 ret = fd_disp_register ( call_the_python_dispatch_callback, how, when, &hdl ); 119 if (ret != 0) { 120 DI_ERROR(ret, NULL, NULL); 121 return NULL; 122 } 123 return hdl; 124 } 125 ~disp_hdl() { 126 struct disp_hdl * hdl = self; 127 int ret = fd_disp_unregister(&hdl); 128 if (ret != 0) { 129 DI_ERROR(ret, NULL, NULL); 130 } 131 /* Now free the callback */ 132 Py_XDECREF(py_dispatch_cb); 133 py_dispatch_cb_n -= 1; 134 if (!py_dispatch_cb_n) 135 py_dispatch_cb = NULL; 136 return; 137 } 138 } 139 140 141 %extend disp_when { 142 disp_when(struct dict_object * app = NULL, struct dict_object * command = NULL, struct dict_object * avp = NULL, struct dict_object * value = NULL) { 143 struct disp_when * w = (struct disp_when *)calloc(1, sizeof(struct disp_when)); 144 if (!w) { 145 DI_ERROR_MALLOC; 146 return NULL; 147 } 148 w->app = app; 149 w->command = command; 150 w->avp = avp; 151 w->value = value; 152 return w; 153 } 154 } -
extensions/dbg_interactive/messages.i
r637 r638 38 38 /****** MESSAGES *********/ 39 39 40 %{ 41 struct anscb_py_layer { 42 PyObject * cb; 43 PyObject * data; 44 }; 45 46 /* If a python callback was provided, it is received in cbdata */ 47 static void anscb_python(void *cbdata, struct msg ** msg) { 48 /* The python callback is received in cbdata */ 49 PyObject * result, *PyMsg; 50 struct anscb_py_layer * l = cbdata; 51 52 if (!l) { 53 fd_log_debug("Internal error! Python callback disappeared...\n"); 54 return; 55 } 56 57 SWIG_PYTHON_THREAD_BEGIN_BLOCK; 58 59 if (!msg || !*msg) { 60 PyMsg = Py_None; 61 } else { 62 PyMsg = SWIG_NewPointerObj((void *)*msg, SWIGTYPE_p_msg, 0 ); 63 } 64 65 result = PyEval_CallFunction(l->cb, "(OO)", PyMsg, l->data); 66 Py_XDECREF(l->cb); 67 Py_XDECREF(l->data); 68 free(l); 69 70 /* The callback is supposed to return a message or NULL */ 71 if (!SWIG_IsOK(SWIG_ConvertPtr(result, (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) { 72 fd_log_debug("Error: Cannot convert the return value to message.\n"); 73 *msg = NULL; 74 } 75 76 Py_XDECREF(result); 77 78 SWIG_PYTHON_THREAD_END_BLOCK; 79 80 } 81 %} 82 40 83 struct msg { 41 84 }; … … 75 118 } 76 119 } 120 121 /* SEND THE MESSAGE */ 122 %delobject send; /* when this has been called, the msg must not be freed anymore */ 123 void send(PyObject * PyCb = NULL, PyObject * data = NULL) { 124 int ret; 125 struct msg * m = $self; 126 struct anscb_py_layer * l = NULL; 127 128 if (PyCb) { 129 l = malloc(sizeof(struct anscb_py_layer)); 130 if (!l) { 131 DI_ERROR_MALLOC; 132 return; 133 } 134 135 Py_XINCREF(PyCb); 136 Py_XINCREF(data); 137 l->cb = PyCb; 138 l->data = data; 139 } 140 141 ret = fd_msg_send(&m, PyCb ? anscb_python : NULL, l); 142 if (ret != 0) { 143 DI_ERROR(ret, NULL, NULL); 144 } 145 } 146 147 /* Create an answer */ 77 148 %delobject create_answer; /* when this has been called, the original msg should not be freed anymore */ 78 149 struct msg * create_answer(struct dictionary * dict = NULL, int flags = 0) { … … 313 384 } 314 385 } 386 387 /* Set the result code */ 388 void rescode_set(char * rescode = "DIAMETER_SUCCESS", char * errormsg = NULL, struct avp * optavp = NULL, int type_id = 0) { 389 int ret = fd_msg_rescode_set( $self, rescode, errormsg, optavp, type_id ); 390 if (ret) { 391 DI_ERROR(ret, NULL, NULL); 392 } 393 } 394 395 /* Add the origin */ 396 void add_origin(int osi = 0) { 397 int ret = fd_msg_add_origin( $self, osi ); 398 if (ret) { 399 DI_ERROR(ret, NULL, NULL); 400 } 401 } 402 315 403 } 316 404 -
extensions/dbg_interactive/peers.i
r637 r638 36 36 /* Do not include this directly, use dbg_interactive.i instead */ 37 37 38 /****** PEERS *********/ 39 40 %{ 41 static void fd_add_cb(struct peer_info *peer, void *data) { 42 /* Callback called when the peer connection completes (or fails) */ 43 PyObject *PyPeer, *PyFunc; 44 PyObject *result = NULL; 45 46 if (!data) { 47 TRACE_DEBUG(INFO, "Internal error: missing callback\n"); 48 return; 49 } 50 PyFunc = data; 51 52 SWIG_PYTHON_THREAD_BEGIN_BLOCK; 53 54 /* Convert the argument */ 55 PyPeer = SWIG_NewPointerObj((void *)peer, SWIGTYPE_p_peer_info, 0 ); 56 57 /* Call the function */ 58 result = PyEval_CallFunction(PyFunc, "(O)", PyPeer); 59 60 Py_XDECREF(result); 61 Py_XDECREF(PyFunc); 62 63 SWIG_PYTHON_THREAD_END_BLOCK; 64 return; 65 } 66 %} 67 68 %extend peer_info { 69 /* Wrapper around fd_peer_add to allow calling the python callback */ 70 void add(PyObject * PyCb=NULL) { 71 int ret; 72 73 if (PyCb) { 74 Py_XINCREF(PyCb); 75 ret = fd_peer_add ( $self, "dbg_interactive", fd_add_cb, PyCb ); 76 } else { 77 ret = fd_peer_add ( $self, "dbg_interactive", NULL, NULL ); 78 } 79 if (ret != 0) { 80 DI_ERROR(ret, NULL, NULL); 81 } 82 } 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 } -
extensions/dbg_interactive/queues.i
r637 r638 36 36 /* Do not include this directly, use dbg_interactive.i instead */ 37 37 38 /****** FIFO QUEUES *********/ 39 40 struct fifo { 41 }; 42 43 %extend fifo { 44 fifo() { 45 struct fifo * q = NULL; 46 int ret = fd_fifo_new(&q); 47 if (ret != 0) { 48 DI_ERROR(ret, NULL, NULL); 49 return NULL; 50 } 51 return q; 52 } 53 ~fifo() { 54 struct fifo *q = self; 55 fd_fifo_del(&q); 56 } 57 58 /* Move all elements to another queue */ 59 void move(struct fifo * to) { 60 int ret = fd_fifo_move($self, to, NULL); 61 if (ret != 0) { 62 DI_ERROR(ret, NULL, NULL); 63 } 64 } 65 66 /* Get the length of the queue (nb elements) */ 67 int length() { 68 int l; 69 int ret = fd_fifo_length ( $self, &l ); 70 if (ret != 0) { 71 DI_ERROR(ret, NULL, NULL); 72 } 73 return l; 74 } 75 76 /* Is the threashold function useful here? TODO... */ 77 78 /* 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); 85 if (ret != 0) { 86 DI_ERROR(ret, NULL, NULL); 87 } 88 } 89 90 /* Get (blocking) */ 91 PyObject * get() { 92 int ret; 93 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; 101 } 102 103 /* TryGet (non-blocking, returns None on empty queue) */ 104 PyObject * tryget() { 105 int ret; 106 PyObject * i = NULL; 107 108 ret = fd_fifo_tryget($self, &i); 109 if (ret == EWOULDBLOCK) { 110 Py_XINCREF(Py_None); 111 return Py_None; 112 } 113 if (ret != 0) { 114 DI_ERROR(ret, NULL, NULL); 115 } 116 117 return i; 118 } 119 120 /* TimedGet (blocking for a while) */ 121 PyObject * timedget(long seconds) { 122 int ret; 123 PyObject * i = NULL; 124 struct timespec ts; 125 126 clock_gettime(CLOCK_REALTIME, &ts); 127 ts.tv_sec += seconds; 128 129 ret = fd_fifo_timedget($self, &i, &ts); 130 if (ret == ETIMEDOUT) { 131 Py_XINCREF(Py_None); 132 return Py_None; 133 } 134 if (ret != 0) { 135 DI_ERROR(ret, NULL, NULL); 136 } 137 138 return i; 139 } 140 141 } 142 143 144 145 -
extensions/dbg_interactive/sessions.i
r637 r638 59 59 }; 60 60 61 %nodefaultctor session_handler; 61 62 %extend session_handler { 62 session_handler() {63 DI_ERROR(EINVAL, PyExc_SyntaxError, "a cleanup callback parameter is required.");64 return NULL;65 }66 63 session_handler(PyObject * PyCb) { 67 64 struct session_handler * hdl = NULL; … … 96 93 } 97 94 } 95 98 96 99 97 struct session {
Note: See TracChangeset
for help on using the changeset viewer.