/* * 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 #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) /** * 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; }; /** * 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); /** * 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); /** * 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(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(struct tlv *t, const char *data, size_t size); #endif /* USURPATION_PROTOCOL_H_INCLUDED */