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