Source code for csp_cmp.h

/* CSP Management Protocol. */
#pragma once

#include <csp/csp.h>
#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

[docs]typedef enum {
CSP_CMP_REQUEST = 0x00,
CSP_CMP_REPLY = 0xff,
} csp_cmp_type_t;
[docs]typedef enum {
CSP_CMP_IDENT = 1,
CSP_CMP_ROUTE_SET_V1 = 2,
CSP_CMP_IF_STATS = 3,
CSP_CMP_PEEK = 4,
CSP_CMP_POKE = 5,
CSP_CMP_CLOCK = 6,
CSP_CMP_ROUTE_SET_V2 = 7,
CSP_CMP_PEEK_V2 = 8,
CSP_CMP_POKE_V2 = 9,
} csp_cmp_code_t;
/* CMP field limits. */
#define CSP_CMP_IDENT_REV_LEN 20
#define CSP_CMP_IDENT_DATE_LEN 12
#define CSP_CMP_IDENT_TIME_LEN 9
#define CSP_CMP_ROUTE_IFACE_LEN 11
#define CSP_CMP_PEEK_MAX_LEN 200
#define CSP_CMP_POKE_MAX_LEN 200
#define CSP_CMP_PEEK_V2_MAX_LEN 196
#define CSP_CMP_POKE_V2_MAX_LEN 196
/* * All CMP wire messages start with type and code. The dispatcher validates this * header before casting packet data to one of the concrete packed layouts below. */
struct csp_cmp_header {
uint8_t type;
uint8_t code;
} __attribute__((__packed__));
/* Packed CMP wire messages. */
struct csp_cmp_ident_msg {
uint8_t type;
uint8_t code;
char hostname[CSP_HOSTNAME_LEN];
char model[CSP_MODEL_LEN];
char revision[CSP_CMP_IDENT_REV_LEN];
char date[CSP_CMP_IDENT_DATE_LEN];
char time[CSP_CMP_IDENT_TIME_LEN];
} __attribute__((__packed__));
struct csp_cmp_route_set_v1_msg {
uint8_t type;
uint8_t code;
uint8_t dest_node;
uint8_t next_hop_via;
char interface[CSP_CMP_ROUTE_IFACE_LEN];
} __attribute__((__packed__));
struct csp_cmp_route_set_v2_msg {
uint8_t type;
uint8_t code;
uint16_t dest_node;
uint16_t next_hop_via;
uint16_t netmask;
char interface[CSP_CMP_ROUTE_IFACE_LEN];
} __attribute__((__packed__));
struct csp_cmp_if_stats_msg {
uint8_t type;
uint8_t code;
char interface[CSP_CMP_ROUTE_IFACE_LEN];
uint32_t tx;
uint32_t rx;
uint32_t tx_error;
uint32_t rx_error;
uint32_t drop;
uint32_t autherr;
uint32_t frame;
uint32_t txbytes;
uint32_t rxbytes;
uint32_t irq;
} __attribute__((__packed__));
struct csp_cmp_peek_msg {
uint8_t type;
uint8_t code;
uint32_t addr;
uint8_t len;
uint8_t data[];
} __attribute__((__packed__));
struct csp_cmp_poke_msg {
uint8_t type;
uint8_t code;
uint32_t addr;
uint8_t len;
uint8_t data[];
} __attribute__((__packed__));
struct csp_cmp_peek_v2_msg {
uint8_t type;
uint8_t code;
uint64_t vaddr;
uint8_t len;
uint8_t data[];
} __attribute__((__packed__));
struct csp_cmp_poke_v2_msg {
uint8_t type;
uint8_t code;
uint64_t vaddr;
uint8_t len;
uint8_t data[];
} __attribute__((__packed__));
struct csp_cmp_clock_msg {
uint8_t type;
uint8_t code;
csp_timestamp_t clock;
} __attribute__((__packed__));
/* Legacy aggregate CMP message kept for source compatibility. */
struct csp_cmp_message {
uint8_t type;
uint8_t code;
union { struct { char hostname[CSP_HOSTNAME_LEN]; char model[CSP_MODEL_LEN]; char revision[CSP_CMP_IDENT_REV_LEN]; char date[CSP_CMP_IDENT_DATE_LEN]; char time[CSP_CMP_IDENT_TIME_LEN]; } ident; struct { uint8_t dest_node; uint8_t next_hop_via; char interface[CSP_CMP_ROUTE_IFACE_LEN]; } route_set_v1; struct { uint16_t dest_node; uint16_t next_hop_via; uint16_t netmask; char interface[CSP_CMP_ROUTE_IFACE_LEN]; } route_set_v2; struct __attribute__((__packed__)) { char interface[CSP_CMP_ROUTE_IFACE_LEN]; uint32_t tx; uint32_t rx; uint32_t tx_error; uint32_t rx_error; uint32_t drop; uint32_t autherr; uint32_t frame; uint32_t txbytes; uint32_t rxbytes; uint32_t irq; } if_stats; struct { uint32_t addr; uint8_t len; char data[CSP_CMP_PEEK_MAX_LEN]; } peek; struct { uint32_t addr; uint8_t len; char data[CSP_CMP_POKE_MAX_LEN]; } poke; struct { uint64_t vaddr; uint8_t len; char data[CSP_CMP_PEEK_V2_MAX_LEN]; } peek_v2; struct { uint64_t vaddr; uint8_t len; char data[CSP_CMP_POKE_V2_MAX_LEN]; } poke_v2; csp_timestamp_t clock; };
} __attribute__((__packed__));
/* Legacy macro for calculating fixed-size aggregate CMP messages. */
#define CMP_SIZE(_memb) (sizeof(((struct csp_cmp_message *)0)->type) + sizeof(((struct csp_cmp_message *)0)->code) + sizeof(((struct csp_cmp_message *)0)->_memb))
/* * Macro for calculating variable-size management messages. * Legacy variable CMP messages include the tail padding from the original * fixed-size member, but the data bytes themselves are not rounded up. */
#define CMP_ALIGN_UP_32(_len) (((_len) + 3u) & ~3u)
#define CMP_VARIABLE_PAYLOAD_SIZE(_packet) (sizeof(struct _packet) - sizeof(struct csp_cmp_header))
#define CMP_VARIABLE_TAIL_SIZE(_packet) (CMP_ALIGN_UP_32(CMP_VARIABLE_PAYLOAD_SIZE(_packet)) - CMP_VARIABLE_PAYLOAD_SIZE(_packet))
#define CMP_VARIABLE_SIZE(_packet, _len) (sizeof(struct _packet) + CMP_VARIABLE_TAIL_SIZE(_packet) + (_len))
#define CMP_PEEK_SIZE(_len) CMP_VARIABLE_SIZE(csp_cmp_peek_msg, _len)
#define CMP_POKE_SIZE(_len) CMP_VARIABLE_SIZE(csp_cmp_poke_msg, _len)
#define CMP_PEEK_V2_SIZE(_len) CMP_VARIABLE_SIZE(csp_cmp_peek_v2_msg, _len)
#define CMP_POKE_V2_SIZE(_len) CMP_VARIABLE_SIZE(csp_cmp_poke_v2_msg, _len)
/* Sets the common CMP header and transacts an exact-size request/reply. */
[docs]int csp_cmp(uint16_t node, uint32_t timeout, uint8_t code, int msg_size, void *msg);
static inline int csp_cmp_ident(uint16_t node, uint32_t timeout, void *msg) { return csp_cmp(node, timeout, CSP_CMP_IDENT, sizeof(struct csp_cmp_ident_msg), msg); }
static inline int csp_cmp_route_set_v1(uint16_t node, uint32_t timeout, void *msg) { return csp_cmp(node, timeout, CSP_CMP_ROUTE_SET_V1, sizeof(struct csp_cmp_route_set_v1_msg), msg); }
static inline int csp_cmp_if_stats(uint16_t node, uint32_t timeout, void *msg) { return csp_cmp(node, timeout, CSP_CMP_IF_STATS, sizeof(struct csp_cmp_if_stats_msg), msg); }
static inline int csp_cmp_clock(uint16_t node, uint32_t timeout, void *msg) { return csp_cmp(node, timeout, CSP_CMP_CLOCK, sizeof(struct csp_cmp_clock_msg), msg); }
static inline int csp_cmp_route_set_v2(uint16_t node, uint32_t timeout, void *msg) { return csp_cmp(node, timeout, CSP_CMP_ROUTE_SET_V2, sizeof(struct csp_cmp_route_set_v2_msg), msg); }
[docs]static inline int csp_cmp_peek(uint16_t node, uint32_t timeout, void *msg) { struct csp_cmp_peek_msg *peek = (struct csp_cmp_peek_msg *)msg; return csp_cmp(node, timeout, CSP_CMP_PEEK, CMP_PEEK_SIZE(peek->len), msg); }
[docs]static inline int csp_cmp_poke(uint16_t node, uint32_t timeout, void *msg) { struct csp_cmp_poke_msg *poke = (struct csp_cmp_poke_msg *)msg; return csp_cmp(node, timeout, CSP_CMP_POKE, CMP_POKE_SIZE(poke->len), msg); }
static inline int csp_cmp_peek_v2(uint16_t node, uint32_t timeout, void *msg) { struct csp_cmp_peek_v2_msg *peek = (struct csp_cmp_peek_v2_msg *)msg; return csp_cmp(node, timeout, CSP_CMP_PEEK_V2, CMP_PEEK_V2_SIZE(peek->len), msg); }
static inline int csp_cmp_poke_v2(uint16_t node, uint32_t timeout, void *msg) { struct csp_cmp_poke_v2_msg *poke = (struct csp_cmp_poke_v2_msg *)msg; return csp_cmp(node, timeout, CSP_CMP_POKE_V2, CMP_POKE_V2_SIZE(poke->len), msg); }
#ifdef __cplusplus } #endif