summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Ramūnas Mažeikis <ramunasnezinomas@gmail.com> 2019-05-18 16:32:20 +0300
committerGravatar Ramūnas Mažeikis <ramunasnezinomas@gmail.com> 2019-05-18 16:32:20 +0300
commit9c8ece1538d31dba9a416c9f29f88e18510f4c75 (patch)
treee03b298870294072975bb1208166c375fd1513bb /src
parent76c83e9d13295089919ce09af01a7e7149777b19 (diff)
downloadusurpation-9c8ece1538d31dba9a416c9f29f88e18510f4c75.tar.gz
usurpation-9c8ece1538d31dba9a416c9f29f88e18510f4c75.tar.bz2
usurpation-9c8ece1538d31dba9a416c9f29f88e18510f4c75.zip
Whole-project: partial implementation of protocol.
This commit is part of ticket #31. Branch is not in a compiling state. Work is being done on utility functions and protocol implementation. To be completed later. Signed-off-by: Ramūnas Mažeikis <ramunasnezinomas@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/common/protocol.c169
-rw-r--r--src/common/protocol_private.h66
-rw-r--r--src/common/utils.c22
3 files changed, 257 insertions, 0 deletions
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));
+}
+