1
#ifndef __AVPROTO$DEF__
2
#define __AVPROTO$DEF__ 1
5
#pragma GCC diagnostic ignored "-Wparentheses"
6
#pragma GCC diagnostic ignored "-Wdate-time"
7
#pragma GCC diagnostic ignored "-Wunused-variable"
13
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
20
** FACILITY: AVProto - Attribute/Value Pair (AKA TLV) based protocol
22
** ABSTRACT: Carring data incapsulated in to the AVP microcontainers
24
** DESCRIPTION: This module contains data structures and constant definition is supposed to be used
25
** in the core AVProto routines as well as in general API routines.
29
** A main idea is imaginated follows :
31
PDU (protocol/packet data unit ) - is a block is supposed to be send to remote peer over network
33
|<- Payload (see Header.len field)-->|
34
+--------+-------+-------+-- ... ----+-------+
35
| Header | TLV 0 | TLV 1 | .... | TLV N |
36
+--------+-------+-------+---- ... --+-------+
39
+-----------+-----------+-----------+-----------+
40
| magic | len | csr | seq |
41
| 8 octets | 4 octets | 4 octets | 4 octets
42
+-----------+-----------+-----------+-----------+
44
T[ag] L[ength] V[alue] :
46
+---------+-----------+-------------------+
47
| Type | Id | Length |
48
| 4 bits | 12 bits | 16 bits |
49
+---------+-----------+-------------------+
50
| optional data (value) |
51
| 0 - 'Length' octets |
52
+---------+-----------+-------------------+
54
** AUTHORS: Ruslan R. Laishev (RRL)
56
** CREATION DATE: 20-JUL-2018
58
** MODIFICATION HISTORY:
60
** 15-FEB-2019 RRL Removed bitfields.
62
** 22-FEB-2019 RRL Added closing for "#ifdef __cplusplus"
63
** some code reorganizing;
65
** 29-JUL-2019 RRL Added declaration for avproto_dump();
66
** improved error handling in the avproto_hget();
82
* AVP/TLV - type of block types to help transparent conversion of the well-know datas
83
* is carried in NBO or to help LE/Be conversion
86
TAG$K_BBLOCK = 0, /* A default type - octets block */
87
TAG$K_WORD = 3, /* 16-bits word, NBO */
88
TAG$K_LONGWORD, /* 32-bits word, NBO */
89
TAG$K_QWORD, /* 64-bits word, NBO */
90
TAG$K_UUID = 8, /* UUID */
93
TAG$K_MAX /* EOL marker, must be last! */
97
#pragma pack (push, 1)
99
#define TAG$M_TYPE 0xf000
100
#define TAG$M_ID (~(TAG$M_TYPE))
102
typedef struct __avproto_tlv__ {
104
unsigned short w_tag; /* Tag's type and id */
105
unsigned short w_len; /* Actual data length in the b_val[] */
107
union { /* Placeholder for data block */
108
unsigned char b_val[0];
109
unsigned short w_val[0];
111
unsigned long long q_val[0];
115
typedef struct __avproto_hdr__ {
116
unsigned char magic[8];
117
unsigned u_len; /* A length of payload follows header */
118
unsigned u_csr; /* Command/Status Register */
120
unsigned u_seq; /* A PDU sequence number is supposed to help
121
parallel and asyncronus processing */
125
typedef struct __avproto_pdu__ {
126
AVPROTO_HDR r_hdr; /* Fixed length header */
127
AVPROTO_TLV r_tlv[0]; /* Placeholder for variable part of PDU */
133
* @brief avproto_encode_tag - encapsulate given 'v_type' and 'v_tag' into the 16-bits field.
134
* return NBO representation of the w_tag;
136
* @param v_type - Tag type, see TAG$K_* constatnts
137
* @param v_tag - Tasg Id, application specific Tag Id
139
* @return - 16 bits TLV.w_tag field, NBO
141
inline static unsigned short avproto_encode_tag
143
unsigned short v_type,
147
return htobe16 ( ( (v_type << 12) | v_tag ));
151
* @brief avproto_decode_tag - extract 'tag id' and 'tag type' field from the TLV.w_tag.
152
* Return w_gat in the Host Order Byte
154
* @param w_tag - TLV.w_tag field, NBO
155
* @param v_type - an address of variable to accept unpacked 'tag type' field
156
* @param v_tag - an address of variable to accept unpacked 'tag id field
158
* @return - 16 bits, TLV_w_tag in Host Order Byte
160
inline static unsigned short avproto_decode_tag
162
unsigned short w_tag,
163
unsigned short *v_type,
164
unsigned short *v_tag
167
unsigned short tag = 0;
169
tag = be16toh(w_tag);
172
*v_tag = tag & TAG$M_ID;
178
int avproto_put (void *pdu, unsigned short pdusz, unsigned v_tag, unsigned v_type, void *val, unsigned valsz);
179
int avproto_get (void *pdu, int *context, unsigned v_tag, unsigned *v_type, void *val, unsigned *valsz);
180
void avproto_dump (void *pdu);
184
* DESCRIPTION: Inialize given PDU's header with given values, reset length of the PDU
188
* sig: A signature string, ASCIZ
189
* pdu: A Prototocol Data Unit
190
* u_csr: A command/status register field
191
* u_seq: PDU's sequence field
199
inline static int avproto_hset (
206
AVPROTO_PDU *pdu = (AVPROTO_PDU *) pdup;
208
memset(&pdu->r_hdr, 0, sizeof(AVPROTO_HDR));
209
strncpy(pdu->r_hdr.magic, sig, sizeof(pdu->r_hdr.magic));
211
pdu->r_hdr.u_csr = htobe32(u_csr);
212
pdu->r_hdr.u_seq = htobe32(u_seq);
214
return STS$K_SUCCESS;
219
* DESCRIPTION: Get information from the PDU's header.
222
* pdu: A Prototocol Data Unit
223
* sig: A signature string, ASCIZ
226
* u_len: A length of the PDU's payload
227
* u_csr: A command/status register field
228
* u_seq: PDU's sequence field
233
inline static int avproto_hget (
242
AVPROTO_PDU *pdu = (AVPROTO_PDU *) pdup;
244
*u_csr = STS$K_ERROR;
246
if ( (len = strlen(sig)) > (sizeof (pdu->r_hdr.magic)) )
249
if ( strncmp(pdu->r_hdr.magic, sig, sizeof (pdu->r_hdr.magic)) )
252
*u_len = be32toh(pdu->r_hdr.u_len);
253
*u_csr = be32toh(pdu->r_hdr.u_csr);
254
*u_seq = be32toh(pdu->r_hdr.u_seq);
256
return STS$K_SUCCESS;
264
#endif /* #ifndef __AVPROTO$DEF__ */