mgmt: Add support of mgmt TLV API
authorHoward Chung <howardchung@google.com>
Wed, 28 Oct 2020 11:52:46 +0000 (19:52 +0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:33 +0000 (19:08 +0530)
This adds API to send multiple TLVs to kernel, it is useful for
mgmt set system config command.

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/shared/mgmt.c
src/shared/mgmt.h

index b327b40..9ea9974 100755 (executable)
@@ -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,
index 6608faa..74b8bef 100755 (executable)
@@ -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,