summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/protocol.h80
-rw-r--r--include/utils.h11
-rw-r--r--project.vim3
-rw-r--r--src/common/protocol.c169
-rw-r--r--src/common/protocol_private.h66
-rw-r--r--src/common/utils.c22
6 files changed, 351 insertions, 0 deletions
diff --git a/include/protocol.h b/include/protocol.h
new file mode 100644
index 0000000..c1b786c
--- /dev/null
+++ b/include/protocol.h
@@ -0,0 +1,80 @@
+/*
+ * Usurpataion --- client-server protocol interface.
+ *
+ * Copyright (C) 2019 Ramūnas Mažeikis
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef PROTOCOL_H_INCLUDED
+#define PROTOCOL_H_INCLUDED
+
+#include <errno.h>
+
+#define SUCCESS (0)
+#define TLV_OVERFLOW (1 << 0)
+
+enum packet_type {
+ REGURAL,
+ HEARTBEAT,
+ DISCOVERY
+};
+
+enum tlv_type {
+ TEXT, /* NULL-terminated string. */
+ FPI1, /* Fixed point. 1 decimal digit of precision. */
+ TIMESTAMP,
+ REQUEST,
+ REPLY,
+ UUID
+};
+
+struct packet_data {
+ enum packet_type type;
+ size_t packet_size;
+ char *data; /* Bytes representing tlv's */
+};
+
+struct tlv {
+ enum tlv_type type;
+ size_t length;
+ void *data;
+};
+
+/*
+ * Reads last packets received, parses and stores them to be later retreived
+ * via get_tlv.
+ * */
+void get_last_data(void);
+
+/* Returns tlv's parsed by get_last_data. Returned tlv is only valid until
+ * next call to get_tlv.
+ * */
+struct tlv * get_tlv(void);
+
+/* Any modifications made to the pending outgoing packet are nullified.
+ * */
+void clear_data(void);
+
+/* Appends data to the next packet to be sent. Type of data is determined by
+ * enum tlv_type.
+ * */
+void push_data(char *data, enum tlv_type);
+
+/* Sends packet towards the other end.
+ * */
+void flush_data(void);
+
+#endif /* PROTOCOL_H_INCLUDED */
diff --git a/include/utils.h b/include/utils.h
new file mode 100644
index 0000000..ca2d2ee
--- /dev/null
+++ b/include/utils.h
@@ -0,0 +1,11 @@
+#ifdef PROJECT_UTILS_H
+#define PROJECT_UTILS_H
+
+typedef int fpi1_t;
+
+fpi1_t add(fpi1_t a, fpi1_t b);
+fpi1_t sub(fpi1_t a, fpi1_t b);
+fpi1_t mul(fpi1_t a, fpi1_t b);
+fpi1_t div(fpi1_t a, fpi1_t b);
+
+#endif /* PROJECT_UTILS_H */
diff --git a/project.vim b/project.vim
new file mode 100644
index 0000000..024222d
--- /dev/null
+++ b/project.vim
@@ -0,0 +1,3 @@
+syn keyword ProjectTypes fpi1_t
+
+hi ProjectTypes ctermfg=green
diff --git a/src/common/protocol.c b/src/common/protocol.c
new file mode 100644
index 0000000..8243c8a
--- /dev/null
+++ b/src/common/protocol.c
@@ -0,0 +1,169 @@
+/*
+ * Usurpataion --- clinet-server protocol implementation.
+ *
+ * Copyright (C) 2019 Ramūnas Mažeikis
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "protocol.h"
+#include "protocol_private.h"
+#include "net.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define READ_INT(x) (*((int*)(x)))
+#define READ_TLV_TYPE(x) (*((int*))(x))
+#define READ_SIZE_T(x) (*((size_t)(x)))
+#define READ_AS(from, type) (*(type*)(from))
+
+#define GET_MSG_CHAR(i) (msg_buf[(i) % MSG_BUF_SIZE])
+#define SET_MSG_CHAR(i, ch) msg_buf[(i) % MSG_BUF_SIZE] = (ch)
+
+/* Increment message cursor */
+#define IMC(x) ((msg_cursor + (x)) % MSG_BUF_SIZE)
+
+/* Begins at 2 because this way we'll have two null's at the beggining
+ * indicating that going back is not possible.
+ * */
+static const int msg_cursor = 2;
+/* Two consecutive null's indicate that going back is not possible.
+ * */
+static char msg_buf[MSG_BUF_SIZE] = {0};
+
+static int tlv_cursor = 0;
+static struct tlv tlv_buf[TLV_BUF_SIZE] = {0};
+
+static size_t packet_cursor = 0;
+/* Outgoing packet.
+ * */
+static char packet_buf[PACKET_MAX_SIZE] = {0};
+
+static void push_bytes(const void * const data, const size_t size)
+{
+ memcpy(packet_buf + packet_cursor, data, size);
+ packet_cursor += size;
+}
+
+void clear_data(void)
+{
+ packet_cursor = 0;
+}
+
+void push_data(char *data, enum tlv_type type)
+{
+ switch (type) {
+ case TEXT:
+ case FPI1:
+ case TIMESTAMP:
+ case REQUEST:
+ case REPLY:
+ case UUID:
+ }
+}
+
+void push_string(char *str)
+{
+ size_t size = strlen(str);
+
+ *((enum tlv_type*)packet_buf) = TEXT;
+ packet_cursor += sizeof(enum tlv_type);
+ *((size_t*)packet_buf) = strlen(str);
+ packet_cursor += sizeof(size_t);
+ push_bytes();
+}
+
+void push_fpi1(fpi1_t num);
+
+void push_timestamp(char *data);
+
+void push_request(char *data);
+
+void push_reply(char *data);
+
+void push_uuid(char *data);
+
+void get_last_data()
+{
+ msg_cursor = 2;
+ msg_buf[0] = '\0';
+ msg_buf[1] = '\0';
+ tlv_cursor = 0;
+ /* Get packet here. Somehow. TODO */
+ get_tlvs(packet_buf, tlv_buf, TLV_BUF_SIZE);
+}
+
+struct tlv * get_tlv(void)
+{
+ if (tlv_buf[tlv_cursor] != NULL) {
+ struct tlv *ret = tlv_buf[tlv_cursor++];
+ } else {
+ ret = NULL;
+ }
+ return ret;
+}
+
+int tlv_count(const struct packet_data * const packet)
+{
+ size_t cursor = 0;
+ size_t length = 0;
+ size_t ret = 0;
+
+ while (cursor < packet->packet_size) {
+ cursor += sizeof(enum tlv_type);
+ length = READ_SIZE_T(packet->data + cursor);
+ cursor += sizeof(size_t) + length;
+ ret++;
+ }
+ if (cursor != packet->packet_size) {
+ errno = TLV_OVERFLOW;
+ }
+ return ret;
+}
+
+size_t get_tlvs( const struct packet_data * const data,
+ const struct tlv *buf,
+ size_t buf_size)
+{
+ size_t tlvs_read = 0;
+ size_t cursor = 0;
+
+ while (cursor < data->packet_size && tlvs_read <= buf_size) {
+ cursor += parse_tlv(data->data, cursor, buf + tlvs_read);
+ tlvs_read++;
+ }
+
+ if (cursor > data->packet_length) {
+ errno = TLV_OVERFLOW;
+ }
+
+ return tlvs_read;
+}
+
+/* Returns how many bytes were consumed by parser.
+ * */
+size_t parse_tlv(char *data, size_t cursor, struct tlv *t)
+{
+ char *begin = data + cursor;
+
+ t->type = READ_TLV_TYPE(data + cursor);
+ cursor += sizeof(enum tlv_type);
+ t->length += READ_SIZE_T(data + cursor);
+ data += sizeof(size_t);
+ t->data = data + cursor;
+
+ return data + cursor - begin + 1UL;
+}
+
diff --git a/src/common/protocol_private.h b/src/common/protocol_private.h
new file mode 100644
index 0000000..3a4b1b2
--- /dev/null
+++ b/src/common/protocol_private.h
@@ -0,0 +1,66 @@
+/*
+ * Usurpataion --- server-client protocol private interface.
+ *
+ * Copyright (C) 2019 Ramūnas Mažeikis
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef PROTOCOL_H_PRIVATE
+#define PROTOCOL_H_PRIVATE
+
+#define TLV_ARR_SIZE (16)
+
+/* Pease don't rape the buffer with long messages, daemon-kun. */
+#define MSG_BUF_SIZE (257)
+
+/* UDP can carry bigger packets but memory is hard to come by and more won't be
+ * needed anyway.
+ * */
+#define PACKET_MAX_SIZE (512)
+
+/* Returns the amount of tlv's int a packet.
+ *
+ * If a tlv reports length that goes beyond the end of a packet, errno is set
+ * to TLV_OVERFLOW. To check this, set errno to 0 first.
+ * */
+size_t tlv_count(const struct packet_data * const packet);
+
+/* Parses a data packet, fills buffer of tlv's of size `buf_size` and returns
+ * the number of tlv's actually parsed.
+ *
+ * To check for errors, set errno to 0 and check after calling.
+ * */
+size_t get_tlvs( const struct packet_data * const data,
+ const struct tlv *buf,
+ size_t buf_size);
+
+/* Takes a null-terminated string and appends it to the next outgoing packet.
+ * */
+void push_string(char *str);
+
+void push_fpi1(fpi1_t num);
+
+void push_timestamp(char *data);
+
+void push_request(char *data);
+
+void push_reply(char *data);
+
+void push_uuid(char *data);
+
+
+
+#endif /* PROTOCOL_H_PRIVATE */
diff --git a/src/common/utils.c b/src/common/utils.c
new file mode 100644
index 0000000..7bcf767
--- /dev/null
+++ b/src/common/utils.c
@@ -0,0 +1,22 @@
+#include "utils.h"
+
+fpi1_t add(fpi1_t a, fpi1_t b)
+{
+ return a + b;
+}
+
+fpi1_t sub(fpi1_t a, fpi1_t b)
+{
+ return a - b;
+}
+
+fpi1_t mul(fpi1_t a, fpi1_t b)
+{
+ return (fpi1_t)(((long)a * (long)b) / 100);
+}
+
+fpi1_t div(fpi1_t a, fpi1_t b)
+{
+ return (fpi1_t)(((long)a * 10) / ((long)b * 10));
+}
+