\doxysection{tlv.\+h}
\label{tlv_8h_source}\index{include/osmocom/gsm/tlv.h@{include/osmocom/gsm/tlv.h}}
\textbf{ Go to the documentation of this file.}
\begin{DoxyCode}{0}
\DoxyCodeLine{1 \textcolor{preprocessor}{\#pragma once}}
\DoxyCodeLine{2 }
\DoxyCodeLine{3 \textcolor{preprocessor}{\#include <stdint.h>}}
\DoxyCodeLine{4 \textcolor{preprocessor}{\#include <string.h>}}
\DoxyCodeLine{5 }
\DoxyCodeLine{6 \textcolor{preprocessor}{\#include <osmocom/core/msgb.h>}}
\DoxyCodeLine{7 \textcolor{preprocessor}{\#include <osmocom/core/byteswap.h>}}
\DoxyCodeLine{8 \textcolor{preprocessor}{\#include <osmocom/core/bit16gen.h>}}
\DoxyCodeLine{9 \textcolor{preprocessor}{\#include <osmocom/core/bit32gen.h>}}
\DoxyCodeLine{10 }
\DoxyCodeLine{15 \textcolor{comment}{/* Terminology / wording}}
\DoxyCodeLine{16 \textcolor{comment}{                tag     length          value   (in bits)}}
\DoxyCodeLine{17 \textcolor{comment}{}}
\DoxyCodeLine{18 \textcolor{comment}{            V   -\/       -\/               8}}
\DoxyCodeLine{19 \textcolor{comment}{           LV   -\/       8               N * 8}}
\DoxyCodeLine{20 \textcolor{comment}{          TLV   8       8               N * 8}}
\DoxyCodeLine{21 \textcolor{comment}{        TL16V   8       16              N * 8}}
\DoxyCodeLine{22 \textcolor{comment}{        TLV16   8       8               N * 16}}
\DoxyCodeLine{23 \textcolor{comment}{         TvLV   8       8/16            N * 8}}
\DoxyCodeLine{24 \textcolor{comment}{        vTvLV   8/16    8/16            N * 8}}
\DoxyCodeLine{25 \textcolor{comment}{        T16LV   16      8               N * 8}}
\DoxyCodeLine{26 \textcolor{comment}{*/}}
\DoxyCodeLine{27 }
\DoxyCodeLine{29 \textcolor{preprocessor}{\#define LV\_GROSS\_LEN(x)         (x+1)}}
\DoxyCodeLine{31 \textcolor{preprocessor}{\#define TLV\_GROSS\_LEN(x)        (x+2)}}
\DoxyCodeLine{33 \textcolor{preprocessor}{\#define TLV16\_GROSS\_LEN(x)      ((2*x)+2)}}
\DoxyCodeLine{35 \textcolor{preprocessor}{\#define TL16V\_GROSS\_LEN(x)      (x+3)}}
\DoxyCodeLine{37 \textcolor{preprocessor}{\#define L16TV\_GROSS\_LEN(x)      (x+3)}}
\DoxyCodeLine{39 \textcolor{preprocessor}{\#define T16LV\_GROSS\_LEN(x)      (x+3)}}
\DoxyCodeLine{40 }
\DoxyCodeLine{42 \textcolor{preprocessor}{\#define TVLV\_MAX\_ONEBYTE        0x7f}}
\DoxyCodeLine{43 }
\DoxyCodeLine{45 \textcolor{keyword}{enum} osmo\_tlv\_parser\_error \{}
\DoxyCodeLine{46         OSMO\_TLVP\_ERR\_OFS\_BEYOND\_BUFFER          = -\/1,}
\DoxyCodeLine{47         OSMO\_TLVP\_ERR\_OFS\_LEN\_BEYOND\_BUFFER  = -\/2,}
\DoxyCodeLine{48         OSMO\_TLVP\_ERR\_UNKNOWN\_TLV\_TYPE            = -\/3,}
\DoxyCodeLine{49 }
\DoxyCodeLine{50         OSMO\_TLVP\_ERR\_MAND\_IE\_MISSING              = -\/50,}
\DoxyCodeLine{51         OSMO\_TLVP\_ERR\_IE\_TOO\_SHORT            = -\/51,}
\DoxyCodeLine{52 \};}
\DoxyCodeLine{53 }
\DoxyCodeLine{55 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint16\_t TVLV\_GROSS\_LEN(uint16\_t len)}
\DoxyCodeLine{56 \{}
\DoxyCodeLine{57         \textcolor{keywordflow}{if} (len <= TVLV\_MAX\_ONEBYTE)}
\DoxyCodeLine{58                 \textcolor{keywordflow}{return} TLV\_GROSS\_LEN(len);}
\DoxyCodeLine{59         \textcolor{keywordflow}{else}}
\DoxyCodeLine{60                 \textcolor{keywordflow}{return} TL16V\_GROSS\_LEN(len);}
\DoxyCodeLine{61 \}}
\DoxyCodeLine{62 }
\DoxyCodeLine{64 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint16\_t VTVL\_GAN\_GROSS\_LEN(uint16\_t tag, uint16\_t len)}
\DoxyCodeLine{65 \{}
\DoxyCodeLine{66         uint16\_t ret = 2;}
\DoxyCodeLine{67 }
\DoxyCodeLine{68         \textcolor{keywordflow}{if} (tag > TVLV\_MAX\_ONEBYTE)}
\DoxyCodeLine{69                 ret++;}
\DoxyCodeLine{70 }
\DoxyCodeLine{71         \textcolor{keywordflow}{if} (len > TVLV\_MAX\_ONEBYTE)}
\DoxyCodeLine{72                 ret++;}
\DoxyCodeLine{73 }
\DoxyCodeLine{74         \textcolor{keywordflow}{return} ret;}
\DoxyCodeLine{75 \}}
\DoxyCodeLine{76 }
\DoxyCodeLine{78 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint16\_t VTVLV\_GAN\_GROSS\_LEN(uint16\_t tag, uint16\_t len)}
\DoxyCodeLine{79 \{}
\DoxyCodeLine{80         uint16\_t ret;}
\DoxyCodeLine{81 }
\DoxyCodeLine{82         \textcolor{keywordflow}{if} (len <= TVLV\_MAX\_ONEBYTE)}
\DoxyCodeLine{83                 ret = TLV\_GROSS\_LEN(len);}
\DoxyCodeLine{84         \textcolor{keywordflow}{else}}
\DoxyCodeLine{85                 ret = TL16V\_GROSS\_LEN(len);}
\DoxyCodeLine{86 }
\DoxyCodeLine{87         \textcolor{keywordflow}{if} (tag > TVLV\_MAX\_ONEBYTE)}
\DoxyCodeLine{88                 ret += 1;}
\DoxyCodeLine{89 }
\DoxyCodeLine{90         \textcolor{keywordflow}{return} ret;}
\DoxyCodeLine{91 \}}
\DoxyCodeLine{92 }
\DoxyCodeLine{93 \textcolor{comment}{/* TLV generation */}}
\DoxyCodeLine{94 }
\DoxyCodeLine{96 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *lv\_put(uint8\_t *buf, uint8\_t len,}
\DoxyCodeLine{97                                 \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{98 \{}
\DoxyCodeLine{99         *buf++ = len;}
\DoxyCodeLine{100         memcpy(buf, val, len);}
\DoxyCodeLine{101         \textcolor{keywordflow}{return} buf + len;}
\DoxyCodeLine{102 \}}
\DoxyCodeLine{103 }
\DoxyCodeLine{111 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tlv\_put(uint8\_t *buf, uint8\_t tag, uint8\_t len,}
\DoxyCodeLine{112                                 \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{113 \{}
\DoxyCodeLine{114         *buf++ = tag;}
\DoxyCodeLine{115         *buf++ = len;}
\DoxyCodeLine{116         \textcolor{keywordflow}{if} (len) \{}
\DoxyCodeLine{117                 \textcolor{keywordflow}{if} (val)}
\DoxyCodeLine{118                         memcpy(buf, val, len);}
\DoxyCodeLine{119                 \textcolor{keywordflow}{else}}
\DoxyCodeLine{120                         memset(buf, 0, len);}
\DoxyCodeLine{121         \}}
\DoxyCodeLine{122         \textcolor{keywordflow}{return} buf + len;}
\DoxyCodeLine{123 \}}
\DoxyCodeLine{124 }
\DoxyCodeLine{126 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tl\_put(uint8\_t *buf, uint8\_t tag, uint8\_t len)}
\DoxyCodeLine{127 \{}
\DoxyCodeLine{128         *buf++ = tag;}
\DoxyCodeLine{129         *buf++ = len;}
\DoxyCodeLine{130         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{131 \}}
\DoxyCodeLine{132 }
\DoxyCodeLine{134 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tlv16\_put(uint8\_t *buf, uint8\_t tag, uint8\_t len,}
\DoxyCodeLine{135                                 \textcolor{keyword}{const} uint16\_t *val)}
\DoxyCodeLine{136 \{}
\DoxyCodeLine{137         *buf++ = tag;}
\DoxyCodeLine{138         *buf++ = len;}
\DoxyCodeLine{139         memcpy(buf, val, len*2);}
\DoxyCodeLine{140         \textcolor{keywordflow}{return} buf + len*2;}
\DoxyCodeLine{141 \}}
\DoxyCodeLine{142 }
\DoxyCodeLine{144 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tl16v\_put(uint8\_t *buf, uint8\_t tag, uint16\_t len,}
\DoxyCodeLine{145                                 \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{146 \{}
\DoxyCodeLine{147         *buf++ = tag;}
\DoxyCodeLine{148         *buf++ = len >> 8;}
\DoxyCodeLine{149         *buf++ = len \& 0xff;}
\DoxyCodeLine{150         memcpy(buf, val, len);}
\DoxyCodeLine{151         \textcolor{keywordflow}{return} buf + len;}
\DoxyCodeLine{152 \}}
\DoxyCodeLine{153 }
\DoxyCodeLine{155 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tl16\_put(uint8\_t *buf, uint8\_t tag, uint16\_t len)}
\DoxyCodeLine{156 \{}
\DoxyCodeLine{157         *buf++ = tag;}
\DoxyCodeLine{158         *buf++ = len >> 8;}
\DoxyCodeLine{159         *buf++ = len \& 0xff;}
\DoxyCodeLine{160         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{161 \}}
\DoxyCodeLine{162 }
\DoxyCodeLine{164 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *t16lv\_put(uint8\_t *buf, uint16\_t tag, uint8\_t len,}
\DoxyCodeLine{165                                 \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{166 \{}
\DoxyCodeLine{167         *buf++ = tag >> 8;}
\DoxyCodeLine{168         *buf++ = tag \& 0xff;}
\DoxyCodeLine{169         *buf++ = len;}
\DoxyCodeLine{170         memcpy(buf, val, len);}
\DoxyCodeLine{171         \textcolor{keywordflow}{return} buf + len;}
\DoxyCodeLine{172 \}}
\DoxyCodeLine{173 }
\DoxyCodeLine{175 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tvlv\_put(uint8\_t *buf, uint8\_t tag, uint16\_t len,}
\DoxyCodeLine{176                                  \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{177 \{}
\DoxyCodeLine{178         uint8\_t *ret;}
\DoxyCodeLine{179 }
\DoxyCodeLine{180         \textcolor{keywordflow}{if} (len <= TVLV\_MAX\_ONEBYTE) \{}
\DoxyCodeLine{181                 ret = tlv\_put(buf, tag, len, val);}
\DoxyCodeLine{182                 buf[1] |= 0x80;}
\DoxyCodeLine{183         \} \textcolor{keywordflow}{else}}
\DoxyCodeLine{184                 ret = tl16v\_put(buf, tag, len, val);}
\DoxyCodeLine{185 }
\DoxyCodeLine{186         \textcolor{keywordflow}{return} ret;}
\DoxyCodeLine{187 \}}
\DoxyCodeLine{188 }
\DoxyCodeLine{193 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tvl\_put(uint8\_t *buf, uint8\_t tag, uint16\_t len)}
\DoxyCodeLine{194 \{}
\DoxyCodeLine{195         uint8\_t *ret;}
\DoxyCodeLine{196 }
\DoxyCodeLine{197         \textcolor{keywordflow}{if} (len <= TVLV\_MAX\_ONEBYTE) \{}
\DoxyCodeLine{198                 ret = tl\_put(buf, tag, len);}
\DoxyCodeLine{199                 buf[1] |= 0x80;}
\DoxyCodeLine{200         \} \textcolor{keywordflow}{else}}
\DoxyCodeLine{201                 ret = tl16\_put(buf, tag, len);}
\DoxyCodeLine{202 }
\DoxyCodeLine{203         \textcolor{keywordflow}{return} ret;}
\DoxyCodeLine{204 \}}
\DoxyCodeLine{205 }
\DoxyCodeLine{207 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *vt\_gan\_put(uint8\_t *buf, uint16\_t tag)}
\DoxyCodeLine{208 \{}
\DoxyCodeLine{209         \textcolor{keywordflow}{if} (tag > TVLV\_MAX\_ONEBYTE) \{}
\DoxyCodeLine{210                 \textcolor{comment}{/* two-\/byte TAG */}}
\DoxyCodeLine{211                 *buf++ = 0x80 | (tag >> 8);}
\DoxyCodeLine{212                 *buf++ = (tag \& 0xff);}
\DoxyCodeLine{213         \} \textcolor{keywordflow}{else}}
\DoxyCodeLine{214                 *buf++ = tag;}
\DoxyCodeLine{215 }
\DoxyCodeLine{216         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{217 \}}
\DoxyCodeLine{218 }
\DoxyCodeLine{219 \textcolor{comment}{/* put (append) vTvL (GAN) field (tag + length)*/}}
\DoxyCodeLine{220 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *vtvl\_gan\_put(uint8\_t *buf, uint16\_t tag, uint16\_t len)}
\DoxyCodeLine{221 \{}
\DoxyCodeLine{222         uint8\_t *ret;}
\DoxyCodeLine{223 }
\DoxyCodeLine{224         ret = vt\_gan\_put(buf, tag);}
\DoxyCodeLine{225         \textcolor{keywordflow}{return} vt\_gan\_put(ret, len);}
\DoxyCodeLine{226 \}}
\DoxyCodeLine{227 }
\DoxyCodeLine{228 \textcolor{comment}{/* put (append) vTvLV (GAN) field (tag + length + val) */}}
\DoxyCodeLine{229 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *vtvlv\_gan\_put(uint8\_t *buf, uint16\_t tag, uint16\_t len,}
\DoxyCodeLine{230                                       \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{231 \{}
\DoxyCodeLine{232         uint8\_t *ret;}
\DoxyCodeLine{233 }
\DoxyCodeLine{234         ret = vtvl\_gan\_put(buf, tag, len );}
\DoxyCodeLine{235 }
\DoxyCodeLine{236         memcpy(ret, val, len);}
\DoxyCodeLine{237         ret = buf + len;}
\DoxyCodeLine{238 }
\DoxyCodeLine{239         \textcolor{keywordflow}{return} ret;}
\DoxyCodeLine{240 \}}
\DoxyCodeLine{241 }
\DoxyCodeLine{243 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tlv16\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint8\_t len, \textcolor{keyword}{const} uint16\_t *val)}
\DoxyCodeLine{244 \{}
\DoxyCodeLine{245         uint8\_t *buf = msgb\_put(msg, TLV16\_GROSS\_LEN(len));}
\DoxyCodeLine{246         \textcolor{keywordflow}{return} tlv16\_put(buf, tag, len, val);}
\DoxyCodeLine{247 \}}
\DoxyCodeLine{248 }
\DoxyCodeLine{250 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tl16v\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint16\_t len,}
\DoxyCodeLine{251                                         \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{252 \{}
\DoxyCodeLine{253         uint8\_t *buf = msgb\_put(msg, TL16V\_GROSS\_LEN(len));}
\DoxyCodeLine{254         \textcolor{keywordflow}{return} tl16v\_put(buf, tag, len, val);}
\DoxyCodeLine{255 \}}
\DoxyCodeLine{256 }
\DoxyCodeLine{257 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_t16lv\_put(\textcolor{keyword}{struct} msgb *msg, uint16\_t tag, uint8\_t len, \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{258 \{}
\DoxyCodeLine{259         uint8\_t *buf = msgb\_put(msg, T16LV\_GROSS\_LEN(len));}
\DoxyCodeLine{260         \textcolor{keywordflow}{return} t16lv\_put(buf, tag, len, val);}
\DoxyCodeLine{261 \}}
\DoxyCodeLine{262 }
\DoxyCodeLine{268 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tvl\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint16\_t len)}
\DoxyCodeLine{269 \{}
\DoxyCodeLine{270         uint8\_t *buf = msgb\_put(msg, TVLV\_GROSS\_LEN(len));}
\DoxyCodeLine{271         \textcolor{keywordflow}{return} tvl\_put(buf, tag, len);}
\DoxyCodeLine{272 \}}
\DoxyCodeLine{273 }
\DoxyCodeLine{275 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tvlv\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint16\_t len,}
\DoxyCodeLine{276                                       \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{277 \{}
\DoxyCodeLine{278         uint8\_t *buf = msgb\_put(msg, TVLV\_GROSS\_LEN(len));}
\DoxyCodeLine{279         \textcolor{keywordflow}{return} tvlv\_put(buf, tag, len, val);}
\DoxyCodeLine{280 \}}
\DoxyCodeLine{281 }
\DoxyCodeLine{283 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tvlv\_put\_16be(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint16\_t val)}
\DoxyCodeLine{284 \{}
\DoxyCodeLine{285         uint16\_t val\_be = osmo\_htons(val);}
\DoxyCodeLine{286         \textcolor{keywordflow}{return} msgb\_tvlv\_put(msg, tag, 2, (\textcolor{keyword}{const} uint8\_t *)\&val\_be);}
\DoxyCodeLine{287 \}}
\DoxyCodeLine{288 }
\DoxyCodeLine{290 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tvlv\_put\_32be(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint32\_t val)}
\DoxyCodeLine{291 \{}
\DoxyCodeLine{292         uint32\_t val\_be = osmo\_htonl(val);}
\DoxyCodeLine{293         \textcolor{keywordflow}{return} msgb\_tvlv\_put(msg, tag, 4, (\textcolor{keyword}{const} uint8\_t *)\&val\_be);}
\DoxyCodeLine{294 \}}
\DoxyCodeLine{295 }
\DoxyCodeLine{297 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_vtvlv\_gan\_put(\textcolor{keyword}{struct} msgb *msg, uint16\_t tag,}
\DoxyCodeLine{298                                           uint16\_t len, \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{299 \{}
\DoxyCodeLine{300         uint8\_t *buf = msgb\_put(msg, VTVLV\_GAN\_GROSS\_LEN(tag, len));}
\DoxyCodeLine{301         \textcolor{keywordflow}{return} vtvlv\_gan\_put(buf, tag, len, val);}
\DoxyCodeLine{302 \}}
\DoxyCodeLine{303 }
\DoxyCodeLine{305 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_l16tv\_put(\textcolor{keyword}{struct} msgb *msg, uint16\_t len, uint8\_t tag,}
\DoxyCodeLine{306                                        \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{307 \{}
\DoxyCodeLine{308         uint8\_t *buf = msgb\_put(msg, L16TV\_GROSS\_LEN(len));}
\DoxyCodeLine{309 }
\DoxyCodeLine{310         *buf++ = len >> 8;}
\DoxyCodeLine{311         *buf++ = len \& 0xff;}
\DoxyCodeLine{312         *buf++ = tag;}
\DoxyCodeLine{313         memcpy(buf, val, len);}
\DoxyCodeLine{314         \textcolor{keywordflow}{return} buf + len;}
\DoxyCodeLine{315 \}}
\DoxyCodeLine{316 }
\DoxyCodeLine{318 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *v\_put(uint8\_t *buf, uint8\_t val)}
\DoxyCodeLine{319 \{}
\DoxyCodeLine{320         *buf++ = val;}
\DoxyCodeLine{321         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{322 \}}
\DoxyCodeLine{323 }
\DoxyCodeLine{325 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tv\_put(uint8\_t *buf, uint8\_t tag,}
\DoxyCodeLine{326                                 uint8\_t val)}
\DoxyCodeLine{327 \{}
\DoxyCodeLine{328         *buf++ = tag;}
\DoxyCodeLine{329         *buf++ = val;}
\DoxyCodeLine{330         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{331 \}}
\DoxyCodeLine{332 }
\DoxyCodeLine{334 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tv\_fixed\_put(uint8\_t *buf, uint8\_t tag,}
\DoxyCodeLine{335                                     \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} len, \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{336 \{}
\DoxyCodeLine{337         *buf++ = tag;}
\DoxyCodeLine{338         memcpy(buf, val, len);}
\DoxyCodeLine{339         \textcolor{keywordflow}{return} buf + len;}
\DoxyCodeLine{340 \}}
\DoxyCodeLine{341 }
\DoxyCodeLine{347 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *tv16\_put(uint8\_t *buf, uint8\_t tag,}
\DoxyCodeLine{348                                  uint16\_t val)}
\DoxyCodeLine{349 \{}
\DoxyCodeLine{350         *buf++ = tag;}
\DoxyCodeLine{351         *buf++ = val >> 8;}
\DoxyCodeLine{352         *buf++ = val \& 0xff;}
\DoxyCodeLine{353         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{354 \}}
\DoxyCodeLine{355 }
\DoxyCodeLine{358 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_lv\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t len, \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{359 \{}
\DoxyCodeLine{360         uint8\_t *buf = msgb\_put(msg, LV\_GROSS\_LEN(len));}
\DoxyCodeLine{361         \textcolor{keywordflow}{return} lv\_put(buf, len, val);}
\DoxyCodeLine{362 \}}
\DoxyCodeLine{363 }
\DoxyCodeLine{366 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tlv\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint8\_t len, \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{367 \{}
\DoxyCodeLine{368         uint8\_t *buf = msgb\_put(msg, TLV\_GROSS\_LEN(len));}
\DoxyCodeLine{369         \textcolor{keywordflow}{return} tlv\_put(buf, tag, len, val);}
\DoxyCodeLine{370 \}}
\DoxyCodeLine{371 }
\DoxyCodeLine{374 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tv\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint8\_t val)}
\DoxyCodeLine{375 \{}
\DoxyCodeLine{376         uint8\_t *buf = msgb\_put(msg, 2);}
\DoxyCodeLine{377         \textcolor{keywordflow}{return} tv\_put(buf, tag, val);}
\DoxyCodeLine{378 \}}
\DoxyCodeLine{379 }
\DoxyCodeLine{382 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tv\_fixed\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag,}
\DoxyCodeLine{383                                         \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} len, \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{384 \{}
\DoxyCodeLine{385         uint8\_t *buf = msgb\_put(msg, 1+len);}
\DoxyCodeLine{386         \textcolor{keywordflow}{return} tv\_fixed\_put(buf, tag, len, val);}
\DoxyCodeLine{387 \}}
\DoxyCodeLine{388 }
\DoxyCodeLine{391 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_v\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t val)}
\DoxyCodeLine{392 \{}
\DoxyCodeLine{393         uint8\_t *buf = msgb\_put(msg, 1);}
\DoxyCodeLine{394         \textcolor{keywordflow}{return} v\_put(buf, val);}
\DoxyCodeLine{395 \}}
\DoxyCodeLine{396 }
\DoxyCodeLine{399 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tl\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag)}
\DoxyCodeLine{400 \{}
\DoxyCodeLine{401         uint8\_t *len = msgb\_v\_put(msg, tag);}
\DoxyCodeLine{402 }
\DoxyCodeLine{403         \textcolor{comment}{/* reserve space for length, len points to this reserved space already */}}
\DoxyCodeLine{404         msgb\_v\_put(msg, 0);}
\DoxyCodeLine{405 }
\DoxyCodeLine{406         \textcolor{keywordflow}{return} len;}
\DoxyCodeLine{407 \}}
\DoxyCodeLine{408 }
\DoxyCodeLine{411 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tv16\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint16\_t val)}
\DoxyCodeLine{412 \{}
\DoxyCodeLine{413         uint8\_t *buf = msgb\_put(msg, 3);}
\DoxyCodeLine{414         \textcolor{keywordflow}{return} tv16\_put(buf, tag, val);}
\DoxyCodeLine{415 \}}
\DoxyCodeLine{416 }
\DoxyCodeLine{419 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tv32\_put(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint32\_t val)}
\DoxyCodeLine{420 \{}
\DoxyCodeLine{421         uint8\_t *buf = msgb\_put(msg, 1 + 4);}
\DoxyCodeLine{422         *buf++ = tag;}
\DoxyCodeLine{423         osmo\_store32be(val, buf);}
\DoxyCodeLine{424         \textcolor{keywordflow}{return} msg-\/>tail;}
\DoxyCodeLine{425 \}}
\DoxyCodeLine{426 }
\DoxyCodeLine{429 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tlv\_push(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint8\_t len, \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{430 \{}
\DoxyCodeLine{431         uint8\_t *buf = msgb\_push(msg, TLV\_GROSS\_LEN(len));}
\DoxyCodeLine{432         tlv\_put(buf, tag, len, val);}
\DoxyCodeLine{433         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{434 \}}
\DoxyCodeLine{435 }
\DoxyCodeLine{437 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tlv1\_push(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint8\_t val)}
\DoxyCodeLine{438 \{}
\DoxyCodeLine{439         \textcolor{keywordflow}{return} msgb\_tlv\_push(msg, tag, 1, \&val);}
\DoxyCodeLine{440 \}}
\DoxyCodeLine{441 }
\DoxyCodeLine{444 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tv\_push(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint8\_t val)}
\DoxyCodeLine{445 \{}
\DoxyCodeLine{446         uint8\_t *buf = msgb\_push(msg, 2);}
\DoxyCodeLine{447         tv\_put(buf, tag, val);}
\DoxyCodeLine{448         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{449 \}}
\DoxyCodeLine{450 }
\DoxyCodeLine{453 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tv16\_push(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint16\_t val)}
\DoxyCodeLine{454 \{}
\DoxyCodeLine{455         uint8\_t *buf = msgb\_push(msg, 3);}
\DoxyCodeLine{456         tv16\_put(buf, tag, val);}
\DoxyCodeLine{457         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{458 \}}
\DoxyCodeLine{459 }
\DoxyCodeLine{462 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tv32\_push(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint32\_t val)}
\DoxyCodeLine{463 \{}
\DoxyCodeLine{464         uint8\_t *buf = msgb\_push(msg, 5);}
\DoxyCodeLine{465         *buf++ = tag;}
\DoxyCodeLine{466         osmo\_store32be(val, buf);}
\DoxyCodeLine{467         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{468 \}}
\DoxyCodeLine{469 }
\DoxyCodeLine{472 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_tvlv\_push(\textcolor{keyword}{struct} msgb *msg, uint8\_t tag, uint16\_t len,}
\DoxyCodeLine{473                                       \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{474 \{}
\DoxyCodeLine{475         uint8\_t *buf = msgb\_push(msg, TVLV\_GROSS\_LEN(len));}
\DoxyCodeLine{476         tvlv\_put(buf, tag, len, val);}
\DoxyCodeLine{477         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{478 \}}
\DoxyCodeLine{479 }
\DoxyCodeLine{480 \textcolor{comment}{/* push (prepend) a vTvL header to a \(\backslash\)ref msgb}}
\DoxyCodeLine{481 \textcolor{comment}{ */}}
\DoxyCodeLine{482 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_vtvl\_gan\_push(\textcolor{keyword}{struct} msgb *msg, uint16\_t tag,}
\DoxyCodeLine{483                                            uint16\_t len)}
\DoxyCodeLine{484 \{}
\DoxyCodeLine{485         uint8\_t *buf = msgb\_push(msg, VTVL\_GAN\_GROSS\_LEN(tag, len));}
\DoxyCodeLine{486         vtvl\_gan\_put(buf, tag, len);}
\DoxyCodeLine{487         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{488 \}}
\DoxyCodeLine{489 }
\DoxyCodeLine{490 }
\DoxyCodeLine{491 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t *msgb\_vtvlv\_gan\_push(\textcolor{keyword}{struct} msgb *msg, uint16\_t tag,}
\DoxyCodeLine{492                                            uint16\_t len, \textcolor{keyword}{const} uint8\_t *val)}
\DoxyCodeLine{493 \{}
\DoxyCodeLine{494         uint8\_t *buf = msgb\_push(msg, VTVLV\_GAN\_GROSS\_LEN(tag, len));}
\DoxyCodeLine{495         vtvlv\_gan\_put(buf, tag, len, val);}
\DoxyCodeLine{496         \textcolor{keywordflow}{return} buf;}
\DoxyCodeLine{497 \}}
\DoxyCodeLine{498 }
\DoxyCodeLine{499 \textcolor{comment}{/* TLV parsing */}}
\DoxyCodeLine{500 }
\DoxyCodeLine{502 \textcolor{keyword}{struct }tlv\_p\_entry \{}
\DoxyCodeLine{503         uint16\_t len;                }
\DoxyCodeLine{504         \textcolor{keyword}{const} uint8\_t *val;  }
\DoxyCodeLine{505 \};}
\DoxyCodeLine{506 }
\DoxyCodeLine{508 \textcolor{keyword}{enum} tlv\_type \{}
\DoxyCodeLine{509         TLV\_TYPE\_NONE,             }
\DoxyCodeLine{510         TLV\_TYPE\_FIXED,           }
\DoxyCodeLine{511         TLV\_TYPE\_T,           }
\DoxyCodeLine{512         TLV\_TYPE\_TV,         }
\DoxyCodeLine{513         TLV\_TYPE\_TLV,               }
\DoxyCodeLine{514         TLV\_TYPE\_TL16V,           }
\DoxyCodeLine{515         TLV\_TYPE\_TvLV,             }
\DoxyCodeLine{516         TLV\_TYPE\_SINGLE\_TV,   }
\DoxyCodeLine{517         TLV\_TYPE\_vTvLV\_GAN,   }
\DoxyCodeLine{518 \};}
\DoxyCodeLine{519 }
\DoxyCodeLine{521 \textcolor{keyword}{struct }tlv\_def \{}
\DoxyCodeLine{522         \textcolor{keyword}{enum} tlv\_type type; }
\DoxyCodeLine{523         uint8\_t fixed\_len;     }
\DoxyCodeLine{524 \};}
\DoxyCodeLine{525 }
\DoxyCodeLine{527 \textcolor{keyword}{struct }tlv\_definition \{}
\DoxyCodeLine{528         \textcolor{keyword}{struct }tlv\_def def[256];}
\DoxyCodeLine{529 \};}
\DoxyCodeLine{530 }
\DoxyCodeLine{532 \textcolor{keyword}{struct }tlv\_parsed \{}
\DoxyCodeLine{533         \textcolor{keyword}{struct }tlv\_p\_entry lv[256];}
\DoxyCodeLine{534 \};}
\DoxyCodeLine{535 }
\DoxyCodeLine{536 \textcolor{keyword}{extern} \textcolor{keyword}{struct }tlv\_definition tvlv\_att\_def;}
\DoxyCodeLine{537 \textcolor{keyword}{extern} \textcolor{keyword}{struct }tlv\_definition vtvlv\_gan\_att\_def;}
\DoxyCodeLine{538 }
\DoxyCodeLine{539 \textcolor{keywordtype}{int} tlv\_parse\_one(uint8\_t *o\_tag, uint16\_t *o\_len, \textcolor{keyword}{const} uint8\_t **o\_val,}
\DoxyCodeLine{540                   \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_definition *def,}
\DoxyCodeLine{541                   \textcolor{keyword}{const} uint8\_t *buf, \textcolor{keywordtype}{int} buf\_len);}
\DoxyCodeLine{542 \textcolor{keywordtype}{int} tlv\_parse(\textcolor{keyword}{struct} tlv\_parsed *dec, \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_definition *def,}
\DoxyCodeLine{543               \textcolor{keyword}{const} uint8\_t *buf, \textcolor{keywordtype}{int} buf\_len, uint8\_t lv\_tag, uint8\_t lv\_tag2);}
\DoxyCodeLine{544 \textcolor{keywordtype}{int} tlv\_parse2(\textcolor{keyword}{struct} tlv\_parsed *dec, \textcolor{keywordtype}{int} dec\_multiples,}
\DoxyCodeLine{545                \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_definition *def, \textcolor{keyword}{const} uint8\_t *buf, \textcolor{keywordtype}{int} buf\_len,}
\DoxyCodeLine{546                uint8\_t lv\_tag, uint8\_t lv\_tag2);}
\DoxyCodeLine{547 \textcolor{comment}{/* take a master (src) tlv def and fill up all empty slots in 'dst' */}}
\DoxyCodeLine{548 \textcolor{keywordtype}{void} tlv\_def\_patch(\textcolor{keyword}{struct} tlv\_definition *dst, \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_definition *src);}
\DoxyCodeLine{549 }
\DoxyCodeLine{550 \textcolor{keywordtype}{int} tlv\_encode\_one(\textcolor{keyword}{struct} msgb *msg, \textcolor{keyword}{enum} tlv\_type type, uint8\_t tag,}
\DoxyCodeLine{551                    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} len, \textcolor{keyword}{const} uint8\_t *val);}
\DoxyCodeLine{552 \textcolor{keywordtype}{int} tlv\_encode(\textcolor{keyword}{struct} msgb *msg, \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_definition *def, \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp);}
\DoxyCodeLine{553 \textcolor{keywordtype}{int} tlv\_encode\_ordered(\textcolor{keyword}{struct} msgb *msg, \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_definition *def, \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp,}
\DoxyCodeLine{554                         \textcolor{keyword}{const} uint8\_t *tag\_order, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} tag\_order\_len);}
\DoxyCodeLine{555 }
\DoxyCodeLine{556 \textcolor{preprocessor}{\#define TLVP\_PRESENT(x, y)      (!!((x)-\/>lv[y].val))}}
\DoxyCodeLine{557 \textcolor{preprocessor}{\#define TLVP\_LEN(x, y)          (x)-\/>lv[y].len}}
\DoxyCodeLine{558 \textcolor{preprocessor}{\#define TLVP\_VAL(x, y)          (x)-\/>lv[y].val}}
\DoxyCodeLine{559 }
\DoxyCodeLine{560 \textcolor{preprocessor}{\#define TLVP\_PRES\_LEN(tp, tag, min\_len) \(\backslash\)}}
\DoxyCodeLine{561 \textcolor{preprocessor}{        (TLVP\_PRESENT(tp, tag) \&\& TLVP\_LEN(tp, tag) >= min\_len)}}
\DoxyCodeLine{562 }
\DoxyCodeLine{573 \textcolor{preprocessor}{\#define TLVP\_GET(\_tp, tag)      (TLVP\_PRESENT(\_tp, tag)? \&(\_tp)-\/>lv[tag] : NULL)}}
\DoxyCodeLine{574 }
\DoxyCodeLine{581 \textcolor{preprocessor}{\#define TLVP\_GET\_MINLEN(\_tp, tag, min\_len) \(\backslash\)}}
\DoxyCodeLine{582 \textcolor{preprocessor}{        (TLVP\_PRES\_LEN(\_tp, tag, min\_len)? \&(\_tp)-\/>lv[tag] : NULL)}}
\DoxyCodeLine{583 }
\DoxyCodeLine{590 \textcolor{preprocessor}{\#define TLVP\_VAL\_MINLEN(\_tp, tag, min\_len) \(\backslash\)}}
\DoxyCodeLine{591 \textcolor{preprocessor}{        (TLVP\_PRES\_LEN(\_tp, tag, min\_len)? (\_tp)-\/>lv[tag].val : NULL)}}
\DoxyCodeLine{592 }
\DoxyCodeLine{593 }
\DoxyCodeLine{600 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint8\_t tlvp\_val8(\textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp, uint8\_t tag, uint8\_t default\_val)}
\DoxyCodeLine{601 \{}
\DoxyCodeLine{602         \textcolor{keyword}{const} uint8\_t *res = TLVP\_VAL\_MINLEN(tp, tag, 1);}
\DoxyCodeLine{603 }
\DoxyCodeLine{604         \textcolor{keywordflow}{if} (res)}
\DoxyCodeLine{605                 \textcolor{keywordflow}{return} res[0];}
\DoxyCodeLine{606 }
\DoxyCodeLine{607         \textcolor{keywordflow}{return} default\_val;}
\DoxyCodeLine{608 \}}
\DoxyCodeLine{609 }
\DoxyCodeLine{615 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint16\_t tlvp\_val16\_unal(\textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp, \textcolor{keywordtype}{int} pos)}
\DoxyCodeLine{616 \{}
\DoxyCodeLine{617         uint16\_t res;}
\DoxyCodeLine{618         memcpy(\&res, TLVP\_VAL(tp, pos), \textcolor{keyword}{sizeof}(res));}
\DoxyCodeLine{619         \textcolor{keywordflow}{return} res;}
\DoxyCodeLine{620 \}}
\DoxyCodeLine{621 }
\DoxyCodeLine{627 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint32\_t tlvp\_val32\_unal(\textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp, \textcolor{keywordtype}{int} pos)}
\DoxyCodeLine{628 \{}
\DoxyCodeLine{629         uint32\_t res;}
\DoxyCodeLine{630         memcpy(\&res, TLVP\_VAL(tp, pos), \textcolor{keyword}{sizeof}(res));}
\DoxyCodeLine{631         \textcolor{keywordflow}{return} res;}
\DoxyCodeLine{632 \}}
\DoxyCodeLine{633 }
\DoxyCodeLine{639 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint16\_t tlvp\_val16be(\textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp, \textcolor{keywordtype}{int} pos)}
\DoxyCodeLine{640 \{}
\DoxyCodeLine{641         \textcolor{keywordflow}{return} osmo\_load16be(TLVP\_VAL(tp, pos));}
\DoxyCodeLine{642 \}}
\DoxyCodeLine{643 }
\DoxyCodeLine{649 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint32\_t tlvp\_val32be(\textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp, \textcolor{keywordtype}{int} pos)}
\DoxyCodeLine{650 \{}
\DoxyCodeLine{651         \textcolor{keywordflow}{return} osmo\_load32be(TLVP\_VAL(tp, pos));}
\DoxyCodeLine{652 \}}
\DoxyCodeLine{653 }
\DoxyCodeLine{654 }
\DoxyCodeLine{655 \textcolor{keyword}{struct }tlv\_parsed *osmo\_tlvp\_copy(\textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp\_orig, \textcolor{keywordtype}{void} *ctx);}
\DoxyCodeLine{656 \textcolor{keywordtype}{int} osmo\_tlvp\_merge(\textcolor{keyword}{struct} tlv\_parsed *dst, \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *src);}
\DoxyCodeLine{657 \textcolor{keywordtype}{int} osmo\_shift\_v\_fixed(uint8\_t **data, \textcolor{keywordtype}{size\_t} *data\_len,}
\DoxyCodeLine{658                        \textcolor{keywordtype}{size\_t} len, uint8\_t **value);}
\DoxyCodeLine{659 \textcolor{keywordtype}{int} osmo\_match\_shift\_tv\_fixed(uint8\_t **data, \textcolor{keywordtype}{size\_t} *data\_len,}
\DoxyCodeLine{660                               uint8\_t tag, \textcolor{keywordtype}{size\_t} len, uint8\_t **value);}
\DoxyCodeLine{661 \textcolor{keywordtype}{int} osmo\_shift\_tlv(uint8\_t **data, \textcolor{keywordtype}{size\_t} *data\_len,}
\DoxyCodeLine{662                    uint8\_t *tag, uint8\_t **value, \textcolor{keywordtype}{size\_t} *value\_len);}
\DoxyCodeLine{663 \textcolor{keywordtype}{int} osmo\_match\_shift\_tlv(uint8\_t **data, \textcolor{keywordtype}{size\_t} *data\_len,}
\DoxyCodeLine{664                    uint8\_t tag, uint8\_t **value, \textcolor{keywordtype}{size\_t} *value\_len);}
\DoxyCodeLine{665 \textcolor{keywordtype}{int} osmo\_shift\_lv(uint8\_t **data, \textcolor{keywordtype}{size\_t} *data\_len,}
\DoxyCodeLine{666                   uint8\_t **value, \textcolor{keywordtype}{size\_t} *value\_len);}
\DoxyCodeLine{667 }
\DoxyCodeLine{668 \textcolor{preprocessor}{\#define MSG\_DEF(name, mand\_ies, flags) \{ name, mand\_ies, ARRAY\_SIZE(mand\_ies), flags \}}}
\DoxyCodeLine{669 }
\DoxyCodeLine{670 \textcolor{keyword}{struct }osmo\_tlv\_prot\_msg\_def \{}
\DoxyCodeLine{672         \textcolor{keyword}{const} \textcolor{keywordtype}{char} *name;}
\DoxyCodeLine{674         \textcolor{keyword}{const} uint8\_t *mand\_ies;}
\DoxyCodeLine{676         uint8\_t mand\_count;}
\DoxyCodeLine{678         uint32\_t flags;}
\DoxyCodeLine{679 \};}
\DoxyCodeLine{680 \textcolor{keyword}{struct }osmo\_tlv\_prot\_ie\_def \{}
\DoxyCodeLine{682         uint16\_t min\_len;}
\DoxyCodeLine{684         \textcolor{keyword}{const} \textcolor{keywordtype}{char} *name;}
\DoxyCodeLine{685 \};}
\DoxyCodeLine{686 }
\DoxyCodeLine{688 \textcolor{keyword}{struct }osmo\_tlv\_prot\_def \{}
\DoxyCodeLine{690         \textcolor{keyword}{const} \textcolor{keywordtype}{char} *name;}
\DoxyCodeLine{692         \textcolor{keyword}{const} \textcolor{keyword}{struct }tlv\_definition *tlv\_def;}
\DoxyCodeLine{694         \textcolor{keyword}{struct }osmo\_tlv\_prot\_msg\_def msg\_def[256];}
\DoxyCodeLine{696         \textcolor{keyword}{struct }osmo\_tlv\_prot\_ie\_def ie\_def[256];}
\DoxyCodeLine{698         \textcolor{keyword}{const} \textcolor{keyword}{struct }value\_string *msgt\_names;}
\DoxyCodeLine{699 \};}
\DoxyCodeLine{700 }
\DoxyCodeLine{701 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_tlv\_prot\_msg\_name(\textcolor{keyword}{const} \textcolor{keyword}{struct} osmo\_tlv\_prot\_def *pdef, uint8\_t msg\_type);}
\DoxyCodeLine{702 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_tlv\_prot\_ie\_name(\textcolor{keyword}{const} \textcolor{keyword}{struct} osmo\_tlv\_prot\_def *pdef, uint8\_t iei);}
\DoxyCodeLine{703 }
\DoxyCodeLine{704 \textcolor{keywordtype}{int} osmo\_tlv\_prot\_validate\_tp(\textcolor{keyword}{const} \textcolor{keyword}{struct} osmo\_tlv\_prot\_def *pdef, uint8\_t msg\_type,}
\DoxyCodeLine{705                               \textcolor{keyword}{const} \textcolor{keyword}{struct} tlv\_parsed *tp, \textcolor{keywordtype}{int} log\_subsys, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *log\_pfx);}
\DoxyCodeLine{706 }
\DoxyCodeLine{707 \textcolor{keywordtype}{int} osmo\_tlv\_prot\_parse(\textcolor{keyword}{const} \textcolor{keyword}{struct} osmo\_tlv\_prot\_def *pdef,}
\DoxyCodeLine{708                         \textcolor{keyword}{struct} tlv\_parsed *dec, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} dec\_multiples, uint8\_t msg\_type,}
\DoxyCodeLine{709                         \textcolor{keyword}{const} uint8\_t *buf, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} buf\_len, uint8\_t lv\_tag, uint8\_t lv\_tag2,}
\DoxyCodeLine{710                         \textcolor{keywordtype}{int} log\_subsys, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *log\_pfx);}
\DoxyCodeLine{711 }
\DoxyCodeLine{712 \textcolor{keyword}{static} \textcolor{keyword}{inline} uint32\_t osmo\_tlv\_prot\_msgt\_flags(\textcolor{keyword}{const} \textcolor{keyword}{struct} osmo\_tlv\_prot\_def *pdef, uint8\_t msg\_type)}
\DoxyCodeLine{713 \{}
\DoxyCodeLine{714         \textcolor{keywordflow}{return} pdef-\/>msg\_def[msg\_type].flags;}
\DoxyCodeLine{715 \}}
\DoxyCodeLine{716 }
\DoxyCodeLine{717 }

\end{DoxyCode}
