summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/meson.build2
-rw-r--r--include/protocol.h137
-rw-r--r--include/tlv.h197
3 files changed, 198 insertions, 138 deletions
diff --git a/include/meson.build b/include/meson.build
index 33e9426..77a8d53 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -1,7 +1,7 @@
header_filenames = [
'utils.h',
'net.h',
- 'protocol.h'
+ 'tlv.h'
]
fw_headers = files(header_filenames)
diff --git a/include/protocol.h b/include/protocol.h
deleted file mode 100644
index 34ad4a3..0000000
--- a/include/protocol.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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
- */
-
-#ifndef USURPATION_PROTOCOL_H_INCLUDED
-#define USURPATION_PROTOCOL_H_INCLUDED
-
-#include <errno.h>
-
-#define E_TLV_OVERFLOW (1 << 0)
-#define E_UNKNOWN_TYPE (1 << 1)
-#define E_IVALID_DESCRIPTOR (1 << 2)
-#define END_OF_PACKET (1 << 3)
-
-/**
- * Regular packets contain tlv's defined by tlv_type.
- *
- * Hearbeat packet tell daemon that device is still alive and listening.
- *
- * Discovery packets are used for what they say.
- */
-enum packet_type {
- REGURAL,
- HEARTBEAT,
- DISCOVERY
-};
-
-/**
- * Message sequence number since beggining of sesssion.
- *
- * Mainly used for identifying lost messages.
- */
-typedef unsigned int msg_idx_t;
-
-enum tlv_type {
- /**
- * NULL-terminated string. To be put in a queue to display on the
- * screen.
- */
- TEXT,
-
- /** Fixed point. 1 decimal digit of precision. */
- FPI1,
-
- /** Literally time_t */
- TIMESTAMP,
-
- /** Represents a request for lost message. Data is unsigned integer
- * that uniquely identifies the message.
- */
- REQUEST,
-
- /**
- * Response to request. Begins with unsigned integer that represents
- * which message is being repeated and the actual null-terminated
- * message after that.
- */
- REPLY,
-
- /**
- * UUID that represents a particular device.
- */
- UUID
-};
-
-/**
- * Packet data itself is a special type of tlv. A packet is either regular,
- * hearbeat or discovery.
- *
- * May be used to send data.
- */
-struct tlv_packet {
- enum packet_type type;
- size_t size;
- size_t offset;
- char *data; /* Bytes representing tlv's */
-};
-
-/**
- * Literally type-length-value
- * */
-struct tlv {
- enum tlv_type type;
- size_t length;
- void *data;
-};
-
-struct tlv_parser {
- char *data;
- size_t offset;
- size_t size;
-};
-
-int get_tlv(struct tlv_parser *parser, struct tlv *ret);
-
-/**
- * Appends data to the next packet to be sent. Type of data is determined by
- * enum tlv_type.
- *
- * In case of overflow return E_TLV_OVERFLOW.
- *
- * On next call after retreiving last packet returns END_OF_PACKET.
- *
- * Overflow can be detected after forming tlv header. This means that the
- * packet may have changes.
- * */
-int push_data(struct tlv_packet *packet, enum tlv_type type, char *data);
-
-
-/**
- * Resets offset to 0 and set entire buffer to 0.
- */
-void clear_data(struct tlv_packet *packet);
-
-
-/**
- * Tells what size of buffer is needed for next tlv.
- */
-size_t tlv_data_size(struct tlv_parser *parser);
-
-#endif /* USURPATION_PROTOCOL_H_INCLUDED */
diff --git a/include/tlv.h b/include/tlv.h
new file mode 100644
index 0000000..b52763a
--- /dev/null
+++ b/include/tlv.h
@@ -0,0 +1,197 @@
+/*
+ * 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
+ */
+
+#ifndef USURPATION_PROTOCOL_H_INCLUDED
+#define USURPATION_PROTOCOL_H_INCLUDED
+
+#if 0
+
+How do we use this API(?), I hear you say. Well, here is a self-contained
+example complete with tedious comments, allocation of buffers and cleanup:
+
+-------------------------------------------------------------------------------
+ 1 | void functy_the_function(void)
+ 2 | {
+ 3 | struct tlv tlv_packet; /* A packet made of tlv's */
+ 4 | struct tlv text; /* Actually useful data */
+ 5 | char *packet; /* Raw bytes to be pushed via UDP */
+ 6 | size_t packet_size; /* Raw packet size */
+ 7 | char message[] = "Get jacked!"; /* Duh! */
+ 9 |
+ 10 | tlv_init(&tlv_packet, REGURAL); /* Initialise tlv_packet to regular */
+ 11 | tlv_init(&text, TEXT); /* Initialise text packet */
+ 12 | tlv_push_data(&text, message, sizeof(message)); /* Push text to appropriate tlv */
+ 13 | tlv_push_tlv(&tlv_packet, &text); /* Push the tlv into tlv packet */
+ 14 |
+ 15 | packet_size = tlv_raw_size(&tlv_packet); /* Get raw size required to push entire tlv_packet as bytes */
+ 16 | packet = (char *)malloc(packet_size); /* Allocate buffer for outgoing packet */
+ 17 | tlv_get_raw(&tlv_packet, packet); /* Flash tlv_packet to buffer */
+ 19 | udp_push(packet, packet_size); /* Push packet via UDP */
+ 20 | udp_flush(); /* Flush to the other side*/
+ 21 |
+ 22 | tlv_destroy(&tlv_packet); /* Free tlv_packet */
+ 23 | free(packet); /* Free packet itself */
+ 24 | return; /* GTFO and save stack space */
+ 25 | }
+-------------------------------------------------------------------------------
+
+A few things to note:
+ * Calling tlv_destroy() on a tlv of type REGURAL or HEARTBEAT destorys
+ all sub-tlv's too.
+ * Tlv's get copies of data, which means the original buffer can be
+ freed immediately.
+
+#endif
+
+
+#include <errno.h>
+
+#define E_TLV_OVERFLOW (1 << 0)
+#define E_UNKNOWN_TYPE (1 << 1)
+#define END_OF_PACKET (1 << 2)
+
+#define TLV_SZ_MAX_RAW (MTU - 64)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+/**
+ * Message sequence number since beggining of sesssion.
+ *
+ * Mainly used for identifying lost messages.
+ */
+typedef unsigned int msg_idx_t;
+
+enum tlv_type {
+ /**
+ * NULL-terminated string. To be put in a queue to display on the
+ * screen.
+ */
+ TEXT,
+
+ /** Fixed point. 1 decimal digit of precision. */
+ FPI1,
+
+ /** Literally time_t */
+ TIMESTAMP,
+
+ /** Represents a request for lost message. Data is unsigned integer
+ * that uniquely identifies the message.
+ */
+ REQUEST,
+
+ /**
+ * Response to request. Begins with unsigned integer that represents
+ * which message is being repeated and the actual null-terminated
+ * message after that.
+ */
+ REPLY,
+
+ /**
+ * UUID that represents a particular device.
+ */
+ UUID,
+
+/* Data of the following types are other tlv's! */
+
+ /**
+ * Just a TLV container.
+ */
+ REGURAL,
+
+ /**
+ * Says "I'm not dead yet.".
+ */
+ HEARTBEAT,
+
+ /**
+ * Says "Bring out yer dead!".
+ */
+ DISCOVERY
+};
+
+/**
+ * Literally type-length-value
+ * */
+struct tlv {
+ enum tlv_type type;
+ size_t length;
+ void *data;
+};
+
+/**
+ * Keeps state of the parsing process.
+ *
+ * Related functions return one tlv at a time.
+ */
+struct tlv_parser {
+ char *data;
+ size_t offset;
+ size_t size;
+};
+
+/**
+ * Fills tlv structure to represent the next tlv in the packet.
+ *
+ * Returns END_OF_PACKET if all tlv's were read of E_TLV_OVERFLOW, if the last
+ * tlv, according to its declared size should not fit in a packet.
+ */
+int tlv_get(struct tlv_parser *parser, struct tlv *ret);
+
+/**
+ * Initialises tlv to sane values.
+ */
+void tlv_init(struct tlv *t, enum tlv_type type);
+
+/**
+ * Frees data held in the tlv structure. The structure itself shall be freed as
+ * needed by calling code.
+ */
+void tlv_destroy(struct tlv *t);
+
+/**
+ * Tells amount of bytes needed to push tlv to a buffer
+ */
+size_t tlv_raw_size(const struct tlv *t);
+
+/**
+ * Pushes tlv to buffer as contiguous data. Check tlv size with tlv_raw_size
+ * beforehand. If you don't do that and overflow --- tough tiddy.
+ */
+int tlv_get_raw(struct tlv *t, char *buf);
+
+/**
+ * Pushes data to tlv. Returns E_TLV_OVERFLOW if pushing data would cause the
+ * final size to be greater than TLV_SZ_MAX_RAW. In case of such error the data is left
+ * untouched.
+ */
+int tlv_push_data(struct tlv *t, const char *data, size_t size);
+
+/**
+ * Pushes a sub-tlv into the packet. 't' can only be REGURAL, HEARTBEAT or
+ * DISCOVERY.
+ */
+int tlv_push_tlv(struct tlv *t, const struct tlv *other);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* USURPATION_PROTOCOL_H_INCLUDED */