2022-12-21 00:38:10 +02:00
|
|
|
#ifndef _JITTERBUG__WIRE_H
|
|
|
|
#define _JITTERBUG__WIRE_H
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdbool.h>
|
2023-01-21 05:43:00 +02:00
|
|
|
#include <sys/uio.h>
|
2023-01-19 05:16:45 +02:00
|
|
|
#include "util.h"
|
2023-01-19 22:47:47 +02:00
|
|
|
#include "try.h"
|
2022-12-21 00:38:10 +02:00
|
|
|
|
|
|
|
|
|
|
|
#define DBUS_PROTOCOL_VERSION 1
|
|
|
|
|
2022-12-21 21:38:48 +02:00
|
|
|
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
|
|
|
#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2
|
|
|
|
#define DBUS_REQUEST_NAME_REPLY_EXISTS 3
|
|
|
|
#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
|
|
|
|
|
2022-12-29 20:10:36 +02:00
|
|
|
#define DBUS_FLAG_NO_REPLY_EXPECTED 0x1
|
|
|
|
#define DBUS_FLAG_NO_AUTO_START 0x1
|
|
|
|
#define DBUS_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION 0x1
|
|
|
|
|
2023-01-23 04:57:56 +02:00
|
|
|
#define UNIQUE_NAME_LENGTH 16
|
2023-01-22 18:18:57 +02:00
|
|
|
|
2022-12-21 00:38:10 +02:00
|
|
|
enum {
|
2022-12-29 20:10:36 +02:00
|
|
|
DBUS_HEADER_FIELD_INVALID = 0,
|
2022-12-21 00:38:10 +02:00
|
|
|
DBUS_HEADER_FIELD_PATH,
|
|
|
|
DBUS_HEADER_FIELD_INTERFACE,
|
|
|
|
DBUS_HEADER_FIELD_MEMBER,
|
|
|
|
DBUS_HEADER_FIELD_ERROR_NAME,
|
|
|
|
DBUS_HEADER_FIELD_REPLY_SERIAL,
|
|
|
|
DBUS_HEADER_FIELD_DESTINATION,
|
|
|
|
DBUS_HEADER_FIELD_SENDER,
|
|
|
|
DBUS_HEADER_FIELD_SIGNATURE,
|
|
|
|
DBUS_HEADER_FIELD_UNIX_FDS,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
2022-12-29 20:10:36 +02:00
|
|
|
DBUS_MESSAGE_INVALID = 0,
|
2022-12-21 00:38:10 +02:00
|
|
|
DBUS_MESSAGE_METHOD_CALL,
|
|
|
|
DBUS_MESSAGE_METHOD_RETURN,
|
|
|
|
DBUS_MESSAGE_ERROR,
|
|
|
|
DBUS_MESSAGE_SIGNAL,
|
|
|
|
};
|
|
|
|
|
2023-01-19 02:46:49 +02:00
|
|
|
typedef struct {
|
2022-12-21 00:38:10 +02:00
|
|
|
uint32_t byte_cursor;
|
|
|
|
uint8_t *data;
|
|
|
|
size_t data_len;
|
2023-01-19 02:46:49 +02:00
|
|
|
} WireCtx;
|
2022-12-21 00:38:10 +02:00
|
|
|
|
|
|
|
// SPEC: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
|
2023-01-19 02:46:49 +02:00
|
|
|
typedef struct {
|
2022-12-23 23:58:18 +02:00
|
|
|
bool present;
|
2022-12-21 00:38:10 +02:00
|
|
|
union {
|
|
|
|
char *str;
|
2022-12-23 23:58:18 +02:00
|
|
|
uint32_t u32;
|
2022-12-21 00:38:10 +02:00
|
|
|
} t;
|
2023-01-19 02:46:49 +02:00
|
|
|
} WireMsgField;
|
2022-12-21 00:38:10 +02:00
|
|
|
#define WIRE_MESSAGE_MAX_HEADER_FIELDS 9
|
2023-01-19 02:46:49 +02:00
|
|
|
typedef struct {
|
2022-12-21 00:38:10 +02:00
|
|
|
uint8_t endianness, type, flags, protocol_version;
|
2023-01-21 05:43:00 +02:00
|
|
|
uint32_t body_length, serial, header_fields_length, header_length;
|
2022-12-21 00:38:10 +02:00
|
|
|
uint8_t header_fields_count;
|
2023-01-19 02:46:49 +02:00
|
|
|
WireMsgField fields[WIRE_MESSAGE_MAX_HEADER_FIELDS]; /* cannot have more than 9 header fields */
|
|
|
|
} WireMsg;
|
|
|
|
typedef struct {
|
2022-12-29 20:10:36 +02:00
|
|
|
uint16_t index;
|
|
|
|
char *str;
|
2023-01-19 02:46:49 +02:00
|
|
|
} WireMsgBodyString;
|
2022-12-21 00:38:10 +02:00
|
|
|
|
2023-01-19 22:47:47 +02:00
|
|
|
bool wire_write_align(WireCtx *c, uint32_t alignment);
|
|
|
|
bool wire_align(WireCtx *c, uint32_t alignment);
|
2023-01-19 05:16:45 +02:00
|
|
|
|
2022-12-21 00:38:10 +02:00
|
|
|
#define _WIRE_DECL_BYTE_TYPE(M_mnemonic, M_type) \
|
2023-01-19 02:46:49 +02:00
|
|
|
M_type *wire_get_##M_mnemonic(WireCtx *c); \
|
|
|
|
M_type *wire_set_##M_mnemonic(WireCtx *c, M_type val); \
|
2022-12-21 00:38:10 +02:00
|
|
|
|
|
|
|
#define _WIRE_DECL_TYPE(M_mnemonic, M_type, M_alignment) \
|
2023-01-19 02:46:49 +02:00
|
|
|
M_type *wire_get_##M_mnemonic(WireCtx *c); \
|
|
|
|
M_type *wire_set_##M_mnemonic(WireCtx *c, M_type val); \
|
2022-12-21 00:38:10 +02:00
|
|
|
|
|
|
|
#define _WIRE_DEF_BYTE_TYPE(M_mnemonic, M_type) \
|
2023-01-19 02:46:49 +02:00
|
|
|
M_type *wire_get_##M_mnemonic(WireCtx *restrict c) { \
|
2023-01-16 16:04:09 +02:00
|
|
|
if (unlikely(c->byte_cursor + 1 >= c->data_len)) return NULL; \
|
2023-01-16 04:10:21 +02:00
|
|
|
M_type *value = (M_type*)&c->data[c->byte_cursor++]; \
|
2022-12-21 00:38:10 +02:00
|
|
|
return value; \
|
|
|
|
} \
|
2023-01-19 02:46:49 +02:00
|
|
|
M_type *wire_set_##M_mnemonic(WireCtx *restrict c, M_type val) { \
|
2023-01-16 16:04:09 +02:00
|
|
|
if (unlikely(c->byte_cursor + 1 >= c->data_len)) return NULL; \
|
2023-01-16 04:10:21 +02:00
|
|
|
M_type *dest = (M_type*)&c->data[c->byte_cursor++]; \
|
2022-12-21 00:38:10 +02:00
|
|
|
*dest = val; \
|
|
|
|
return dest; \
|
|
|
|
} \
|
|
|
|
|
|
|
|
#define _WIRE_DEF_TYPE(M_mnemonic, M_type, M_alignment) \
|
2023-01-19 02:46:49 +02:00
|
|
|
M_type *wire_get_##M_mnemonic(WireCtx *restrict c) { \
|
2023-01-16 16:04:09 +02:00
|
|
|
if (unlikely(!wire_align(c, M_alignment))) return NULL; \
|
2022-12-21 00:38:10 +02:00
|
|
|
uint32_t new_cursor = c->byte_cursor + sizeof(M_type); \
|
2023-01-16 16:04:09 +02:00
|
|
|
if (unlikely(new_cursor >= c->data_len)) return NULL; \
|
2022-12-21 00:38:10 +02:00
|
|
|
M_type *value = (M_type*)&c->data[c->byte_cursor]; \
|
|
|
|
c->byte_cursor = new_cursor; \
|
|
|
|
return value; \
|
|
|
|
} \
|
2023-01-19 02:46:49 +02:00
|
|
|
M_type *wire_set_##M_mnemonic(WireCtx *restrict c, M_type val) { \
|
2023-01-16 16:04:09 +02:00
|
|
|
if (unlikely(!wire_write_align(c, M_alignment))) return NULL; \
|
2022-12-21 00:38:10 +02:00
|
|
|
uint32_t new_cursor = c->byte_cursor + sizeof(M_type); \
|
2023-01-16 16:04:09 +02:00
|
|
|
if (unlikely(new_cursor >= c->data_len)) return NULL; \
|
2022-12-21 00:38:10 +02:00
|
|
|
M_type *dest = (M_type*)&c->data[c->byte_cursor]; \
|
|
|
|
*dest = val; \
|
|
|
|
c->byte_cursor = new_cursor; \
|
|
|
|
return dest; \
|
|
|
|
} \
|
|
|
|
|
2023-01-19 02:46:49 +02:00
|
|
|
bool wire_align(WireCtx *c, uint32_t alignment);
|
|
|
|
bool wire_write_align(WireCtx *c, uint32_t alignment);
|
2022-12-21 00:38:10 +02:00
|
|
|
|
|
|
|
// SPEC: https://dbus.freedesktop.org/doc/dbus-specification.html#id-1.4.6
|
2023-01-16 00:39:13 +02:00
|
|
|
_WIRE_DECL_BYTE_TYPE(i8, int8_t)
|
|
|
|
_WIRE_DECL_BYTE_TYPE(u8, uint8_t)
|
|
|
|
_WIRE_DECL_TYPE(i16, int16_t, 2)
|
|
|
|
_WIRE_DECL_TYPE(u16, uint16_t, 2)
|
|
|
|
_WIRE_DECL_TYPE(i32, int32_t, 4)
|
|
|
|
_WIRE_DECL_TYPE(u32, uint32_t, 4)
|
|
|
|
_WIRE_DECL_TYPE(boolean, uint32_t, 4)
|
2022-12-21 00:38:10 +02:00
|
|
|
|
2022-12-26 21:13:09 +02:00
|
|
|
|
2023-01-19 02:46:49 +02:00
|
|
|
char *wire_get_string_impl(WireCtx *c, bool as_signature);
|
|
|
|
char *wire_set_string_impl(WireCtx *c, const char *str, bool as_signature);
|
|
|
|
char *wire_get_string_check(WireCtx *c, int min_length, int max_length);
|
2023-01-22 18:18:57 +02:00
|
|
|
char *wire_set_string_fixed(WireCtx *c, const char *str, uint32_t len);
|
2023-01-19 02:46:49 +02:00
|
|
|
int wire_parse_message(WireCtx *c, WireMsg *msg);
|
|
|
|
int wire_compose_reply(WireCtx *c, WireMsg *msg, const char *signature, uint32_t **out_body_length);
|
|
|
|
int wire_compose_error(WireCtx *c, WireMsg *msg, const char *error_name);
|
2023-01-21 05:43:00 +02:00
|
|
|
int wire_compose_unicast_reply(WireCtx *msg_c, WireMsg *msg, char *sender_unique_name, struct iovec bufs[2], WireCtx *header_ctx);
|
2023-01-19 02:46:49 +02:00
|
|
|
int wire_compose_signal(WireCtx *c, WireMsg *out_msg, const char *signature, const char *member, uint32_t **out_body_length);
|
|
|
|
int wire_collect_strings(WireCtx *c, WireMsg *msg, WireMsgBodyString *strings, int strings_count);
|
2022-12-21 00:38:10 +02:00
|
|
|
|
2023-01-19 02:46:49 +02:00
|
|
|
static inline char *wire_get_signature(WireCtx *c) {
|
2022-12-26 21:13:09 +02:00
|
|
|
return wire_get_string_impl(c, true);
|
|
|
|
}
|
|
|
|
|
2023-01-19 02:46:49 +02:00
|
|
|
static inline char *wire_set_signature(WireCtx *c, const char *str) {
|
2022-12-26 21:13:09 +02:00
|
|
|
return wire_set_string_impl(c, str, true);
|
|
|
|
}
|
|
|
|
|
2023-01-19 02:46:49 +02:00
|
|
|
static inline char *wire_get_string(WireCtx *c) {
|
2022-12-26 21:13:09 +02:00
|
|
|
return wire_get_string_impl(c, false);
|
|
|
|
}
|
|
|
|
|
2023-01-19 02:46:49 +02:00
|
|
|
static inline char *wire_set_string(WireCtx *c, const char *str) {
|
2022-12-26 21:13:09 +02:00
|
|
|
return wire_set_string_impl(c, str, false);
|
|
|
|
}
|
|
|
|
|
2023-01-19 22:47:47 +02:00
|
|
|
char *wire_set_signature_single_char(WireCtx *c, const char s);
|
|
|
|
|
2023-01-10 15:17:50 +02:00
|
|
|
// maximum name length is 255
|
2023-01-19 02:46:49 +02:00
|
|
|
static inline char *wire_get_name_string(WireCtx *c) {
|
2023-01-10 15:17:50 +02:00
|
|
|
return wire_get_string_check(c, 1, 255);
|
|
|
|
}
|
|
|
|
|
2022-12-26 21:13:09 +02:00
|
|
|
|
2022-12-21 00:38:10 +02:00
|
|
|
#endif // _JITTERBUG__WIRE_H
|