3 * Python bindings for TIPC
4 * Alberto Bertogli (albertito@gmail.com)
6 * This is the low-level module, used by the python one to construct
12 #include <sys/types.h> /* socket defines */
13 #include <sys/socket.h> /* socket functions */
14 #include <stdlib.h> /* malloc() */
15 #include <stdint.h> /* uint32_t and friends */
16 #include <arpa/inet.h> /* htonls() and friends */
17 #include <string.h> /* memcpy() */
19 #include <linux/tipc.h> /* TIPC stuff */
23 * Internal useful functions
26 static int fill_sockaddr(struct sockaddr_tipc
*sa
, PyObject
*addr
)
28 unsigned int atype
, stype
, lower
, upper
;
29 unsigned int scope
= TIPC_CLUSTER_SCOPE
;
31 if (!PyArg_ParseTuple(addr
, "iiii|i;Invalid TIPC address format",
32 &atype
, &stype
, &lower
, &upper
, &scope
))
35 memset(sa
, 0, sizeof(struct sockaddr_tipc
));
40 if (atype
== TIPC_ADDR_NAME
) {
41 sa
->addrtype
= TIPC_ADDR_NAME
;
42 sa
->addr
.name
.name
.type
= stype
;
43 sa
->addr
.name
.name
.instance
= lower
;
45 sa
->addrtype
= TIPC_ADDR_NAMESEQ
;
46 sa
->addr
.nameseq
.type
= stype
;
47 sa
->addr
.nameseq
.lower
= lower
;
48 sa
->addr
.nameseq
.upper
= upper
;
53 static PyObject
*sa_to_tuple(const struct sockaddr_tipc
*sa
)
55 if (sa
->addrtype
== TIPC_ADDR_NAMESEQ
) {
56 return Py_BuildValue("iiiii",
58 sa
->addr
.nameseq
.type
,
59 sa
->addr
.nameseq
.lower
,
60 sa
->addr
.nameseq
.upper
,
63 return Py_BuildValue("iiiii",
65 sa
->addr
.name
.name
.type
,
66 sa
->addr
.name
.name
.instance
,
67 sa
->addr
.name
.name
.instance
,
77 static PyObject
*tipc_socket(PyObject
*self
, PyObject
*args
)
81 if (!PyArg_ParseTuple(args
, "i:tipc_socket", &stype
)) {
85 Py_BEGIN_ALLOW_THREADS
86 fd
= socket(AF_TIPC
, stype
, 0);
89 return PyErr_SetFromErrno(PyExc_IOError
);
91 return PyLong_FromLong(fd
);
95 static PyObject
*tipc_bind(PyObject
*self
, PyObject
*args
)
98 struct sockaddr_tipc sa
;
101 if (!PyArg_ParseTuple(args
, "iO:tipc_bind", &fd
, &addr
))
104 if (!fill_sockaddr(&sa
, addr
))
107 Py_BEGIN_ALLOW_THREADS
108 rv
= bind(fd
, (struct sockaddr
*) &sa
, sizeof(sa
));
112 return PyErr_SetFromErrno(PyExc_IOError
);
114 return PyLong_FromLong(rv
);
118 static PyObject
*tipc_connect(PyObject
*self
, PyObject
*args
)
121 struct sockaddr_tipc sa
;
124 if (!PyArg_ParseTuple(args
, "iO:tipc_connect", &fd
, &addr
))
127 if (!fill_sockaddr(&sa
, addr
))
130 Py_BEGIN_ALLOW_THREADS
131 rv
= connect(fd
, (struct sockaddr
*) &sa
, sizeof(sa
));
135 return PyErr_SetFromErrno(PyExc_IOError
);
137 return PyLong_FromLong(rv
);
141 static PyObject
*tipc_accept(PyObject
*self
, PyObject
*args
)
144 struct sockaddr_tipc sa
;
145 socklen_t salen
= sizeof(sa
);
147 if (!PyArg_ParseTuple(args
, "i:tipc_accept", &fd
)) {
151 Py_BEGIN_ALLOW_THREADS
152 newfd
= accept(fd
, (struct sockaddr
*) &sa
, &salen
);
156 return PyErr_SetFromErrno(PyExc_IOError
);
157 return Py_BuildValue("iO", newfd
, sa_to_tuple(&sa
));
161 static PyObject
*tipc_sendto(PyObject
*self
, PyObject
*args
)
166 struct sockaddr_tipc sa
;
169 if (!PyArg_ParseTuple(args
, "is#O:tipc_sendto", &fd
, &buf
, &len
, &addr
))
172 if (!fill_sockaddr(&sa
, addr
))
175 Py_BEGIN_ALLOW_THREADS
176 rv
= sendto(fd
, buf
, len
, 0, (struct sockaddr
*) &sa
, sizeof(sa
));
180 return PyErr_SetFromErrno(PyExc_IOError
);
182 return PyLong_FromLong(rv
);
185 static PyObject
*tipc_recvfrom(PyObject
*self
, PyObject
*args
)
190 struct sockaddr_tipc sa
;
191 socklen_t salen
= sizeof(sa
);
195 if (!PyArg_ParseTuple(args
, "ii:tipc_recvfrom", &fd
, &maxlen
)) {
199 buf
= malloc(maxlen
);
201 return PyErr_NoMemory();
203 Py_BEGIN_ALLOW_THREADS
204 rv
= recvfrom(fd
, buf
, maxlen
, 0,
205 (struct sockaddr
*) &sa
, &salen
);
209 return PyErr_SetFromErrno(PyExc_IOError
);
211 str
= PyString_FromStringAndSize(buf
, rv
);
214 return Py_BuildValue("OO", str
, sa_to_tuple(&sa
));
217 static PyObject
*tipc_build_subscr(PyObject
*self
, PyObject
*args
)
219 int stype
, lower
, upper
;
220 uint32_t timeout
, filter
;
221 struct tipc_subscr subs
;
223 if (!PyArg_ParseTuple(args
, "iiiii:tipc_build_subscr",
224 &stype
, &lower
, &upper
, &timeout
, &filter
)) {
228 subs
.seq
.type
= stype
;
229 subs
.seq
.lower
= lower
;
230 subs
.seq
.upper
= upper
;
231 subs
.timeout
= timeout
;
232 subs
.filter
= filter
;
234 return PyString_FromStringAndSize((char *) &subs
,
238 static PyObject
*tipc_parse_event(PyObject
*self
, PyObject
*args
)
242 struct tipc_event
*event
;
244 if (!PyArg_ParseTuple(args
, "s#:tipc_parse_event",
249 /* Return None if the buffer looks strange */
250 if (len
< sizeof(event
))
251 return Py_BuildValue("");
253 event
= (struct tipc_event
*) buf
;
255 return Py_BuildValue("iii(iiiii)",
269 static PyMethodDef pytipc_functions
[] = {
270 { "socket", (PyCFunction
) tipc_socket
, METH_VARARGS
, NULL
},
271 { "bind", (PyCFunction
) tipc_bind
, METH_VARARGS
, NULL
},
272 { "connect", (PyCFunction
) tipc_connect
, METH_VARARGS
, NULL
},
273 { "accept", (PyCFunction
) tipc_accept
, METH_VARARGS
, NULL
},
274 { "sendto", (PyCFunction
) tipc_sendto
, METH_VARARGS
, NULL
},
275 { "recvfrom", (PyCFunction
) tipc_recvfrom
, METH_VARARGS
, NULL
},
276 { "build_subscr", (PyCFunction
) tipc_build_subscr
, METH_VARARGS
, NULL
},
277 { "parse_event", (PyCFunction
) tipc_parse_event
, METH_VARARGS
, NULL
},
281 PyMODINIT_FUNC
inittipc_ll(void)
285 m
= Py_InitModule("tipc_ll", pytipc_functions
);
286 PyModule_AddIntConstant(m
, "AF_TIPC", AF_TIPC
);
289 PyModule_AddIntConstant(m
, "TIPC_ADDR_NAME", TIPC_ADDR_NAME
);
290 PyModule_AddIntConstant(m
, "TIPC_ADDR_NAMESEQ", TIPC_ADDR_NAMESEQ
);
292 PyModule_AddIntConstant(m
, "TIPC_ZONE_SCOPE", TIPC_ZONE_SCOPE
);
293 PyModule_AddIntConstant(m
, "TIPC_CLUSTER_SCOPE", TIPC_CLUSTER_SCOPE
);
294 PyModule_AddIntConstant(m
, "TIPC_NODE_SCOPE", TIPC_NODE_SCOPE
);
297 /* for setsockopt() */
298 PyModule_AddIntConstant(m
, "SOL_TIPC", SOL_TIPC
);
299 PyModule_AddIntConstant(m
, "TIPC_IMPORTANCE", TIPC_IMPORTANCE
);
300 PyModule_AddIntConstant(m
, "TIPC_SRC_DROPPABLE", TIPC_SRC_DROPPABLE
);
301 PyModule_AddIntConstant(m
, "TIPC_DEST_DROPPABLE",
302 TIPC_DEST_DROPPABLE
);
303 PyModule_AddIntConstant(m
, "TIPC_CONN_TIMEOUT", TIPC_CONN_TIMEOUT
);
305 PyModule_AddIntConstant(m
, "TIPC_LOW_IMPORTANCE",
306 TIPC_LOW_IMPORTANCE
);
307 PyModule_AddIntConstant(m
, "TIPC_MEDIUM_IMPORTANCE",
308 TIPC_MEDIUM_IMPORTANCE
);
309 PyModule_AddIntConstant(m
, "TIPC_HIGH_IMPORTANCE",
310 TIPC_HIGH_IMPORTANCE
);
311 PyModule_AddIntConstant(m
, "TIPC_CRITICAL_IMPORTANCE",
312 TIPC_CRITICAL_IMPORTANCE
);
314 /* for subscriptions */
315 PyModule_AddIntConstant(m
, "TIPC_SUB_PORTS", TIPC_SUB_PORTS
);
316 PyModule_AddIntConstant(m
, "TIPC_SUB_SERVICE", TIPC_SUB_SERVICE
);
317 PyModule_AddIntConstant(m
, "TIPC_SUB_CANCEL", TIPC_SUB_CANCEL
);
318 PyModule_AddIntConstant(m
, "TIPC_WAIT_FOREVER", TIPC_WAIT_FOREVER
);
319 PyModule_AddIntConstant(m
, "TIPC_PUBLISHED", TIPC_PUBLISHED
);
320 PyModule_AddIntConstant(m
, "TIPC_WITHDRAWN", TIPC_WITHDRAWN
);
321 PyModule_AddIntConstant(m
, "TIPC_SUBSCR_TIMEOUT", TIPC_SUBSCR_TIMEOUT
);
322 PyModule_AddIntConstant(m
, "TIPC_CFG_SRV", TIPC_CFG_SRV
);
323 PyModule_AddIntConstant(m
, "TIPC_TOP_SRV", TIPC_TOP_SRV
);