15void pc_lwm2m_tlv_init(Lwm2mTlvWriter *w, uint8_t *buf,
size_t cap)
23bool pc_lwm2m_tlv_write(Lwm2mTlvWriter *w, uint8_t id_type, uint16_t
id,
const uint8_t *value,
size_t value_len)
25 if (!w || (value_len && !value))
29 uint8_t type = (uint8_t)(id_type & LWM2M_TLV_IDKIND_MASK);
30 bool id16 =
id > 0xFF;
33 type |= LWM2M_TLV_ID16_FLAG;
37 if (value_len <= LWM2M_TLV_INLINE_LEN_MASK)
40 type |= (uint8_t)value_len;
42 else if (value_len <= 0xFF)
45 type |= (uint8_t)(1 << LWM2M_TLV_LENTYPE_SHIFT);
47 else if (value_len <= 0xFFFF)
50 type |= (uint8_t)(2 << LWM2M_TLV_LENTYPE_SHIFT);
52 else if (value_len <= 0xFFFFFF)
55 type |= (uint8_t)(3 << LWM2M_TLV_LENTYPE_SHIFT);
62 size_t need = 1 + (id16 ? 2 : 1) + lenbytes + value_len;
63 if (w->error || w->pos + need > w->cap)
69 w->buf[w->pos++] = type;
72 w->buf[w->pos++] = (uint8_t)(
id >> 8);
74 w->buf[w->pos++] = (uint8_t)
id;
75 for (
size_t i = 0; i < lenbytes; i++)
77 w->buf[w->pos++] = (uint8_t)(value_len >> (8 * (lenbytes - 1 - i)));
81 memcpy(w->buf + w->pos, value, value_len);
87bool pc_lwm2m_tlv_write_int(Lwm2mTlvWriter *w, uint16_t
id, int64_t v)
90 if (v >= -128 && v <= 127)
94 else if (v >= -32768 && v <= 32767)
98 else if (v >= -2147483648LL && v <= 2147483647LL)
107 for (
size_t i = 0; i < n; i++)
109 b[i] = (uint8_t)((uint64_t)v >> (8 * (n - 1 - i)));
111 return pc_lwm2m_tlv_write(w, LWM2M_TLV_RESOURCE,
id, b, n);
114bool pc_lwm2m_tlv_write_bool(Lwm2mTlvWriter *w, uint16_t
id,
bool v)
116 uint8_t b = v ? 1 : 0;
117 return pc_lwm2m_tlv_write(w, LWM2M_TLV_RESOURCE,
id, &b, 1);
120bool pc_lwm2m_tlv_write_string(Lwm2mTlvWriter *w, uint16_t
id,
const char *s)
126 return pc_lwm2m_tlv_write(w, LWM2M_TLV_RESOURCE,
id, (
const uint8_t *)s, strnlen(s, w->cap + 1));
129bool pc_lwm2m_tlv_write_float(Lwm2mTlvWriter *w, uint16_t
id,
double v)
132 memcpy(&bits, &v, 8);
134 for (
size_t i = 0; i < 8; i++)
136 b[i] = (uint8_t)(bits >> (8 * (7 - i)));
138 return pc_lwm2m_tlv_write(w, LWM2M_TLV_RESOURCE,
id, b, 8);
141size_t pc_lwm2m_tlv_finish(Lwm2mTlvWriter *w)
143 return w->error ? 0 : w->pos;
146bool pc_lwm2m_tlv_read(
const uint8_t *buf,
size_t len,
size_t *pos, Lwm2mTlv *out)
148 if (!buf || !pos || !out || *pos >= len)
153 uint8_t type = buf[p++];
154 bool id16 = (type & LWM2M_TLV_ID16_FLAG) != 0;
155 if (p + (id16 ? 2u : 1u) > len)
159 uint16_t
id = buf[p++];
162 id = (uint16_t)((
id << 8) | buf[p++]);
165 uint8_t lentype = (uint8_t)((type >> LWM2M_TLV_LENTYPE_SHIFT) & LWM2M_TLV_LENTYPE_MASK);
169 vlen = type & LWM2M_TLV_INLINE_LEN_MASK;
173 if (p + lentype > len)
178 for (uint8_t i = 0; i < lentype; i++)
180 vlen = (vlen << 8) | buf[p++];
188 out->id_type = (uint8_t)(type & LWM2M_TLV_IDKIND_MASK);
190 out->value = buf + p;
191 out->value_len = vlen;
196bool pc_lwm2m_tlv_value_int(
const uint8_t *value,
size_t len, int64_t *out)
198 if (!value || (len != 1 && len != 2 && len != 4 && len != 8))
202 int64_t r = (value[0] & 0x80) ? -1 : 0;
203 for (
size_t i = 0; i < len; i++)
205 r = (int64_t)(((uint64_t)r << 8) | value[i]);