blob: bc392515be8900be2c6990c1db025103bc43bb5e [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*********************************************************************************************************
2* Software License Agreement (BSD License) *
3* Author: Sebastien Decugis <sdecugis@freediameter.net> *
4* *
5* Copyright (c) 2013, WIDE Project and NICT *
6* All rights reserved. *
7* *
8* Redistribution and use of this software in source and binary forms, with or without modification, are *
9* permitted provided that the following conditions are met: *
10* *
11* * Redistributions of source code must retain the above *
12* copyright notice, this list of conditions and the *
13* following disclaimer. *
14* *
15* * Redistributions in binary form must reproduce the above *
16* copyright notice, this list of conditions and the *
17* following disclaimer in the documentation and/or other *
18* materials provided with the distribution. *
19* *
20* * Neither the name of the WIDE Project or NICT nor the *
21* names of its contributors may be used to endorse or *
22* promote products derived from this software without *
23* specific prior written permission of WIDE Project and *
24* NICT. *
25* *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34*********************************************************************************************************/
35
36/* Do not include this directly, use dbg_interactive.i instead */
37
38/****** DISPATCH *********/
39
40
41%{
42/* call it (will be called from a different thread than the interpreter, when message arrives) */
43static int call_the_python_dispatch_callback(struct msg **msg, struct avp *avp, struct session *session, void * pycb, enum disp_action *action) {
44 PyObject *PyMsg, *PyAvp, *PySess;
45 PyObject *cb, *result = NULL;
46 int ret = 0;
47
48 if (!pycb) {
49 fd_log_debug("Internal error: missing the callback!");
50 return ENOTSUP;
51 }
52 cb = pycb;
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 = PyObject_CallFunction(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 ].");
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.");
73 ret = EINVAL;
74 goto out;
75 }
76 if (ret) {
77 TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)", 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.");
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.");
89 ret = EINVAL;
90 goto out;
91 }
92
93 TRACE_DEBUG(FULL, "Python callback return: *action = %d", *action);
94out:
95 Py_XDECREF(result);
96
97 SWIG_PYTHON_THREAD_END_BLOCK;
98 return ret;
99}
100%}
101
102struct 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
111 Py_XINCREF(PyCb);
112
113 ret = fd_disp_register ( call_the_python_dispatch_callback, how, when, PyCb, &hdl );
114 if (ret != 0) {
115 DI_ERROR(ret, NULL, NULL);
116 return NULL;
117 }
118 return hdl;
119 }
120 ~disp_hdl() {
121 struct disp_hdl * hdl = self;
122 PyObject * cb = NULL;
123 int ret = fd_disp_unregister(&hdl, (void *)&cb);
124 if (ret != 0) {
125 DI_ERROR(ret, NULL, NULL);
126 }
127 Py_XDECREF(cb);
128 return;
129 }
130}
131
132
133%extend disp_when {
134 disp_when(struct dict_object * app = NULL, struct dict_object * command = NULL, struct dict_object * avp = NULL, struct dict_object * value = NULL) {
135 struct disp_when * w = (struct disp_when *)calloc(1, sizeof(struct disp_when));
136 if (!w) {
137 DI_ERROR_MALLOC;
138 return NULL;
139 }
140 w->app = app;
141 w->command = command;
142 w->avp = avp;
143 w->value = value;
144 return w;
145 }
146}