blob: a256cf796f735d59fce5e402e86e7121c4801ed3 [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/****** PEERS *********/
39
40%{
41static 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");
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 = PyObject_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 peer_info () {
70 struct peer_info *np = (struct peer_info *)calloc(1, sizeof(struct peer_info));
71 if (!np) {
72 DI_ERROR_MALLOC;
73 return NULL;
74 }
75
76 fd_list_init(&np->pi_endpoints, NULL);
77
78 return np;
79 }
80
81 /* Wrapper around fd_peer_add to allow calling the python callback */
82 %delobject add;
83 void add(PyObject * PyCb=NULL) {
84 int ret;
85
86 if (PyCb) {
87 Py_XINCREF(PyCb);
88 ret = fd_peer_add ( $self, "dbg_interactive", fd_add_cb, PyCb );
89 } else {
90 ret = fd_peer_add ( $self, "dbg_interactive", NULL, NULL );
91 }
92 if (ret != 0) {
93 DI_ERROR(ret, NULL, NULL);
94 }
95 }
96}
97
98%inline %{
99static struct peer_hdr * peer_search(char *STRING, size_t LENGTH) {
100 struct peer_hdr *r = NULL;
101 int ret = fd_peer_getbyid( STRING, LENGTH, 0, &r );
102 if (ret) {
103 DI_ERROR(ret, NULL, NULL);
104 return NULL;
105 }
106 return r;
107}
108%}
109
110%{
111static PyObject * validate_cb_py = NULL;
112static PyObject * validate_cb2_py = NULL;
113
114/* C wrapper that calls validate_cb2_py */
115int call_the_python_validate_callback2(struct peer_info * info) {
116 PyObject *PyInfo;
117 PyObject *result = NULL;
118 int ret = 0;
119
120 if (!validate_cb2_py) {
121 fd_log_debug("Internal error: missing the callback2!");
122 return ENOTSUP;
123 }
124
125 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
126 /* Convert the arguments */
127 PyInfo = SWIG_NewPointerObj((void *)info, SWIGTYPE_p_peer_info, 0 );
128
129 /* Call the function */
130 result = PyObject_CallFunction(validate_cb2_py, "(O)", PyInfo);
131
132 /* The result is an integer */
133 if ((result == NULL) || !SWIG_IsOK(SWIG_AsVal_int(result, &ret))) {
134 fd_log_debug("Error: The Python callback did not return an integer.");
135 ret = EINVAL;
136 goto out;
137 }
138
139out:
140 Py_XDECREF(result);
141 SWIG_PYTHON_THREAD_END_BLOCK;
142 return ret;
143}
144
145/* C wrapper that calls validate_cb_py */
146int call_the_python_validate_callback(struct peer_info * info, int * auth, int (**cb2)(struct peer_info *)) {
147 PyObject *PyInfo;
148 PyObject *result = NULL;
149 int ret = 0;
150
151 if (!validate_cb_py) {
152 fd_log_debug("Internal error: missing the callback!");
153 return ENOTSUP;
154 }
155
156 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
157 /* Convert the arguments */
158 PyInfo = SWIG_NewPointerObj((void *)info, SWIGTYPE_p_peer_info, 0 );
159
160 /* Call the function */
161 result = PyObject_CallFunction(validate_cb_py, "(O)", PyInfo);
162
163 /* The result is supposedly -1, 1, or a cb2 */
164 if (result == NULL) {
165 fd_log_debug("Error: The Python callback did not return a value.");
166 ret = EINVAL;
167 goto out;
168 }
169
170 if (PyCallable_Check(result)) {
171 if (cb2) {
172 if (validate_cb2_py && (validate_cb2_py != result)) {
173 fd_log_debug("Only 1 register callback2 is supported currently");
174 ret = ENOTSUP;
175 goto out;
176 }
177 validate_cb2_py = result;
178 *cb2 = call_the_python_validate_callback2;
179 *auth = 1;
180 goto out_nodec;
181 } else {
182 *auth = 1;
183 goto out; /* ignore the callback since it won't be used */
184 }
185 } else { /* In this case, the return value must be -1, 0, or 1 */
186 if (!SWIG_IsOK(SWIG_AsVal_int(result, auth))) {
187 fd_log_debug("Error: Cannot convert the return value to integer.");
188 ret = EINVAL;
189 goto out;
190 }
191 }
192
193out:
194 Py_XDECREF(result);
195out_nodec:
196 SWIG_PYTHON_THREAD_END_BLOCK;
197 TRACE_DEBUG(FULL, "ret=%d, *auth=%d, cb2=%p, *cb2=%p", ret, *auth, cb2, cb2 ? *cb2 : NULL);
198 return ret;
199}
200
201%}
202
203%inline %{
204static void peer_validate_register(PyObject * PyCb) {
205 int ret ;
206
207 if (!PyCb) {
208 DI_ERROR(EINVAL, NULL, "The callback must be provided");
209 return;
210 }
211
212 if (validate_cb_py) {
213 if (PyCb != validate_cb_py) {
214 DI_ERROR(ENOTSUP, PyExc_RuntimeError, "Only 1 register callback is supported currently");
215 return;
216 }
217 } else {
218 validate_cb_py = PyCb;
219 Py_XINCREF(PyCb);
220 }
221
222 ret = fd_peer_validate_register ( call_the_python_validate_callback );
223 if (ret) {
224 DI_ERROR(ret, NULL, NULL);
225 }
226}
227%}