@@ -68,6 +68,11 @@ struct mgmt_notify {
void *user_data;
};
+struct mgmt_tlv_list {
+ struct queue *tlv_queue;
+ uint16_t size;
+};
+
static void destroy_request(void *data)
{
struct mgmt_request *request = data;
@@ -558,6 +563,95 @@ static struct mgmt_request *create_request(uint16_t opcode, uint16_t index,
return request;
}
+struct mgmt_tlv_list *mgmt_tlv_list_new(void)
+{
+ struct mgmt_tlv_list *tlv_list = new0(struct mgmt_tlv_list, 1);
+
+ tlv_list->tlv_queue = queue_new();
+ tlv_list->size = 0;
+
+ return tlv_list;
+}
+
+static struct mgmt_tlv *mgmt_tlv_new(uint16_t type, uint8_t length,
+ void *value)
+{
+ struct mgmt_tlv *entry = malloc(sizeof(*entry) + length);
+
+ if (!entry)
+ return NULL;
+
+ entry->type = htobs(type);
+ entry->length = length;
+ memcpy(entry->value, value, length);
+
+ return entry;
+}
+
+static void mgmt_tlv_free(struct mgmt_tlv *entry)
+{
+ free(entry);
+}
+
+void mgmt_tlv_list_free(struct mgmt_tlv_list *tlv_list)
+{
+ queue_destroy(tlv_list->tlv_queue, NULL);
+ free(tlv_list);
+}
+
+bool mgmt_tlv_add(struct mgmt_tlv_list *tlv_list, uint16_t type, uint8_t length,
+ void *value)
+{
+ struct mgmt_tlv *entry = mgmt_tlv_new(type, length, value);
+
+ if (!entry)
+ return false;
+
+ if (!queue_push_tail(tlv_list->tlv_queue, entry)) {
+ mgmt_tlv_free(entry);
+ return false;
+ }
+
+ tlv_list->size += sizeof(*entry) + entry->length;
+ return true;
+}
+
+static void mgmt_tlv_to_buf(void *data, void *user_data)
+{
+ struct mgmt_tlv *entry = data;
+ uint8_t **buf_ptr = user_data;
+ size_t entry_size = sizeof(*entry) + entry->length;
+
+ memcpy(*buf_ptr, entry, entry_size);
+ *buf_ptr += entry_size;
+}
+
+unsigned int mgmt_send_tlv(struct mgmt *mgmt, uint16_t opcode, uint16_t index,
+ struct mgmt_tlv_list *tlv_list,
+ mgmt_request_func_t callback,
+ void *user_data, mgmt_destroy_func_t destroy)
+{
+ uint8_t *buf, *buf_ptr;
+ unsigned int ret;
+
+ if (!tlv_list)
+ return 0;
+
+ buf = malloc(tlv_list->size);
+
+ if (!buf)
+ return 0;
+
+ buf_ptr = buf;
+
+ queue_foreach(tlv_list->tlv_queue, mgmt_tlv_to_buf, &buf_ptr);
+
+ ret = mgmt_send(mgmt, opcode, index, tlv_list->size, (void *)buf,
+ callback, user_data, destroy);
+ free(buf);
+ return ret;
+}
+
unsigned int mgmt_send(struct mgmt *mgmt, uint16_t opcode, uint16_t index,
uint16_t length, const void *param,
mgmt_request_func_t callback,
@@ -16,6 +16,7 @@
typedef void (*mgmt_destroy_func_t)(void *user_data);
struct mgmt;
+struct mgmt_tlv_list;
struct mgmt *mgmt_new(int fd);
struct mgmt *mgmt_new_default(void);
@@ -33,6 +34,14 @@ bool mgmt_set_close_on_unref(struct mgmt *mgmt, bool do_close);
typedef void (*mgmt_request_func_t)(uint8_t status, uint16_t length,
const void *param, void *user_data);
+struct mgmt_tlv_list *mgmt_tlv_list_new(void);
+void mgmt_tlv_list_free(struct mgmt_tlv_list *tlv_list);
+bool mgmt_tlv_add(struct mgmt_tlv_list *tlv_list, uint16_t type, uint8_t length,
+ void *value);
+unsigned int mgmt_send_tlv(struct mgmt *mgmt, uint16_t opcode, uint16_t index,
+ struct mgmt_tlv_list *tlv_list,
+ mgmt_request_func_t callback,
+ void *user_data, mgmt_destroy_func_t destroy);
unsigned int mgmt_send(struct mgmt *mgmt, uint16_t opcode, uint16_t index,
uint16_t length, const void *param,
mgmt_request_func_t callback,