xref: /dpdk/lib/telemetry/telemetry_data.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4 
5 #undef RTE_USE_LIBBSD
6 #include <rte_string_fns.h>
7 
8 #include "telemetry_data.h"
9 
10 int
11 rte_tel_data_start_array(struct rte_tel_data *d, enum rte_tel_value_type type)
12 {
13 	enum tel_container_types array_types[] = {
14 			RTE_TEL_ARRAY_STRING, /* RTE_TEL_STRING_VAL = 0 */
15 			RTE_TEL_ARRAY_INT,    /* RTE_TEL_INT_VAL = 1 */
16 			RTE_TEL_ARRAY_U64,    /* RTE_TEL_u64_VAL = 2 */
17 			RTE_TEL_ARRAY_CONTAINER, /* RTE_TEL_CONTAINER = 3 */
18 	};
19 	d->type = array_types[type];
20 	d->data_len = 0;
21 	return 0;
22 }
23 
24 int
25 rte_tel_data_start_dict(struct rte_tel_data *d)
26 {
27 	d->type = RTE_TEL_DICT;
28 	d->data_len = 0;
29 	return 0;
30 }
31 
32 int
33 rte_tel_data_string(struct rte_tel_data *d, const char *str)
34 {
35 	d->type = RTE_TEL_STRING;
36 	d->data_len = strlcpy(d->data.str, str, sizeof(d->data.str));
37 	if (d->data_len >= RTE_TEL_MAX_SINGLE_STRING_LEN) {
38 		d->data_len = RTE_TEL_MAX_SINGLE_STRING_LEN - 1;
39 		return E2BIG; /* not necessarily and error, just truncation */
40 	}
41 	return 0;
42 }
43 
44 int
45 rte_tel_data_add_array_string(struct rte_tel_data *d, const char *str)
46 {
47 	if (d->type != RTE_TEL_ARRAY_STRING)
48 		return -EINVAL;
49 	if (d->data_len >= RTE_TEL_MAX_ARRAY_ENTRIES)
50 		return -ENOSPC;
51 	const size_t bytes = strlcpy(d->data.array[d->data_len++].sval,
52 			str, RTE_TEL_MAX_STRING_LEN);
53 	return bytes < RTE_TEL_MAX_STRING_LEN ? 0 : E2BIG;
54 }
55 
56 int
57 rte_tel_data_add_array_int(struct rte_tel_data *d, int x)
58 {
59 	if (d->type != RTE_TEL_ARRAY_INT)
60 		return -EINVAL;
61 	if (d->data_len >= RTE_TEL_MAX_ARRAY_ENTRIES)
62 		return -ENOSPC;
63 	d->data.array[d->data_len++].ival = x;
64 	return 0;
65 }
66 
67 int
68 rte_tel_data_add_array_u64(struct rte_tel_data *d, uint64_t x)
69 {
70 	if (d->type != RTE_TEL_ARRAY_U64)
71 		return -EINVAL;
72 	if (d->data_len >= RTE_TEL_MAX_ARRAY_ENTRIES)
73 		return -ENOSPC;
74 	d->data.array[d->data_len++].u64val = x;
75 	return 0;
76 }
77 
78 int
79 rte_tel_data_add_array_container(struct rte_tel_data *d,
80 		struct rte_tel_data *val, int keep)
81 {
82 	if (d->type != RTE_TEL_ARRAY_CONTAINER ||
83 			(val->type != RTE_TEL_ARRAY_U64
84 			&& val->type != RTE_TEL_ARRAY_INT
85 			&& val->type != RTE_TEL_ARRAY_STRING))
86 		return -EINVAL;
87 	if (d->data_len >= RTE_TEL_MAX_ARRAY_ENTRIES)
88 		return -ENOSPC;
89 
90 	d->data.array[d->data_len].container.data = val;
91 	d->data.array[d->data_len++].container.keep = !!keep;
92 	return 0;
93 }
94 
95 int
96 rte_tel_data_add_dict_string(struct rte_tel_data *d, const char *name,
97 		const char *val)
98 {
99 	struct tel_dict_entry *e = &d->data.dict[d->data_len];
100 	size_t nbytes, vbytes;
101 
102 	if (d->type != RTE_TEL_DICT)
103 		return -EINVAL;
104 	if (d->data_len >= RTE_TEL_MAX_DICT_ENTRIES)
105 		return -ENOSPC;
106 
107 	d->data_len++;
108 	e->type = RTE_TEL_STRING_VAL;
109 	vbytes = strlcpy(e->value.sval, val, RTE_TEL_MAX_STRING_LEN);
110 	nbytes = strlcpy(e->name, name, RTE_TEL_MAX_STRING_LEN);
111 	if (vbytes >= RTE_TEL_MAX_STRING_LEN ||
112 			nbytes >= RTE_TEL_MAX_STRING_LEN)
113 		return E2BIG;
114 	return 0;
115 }
116 
117 int
118 rte_tel_data_add_dict_int(struct rte_tel_data *d, const char *name, int val)
119 {
120 	struct tel_dict_entry *e = &d->data.dict[d->data_len];
121 	if (d->type != RTE_TEL_DICT)
122 		return -EINVAL;
123 	if (d->data_len >= RTE_TEL_MAX_DICT_ENTRIES)
124 		return -ENOSPC;
125 
126 	d->data_len++;
127 	e->type = RTE_TEL_INT_VAL;
128 	e->value.ival = val;
129 	const size_t bytes = strlcpy(e->name, name, RTE_TEL_MAX_STRING_LEN);
130 	return bytes < RTE_TEL_MAX_STRING_LEN ? 0 : E2BIG;
131 }
132 
133 int
134 rte_tel_data_add_dict_u64(struct rte_tel_data *d,
135 		const char *name, uint64_t val)
136 {
137 	struct tel_dict_entry *e = &d->data.dict[d->data_len];
138 	if (d->type != RTE_TEL_DICT)
139 		return -EINVAL;
140 	if (d->data_len >= RTE_TEL_MAX_DICT_ENTRIES)
141 		return -ENOSPC;
142 
143 	d->data_len++;
144 	e->type = RTE_TEL_U64_VAL;
145 	e->value.u64val = val;
146 	const size_t bytes = strlcpy(e->name, name, RTE_TEL_MAX_STRING_LEN);
147 	return bytes < RTE_TEL_MAX_STRING_LEN ? 0 : E2BIG;
148 }
149 
150 int
151 rte_tel_data_add_dict_container(struct rte_tel_data *d, const char *name,
152 		struct rte_tel_data *val, int keep)
153 {
154 	struct tel_dict_entry *e = &d->data.dict[d->data_len];
155 
156 	if (d->type != RTE_TEL_DICT || (val->type != RTE_TEL_ARRAY_U64
157 			&& val->type != RTE_TEL_ARRAY_INT
158 			&& val->type != RTE_TEL_ARRAY_STRING
159 			&& val->type != RTE_TEL_DICT))
160 		return -EINVAL;
161 	if (d->data_len >= RTE_TEL_MAX_DICT_ENTRIES)
162 		return -ENOSPC;
163 
164 	d->data_len++;
165 	e->type = RTE_TEL_CONTAINER;
166 	e->value.container.data = val;
167 	e->value.container.keep = !!keep;
168 	const size_t bytes = strlcpy(e->name, name, RTE_TEL_MAX_STRING_LEN);
169 	return bytes < RTE_TEL_MAX_STRING_LEN ? 0 : E2BIG;
170 }
171 
172 struct rte_tel_data *
173 rte_tel_data_alloc(void)
174 {
175 	return malloc(sizeof(struct rte_tel_data));
176 }
177 
178 void
179 rte_tel_data_free(struct rte_tel_data *data)
180 {
181 	free(data);
182 }
183