Changeset 638:9448cba86673 in freeDiameter
- Timestamp:
- Dec 17, 2010, 6:41:19 PM (13 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/dbg_interactive.py.sample
r637 r638 104 104 105 105 ############# Hash ############ 106 hex(fd_hash("hello world")) # A typemap is applied to accept binary data 106 107 hex(fd_hash("hello world")) # It accepts binary data 107 108 108 109 … … 122 123 d.vendors_list() 123 124 125 # Compact invocation also possible: 126 v2 = dict_vendor_data(124, "My test vendor 2") 127 del v2 128 124 129 # New application 125 130 a = dict_application_data() … … 128 133 my_appl = d.new_obj(DICT_APPLICATION, a, my_vendor) 129 134 del a 135 136 a2 = dict_application_data(99, "My test appl 2") 137 del a2 130 138 131 139 # New type (callbacks are not supported yet...) … … 139 147 del t 140 148 149 t2 = dict_type_data(AVP_TYPE_UNSIGNED32, "u32 type") 150 del t2 151 141 152 # Constants 142 153 c = dict_enumval_data() … … 150 161 d.new_obj(DICT_ENUMVAL, c, my_type_os) 151 162 del c 163 164 c2 = dict_enumval_data("enum 23", 23) # The constructor only accepts unsigned32, for other values, set them afterwards 165 c3 = dict_enumval_data("enum other") 166 c3.os = "other value" 167 del c2 168 del c3 152 169 153 170 # AVP … … 166 183 my_avp_os = d.new_obj(DICT_AVP, a, my_type_os) 167 184 del a 185 186 a2 = dict_avp_data(235, "no vendor, not mandatory", AVP_TYPE_OCTETSTRING) 187 a3 = dict_avp_data(236, "vendor 12, not mandatory", AVP_TYPE_OCTETSTRING, 12) 188 a4 = dict_avp_data(237, "vendor 12, mandatory", AVP_TYPE_OCTETSTRING, 12, 1) 189 a5 = dict_avp_data(238, "no vendor, mandatory", AVP_TYPE_OCTETSTRING, 0, 1) 190 del a2 191 del a3 192 del a4 193 del a5 194 168 195 169 196 # Command … … 178 205 my_ans = d.new_obj(DICT_COMMAND, c, my_appl) 179 206 del c 207 208 c2 = dict_cmd_data(346, "Second-Request", 1) # Default created with PROXIABLE flag. 209 c3 = dict_cmd_data(346, "Second-Answer", 0) 210 del c2 211 del c3 180 212 181 213 # Rule … … 195 227 del d 196 228 229 r2 = dict_rule_data(my_avp_int, RULE_REQUIRED) # min & max are optional parameters, default to -1 230 r3 = dict_rule_data(my_avp_int, RULE_REQUIRED, 2, 3) # min is 2, max is 3 231 r4 = dict_rule_data(my_avp_int, RULE_FIXED_HEAD) # The r4.rule_order = 1 by default, change afterwards if needed. 232 del r2 233 del r3 234 del r4 197 235 198 236 ####### Now play with the "real" dictionary … … 272 310 ## AVP 273 311 274 # Create empty (as for messages, pass None or a dictionary object as 1st param, and flags as optional 2nd param)312 # Create empty 275 313 blank_avp = avp() 276 314 del blank_avp 277 315 316 # Create from dictionary definitions 278 317 oh = avp(cvar.fd_g_config.cnf_dict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Host")) # Octet String 279 318 vi = avp(cvar.fd_g_config.cnf_dict.search ( DICT_AVP, AVP_BY_NAME, "Vendor-Id")) # U32 … … 289 328 vsai.add_child(vi) # call as add_child(vi, 1) to add the new AVP at the beginning, default is at the end 290 329 330 # It is possible to initialize the AVP with a blank value as follow: 331 blank_with_value = avp(None, AVPFL_SET_BLANK_VALUE) 332 # it enables this without doing the setval call: 333 blank_with_value.header().avp_value.u32 = 12 334 291 335 292 336 ## Messages 293 337 294 # Create empt y338 # Create empt (as for avps, pass None or a dictionary object as 1st param, and flags as optional 2nd param)y 295 339 a_msg = msg() 296 340 a_msg.dump() … … 358 402 hex(oh_hdr.avp_flags) 359 403 oh_hdr.avp_vendor 360 oh_hdr.avp_value.os.dump() # The initial avp value must be set with setval(), but then this accessor is allowed. 404 oh_hdr.avp_value.os.as_str() 405 361 406 362 407 # Get or set the routing data … … 390 435 391 436 392 393 394 395 396 397 398 399 400 ######################### old stuff (need update) ###################### 401 402 403 # Create a new peer_info structure and add the peer to the framework. 404 mypeer = peer_info() 405 mypeer.pi_diamid = "nas.testbed.aaa" 406 mypeer.config.pic_flags.pro4 = 1 # 1 for TCP, for some reason PI_P4_TCP is not defined 407 fd_peer_add(mypeer, "python", None, None) 408 del mypeer 409 437 # Send a message: 438 mydwr.send() 439 440 # Optionaly, a callback can be registered when a message is sent, with an optional object. 441 # This callback takes the answer message as parameter and should return None or a message. (cf. fd_msg_send) 442 def send_callback(msg, obj): 443 print "Received answer:" 444 msg.dump() 445 print "Associated data:" 446 obj 447 return None 448 449 mydwr.send(send_callback, some_object) 450 451 452 # Set a result code in an answer message. 453 dwa = mydwr.create_answer() 454 dwa.rescode_set() # This adds the DIAMETER_SUCCESS result code 455 dwa.rescode_set("DIAMETER_LIMITED_SUCCESS" ) # This adds a different result code 456 dwa.rescode_set("DIAMETER_LIMITED_SUCCESS", "Something went not so well" ) # This adds a different result code + specified Error-Message 457 dwa.rescode_set("DIAMETER_INVALID_AVP", None, faulty_avp ) # This adds a Failed-AVP 458 dwa.rescode_set("DIAMETER_SUCCESS", None, None, 1 ) # This adds origin information (see fd_msg_rescode_set's type_id for more info) 459 460 # Set the origin to local host 461 mydwr.add_origin() # adds Origin-Host & Origin-Realm 462 mydwr.add_origin(1) # adds Origin-State-Id in addition. 463 464 465 ############# DISPATCH (aka. server application) ############ 466 467 # As for sessions, only one dispatch handler can be registered in this extension at the moment. 468 # The callback for the handler has the following syntax: 469 def dispatch_cb_model(inmsg, inavp, insession): 470 print "Callback trigged on message: " 471 inmsg.dump() 472 # inavp is None or the AVP that trigged the callback, depending on how it was registered. 473 if inavp: 474 print "From the following AVP:" 475 inavp.dump() 476 else: 477 print "No AVP" 478 # Session is provided only if a Session-Id is in the message 479 if insession: 480 print "The session is: ", insession.getsid() 481 else: 482 print "No session" 483 # Now, for the return value. 484 # This callback must return 3 elements: 485 # - an integer which is interpreted as an error code (errno.h) 486 # - a message or None, depending on the next item 487 # - an enum disp_action value, with the same meaning as in C (see libfreeDiameter.h) 488 del inmsg 489 return [ 0, None, DISP_ACT_CONT ] 490 491 492 ### Example use: rebuild the server-side of test_app.fdx in python 493 494 # The following block defines the dictionary objects from the test_app.fdx application that we use on the remote peer 495 gdict = cvar.fd_g_config.cnf_dict 496 d_si = gdict.search ( DICT_AVP, AVP_BY_NAME, "Session-Id" ) 497 d_oh = gdict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Host" ) 498 d_or = gdict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Realm" ) 499 d_dh = gdict.search ( DICT_AVP, AVP_BY_NAME, "Destination-Host" ) 500 d_dr = gdict.search ( DICT_AVP, AVP_BY_NAME, "Destination-Realm" ) 501 d_rc = gdict.search ( DICT_AVP, AVP_BY_NAME, "Result-Code" ) 502 d_vnd = gdict.new_obj(DICT_VENDOR, dict_vendor_data(999999, "app_test_py vendor") ) 503 d_app = gdict.new_obj(DICT_APPLICATION, dict_application_data(0xffffff, "app_test_py appli"), d_vnd) 504 d_req = gdict.new_obj(DICT_COMMAND, dict_cmd_data(0xfffffe, "Test_py-Request", 1), d_app) 505 d_ans = gdict.new_obj(DICT_COMMAND, dict_cmd_data(0xfffffe, "Test_py-Answer", 0), d_app) 506 d_avp = gdict.new_obj(DICT_AVP, dict_avp_data(0xffffff, "app_test_py avp", AVP_TYPE_INTEGER32, 999999 )) 507 gdict.new_obj(DICT_RULE, dict_rule_data(d_si, RULE_FIXED_HEAD, 1, 1), d_req) 508 gdict.new_obj(DICT_RULE, dict_rule_data(d_si, RULE_FIXED_HEAD, 1, 1), d_ans) 509 gdict.new_obj(DICT_RULE, dict_rule_data(d_avp, RULE_REQUIRED, 1, 1), d_req) 510 gdict.new_obj(DICT_RULE, dict_rule_data(d_avp, RULE_REQUIRED, 1, 1), d_ans) 511 gdict.new_obj(DICT_RULE, dict_rule_data(d_oh, RULE_REQUIRED, 1, 1), d_req) 512 gdict.new_obj(DICT_RULE, dict_rule_data(d_oh, RULE_REQUIRED, 1, 1), d_ans) 513 gdict.new_obj(DICT_RULE, dict_rule_data(d_or, RULE_REQUIRED, 1, 1), d_req) 514 gdict.new_obj(DICT_RULE, dict_rule_data(d_or, RULE_REQUIRED, 1, 1), d_ans) 515 gdict.new_obj(DICT_RULE, dict_rule_data(d_dr, RULE_REQUIRED, 1, 1), d_req) 516 gdict.new_obj(DICT_RULE, dict_rule_data(d_dh, RULE_OPTIONAL, 0, 1), d_req) 517 gdict.new_obj(DICT_RULE, dict_rule_data(d_rc, RULE_REQUIRED, 1, 1), d_ans) 518 519 # Now, create the Test_app server callback: 520 def test_app_cb(inmsg, inavp, insession): 521 tval = inmsg.search(d_avp).header().avp_value.u32 522 print "Py ECHO Test message from '%s' with test value %x, replying..." % (inmsg.search(d_oh).header().avp_value.os.as_str(), tval) 523 answ = inmsg.create_answer() 524 answ.rescode_set() 525 answ.add_origin() 526 ta = avp(d_avp, AVPFL_SET_BLANK_VALUE) 527 ta.header().avp_value.u32 = tval 528 answ.add_child(ta) 529 return [ 0, answ, DISP_ACT_SEND ] 530 531 # Register the callback for dispatch thread: 532 hdl = disp_hdl(test_app_cb, DISP_HOW_CC, disp_when(d_app, d_req)) # disp_when() takes 0 to 4 arguments as follow: (app=NULL, cmd=NULL, avp=NULL, val=NULL) 533 534 # Don't forget to register the application in the daemon for CER/CEA capabilities. 535 fd_disp_app_support ( d_app, d_vnd, 1, 0 ) 536 537 538 ### For the fun, the client part of the test_app: 539 540 def receive_answer(ans, testval): 541 try: 542 tval = ans.search(d_avp).header().avp_value.u32 543 except: 544 print "Error in receive_answer: no Test-AVP included" 545 tval = 0 546 try: 547 print "Py RECV %x (expected: %x) Status: %d From: '%s'" % (tval, testval, ans.search(d_rc).header().avp_value.u32, ans.search(d_oh).header().avp_value.os.as_str()) 548 except: 549 print "Error in receive_answer: Result-Code or Origin-Host are missing" 550 del ans 551 return None 552 553 import random 554 555 def send_query(destrealm="localdomain"): 556 qry = msg(d_req) 557 sess = session() 558 tv = random.randint(1, 1<<32) 559 # Session-Id 560 a = avp(d_si, AVPFL_SET_BLANK_VALUE) 561 a.header().avp_value.os = sess.getsid() 562 qry.add_child(a) 563 # Destination-Realm 564 a = avp(d_dr, AVPFL_SET_BLANK_VALUE) 565 a.header().avp_value.os = destrealm 566 qry.add_child(a) 567 # Origin-Host, Origin-Realm 568 qry.add_origin() 569 # Test-AVP 570 a = avp(d_avp, AVPFL_SET_BLANK_VALUE) 571 a.header().avp_value.u32 = tv 572 qry.add_child(a) 573 print "Py SEND %x to '%s'" % (tv, destrealm) 574 qry.send(receive_answer, tv) 575 576 send_query() 577 578 579 ############# FIFO queues ############ 580 581 myqueue = fifo() 582 583 # enqueue any object 584 myqueue.post(3) 585 myqueue.post("blah") 586 myqueue.post( [ 3, 2 ] ) 587 588 # Simple get (blocks when the queue is empty) 589 myqueue.get() 590 591 # Try get: returns the next object, or None if the queue is empty 592 myqueue.tryget() 593 594 # timed get: like get, but returns None after x seconds 595 myqueue.timedget(3) 596 597 # Show the number of items in the queue 598 myqueue.length() 599 600 del myqueue 601 602 603 604 ############# PEERS ############ 605 606 # Get the list of peers defined in the system 607 # (well, we are supposed actually to readlock fd_g_peers_rw before doing this, but it should be fine most of the time) 608 peers = cvar.fd_g_peers.enum_as("struct peer_hdr *") 609 for p in peers: 610 print "Peer:", p.info.pi_diamid 611 612 613 # Create a new peer 614 np = peer_info() 615 np.pi_diamid = "nas.localdomain" 616 np.config.pic_flags.pro4 = 1 # 1 for TCP, for some reason PI_P4_TCP is not defined 617 618 619 620 621 # Add this peer into the framework. 622 np.add() 623 624 # It is possible to specify a callback for when the connection completes or fails to this peer. 625 # The prototype is as follow: 626 def add_cb(peer): 627 if peer: 628 if peer.runtime.pir_state == STATE_OPEN: 629 print "Connection to peer '%s' completed" % (peer.pi_diamid) 630 # can find more information in peer.runtime.* 631 else: 632 print "Connection to peer '%s' failed (state:%d)" % (peer.pi_diamid, peer.runtime.pir_state) 633 else: 634 print "The peer has been destroyed before it completed the connection." 635 636 # Then add the peer simply like this: 637 np.add(add_cb) 638 639 -
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 { -
include/freeDiameter/libfreeDiameter.h
r637 r638 1877 1877 1878 1878 /* Some flags used in the functions bellow */ 1879 #define AVPFL_SET_BLANK_VALUE 0x01 /* When creating an AVP, initialize its value to a blank area */ 1880 #define AVPFL_MAX AVPFL_SET_BLANK_VALUE /* The biggest valid flag value */ 1881 1879 1882 #define MSGFL_ALLOC_ETEID 0x01 /* When creating a message, a new end-to-end ID is allocated and set in the message */ 1880 1883 #define MSGFL_ANSW_ERROR 0x02 /* When creating an answer message, set the 'E' bit and use the generic error ABNF instead of command-specific ABNF */ … … 1890 1893 * PARAMETERS: 1891 1894 * model : Pointer to a DICT_AVP dictionary object describing the avp to create, or NULL. 1892 * flags : Flags to use in creation ( not used yet, should be 0).1895 * flags : Flags to use in creation (AVPFL_*). 1893 1896 * avp : Upon success, pointer to the new avp is stored here. 1894 1897 * -
libfreeDiameter/messages.c
r637 r638 140 140 141 141 /* Macro to validate a MSGFL_ value */ 142 #define CHECK_AVPFL(_fl) ( ((_fl) & (- (AVPFL_MAX << 1) )) == 0 ) 142 143 #define CHECK_MSGFL(_fl) ( ((_fl) & (- (MSGFL_MAX << 1) )) == 0 ) 143 144 … … 200 201 201 202 /* Check the parameters */ 202 CHECK_PARAMS( avp && CHECK_ MSGFL(flags) );203 CHECK_PARAMS( avp && CHECK_AVPFL(flags) ); 203 204 204 205 if (model) { … … 223 224 new->avp_public.avp_len = GETINITIALSIZE(dictdata.avp_basetype, dictdata.avp_flag_val ); 224 225 new->avp_public.avp_vendor = dictdata.avp_vendor; 226 } 227 228 if (flags & AVPFL_SET_BLANK_VALUE) { 229 new->avp_public.avp_value = &new->avp_storage; 225 230 } 226 231
Note: See TracChangeset
for help on using the changeset viewer.