From 1ad1390e5663f44bbfe9d93a449018e6a89123d4 Mon Sep 17 00:00:00 2001 From: David Phillips Date: Tue, 28 Aug 2018 18:06:07 +1200 Subject: Add simple 'alarms' Python module for interfacing with alarmd --- lib/Makefile | 10 ++- lib/python/Makefile | 19 ++++++ lib/python/alarms.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 lib/python/Makefile create mode 100644 lib/python/alarms.c (limited to 'lib') diff --git a/lib/Makefile b/lib/Makefile index 2c9ccc9..43a9d87 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,7 +1,11 @@ +CFLAGS += -I../inc/ -CFLAGS += "-I../inc/" +all: libalarm.so python -libalarm.so: libalarm.o +python: + make -C python + +%.so: %.o $(CC) -shared -o $@ $< $(LDFLAGS) %.o: %.c @@ -9,3 +13,5 @@ libalarm.so: libalarm.o clean: rm libalarm.{s,}o + +.PHONY: python diff --git a/lib/python/Makefile b/lib/python/Makefile new file mode 100644 index 0000000..1e2c24a --- /dev/null +++ b/lib/python/Makefile @@ -0,0 +1,19 @@ +PYTHONINC = /usr/include/python3.7m/ + +LDFLAGS += "-luuid" +CFLAGS += -fPIC \ + -I$(PYTHONINC) \ + -I../../inc/ + +all: alarms.so + +%.so: %.o + $(CC) -shared -o $@ $< $(LDFLAGS) + +%.o: %.c + $(CC) -c -o $@ $< $(LDFLAGS) $(CFLAGS) + +.PHONY: clean +clean: + - rm -f alarms.{s,}o + diff --git a/lib/python/alarms.c b/lib/python/alarms.c new file mode 100644 index 0000000..57670e8 --- /dev/null +++ b/lib/python/alarms.c @@ -0,0 +1,188 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alarmd_proto.h" +#include "pyalarmd_proto.h" + +static PyMethodDef ExportedMethods[] = { + {"connect" , pyalarmd_connect , METH_VARARGS, "FIXME"}, + {"disconnect" , pyalarmd_disconnect, METH_VARARGS, "FIXME"}, + {"register_alarm" , pyalarmd_register , METH_VARARGS, "FIXME"}, + {"deregister_alarm", pyalarmd_deregister, METH_VARARGS, "FIXME"}, + {"raise_alarm" , pyalarmd_raise , METH_VARARGS, "FIXME"}, + {"clear_alarm" , pyalarmd_clear , METH_VARARGS, "FIXME"}, + {NULL , NULL , 0 , NULL } +}; + + +static struct PyModuleDef alarm_python = { + PyModuleDef_HEAD_INIT, + "alarms", /* module name */ + NULL, /* FIXME reference doc */ + -1, /* storage size -1 since state kept in global variables. */ + ExportedMethods +}; + +static PyObject *alarmd_error; + +/* Helper function */ +int send_packet_uuid(int sock, uint32_t packet_type, uuid_t uuid) +{ + return (send(sock, &packet_type, sizeof(packet_type), 0) != sizeof(packet_type) + || send(sock, uuid, sizeof(uuid_t), 0) != 16); +} + +PyObject* PyInit_alarms(void) { + PyObject *module = NULL; + + module = PyModule_Create(&alarm_python); + alarmd_error = PyErr_NewException("alarms.error", NULL, NULL); + PyModule_AddObject(module, "error", alarmd_error); + + return module; +} + +PyObject* pyalarmd_connect(PyObject *self, PyObject *args) { + const char *path = NULL; + int sock = 0; + struct sockaddr_un server; + + if (!PyArg_ParseTuple(args, "s", &path)) { + return NULL; + } + + if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + PyErr_SetFromErrno(alarmd_error); + return NULL; + } + + server.sun_family = AF_UNIX; + strcpy(server.sun_path, path); + if (connect(sock, (struct sockaddr *)&server, strlen(server.sun_path) + sizeof(server.sun_family)) < 0) { + close(sock); + PyErr_SetFromErrno(alarmd_error); + return NULL; + } + return PyLong_FromLong(sock); +} + +PyObject* pyalarmd_disconnect(PyObject *self, PyObject *args) { + int sock = 0; + + if (!PyArg_ParseTuple(args, "i", &sock)) { + return NULL; + } + + close(sock); + + Py_RETURN_NONE; +} + +PyObject* pyalarmd_register(PyObject *self, PyObject *args) +{ + int sock = 0; + char *desc; + char uuid_str[37]; + uuid_t uuid; + uint8_t length = 0; + uint32_t packet_type = 0; + + if (!PyArg_ParseTuple(args, "is", &sock, &desc)) { + return NULL; + } + + packet_type = ALARMD_PACKET_TYPE_REGISTER; + if (send(sock, &packet_type, sizeof(packet_type), 0) != sizeof(packet_type)) { + PyErr_SetFromErrno(alarmd_error); + return NULL; + } + + length = strlen(desc); + if (send(sock, &length, sizeof(length), 0) != sizeof(length)) { + PyErr_SetFromErrno(alarmd_error); + return NULL; + } + + if (send(sock, desc, strlen(desc), 0) != strlen(desc)) { + PyErr_SetFromErrno(alarmd_error); + return NULL; + } + + if (recv(sock, &uuid, sizeof(uuid), 0) != sizeof(uuid)) { + PyErr_SetFromErrno(alarmd_error); + return NULL; + } + + uuid_unparse(uuid, uuid_str); + + return Py_BuildValue("s", uuid_str); +} + +PyObject* pyalarmd_deregister(PyObject *self, PyObject *args) +{ + int sock = 0; + char *uuid_str = NULL; + uuid_t uuid; + + if (!PyArg_ParseTuple(args, "is", &sock, &uuid_str)) { + return NULL; + } + + if (uuid_parse(uuid_str, uuid) < 0) { + PyErr_SetString(alarmd_error, "Invalid UUID"); + return NULL; + } + + send_packet_uuid(sock, ALARMD_PACKET_TYPE_DEREGISTER, uuid); + + Py_RETURN_NONE; +} + +PyObject* pyalarmd_raise(PyObject *self, PyObject *args) +{ + int sock = 0; + char *uuid_str = NULL; + uuid_t uuid; + + if (!PyArg_ParseTuple(args, "is", &sock, &uuid_str)) { + return NULL; + } + + if (uuid_parse(uuid_str, uuid) < 0) { + PyErr_SetString(alarmd_error, "Invalid UUID"); + return NULL; + } + + send_packet_uuid(sock, ALARMD_PACKET_TYPE_RAISE, uuid); + + Py_RETURN_NONE; +} + +PyObject* pyalarmd_clear(PyObject *self, PyObject *args) +{ + int sock = 0; + char *uuid_str = NULL; + uuid_t uuid; + + if (!PyArg_ParseTuple(args, "is", &sock, &uuid_str)) { + return NULL; + } + + if (uuid_parse(uuid_str, uuid) < 0) { + PyErr_SetString(alarmd_error, "Invalid UUID"); + return NULL; + } + + send_packet_uuid(sock, ALARMD_PACKET_TYPE_CLEAR, uuid); + + Py_RETURN_NONE; +} -- cgit v1.1