summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/protocol.h106
-rw-r--r--src/common/protocol.c91
2 files changed, 80 insertions, 117 deletions
diff --git a/include/protocol.h b/include/protocol.h
index e15ef6a..387424f 100644
--- a/include/protocol.h
+++ b/include/protocol.h
@@ -21,6 +21,41 @@
#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:
+
+-------------------------------------------------------------------------------
+ 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(&text); /* Free text tlv */
+ 23 | tlv_destroy(&tlv_packet); /* Free tlv_packet */
+ 24 | free(packet); /* Free packet itself */
+ 25 | return; /* GTFO and save stack space */
+ 26 | }
+-------------------------------------------------------------------------------
+
+#endif
+
+
#include <errno.h>
#define E_TLV_OVERFLOW (1 << 0)
@@ -30,19 +65,6 @@
#define TLV_SZ_MAX_RAW (MTU - 64)
/**
- * 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.
@@ -77,20 +99,24 @@ enum tlv_type {
/**
* UUID that represents a particular device.
*/
- UUID
-};
+ 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 */
+/* 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
};
/**
@@ -122,24 +148,6 @@ struct tlv_parser {
int tlv_get(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 tlv_push_data(struct tlv_packet *packet, enum tlv_type type, char *data);
-
-/**
- * Resets offset to 0 and set entire buffer to 0.
- */
-void tlv_clear_data(struct tlv_packet *packet);
-
-/**
* Initialises tlv to sane values.
*/
void tlv_init(struct tlv *t, enum tlv_type type);
@@ -153,7 +161,7 @@ void tlv_destroy(struct tlv *t);
/**
* Tells amount of bytes needed to push tlv to a buffer
*/
-size_t tlv_raw_size(struct tlv *t);
+size_t tlv_raw_size(const struct tlv *t);
/**
* Pushes tlv to buffer as contiguous data. Check tlv size with tlv_raw_size
@@ -166,6 +174,12 @@ int tlv_get_raw(struct tlv *t, char *buf);
* final size to be greater than TLV_SZ_MAX_RAW. In case of such error the data is left
* untouched.
*/
-int tlv_push(struct tlv *t, const char *data, size_t size);
+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);
#endif /* USURPATION_PROTOCOL_H_INCLUDED */
diff --git a/src/common/protocol.c b/src/common/protocol.c
index ed636d2..90dfc92 100644
--- a/src/common/protocol.c
+++ b/src/common/protocol.c
@@ -32,75 +32,6 @@
#include "net.h"
#include "utils.h"
-#if 0
-int tlv_push(struct tlv_packet *packet, enum tlv_type type, char *data)
-{
- int ret = 0;
- size_t size;
-
- switch (type) {
- case TEXT:
- size = strlen(data) + 1;
- break;
- case FPI1:
- size = sizeof(fpi1_t);
- break;
- case TIMESTAMP:
- size = sizeof(time_t);
- break;
- case REQUEST:
- size = sizeof(msg_idx_t);
- break;
- case REPLY:
- size = sizeof(msg_idx_t) + strlen(data + sizeof(msg_idx_t));
- break;
- case UUID:
- size = sizeof(uuid_t);
- break;
- default:
- ret = E_UNKNOWN_TYPE;
- }
- ret |= push_tlv_header(packet, type, size);
- ret |= push_bytes(packet, data, size);
- return ret;
-}
-
-#endif
-
-void tlv_clear_data(struct tlv_packet *packet)
-{
- packet->offset = 0;
- packet->type = 0;
- memset(packet->data, 0, packet->size);
-}
-
-static int push_bytes(struct tlv_packet *packet, char *data, size_t size)
-{
- int ret = 0;
-
- if (packet->offset + size >= packet->size) {
- ret = E_TLV_OVERFLOW;
- } else {
- memcpy(packet->data + packet->offset, data, size);
- packet->offset += size;
- }
-}
-
-static int push_tlv_header(struct tlv_packet *packet, enum tlv_type type, size_t size)
-{
- int ret = 0;
-
- if (packet->offset + sizeof(type) + sizeof(size) >= packet->size) {
- ret = E_TLV_OVERFLOW;
- } else {
- memcpy(packet->data + packet->size, type, sizeof(type));
- packet->offset += sizeof(type);
- memcpy(packet->data + packet->offset, size, sizeof(size));
- packet->offset += sizeof(size);
- }
- return ret;
-}
-
int tlv_get(struct tlv_parser *parser, struct tlv *ret)
{
int retval = 0;
@@ -141,12 +72,12 @@ void tlv_destroy(struct tlv *t)
t->length = 0;
}
-size_t tlv_raw_size(struct tlv *t)
+size_t tlv_raw_size(const struct tlv *t)
{
return sizeof(*t) + t->length;
}
-int tlv_push(struct tlv *t, const char *data, size_t size)
+int tlv_push_data(struct tlv *t, const char *data, size_t size)
{
int ret = 0;
size_t final_size = tlv_raw_size(t) + size;
@@ -165,4 +96,22 @@ void tlv_init(struct tlv *t, enum tlv_type type)
t->type = type;
t->length = 0;
t->data = NULL;
+}
+
+int tlv_push_tlv(struct tlv *t, const struct tlv *other)
+{
+ int ret = 0;
+ size_t other_size;
+ size_t final_size;
+
+ other_size = tlv_raw_size(other);
+ final_size = tlv_raw_size(t) + other_size;
+ if (final_size > TLV_SZ_MAX_RAW) {
+ ret = E_TLV_OVERFLOW;
+ } else {
+ tlv_get_raw(other, t->data + t->length);
+ t->length = final_size;
+ }
+
+ return ret;
} \ No newline at end of file