mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-26 02:19:26 +01:00
ie: Adding IE builder support
These functions can be used to create IE TLV messages.
This commit is contained in:
parent
8cb16f41a8
commit
b90d914a3f
104
src/ie.c
104
src/ie.c
@ -74,3 +74,107 @@ bool ie_tlv_iter_next(struct ie_tlv_iter *iter)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TLV_HEADER_LEN 2
|
||||
|
||||
static bool ie_tlv_builder_init_recurse(struct ie_tlv_builder *builder,
|
||||
unsigned char *tlv, unsigned int size)
|
||||
{
|
||||
if (!builder)
|
||||
return false;
|
||||
|
||||
if (!tlv) {
|
||||
memset(builder->buf, 0, MAX_BUILDER_SIZE);
|
||||
builder->tlv = builder->buf;
|
||||
builder->max = MAX_BUILDER_SIZE;
|
||||
} else {
|
||||
builder->tlv = tlv;
|
||||
builder->max = size;
|
||||
}
|
||||
|
||||
builder->pos = 0;
|
||||
builder->parent = NULL;
|
||||
builder->tag = 0xffff;
|
||||
builder->len = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ie_tlv_builder_init(struct ie_tlv_builder *builder)
|
||||
{
|
||||
return ie_tlv_builder_init_recurse(builder, NULL, 0);
|
||||
}
|
||||
|
||||
static void ie_tlv_builder_write_header(struct ie_tlv_builder *builder)
|
||||
{
|
||||
unsigned char *tlv = builder->tlv + builder->pos;
|
||||
|
||||
tlv[0] = builder->tag;
|
||||
tlv[1] = builder->len;
|
||||
}
|
||||
|
||||
bool ie_tlv_builder_set_length(struct ie_tlv_builder *builder,
|
||||
unsigned int new_len)
|
||||
{
|
||||
unsigned int new_pos = builder->pos + TLV_HEADER_LEN + new_len;
|
||||
|
||||
if (new_pos > builder->max)
|
||||
return false;
|
||||
|
||||
if (builder->parent)
|
||||
ie_tlv_builder_set_length(builder->parent, new_pos);
|
||||
|
||||
builder->len = new_len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ie_tlv_builder_next(struct ie_tlv_builder *builder, unsigned int new_tag)
|
||||
{
|
||||
if (new_tag > 0xff)
|
||||
return false;
|
||||
|
||||
if (builder->tag != 0xffff) {
|
||||
ie_tlv_builder_write_header(builder);
|
||||
builder->pos += TLV_HEADER_LEN + builder->len;
|
||||
}
|
||||
|
||||
if (!ie_tlv_builder_set_length(builder, 0))
|
||||
return false;
|
||||
|
||||
builder->tag = new_tag;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char *ie_tlv_builder_get_data(struct ie_tlv_builder *builder)
|
||||
{
|
||||
return builder->tlv + TLV_HEADER_LEN + builder->pos;
|
||||
}
|
||||
|
||||
bool ie_tlv_builder_recurse(struct ie_tlv_builder *builder,
|
||||
struct ie_tlv_builder *recurse)
|
||||
{
|
||||
unsigned char *end = builder->buf + builder->max;
|
||||
unsigned char *data = ie_tlv_builder_get_data(builder);
|
||||
|
||||
if (!ie_tlv_builder_init_recurse(recurse, data, end - data))
|
||||
return false;
|
||||
|
||||
recurse->parent = builder;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ie_tlv_builder_finalize(struct ie_tlv_builder *builder,
|
||||
unsigned int *out_len)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
ie_tlv_builder_write_header(builder);
|
||||
|
||||
len = builder->pos + TLV_HEADER_LEN + builder->len;
|
||||
|
||||
if (out_len)
|
||||
*out_len = len;
|
||||
}
|
||||
|
23
src/ie.h
23
src/ie.h
@ -163,9 +163,32 @@ struct ie_tlv_iter {
|
||||
const unsigned char *data;
|
||||
};
|
||||
|
||||
#define MAX_BUILDER_SIZE (8 * 1024)
|
||||
|
||||
struct ie_tlv_builder {
|
||||
unsigned char buf[MAX_BUILDER_SIZE];
|
||||
|
||||
unsigned int max;
|
||||
unsigned int pos;
|
||||
unsigned char *tlv;
|
||||
struct ie_tlv_builder *parent;
|
||||
|
||||
unsigned int tag;
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
void ie_tlv_iter_init(struct ie_tlv_iter *iter, const unsigned char *tlv,
|
||||
unsigned int len);
|
||||
void ie_tlv_iter_recurse(struct ie_tlv_iter *iter,
|
||||
struct ie_tlv_iter *recurse);
|
||||
unsigned int ie_tlv_iter_get_tag(struct ie_tlv_iter *iter);
|
||||
bool ie_tlv_iter_next(struct ie_tlv_iter *iter);
|
||||
bool ie_tlv_builder_init(struct ie_tlv_builder *builder);
|
||||
bool ie_tlv_builder_set_length(struct ie_tlv_builder *builder,
|
||||
unsigned int new_len);
|
||||
bool ie_tlv_builder_next(struct ie_tlv_builder *builder, unsigned int new_tag);
|
||||
unsigned char *ie_tlv_builder_get_data(struct ie_tlv_builder *builder);
|
||||
bool ie_tlv_builder_recurse(struct ie_tlv_builder *builder,
|
||||
struct ie_tlv_builder *recurse);
|
||||
void ie_tlv_builder_finalize(struct ie_tlv_builder *builder,
|
||||
unsigned int *out_len);
|
||||
|
Loading…
Reference in New Issue
Block a user