#include <sys/types.h>
#include <sys/queue.h>
#define LDC_VERSION_MAJOR 1
#define LDC_VERSION_MINOR 0
#define LDC_PKT_PAYLOAD 48
struct ldc_pkt {
uint8_t type;
uint8_t stype;
uint8_t ctrl;
uint8_t env;
uint32_t seqid;
uint16_t major;
uint16_t minor;
uint32_t ackid;
uint64_t data[6];
};
#define LDC_CTRL 0x01
#define LDC_DATA 0x02
#define LDC_ERR 0x10
#define LDC_INFO 0x01
#define LDC_ACK 0x02
#define LDC_NACK 0x04
#define LDC_VERS 0x01
#define LDC_RTS 0x02
#define LDC_RTR 0x03
#define LDC_RDX 0x04
#define LDC_MODE_RAW 0x00
#define LDC_MODE_UNRELIABLE 0x01
#define LDC_MODE_RELIABLE 0x03
#define LDC_LEN_MASK 0x3f
#define LDC_FRAG_MASK 0xc0
#define LDC_FRAG_START 0x40
#define LDC_FRAG_STOP 0x80
#define LDC_MSG_MAX 4096
struct ldc_conn {
int lc_fd;
uint32_t lc_tx_seqid;
uint8_t lc_state;
#define LDC_SND_VERS 1
#define LDC_RCV_VERS 2
#define LDC_SND_RTS 3
#define LDC_SND_RTR 4
#define LDC_SND_RDX 5
uint64_t lc_msg[LDC_MSG_MAX / 8];
size_t lc_len;
void *lc_cookie;
void (*lc_reset)(struct ldc_conn *);
void (*lc_start)(struct ldc_conn *);
void (*lc_rx_data)(struct ldc_conn *, void *, size_t);
};
void ldc_rx_ctrl(struct ldc_conn *, struct ldc_pkt *);
void ldc_rx_data(struct ldc_conn *, struct ldc_pkt *);
void ldc_send_vers(struct ldc_conn *);
void ldc_reset(struct ldc_conn *);
struct ds_msg {
uint32_t msg_type;
uint32_t payload_len;
uint64_t data[5];
};
struct ds_init_req {
uint32_t msg_type;
uint32_t payload_len;
uint16_t major_vers;
uint16_t minor_vers;
} __packed;
struct ds_init_ack {
uint32_t msg_type;
uint32_t payload_len;
uint16_t minor_vers;
} __packed;
#define DS_INIT_REQ 0x00
#define DS_INIT_ACK 0x01
#define DS_INIT_NACK 0x02
struct ds_reg_req {
uint32_t msg_type;
uint32_t payload_len;
uint64_t svc_handle;
uint16_t major_vers;
uint16_t minor_vers;
char svc_id[1];
} __packed;
#define DS_REG_REQ 0x03
struct ds_reg_ack {
uint32_t msg_type;
uint32_t payload_len;
uint64_t svc_handle;
uint16_t minor_vers;
uint8_t _reserved[6];
} __packed;
#define DS_REG_ACK 0x04
struct ds_reg_nack {
uint32_t msg_type;
uint32_t payload_len;
uint64_t svc_handle;
uint64_t result;
uint16_t major_vers;
uint8_t _reserved[6];
} __packed;
#define DS_REG_NACK 0x05
struct ds_unreg {
uint32_t msg_type;
uint32_t payload_len;
uint64_t svc_handle;
} __packed;
#define DS_UNREG 0x06
#define DS_UNREG_ACK 0x07
#define DS_UNREG_NACK 0x08
struct ds_data {
uint32_t msg_type;
uint32_t payload_len;
uint64_t svc_handle;
uint64_t data[4];
};
#define DS_DATA 0x09
struct ds_nack {
uint32_t msg_type;
uint32_t payload_len;
uint64_t svc_handle;
uint64_t result;
} __packed;
#define DS_NACK 0x0a
#define DS_REG_VER_NACK 0x01
#define DS_REG_DUP 0x02
#define DS_INV_HDL 0x03
#define DS_TYPE_UNKNOWN 0x04
struct ds_service {
const char *ds_svc_id;
uint16_t ds_major_vers;
uint16_t ds_minor_vers;
void (*ds_start)(struct ldc_conn *, uint64_t);
void (*ds_rx_data)(struct ldc_conn *, uint64_t, void *,
size_t);
};
void ldc_ack(struct ldc_conn *, uint32_t);
void ds_rx_msg(struct ldc_conn *, void *, size_t);
void ds_init_ack(struct ldc_conn *);
void ds_reg_ack(struct ldc_conn *, uint64_t, uint16_t);
void ds_reg_nack(struct ldc_conn *, uint64_t, uint16_t);
void ds_unreg_ack(struct ldc_conn *, uint64_t);
void ds_unreg_nack(struct ldc_conn *, uint64_t);
void ds_receive_msg(struct ldc_conn *lc, void *, size_t);
void ds_send_msg(struct ldc_conn *lc, void *, size_t);
struct ds_conn_svc {
struct ds_service *service;
uint64_t svc_handle;
uint32_t ackid;
TAILQ_ENTRY(ds_conn_svc) link;
};
struct ds_conn {
char *path;
void *cookie;
int id;
struct ldc_conn lc;
int fd;
TAILQ_HEAD(ds_conn_svc_head, ds_conn_svc) services;
TAILQ_ENTRY(ds_conn) link;
};
struct ds_conn *ds_conn_open(const char *, void *);
void ds_conn_register_service(struct ds_conn *, struct ds_service *);
void ds_conn_serve(void);
void ds_conn_handle(struct ds_conn *);