Navigation


Embedded Python interpreter

This dbg_interactive.fdx extension gives access to the freeDiameter framework through a Python interface layer. It can be used both to run pre-existing scripts or through an interactive console directly for quick tests / monitoring of the daemon's state.

A warning anyway: this python layer should not be used for any purpose other than quick prototyping and/or debug. The memory management and the efficiency are bellow the level of the framework itself -- although still pretty usable.

Configuration

dbg_interactive_xml.fdx extension does not use a configuration file. It is possible however to specify a file associated with the extension in the main {{freeDiameter.conf}} file. In that case, this file should be a python script, that will be executed by the embedded python interpreter. If no such file is provided, the interpreter is run interactively (as long as the daemon is run with a usable console).

Usage

The list of all usable functions is given in dbg_interactive.py.sample. Here is a brief example of how to re-create the test_app.fdx client and server function from python:

# Load / create the dictionary objects
gdict = cvar.fd_g_config.cnf_dict
d_si = gdict.search ( DICT_AVP, AVP_BY_NAME, "Session-Id" )
d_oh  = gdict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Host" )
d_or  = gdict.search ( DICT_AVP, AVP_BY_NAME, "Origin-Realm" )
d_dh  = gdict.search ( DICT_AVP, AVP_BY_NAME, "Destination-Host" )
d_dr  = gdict.search ( DICT_AVP, AVP_BY_NAME, "Destination-Realm" )
d_rc  = gdict.search ( DICT_AVP, AVP_BY_NAME, "Result-Code" )
d_vnd = gdict.new_obj(DICT_VENDOR, dict_vendor_data(999999, "app_test_py vendor") )
d_app = gdict.new_obj(DICT_APPLICATION, dict_application_data(0xffffff, "app_test_py appli"), d_vnd)
d_req = gdict.new_obj(DICT_COMMAND, dict_cmd_data(0xfffffe, "Test_py-Request", 1), d_app)
d_ans = gdict.new_obj(DICT_COMMAND, dict_cmd_data(0xfffffe, "Test_py-Answer",  0), d_app)
d_avp = gdict.new_obj(DICT_AVP, dict_avp_data(0xffffff, "app_test_py avp", AVP_TYPE_INTEGER32, 999999 ))
# (skip rules in the example)

###### Server part:
def test_app_cb(inmsg, inavp, insession):
   tval = inmsg.search(d_avp).header().avp_value.u32
   print "Py ECHO Test message from '%s' with test value %x, replying..." % (inmsg.search(d_oh).header().avp_value.os.as_str(), tval)
   answ = inmsg.create_answer()
   answ.rescode_set()
   answ.add_origin()
   ta = avp(d_avp, AVPFL_SET_BLANK_VALUE)
   ta.header().avp_value.u32 = tval
   answ.add_child(ta)
   return [ 0, answ, DISP_ACT_SEND ]

# Register the callback for dispatch thread:
hdl = disp_hdl(test_app_cb, DISP_HOW_CC, disp_when(d_app, d_req))

# Don't forget to register the application in the daemon for CER/CEA capabilities.
fd_disp_app_support ( d_app, d_vnd, 1, 0 )

###### Client part:
def receive_answer(ans, testval):
    tval = ans.search(d_avp).header().avp_value.u32
    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())
    del ans
    return None

import random
def send_query(destrealm="localdomain"):
   qry = msg(d_req)
   sess = session()
   tv = random.randint(1, 1<<32)
   # Session-Id
   a = avp(d_si, AVPFL_SET_BLANK_VALUE)
   a.header().avp_value.os = sess.getsid()
   qry.add_child(a)
   # Destination-Realm
   a = avp(d_dr, AVPFL_SET_BLANK_VALUE)
   a.header().avp_value.os = destrealm
   qry.add_child(a)
   # Origin-Host, Origin-Realm
   qry.add_origin()
   # Test-AVP
   a = avp(d_avp, AVPFL_SET_BLANK_VALUE)
   a.header().avp_value.u32 = tv
   qry.add_child(a)
   print "Py SEND %x to '%s'" % (tv, destrealm)
   qry.send(receive_answer, tv)

send_query()

This is a simplified version without error checking, but it should give a good idea of the simplicity of use of the python interface.

Output

This application does not produce any particular output -- well, all depends on what is done in python.

Troubleshooting

Last modified 10 years ago Last modified on Mar 4, 2011, 5:48:50 PM