diff options
author | 2019-05-21 19:16:22 +0300 | |
---|---|---|
committer | 2019-05-21 19:16:22 +0300 | |
commit | 36b3e7f310c624b7b4e31829090dd02131c528d5 (patch) | |
tree | 492df5090f64e298cad3f8995ef9d6a611b45c9d /src/device/protocol_device.c | |
parent | cabb90c1240015ee5cd17d91573588527bcc2482 (diff) | |
download | usurpation-36b3e7f310c624b7b4e31829090dd02131c528d5.tar.gz usurpation-36b3e7f310c624b7b4e31829090dd02131c528d5.tar.bz2 usurpation-36b3e7f310c624b7b4e31829090dd02131c528d5.zip |
Protocol: implementation of device-side protocol.
Parts of protocol specific for device are implementepd to reflect the
fact that the device is a client. This effectively means that device
gets a single connection only and severe memory restrictions about
which the daemon might get informed about in the future.
Signed-off-by: Ramūnas Mažeikis <ramunasnezinomas@gmail.com>
Diffstat (limited to 'src/device/protocol_device.c')
-rwxr-xr-x | src/device/protocol_device.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/device/protocol_device.c b/src/device/protocol_device.c new file mode 100755 index 0000000..3b3d8c8 --- /dev/null +++ b/src/device/protocol_device.c @@ -0,0 +1,86 @@ +#include "net.h" +#include "protocol.h" +#include "protocol_private.h" +#include "protocol_device_private.h" +#include "settings.h" +#include <time.h> +#include <stdlib.h> +#include <string.h> + +#define READ_AS(type, from) (*((type*)(from))) + +static struct connection_t connection; + +cd_t protocol_init(void) +{ + connection.is_live = 1; + connection.nd = net_init(setting_port()); + return 0; +} + +static int push_bytes(cd_t cd, char *data, size_t size) +{ + int ret = 0; + + if (cd >= MAX_CONNECTIONS) { + ret = E_IVALID_DESCRIPTOR; + } else if (connection.outp_crs + size >= sizeof(connection.outp_buf)) { + ret = E_PACKET_OVERFLOW; + } else { + memcpy(connection.outp_buf, data, size); + connection.outp_crs += size; + } + return ret; +} + +static int push_tlv_header(cd_t cd, enum tlv_type type, size_t size) +{ + int ret = 0; + + if (cd >= MAX_CONNECTIONS) { + errno = E_IVALID_DESCRIPTOR; + ret = NULL; + } else if (connection.outp_crs >= MAX_PACKET_SIZE_IN) { + errno = E_TLV_OVERFLOW; + ret = NULL; + } else { + READ_AS(enum tlv_type, connection.outp_buf + connection.outp_crs) + = type; + connection.outp_crs += sizeof(enum tlv_type); + READ_AS(size_t, connection.outp_buf + connection.outp_crs) = size; + connection.outp_crs += sizeof(size_t); + } + return ret; +} + +struct tlv * get_tlv(cd_t cd) +{ + struct tlv *ret = &connection.next_tlv; + size_t offset = connection.inp_crs; + char *data = connection.inp_buf; + + if (cd >= MAX_CONNECTIONS) { + errno = E_IVALID_DESCRIPTOR; + ret = NULL; + } else if (offset >= MAX_PACKET_SIZE_IN) { + errno = E_TLV_OVERFLOW; + ret = NULL; + } else { + ret->type = READ_AS(enum tlv_type, data + offset); + offset += sizeof(enum tlv_type); + ret->length = READ_AS(size_t, data + offset); + offset += sizeof(size_t); + ret->data = data + offset; + connection.inp_crs = offset; + } + return ret; +} + + +int get_last_data(cd_t cd) +{ + if (cd >= MAX_CONNECTIONS) { + return E_IVALID_DESCRIPTOR; + } + net_getlastdata(connection.nd, connection.inp_buf); +} |