Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
oai
freediameter
Commits
12b195dd
Commit
12b195dd
authored
Dec 15, 2010
by
Sebastien Decugis
Browse files
Still making progress on the dbg_interactive interface.
parent
bcdce685
Changes
2
Hide whitespace changes
Inline
Side-by-side
doc/dbg_interactive.py.sample
View file @
12b195dd
...
...
@@ -94,7 +94,7 @@ d.dump()
v = dict_vendor_data()
v.vendor_id = 123
v.vendor_name = "My test vendor"
r,
my_vendor =
fd_dict_new(d,
DICT_VENDOR, v
, None
)
my_vendor =
d.new_obj(
DICT_VENDOR, v)
del v
d.dump()
d.vendors_list()
...
...
@@ -103,29 +103,29 @@ d.vendors_list()
a = dict_application_data()
a.application_id = 99
a.application_name = "My test appl"
r,
my_appl =
fd_dict_new(d,
DICT_APPLICATION, a, my_vendor)
my_appl =
d.new_obj(
DICT_APPLICATION, a, my_vendor)
del a
# New type (callbacks are not supported yet...)
t = dict_type_data()
t.type_base = AVP_TYPE_INTEGER32
t.type_name = "My integer AVP"
r,
my_type_int =
fd_dict_new(d,
DICT_TYPE, t, my_appl)
my_type_int =
d.new_obj(
DICT_TYPE, t, my_appl)
t.type_base = AVP_TYPE_OCTETSTRING
t.type_name = "My binary buffer AVP"
r,
my_type_os =
fd_dict_new(d,
DICT_TYPE, t, my_appl)
my_type_os =
d.new_obj(
DICT_TYPE, t, my_appl)
del t
# Constants
c = dict_enumval_data()
c.enum_name = "AVP_VALUE_TROIS"
c.enum_value.i32 = 3
fd_dict_new(d,
DICT_ENUMVAL, c, my_type_int)
d.new_obj(
DICT_ENUMVAL, c, my_type_int)
c.enum_name = "A_BUFFER_CONSTANT"
c.enum_value.os = "This is a very long AVP value that we prefer to represent as a constant"
c.enum_value.os.dump()
fd_dict_new(d,
DICT_ENUMVAL, c, my_type_os)
d.new_obj(
DICT_ENUMVAL, c, my_type_os)
del c
# AVP
...
...
@@ -134,14 +134,14 @@ a.avp_code = 234
a.avp_name = "my integer avp"
a.avp_flag_mask = AVP_FLAG_MANDATORY
a.avp_basetype = AVP_TYPE_INTEGER32
r,
my_avp_int =
fd_dict_new(d,
DICT_AVP, a, my_type_int)
my_avp_int =
d.new_obj(
DICT_AVP, a, my_type_int)
a.avp_vendor = 123
a.avp_name = "my OS avp"
a.avp_flag_mask = AVP_FLAG_MANDATORY + AVP_FLAG_VENDOR
a.avp_flag_val = AVP_FLAG_VENDOR
a.avp_basetype = AVP_TYPE_OCTETSTRING
r,
my_avp_os =
fd_dict_new(d,
DICT_AVP, a, my_type_os)
my_avp_os =
d.new_obj(
DICT_AVP, a, my_type_os)
del a
# Command
...
...
@@ -150,24 +150,24 @@ c.cmd_code = 345
c.cmd_name = "My-Python-Request"
c.cmd_flag_mask = CMD_FLAG_REQUEST + CMD_FLAG_PROXIABLE
c.cmd_flag_val = CMD_FLAG_REQUEST + CMD_FLAG_PROXIABLE
r,
my_req =
fd_dict_new(d,
DICT_COMMAND, c, my_appl)
my_req =
d.new_obj(
DICT_COMMAND, c, my_appl)
c.cmd_name = "My-Python-Answer"
c.cmd_flag_val = CMD_FLAG_PROXIABLE
r,
my_ans =
fd_dict_new(d,
DICT_COMMAND, c, my_appl)
my_ans =
d.new_obj(
DICT_COMMAND, c, my_appl)
del c
# Rule
r
d
= dict_rule_data()
r
d
.rule_avp = my_avp_int
r
d
.rule_position = RULE_REQUIRED
r
d
.rule_min = -1
r
d
.rule_max = -1
r, my_rule1 = fd_dict_new(d,
DICT_RULE, r
d
, my_req)
r, my_rule2 = fd_dict_new(d,
DICT_RULE, r
d
, my_ans)
r
d
.rule_avp = my_avp_os
r, my_rule3 = fd_dict_new(d,
DICT_RULE, r
d
, my_req)
r, my_rule4 = fd_dict_new(d,
DICT_RULE, r
d
, my_ans)
del r
d
r = dict_rule_data()
r.rule_avp = my_avp_int
r.rule_position = RULE_REQUIRED
r.rule_min = -1
r.rule_max = -1
d.new_obj(
DICT_RULE, r, my_req)
d.new_obj(
DICT_RULE, r, my_ans)
r.rule_avp = my_avp_os
d.new_obj(
DICT_RULE, r, my_req)
d.new_obj(
DICT_RULE, r, my_ans)
del r
d.dump()
del d
...
...
@@ -177,70 +177,70 @@ del d
gdict = cvar.fd_g_config.cnf_dict
r,
appl =
fd_
dict
_
search (
gdict,
DICT_APPLICATION, APPLICATION_BY_ID, 3
, -1
)
obj
.dump()
r,
avp =
fd_
dict
_
search(
gdict,
DICT_AVP, AVP_BY_NAME, "Origin-Host"
, -1
)
obj
.dump()
r,
errcmd =
fd_
dict
_get_
error_cmd(
gdict
)
appl =
g
dict
.
search ( DICT_APPLICATION, APPLICATION_BY_ID, 3 )
appl
.dump()
avp =
g
dict
.
search
( DICT_AVP, AVP_BY_NAME, "Origin-Host")
avp
.dump()
errcmd =
g
dict
.
error_cmd()
data = dict_avp_data()
fd_dict_getval(avp, data)
print data.avp_code
del data
v = avp.getval()
print v.avp_code
del v
r, t = fd_dict_gettype(appl)
t = avp.gettype()
print t
del t
r,
dict =
fd_dict_
getdict(
avp
)
dict =
avp.
getdict()
del dict
############# Sessions ############
# handler
def my_cleanup(state,sid):
print "Cleaning up python state for session:", sid
print "Received state:", state
del state
hdl = session_handler(my_cleanup)
hdl.dump()
del hdl
hdl = session_handler(my_cleanup)
# Session
hdl = session_handler(my_cleanup)
s1 = session()
s1.getsid()
s2 = session("this.is.a.full.session.id")
r,s3,isnew = fd_sess_fromsid("this.is.a.full.session.id")
s4 = session("host.id", "opt.part")
s4.settimeout(30) # the python wrapper takes a number of seconds as parameter for simplicity
s4.dump()
# states
mystate = [ 34, "blah", [ 32, 12 ] ]
s1.store(hdl, mystate)
del mystate
gotstate = s1.retrieve(hdl)
print gotstate
del gotstate
# state
mystate = [ 34, "clah", [ 32, 12 ] ]
s4.store(hdl, mystate)
############# Routing ############
rd = rt_data()
## TODO : debug the following (segfault)
rd.add("p1.testbed.aaa", "testbed.aaa")
rd.add("p2.testbed.aaa", "testbed.aaa")
rd.add("p3.testbed.aaa", "testbed.aaa")
rd.add("p4.testbed.aaa", "testbed.aaa")
def my_cleanup(state,sid):
print "Cleaning up python state for session:", sid
print "Received state:", state
hdl = session_handler(my_cleanup)
s4 = session("host.id", "opt.part")
mystate = [ 34, "clah", [ 32, 12 ] ]
s4.store(hdl, mystate)
del hdl
rd.remove("p2.testbed.aaa")
rd.error("p3.testbed.aaa", "relay.testbed.aaa", 3002)
list = rd.extract(-1)
list[0].dump()
...
...
@@ -249,22 +249,6 @@ del hdl
######################### old stuff (need update) ######################
# Routing data
prtd = new_rt_data_pptr()
fd_rtd_init(prtd)
fd_rtd_candidate_add(rt_data_pptr_value(prtd), "p1.testbed.aaa", "testbed.aaa")
fd_rtd_candidate_add(rt_data_pptr_value(prtd), "p2.testbed.aaa", "testbed.aaa")
fd_rtd_candidate_add(rt_data_pptr_value(prtd), "p3.testbed.aaa", "testbed.aaa")
fd_rtd_candidate_del(rt_data_pptr_value(prtd), "p2.testbed.aaa", 0)
pcands = new_fd_list_pptr()
fd_rtd_candidate_extract(rt_data_pptr_value(prtd), pcands, 0)
li = fd_list_pptr_value(pcands)
li = fd_list_next_get(li)
c = fd_list_to_rtd_candidate(li)
rtd_candidate_diamid_get(c)
li = fd_list_next_get(li)
c = fd_list_to_rtd_candidate(li)
rtd_candidate_diamid_get(c)
# Messages
...
...
extensions/dbg_interactive/dbg_interactive.i
View file @
12b195dd
...
...
@@ -50,9 +50,10 @@
%
include
<
cstring
.
i
>
%
include
<
typemaps
.
i
>
/* Some functions are not available through the wrapper
, or accessed differently
*/
/* Some functions are not available through the wrapper */
%
ignore
fd_lib_init
;
%
ignore
fd_lib_fini
;
/* -- the following functions are better accessed differently, but we leave their definitions just in case
%ignore fd_dict_init;
%ignore fd_dict_fini;
%ignore fd_sess_handler_create_internal;
...
...
@@ -63,7 +64,13 @@
%ignore fd_sess_reclaim;
%ignore fd_sess_state_store_internal;
%ignore fd_sess_state_retrieve_internal;
%ignore fd_rtd_init;
%ignore fd_rtd_free;
%ignore fd_rtd_candidate_add;
%ignore fd_rtd_candidate_del;
%ignore fd_rtd_candidate_extract;
%ignore fd_rtd_error_add;
*/
/* Inline functions seems to give problems to SWIG -- just remove the inline definition */
%
define
__inline__
...
...
@@ -74,30 +81,77 @@
%
immutable
peer_state_str
;
/* Create a generic error handling mechanism so that functions can provoke an exception */
%
{
/* This is not thread-safe etc. but it should work /most of the time/. */
static
int
wrapper_errno
;
static
PyObject
*
wrapper_errno_py
;
static
char
*
wrapper_error_txt
;
/* if NULL, use strerror(errno) */
#
define
DI_ERROR
(
code
,
pycode
,
str
)
{
\
fd_log_debug
(
"[dbg_interactive] ERROR: %s: %s
\n
"
,
__PRETTY_FUNCTION__
,
str
?
str
:
strerror
(
code
))
;
\
wrapper_errno
=
code
;
\
wrapper_errno_py
=
pycode
;
\
wrapper_error_txt
=
str
;
\
}
#
define
DI_ERROR_MALLOC
\
DI_ERROR
(
ENOMEM
,
PyExc_MemoryError
,
NULL
)
%
}
%
exception
{
/* reset the errno */
wrapper_errno
=
0
;
/* Call the function -- it will use DI_ERROR macro in case of error */
$
action
/* Now, test for error */
if
(
wrapper_errno
)
{
char
*
str
=
wrapper_error_txt
?
wrapper_error_txt
:
strerror
(
wrapper_errno
)
;
PyObject
*
exc
=
wrapper_errno_py
;
if
(
!
exc
)
{
switch
(
wrapper_errno
)
{
case
ENOMEM
:
exc
=
PyExc_MemoryError
;
break
;
case
EINVAL
:
exc
=
PyExc_ValueError
;
break
;
default
:
exc
=
PyExc_RuntimeError
;
}
}
SWIG_PYTHON_THREAD_BEGIN_BLOCK
;
PyErr_SetString
(
exc
,
str
)
;
SWIG_fail
;
SWIG_PYTHON_THREAD_END_BLOCK
;
}
}
/***********************************
Some types & typemaps for usability
***********************************/
/* for fd_hash */
%
apply
(
char
*
STRING
,
size_t
LENGTH
)
{
(
char
*
string
,
size_t
len
)
}
;
/* for dictionary functions */
%
typemap
(
in
,
numinputs
=
0
,
noblock
=
1
)
SWIGTYPE
**
OUTPUT
(
void
*
temp
=
NULL
)
{
$
1
=
(
void
*
)
&
temp;
}
%
typemap
(
argout
,
noblock
=
1
)
SWIGTYPE
**
OUTPUT
{
%
append_output
(
SWIG_NewPointerObj
(
*
$
1
,
$
*
1
_descriptor
,
0
))
;
}
%
apply
SWIGTYPE
**
OUTPUT
{
struct
dict_object
**
ref
}
;
%
apply
SWIGTYPE
**
OUTPUT
{
struct
dict_object
**
obj
}
;
%
apply
SWIGTYPE
**
OUTPUT
{
struct
dict_object
**
result
}
;
%
apply
SWIGTYPE
**
OUTPUT
{
struct
dictionary
**
dict
}
;
/* this is for fd_dict_getdict, not fd_dict_init (use constructor) */
%
apply
int
*
OUTPUT
{
enum
dict_object_type
*
type
}
;
%
apply
(
char
*
STRING
,
size_t
LENGTH
)
{
(
char
*
sid
,
size_t
len
)
}
;
%
apply
SWIGTYPE
**
OUTPUT
{
struct
session
**
session
}
;
%
apply
int
*
OUTPUT
{
int
*
new
}
;
/* Callbacks defined in python */
%
typemap
(
in
)
PyObject
*
PyCb
{
if
(
!
PyCallable_Check
(
$
input
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Need a callable object!"
)
;
SWIG_fail
;
}
$
1
=
$
input
;
}
/*********************************************************
Now, create wrappers for (almost) all objects from fD API
*********************************************************/
...
...
@@ -120,8 +174,7 @@ extensions to the freeDiameter API.
struct
fd_list
*
li
;
li
=
(
struct
fd_list
*
)
malloc
(
sizeof
(
struct
fd_list
))
;
if
(
!
li
)
{
fd_log_debug
(
"Out of memory!
\n
"
)
;
PyErr_SetString
(
PyExc_MemoryError
,
"Not enough memory"
)
;
DI_ERROR_MALLOC
;
return
NULL
;
}
fd_list_init
(
li
,
o
)
;
...
...
@@ -152,43 +205,80 @@ struct dictionary {
struct
dictionary
*
r
=
NULL
;
int
ret
=
fd_dict_init
(
&
r);
if
(
ret
!=
0
)
{
fd_log_debug
(
"Error: %s
\n
"
,
strerror
(
ret
))
;
PyErr_SetString
(
PyExc_MemoryError
,
"Not enough memory"
)
;
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
NULL
;
}
return
r
;
}
~
dictionary
()
{
if
(
self
)
{
struct
dictionary
*
d
=
self
;
int
ret
=
fd_dict_fini
(
&
d);
if
(
ret
!=
0
)
{
fd_log_debug
(
"Error: %s
\n
"
,
strerror
(
ret
))
;
}
return
;
struct
dictionary
*
d
=
self
;
int
ret
=
fd_dict_fini
(
&
d);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
}
return
;
}
void
dump
()
{
if
(
$
self
)
{
fd_dict_dump
(
$
self
)
;
}
fd_dict_dump
(
$
self
)
;
}
PyObject
*
vendors_list
()
{
uint32_t
*
list
=
NULL
,
*
li
;
PyObject
*
ret
;
if
(
!
$
self
)
{
PyErr_SetString
(
PyExc_SyntaxError
,
"dict_object cannot be created directly. Use fd_dict_new."
)
;
return
NULL
;
}
SWIG_PYTHON_THREAD_BEGIN_BLOCK
;
ret
=
PyList_New
(
0
)
;
list
=
fd_dict_get_vendorid_list
(
$
self
)
;
for
(
li
=
list
;
*
li
!=
0
;
li
++
)
{
PyList_Append
(
ret
,
PyInt_FromLong
((
long
)
*
li
))
;
}
free
(
list
)
;
SWIG_PYTHON_THREAD_END_BLOCK
;
return
ret
;
}
struct
dict_object
*
new_obj
(
enum
dict_object_type
type
,
void
*
data
,
struct
dict_object
*
parent
=
NULL
)
{
struct
dict_object
*
obj
=
NULL
;
int
ret
=
fd_dict_new
(
$
self
,
type
,
data
,
parent
,
&
obj);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
NULL
;
}
return
obj
;
}
struct
dict_object
*
search
(
enum
dict_object_type
type
,
int
criteria
,
int
what_by_val
)
{
struct
dict_object
*
obj
=
NULL
;
int
ret
=
fd_dict_search
(
$
self
,
type
,
criteria
,
&
what_by_val,
&
obj,
ENOENT
);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
NULL
;
}
return
obj
;
}
struct
dict_object
*
search
(
enum
dict_object_type
type
,
int
criteria
,
char
*
what_by_string
)
{
struct
dict_object
*
obj
=
NULL
;
int
ret
=
fd_dict_search
(
$
self
,
type
,
criteria
,
what_by_string
,
&
obj,
ENOENT
);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
NULL
;
}
return
obj
;
}
struct
dict_object
*
search
(
enum
dict_object_type
type
,
int
criteria
,
void
*
what
)
{
struct
dict_object
*
obj
=
NULL
;
int
ret
=
fd_dict_search
(
$
self
,
type
,
criteria
,
what
,
&
obj,
ENOENT
);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
NULL
;
}
return
obj
;
}
struct
dict_object
*
error_cmd
()
{
struct
dict_object
*
obj
=
NULL
;
int
ret
=
fd_dict_get_error_cmd
(
$
self
,
&
obj
);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
NULL
;
}
return
obj
;
}
}
struct
dict_object
{
...
...
@@ -196,34 +286,80 @@ struct dict_object {
%
extend
dict_object
{
dict_object
()
{
fd_log_debug
(
"Error: dict_object cannot be created directly. Use fd_dict_new
\n
"
)
;
PyErr_SetString
(
PyExc_SyntaxError
,
"dict_object cannot be created directly. Use fd_dict_new."
)
;
DI_ERROR
(
EINVAL
,
PyExc_SyntaxError
,
"dict_object cannot be created directly. Use fd_dict_new()."
)
;
return
NULL
;
}
~
dict_object
()
{
fd_log_debug
(
"
Error
:
dict_object cannot be destroyed directly. Destroy the parent dictionary.
\n
"
)
;
DI_ERROR
(
EINVAL
,
PyExc_Syntax
Error
,
"
dict_object cannot be destroyed directly. Destroy the parent dictionary."
)
;
return
;
}
void
dump
()
{
if
(
$
self
)
{
fd_dict_dump_object
(
$
self
)
;
fd_dict_dump_object
(
$
self
)
;
}
enum
dict_object_type
gettype
()
{
enum
dict_object_type
t
;
int
ret
=
fd_dict_gettype
(
$
self
,
&
t);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
0
;
}
return
t
;
}
struct
dictionary
*
getdict
()
{
struct
dictionary
*
d
;
int
ret
=
fd_dict_getdict
(
$
self
,
&
d
);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
NULL
;
}
return
d
;
}
/* Since casting the pointer requires intelligence, we do it here instead of giving it to SWIG */
PyObject
*
getval
()
{
/* first, get the type */
enum
dict_object_type
t
;
int
ret
=
fd_dict_gettype
(
$
self
,
&
t);
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
return
NULL
;
}
switch
(
t
)
{
%
define
%
GETVAL_CASE
(
TYPE
,
STRUCT
)
case
TYPE
:
{
PyObject
*
v
=
NULL
;
struct
STRUCT
*
data
=
NULL
;
data
=
malloc
(
sizeof
(
struct
STRUCT
))
;
if
(
!
data
)
{
DI_ERROR_MALLOC
;
return
NULL
;
}
ret
=
fd_dict_getval
(
$
self
,
data
)
;
if
(
ret
!=
0
)
{
DI_ERROR
(
ret
,
NULL
,
NULL
)
;
free
(
data
)
;
return
NULL
;
}
SWIG_PYTHON_THREAD_BEGIN_BLOCK
;
v
=
SWIG_NewPointerObj
((
void
*
)
data
,
SWIGTYPE_p_
##
STRUCT
,
SWIG_POINTER_OWN
)
;
Py_XINCREF
(
v
)
;
SWIG_PYTHON_THREAD_END_BLOCK
;
return
v
;
}
break
%
enddef
%
GETVAL_CASE
(
DICT_VENDOR
,
dict_vendor_data
)
;
%
GETVAL_CASE
(
DICT_APPLICATION
,
dict_application_data
)
;
%
GETVAL_CASE
(
DICT_TYPE
,
dict_type_data
)
;
%
GETVAL_CASE
(
DICT_ENUMVAL
,
dict_enumval_data
)
;
%
GETVAL_CASE
(
DICT_AVP
,
dict_avp_data
)
;
%
GETVAL_CASE
(
DICT_COMMAND
,
dict_cmd_data
)
;
%
GETVAL_CASE
(
DICT_RULE
,
dict_rule_data
)
;
default
:
DI_ERROR
(
EINVAL
,
PyExc_SystemError
,
"Internal error: Got invalid object type"
)
;
}
return
NULL
;
}
}
/* overload the search function to allow passing integers & string criteria directly */
%
rename
(
fd_dict_search
)
fd_dict_search_int
;
%
inline
%
{
int
fd_dict_search_int
(
struct
dictionary
*
dict
,
enum
dict_object_type
type
,
int
criteria
,
int
what_by_val
,
struct
dict_object
**
result
,
int
retval
)
{
return
fd_dict_search
(
dict
,
type
,
criteria
,
&
what_by_val,
result,
retval
);
}
%
}
%
rename
(
fd_dict_search
)
fd_dict_search_string
;
%
inline
%
{
int
fd_dict_search_string
(
struct
dictionary
*
dict
,
enum
dict_object_type
type
,
int
criteria
,
char
*
what_by_string
,
struct
dict_object
**
result
,
int
retval
)
{
return
fd_dict_search
(
dict
,
type
,
criteria
,
what_by_string
,
result
,
retval
)
;
}
%
}
/* The following wrapper leaks memory each time an union avp_value is assigned an octet string.
TODO: fix this leak by better understanding SWIG...
...
...
@@ -243,8 +379,7 @@ int fd_dict_search_string ( struct dictionary * dict, enum dict_object_type type
/* free($self->os.data); -- do not free, in case the previous value was not an OS */
$
self-
>
os
.
data
=
malloc
(
LENGTH
)
;
if
(
!
$
self-
>
os
.
data
)
{
fd_log_debug
(
"Out of memory!
\n
"
)
;
PyErr_SetString
(
PyExc_MemoryError
,
"Not enough memory"
)
;
DI_ERROR_MALLOC
;
return
;
}
memcpy
(
$
self-
>
os
.
data
,
STRING
,
LENGTH
)
;
...
...
@@ -254,8 +389,7 @@ int fd_dict_search_string ( struct dictionary * dict, enum dict_object_type type
/* free($self->os.data); -- do not free, in case the previous value was not an OS */
$
self-
>
os
.
data
=
malloc
(
os-
>
len
)
;
if
(
!
$
self-
>
os
.
data
)
{
fd_log_debug
(
"Out of memory!
\n
"
)
;
PyErr_SetString
(
PyExc_MemoryError
,
"Not enough memory"
)
;
DI_ERROR_MALLOC
;
return
;
}
memcpy
(
$
self-
>
os
.
data
,
os-
>
data
,
os-
>
len
)
;
...
...
@@ -265,33 +399,33 @@ int fd_dict_search_string ( struct dictionary * dict, enum dict_object_type type
%
extend
avp_value_os
{
void
dump
()
{
if
(
$
self
)
{
%
#
define
LEN_MAX
20
int
i
,
n
=
LEN_MAX
;
if
(
$
self-
>
len
<
LEN_MAX
)
n
=
$
self-
>
len
;
fd_log_debug
(
"l:%u, v:["
,
$
self-
>
len
)
;
for
(
i
=
0
;
i
<
n
;
i
++
)
fd_log_debug
(
"%02.2X"
,
$
self-
>
data
[
i
])
;
fd_log_debug
(
"] '%.*s%s'
\n
"
,
n
,
$
self-
>
data
,
n
==
LEN_MAX
?
"..."
:
""
)
;
}
%
#
define
LEN_MAX
20
int
i
,
n
=
LEN_MAX
;
if
(
$
self-
>
len
<
LEN_MAX
)
n
=
$
self-
>
len
;
fd_log_debug
(
"l:%u, v:["
,
$
self-
>
len
)
;
for
(
i
=
0
;
i
<
n
;
i
++
)
fd_log_debug
(
"%02.2X"
,
$
self-
>
data
[
i
])
;
fd_log_debug
(
"] '%.*s%s'
\n
"
,
n
,
$
self-
>
data
,
n
==
LEN_MAX
?
"..."
:
""
)
;
}
}
/****** SESSIONS *********/
%
{
/*
At the moment, only 1 callback is supported...
*/
/*
store the python callback function here
*/
static
PyObject
*
py_cleanup_cb
=
NULL
;
/* call it (might be called from a different thread than the interpreter, when session times out) */
static
void
call_the_python_cleanup_callback
(
session_state
*
state
,
char
*
sid
)
{
PyObject
*
result
;
if
(
!
py_cleanup_cb
)
return
;
/* Call the function */
SWIG_PYTHON_THREAD_BEGIN_BLOCK
;
result
=
PyEval_CallFunction
(
py_cleanup_cb
,
"(Os)"
,
state
,
sid
)
;
Py_XDECREF
(
result
)
;
SWIG_PYTHON_THREAD_END_BLOCK
;
return
;
}
%
}
...
...
@@ -301,47 +435,39 @@ struct session_handler {
%
extend
session_handler
{
session_handler
()
{
fd_log_debug
(
"Error: a cleanup callback parameter is required.
\n
"
)
;
PyErr_SetString
(
PyExc_SyntaxError
,
"Error: a cleanup callback parameter is required.
\n
"
)
;
DI_ERROR
(
EINVAL
,
PyExc_SyntaxError
,
"a cleanup callback parameter is required."
)
;
return
NULL
;
}
session_handler
(
PyObject
*
PyC
leanupC
b
)
{
session_handler
(
PyObject
*
PyCb
)
{
struct
session_handler
*
hdl
=
NULL
;
int
ret
;
if
(
py_cleanup_cb
)
{
fd_log_debug
(
"dbg_interactive supports only 1 session handler in python at the moment
\n
"
)
;
PyErr_SetString
(
PyExc_SyntaxError
,
"dbg_interactive supports only 1 session handler in python at the moment
\n
"
)
;
return
NULL
;