aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2018-08-28 18:06:07 +1200
committerDavid Phillips <david@sighup.nz>2018-08-28 18:06:07 +1200
commit1ad1390e5663f44bbfe9d93a449018e6a89123d4 (patch)
tree1b21eecaad7c1b8ccac691da20315b5dd0827058 /lib
parente196fa9f981da1eee2313f6817318397ea74f5d5 (diff)
downloadalarmd-1ad1390e5663f44bbfe9d93a449018e6a89123d4.tar.xz
Add simple 'alarms' Python module for interfacing with alarmd
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile10
-rw-r--r--lib/python/Makefile19
-rw-r--r--lib/python/alarms.c188
3 files changed, 215 insertions, 2 deletions
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 <Python.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <uuid/uuid.h>
+
+#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;
+}