From df5f58c125df84478e95513aec751756fccd7037 Mon Sep 17 00:00:00 2001
From: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
Date: Sun, 23 Mar 2025 22:39:15 +0530
Subject: [PATCH 1/6] qosmngr: transform from dm_plugin to unified daemon for
 bbfdm

---
 Makefile                      | 26 ++++------------
 bbf_plugin/Makefile           | 26 ----------------
 bbf_plugin/qos_bbf_vendor.c   | 48 ------------------------------
 bbf_plugin/qos_bbf_vendor.h   | 20 -------------
 include/qosmngr.h             |  4 ++-
 src/main.c                    | 30 +++++++++++++++++--
 {bbf_plugin => src}/qos_bbf.c | 56 +++++++++++++++++++++++++++++------
 {bbf_plugin => src}/qos_bbf.h |  0
 src/qosmngr.c                 | 33 ++++++++++++---------
 9 files changed, 102 insertions(+), 141 deletions(-)
 delete mode 100644 bbf_plugin/Makefile
 delete mode 100644 bbf_plugin/qos_bbf_vendor.c
 delete mode 100644 bbf_plugin/qos_bbf_vendor.h
 rename {bbf_plugin => src}/qos_bbf.c (97%)
 rename {bbf_plugin => src}/qos_bbf.h (100%)

diff --git a/Makefile b/Makefile
index d6e8359..172212b 100644
--- a/Makefile
+++ b/Makefile
@@ -3,19 +3,15 @@ include common.mk
 
 -include Makefile.diag.inc
 
-QOSMNGR_LIB=libqosmngr.so
-PLUGIN = bbf_plugin
-
 GCOV=gcov
 SRC_DIR = src
 
 CODECOVERAGE_SRC = $(addprefix $(SRC_DIR)/, qosmngr.c )
 PROG = $(PROJECT_TOPLEVEL)/qosmngr
-SHARED_LIB = $(PROJECT_TOPLEVEL)/libqosmngr.so
-OBJS = $(addprefix $(SRC_DIR)/, main.o qosmngr.o )
+OBJS = $(addprefix $(SRC_DIR)/, main.o qosmngr.o qos_bbf.o)
 
 PROG_CFLAGS = $(CFLAGS) -I$(INCLUDE_DIR) $(DIAG_CFLAGS) -Werror -fstrict-aliasing
-PROG_LDFLAGS = $(LDFLAGS)
+PROG_LDFLAGS = $(LDFLAGS) -lbbfdm-ubus -lbbfdm-api
 PROG_LIBS = $(COMMON_LDFLAGS) -lgcov
 
 # MUSL has the following issue in snprintf, so it is ignored:
@@ -23,18 +19,10 @@ PROG_CFLAGS += -Wno-format-nonliteral
 
 .PHONY: all clean
 
-all: version $(PLUGIN) $(PROG)
-
-$(PLUGIN): $(OBJS)
-	$(MAKE) -C ./bbf_plugin
-
-$(PROG): $(INCLUDE_DIR)/version.h $(OBJS)
-	$(CC) $(PROG_LDFLAGS) -o $@ $^ $(PROG_LIBS)
+all: version $(PROG)
 
-${QOSMNGR_LIB}:
-	$(CC) $(PROG_LDFLAGS) -shared -o $@ $^ $(PROG_LIBS)
-
-$(SHARED_LIB): $(INCLUDE_DIR)/version.h $(OBJS)
+$(PROG): $(OBJS)
+	$(CC) -o $@ $^ $(PROG_LDFLAGS) $(PROG_LIBS)
 
 version: $(INCLUDE_DIR)/version.h
 
@@ -47,8 +35,6 @@ $(INCLUDE_DIR)/version.h: $(PROJECT_TOPLEVEL)/VERSION
 	echo "const char *qosmngr_xtra_version = \"$$xver$$dirty\";" >> $@; \
 	)
 
-test: ${QOSMNGR_LIB}
-
 coverage: CFLAGS += -g -O0 -fprofile-arcs -ftest-coverage -fPIC
 coverage: LDFLAGS += --coverage
 coverage: test $(PROG)
@@ -61,7 +47,7 @@ functional-test: test
 	$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
 
 clean:
-	rm -f *.o $(SHARED_LIB) $(PROG) $(INCLUDE_DIR)/version.h
+	rm -f *.o $(PROG) $(INCLUDE_DIR)/version.h
 	rm -f *.xml *.html
 	find -name '*.gcda' -exec rm {} -fv \;
 	find -name '*.gcno' -exec rm {} -fv \;
diff --git a/bbf_plugin/Makefile b/bbf_plugin/Makefile
deleted file mode 100644
index e170fd1..0000000
--- a/bbf_plugin/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-LIB_QOS_BBF := libqos_bbf.so
-LIB_QOS_BBF_VENDOR := libqos_vendor_bbf.so
-
-OBJS  := qos_bbf.o
-OBJS_VENDOR  := qos_bbf_vendor.o
-
-LIB_CFLAGS = $(CFLAGS) -Wall -Werror
-LIB_LDFLAGS = $(LDFLAGS)
-FPIC := -fPIC
-
-.PHONY: all
-
-%.o: %.c
-	$(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $<
-
-all: $(LIB_QOS_BBF) $(LIB_QOS_BBF_VENDOR)
-
-$(LIB_QOS_BBF): $(OBJS)
-	$(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
-
-$(LIB_QOS_BBF_VENDOR): $(OBJS_VENDOR)
-	$(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
-
-clean:
-	rm -f *.o $(LIB_QOS_BBF) $(LIB_QOS_BBF_VENDOR)
-
diff --git a/bbf_plugin/qos_bbf_vendor.c b/bbf_plugin/qos_bbf_vendor.c
deleted file mode 100644
index 07c41e1..0000000
--- a/bbf_plugin/qos_bbf_vendor.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2024 iopsys Software Solutions AB
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- *	Author: Rohit Topno <r.topno@gxgroup.eu>
- */
-
-#include "qos_bbf_vendor.h"
-
-/*************************************************************
- * GET & SET PARAM
-*************************************************************/
-static int get_QoSClassification_VLANIDMark(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
-{
-	*value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "vid_mark", "-1");
-	return 0;
-}
-
-static int set_QoSClassification_VLANIDMark(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
-{
-	switch (action)	{
-	case VALUECHECK:
-		if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1",NULL}}, 1))
-			return FAULT_9007;
-		break;
-	case VALUESET:
-		dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "vid_mark", value);
-		break;
-	}
-	return 0;
-}
-
-/* ********** DynamicObj ********** */
-DM_MAP_OBJ tDynamicObj[] = {
-/* parentobj, nextobject, parameter */
-{"Device.QoS.Classification.{i}.", NULL, tQoSClassificationParams},
-{0}
-};
-
-/* *** Device.QoS.Classification.{i}. *** */
-DMLEAF tQoSClassificationParams[] = {
-/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
-{BBF_VENDOR_PREFIX"VLANIDMark", &DMWRITE, DMT_UNINT, get_QoSClassification_VLANIDMark, set_QoSClassification_VLANIDMark, BBFDM_BOTH},
-{0}
-};
diff --git a/bbf_plugin/qos_bbf_vendor.h b/bbf_plugin/qos_bbf_vendor.h
deleted file mode 100644
index b5eecf4..0000000
--- a/bbf_plugin/qos_bbf_vendor.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-/*
- * Copyright (C) 2024 iopsys Software Solutions AB
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- *	Author: Rohit Topno <r.topno@gxgroup.eu>
- *
- */
-
-#ifndef __IOPSYS_QOS_H
-#define __IOPSYS_QOS_H
-
-#include "libbbfdm-api/dmcommon.h"
-
-extern DMLEAF tQoSClassificationParams[];
-
-#endif //__IOPSYS_QOS_H
diff --git a/include/qosmngr.h b/include/qosmngr.h
index d745993..b64c21c 100644
--- a/include/qosmngr.h
+++ b/include/qosmngr.h
@@ -63,8 +63,10 @@ struct qos_queue {
 	struct qos_queue_config config;
 };
 
+int init_qstat(void);
 int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 		       struct ubus_request_data *req, const char *method,
 		       struct blob_attr *msg);
-
+int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
+				char *ifname, int qid);
 #endif /* QOSMNGR_H */
diff --git a/src/main.c b/src/main.c
index 68ffc63..bed269a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,7 +2,7 @@
 /*
  * main.c - qosmngr's boilerplate and entry point
  *
- * Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
+ * Copyright (C) 2020-2025 iopsys Software Solutions AB. All rights reserved.
  *
  * Author: Oskar Viljasaar <oskar.viljasaar@iopsys.eu>
  *
@@ -25,13 +25,18 @@
 #include <stdlib.h>
 
 #include <libubus.h>
+#include <libbbfdm-ubus/bbfdm-ubus.h>
 
 #include "qosmngr.h"
 #include "version.h"
 
+#include "qos_bbf.h"
+
 const char *ubus_socket;
 
 struct ubus_context *ctx = NULL;
+extern DM_MAP_OBJ tDynamicObj[];
+static struct bbfdm_context bbfdm_ctx = {0};
 
 const struct blobmsg_policy get_status_policy[NUM_QOS_POLICY] = {
       [QOS_POLICY_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
@@ -90,12 +95,19 @@ int main(int argc, char **argv)
 	int ret;
 	int ch;
 	int num_of_q = QOS_MIN_Q_NUM_PER_PORT;
+        int log_level = 6; // default LOG_INFO
+
 
 	/* Logging to syslog */
 	openlog("qosmngr", LOG_PID|LOG_CONS, LOG_LOCAL1);
 
-	while ((ch = getopt(argc, argv, "vsq:e:")) != -1) {
+	while ((ch = getopt(argc, argv, "lvsq:e:")) != -1) {
 		switch (ch) {
+		case 'l':
+			log_level = (int)strtoul(optarg, NULL, 10);
+			if (log_level < 0 || log_level > 7)
+				log_level = 6;
+			break;
 		case 'v':
 			qosmngr_version();
 			exit(0);
@@ -127,10 +139,22 @@ int main(int argc, char **argv)
 	if (ret)
 		goto out;
 
+        memset(&bbfdm_ctx, 0, sizeof(struct bbfdm_context));
+        bbfdm_ubus_set_service_name(&bbfdm_ctx, "qosmngr");
+        bbfdm_ubus_set_log_level(log_level);
+        bbfdm_ubus_load_data_model(tDynamicObj);
+
+	if (bbfdm_ubus_regiter_init(&bbfdm_ctx)) {
+		syslog(LOG_ERR, "Failed to register ubus");
+		goto out;
+	}
+
+	init_qstat();
+
 	/* Main loop of qosmngr */
 	uloop_run();
-
  out:
+	bbfdm_ubus_regiter_free(&bbfdm_ctx);;
 	ubus_free(ctx);
 	uloop_done();
 
diff --git a/bbf_plugin/qos_bbf.c b/src/qos_bbf.c
similarity index 97%
rename from bbf_plugin/qos_bbf.c
rename to src/qos_bbf.c
index 4b4ca12..49fad34 100644
--- a/bbf_plugin/qos_bbf.c
+++ b/src/qos_bbf.c
@@ -11,6 +11,8 @@
 
 #include "qos_bbf.h"
 #include "libbbfdm_api.h"
+#include "qosmngr.h"
+
 #define PROTOCOLS_FILE "/etc/protocols"
 
 /*************************************************************
@@ -73,7 +75,7 @@ static unsigned long qos_get_new_order(void)
 
 	uci_foreach_sections("qos", "classify", s) {
 		dmuci_get_value_by_section_string(s, "order", &order);
-		unsigned long order_tol = DM_STRTOL(order);
+		unsigned long order_tol = DM_STRTOUL(order);
 		if (order_tol > max)
 			max = order_tol;
 	}
@@ -99,11 +101,11 @@ static void qos_update_order(const char *order, bool is_del)
 {
 	struct uci_section *classify_s = NULL;
 	char *curr_order = NULL;
-	unsigned long order_tol = DM_STRTOL(order);
+	unsigned long order_tol = DM_STRTOUL(order);
 
 	uci_foreach_sections("qos", "classify", classify_s) {
 		dmuci_get_value_by_section_string(classify_s, "order", &curr_order);
-		unsigned long curr_order_tol = DM_STRTOL(curr_order);
+		unsigned long curr_order_tol = DM_STRTOUL(curr_order);
 		if (curr_order_tol >= order_tol) {
 			char new_order[16] = {0};
 
@@ -1347,6 +1349,26 @@ static int set_QoSClassification_Policer(char *refparam, struct dmctx *ctx, void
 	return 0;
 }
 
+static int get_QoSClassification_VLANIDMark(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	*value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "vid_mark", "-1");
+	return 0;
+}
+
+static int set_QoSClassification_VLANIDMark(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+	switch (action)	{
+	case VALUECHECK:
+		if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1",NULL}}, 1))
+			return FAULT_9007;
+		break;
+	case VALUESET:
+		dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "vid_mark", value);
+		break;
+	}
+	return 0;
+}
+
 static int get_QoSPolicer_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
 	*value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "enable", "1");
@@ -1846,15 +1868,30 @@ static int get_QoSQueueStats_value(void *data, char *option, char **value)
 	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "queue", &queue_link);
 	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "interface", &intf_link);
 
-	if (queue_link && *queue_link && intf_link && *intf_link) {
-		json_object *res = NULL;
+	if (queue_link && *queue_link && DM_STRLEN(queue_link) > 2 && intf_link && *intf_link) {
 		char queue_id[8] = {0};
 
 		snprintf(queue_id, sizeof(queue_id), "%c", queue_link[2]);
-		dmubus_call("qos", "queue_stats", UBUS_ARGS{{"ifname", intf_link, String}, {"qid", queue_id, Integer}}, 2, &res);
-		DM_ASSERT(res, *value = "0");
-		json_object *queue_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "queues");
-		*value = dmjson_get_value(queue_obj, 1, option);
+		int qid = (int) DM_STRTOL(queue_id);
+	        struct qos_stats stats = {0};
+
+		if (!prepare_stats_blob(NULL, &stats, NULL, intf_link, qid)) {
+			char val_buf[65] = {0};
+
+			if (!DM_STRNCMP(option, "tx_packets", DM_STRLEN("tx_packets"))) {
+				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_packets);
+				*value = dmstrdup(val_buf);
+			} else if (!DM_STRNCMP(option, "tx_bytes", DM_STRLEN("tx_bytes"))) {
+				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_bytes);
+				*value = dmstrdup(val_buf);
+			} else if (!DM_STRNCMP(option, "tx_dropped_packets", DM_STRLEN("tx_dropped_packets"))) {
+				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_dropped_packets);
+				*value = dmstrdup(val_buf);
+			} else if (!DM_STRNCMP(option, "tx_dropped_bytes", DM_STRLEN("tx_dropped_bytes"))) {
+				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_dropped_bytes);
+				*value = dmstrdup(val_buf);
+			}
+		}
 	}
 	return 0;
 }
@@ -2108,6 +2145,7 @@ DMLEAF tQoSClassificationParams[] = {
 {"TrafficClass", &DMWRITE, DMT_INT, get_QoSClassification_TrafficClass, set_QoSClassification_TrafficClass, BBFDM_BOTH},
 {"Policer", &DMWRITE, DMT_STRING, get_QoSClassification_Policer, set_QoSClassification_Policer, BBFDM_BOTH},
 //{"App", &DMWRITE, DMT_STRING, get_QoSClassification_App, set_QoSClassification_App, BBFDM_BOTH},
+{BBF_VENDOR_PREFIX"VLANIDMark", &DMWRITE, DMT_UNINT, get_QoSClassification_VLANIDMark, set_QoSClassification_VLANIDMark, BBFDM_BOTH},
 {0}
 };
 
diff --git a/bbf_plugin/qos_bbf.h b/src/qos_bbf.h
similarity index 100%
rename from bbf_plugin/qos_bbf.h
rename to src/qos_bbf.h
diff --git a/src/qosmngr.c b/src/qosmngr.c
index 4c05a3f..c5250fa 100644
--- a/src/qosmngr.c
+++ b/src/qosmngr.c
@@ -150,7 +150,7 @@ static int init_interface(const char *ifname, size_t index)
  *  @param none
  *  retrun integer value 0 on success and -1 on failure
  */
-static int init_qstat(void)
+int init_qstat(void)
 {
 	int ret = 0;
 
@@ -299,6 +299,7 @@ static int init_qstat(void)
 		ret = init_interface(json_object_get_string(wan_device), i);
 
 	json_object_put(board_json);
+	init_flag = 0;
 
 free_and_return:
 	free(buffer);
@@ -313,9 +314,9 @@ free_and_return:
  *  @param dd output parameter pointer to void used for blob buffer array elements
  *  @param ifname input parameter pointer to char for which to get stats
  *  @param qid input parameter integer queue identifier for which to get stats
- *  retrun integer value 0 on success and -1 on failure
+ *  return integer value 0 on success and -1 on failure
  */
-static int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
+int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
 				char *ifname, int qid)
 {
 	int index;
@@ -332,8 +333,8 @@ static int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void
 
 	index = get_interface_index(ifname);
 	if (index < 0 || index >= interface_count) {
-		syslog(LOG_ERR, "Invalid interface index %d (out of %zu)",
-		       index, interface_count);
+		syslog(LOG_ERR, "Invalid interface index %d (out of %zu) for interface %s",
+		       index, interface_count, ifname);
 		return -1;
 	}
 
@@ -358,19 +359,24 @@ static int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void
 		q_stat->tx_bytes += stats->tx_bytes;
 		q_stat->tx_dropped_packets += stats->tx_dropped_packets;
 		q_stat->tx_dropped_bytes += stats->tx_dropped_bytes;
+
+		// update the contents so the caller gets latest data
+		memcpy(stats, q_stat, sizeof(struct qos_stats));
 	}
 
-	dd = blobmsg_open_table(b, "");
+	if (b) {
+		dd = blobmsg_open_table(b, "");
 
-	blobmsg_add_string(b, "iface", ifname);
-	blobmsg_add_u32(b, "qid", (uint32_t)qid);
-        blobmsg_add_u64(b, "tx_packets", (uint64_t)q_stat->tx_packets);
-        blobmsg_add_u64(b, "tx_bytes", (uint64_t)q_stat->tx_bytes);
-        blobmsg_add_u64(b, "tx_dropped_packets", (uint64_t)q_stat->tx_dropped_packets);
-        blobmsg_add_u64(b, "tx_dropped_bytes", (uint64_t)q_stat->tx_dropped_bytes);
+		blobmsg_add_string(b, "iface", ifname);
+		blobmsg_add_u32(b, "qid", (uint32_t)qid);
+	        blobmsg_add_u64(b, "tx_packets", (uint64_t)q_stat->tx_packets);
+	        blobmsg_add_u64(b, "tx_bytes", (uint64_t)q_stat->tx_bytes);
+        	blobmsg_add_u64(b, "tx_dropped_packets", (uint64_t)q_stat->tx_dropped_packets);
+	        blobmsg_add_u64(b, "tx_dropped_bytes", (uint64_t)q_stat->tx_dropped_bytes);
 
 
-	blobmsg_close_table(b, dd);
+		blobmsg_close_table(b, dd);
+	}
 
 	return ret;
 }
@@ -544,7 +550,6 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 			return ret;
 		}
 		syslog(LOG_INFO, "Initialized gobal q_stat successfully");
-		init_flag = 0;
 	}
 
 	blob_buf_init(&b, 0);
-- 
GitLab


From 441602943935a597441ee3e33da44025b992928b Mon Sep 17 00:00:00 2001
From: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
Date: Mon, 24 Mar 2025 20:28:31 +0530
Subject: [PATCH 2/6] qosmngr: correctly process EtherType between hex and
 decimal

---
 Makefile      |  6 ++++--
 src/qos_bbf.c | 15 ++++++++++++++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 172212b..1593044 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@ PROG_CFLAGS += -Wno-format-nonliteral
 
 all: version $(PROG)
 
-$(PROG): $(OBJS)
+$(PROG): $(INCLUDE_DIR)/version.h $(OBJS)
 	$(CC) -o $@ $^ $(PROG_LDFLAGS) $(PROG_LIBS)
 
 version: $(INCLUDE_DIR)/version.h
@@ -35,7 +35,9 @@ $(INCLUDE_DIR)/version.h: $(PROJECT_TOPLEVEL)/VERSION
 	echo "const char *qosmngr_xtra_version = \"$$xver$$dirty\";" >> $@; \
 	)
 
-coverage: CFLAGS += -g -O0 -fprofile-arcs -ftest-coverage -fPIC
+test: $(PROG)
+
+coverage: CFLAGS += -g -O0 -fprofile-arcs -ftest-coverage -fPIC -DBBF_VENDOR_PREFIX='"X_IOWRT_EU"'
 coverage: LDFLAGS += --coverage
 coverage: test $(PROG)
 	$(foreach testprog, $(CODECOVERAGE_SRC), $(GCOV) $(testprog);)
diff --git a/src/qos_bbf.c b/src/qos_bbf.c
index 49fad34..e35b4c1 100644
--- a/src/qos_bbf.c
+++ b/src/qos_bbf.c
@@ -948,6 +948,13 @@ static int set_QoSClassification_DestMACAddress(char *refparam, struct dmctx *ct
 static int get_QoSClassification_Ethertype(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
 	*value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "ethertype", "-1");
+	// if value is not -1
+	if (DM_STRNCMP(*value, "-1", DM_STRLEN("-1"))) {
+		char *endptr = NULL;
+		long ethertype = strtol(*value, &endptr, 16);
+		dmasprintf(value, "%ld", ethertype);
+	}
+
 	return 0;
 }
 
@@ -959,7 +966,13 @@ static int set_QoSClassification_Ethertype(char *refparam, struct dmctx *ctx, vo
 			return FAULT_9007;
 		break;
 	case VALUESET:
-		dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "ethertype", value);
+		char *hex_str = NULL;
+		char *endptr;
+		long ethertype = strtol(value, &endptr, 10);
+
+		dmasprintf(&hex_str, "0x%04X", (unsigned int)ethertype);
+
+		dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "ethertype", hex_str);
 		break;
 	}
 	return 0;
-- 
GitLab


From bc98d77fb606f4901448b1ed1252539d880c7a30 Mon Sep 17 00:00:00 2001
From: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
Date: Tue, 25 Mar 2025 20:00:33 +0530
Subject: [PATCH 3/6] qosmngr: make qos ubus object conditional on compilation
 flag

---
 src/main.c    | 33 +++++++++++--------
 src/qos_bbf.c | 89 ++++++++++++++++++++++++++++-----------------------
 src/qosmngr.c |  5 +--
 3 files changed, 72 insertions(+), 55 deletions(-)

diff --git a/src/main.c b/src/main.c
index bed269a..0d85e90 100644
--- a/src/main.c
+++ b/src/main.c
@@ -38,6 +38,7 @@ struct ubus_context *ctx = NULL;
 extern DM_MAP_OBJ tDynamicObj[];
 static struct bbfdm_context bbfdm_ctx = {0};
 
+#ifdef UBUS_SUPPORT
 const struct blobmsg_policy get_status_policy[NUM_QOS_POLICY] = {
       [QOS_POLICY_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
       [QOS_POLICY_QID] = { .name = "qid", .type = BLOBMSG_TYPE_INT32},
@@ -57,16 +58,6 @@ static struct ubus_object test_object = {
         .n_methods = ARRAY_SIZE(qos_methods),
 };
 
-/**
- *  To get the qosmngr version
- *  @param : none
- *  return : none
- */
-void qosmngr_version(void)
-{
-	syslog(LOG_ERR, "version       : %s.%s\n", qosmngr_base_version, qosmngr_xtra_version);
-}
-
 /**
  *  To expose the qosmngr object on ubus i.e., qos with method queue_stats
  *  @param context input parameter pointer to ubus context
@@ -83,6 +74,17 @@ static int qosmngr_publish_object(struct ubus_context *context)
 
 	return ret;
 }
+#endif
+
+/**
+ *  To get the qosmngr version
+ *  @param : none
+ *  return : none
+ */
+void qosmngr_version(void)
+{
+	syslog(LOG_ERR, "version       : %s.%s\n", qosmngr_base_version, qosmngr_xtra_version);
+}
 
 /**
  *  Main function for qosmngr, everything starts here
@@ -92,7 +94,6 @@ static int qosmngr_publish_object(struct ubus_context *context)
  */
 int main(int argc, char **argv)
 {
-	int ret;
 	int ch;
 	int num_of_q = QOS_MIN_Q_NUM_PER_PORT;
         int log_level = 6; // default LOG_INFO
@@ -104,7 +105,10 @@ int main(int argc, char **argv)
 	while ((ch = getopt(argc, argv, "lvsq:e:")) != -1) {
 		switch (ch) {
 		case 'l':
-			log_level = (int)strtoul(optarg, NULL, 10);
+			if (optarg) {
+				log_level = (int)strtoul(optarg, NULL, 10);
+			}
+
 			if (log_level < 0 || log_level > 7)
 				log_level = 6;
 			break;
@@ -135,9 +139,12 @@ int main(int argc, char **argv)
 
 	ubus_add_uloop(ctx);
 
+#ifdef UBUS_SUPPORT
+	int ret;
 	ret = qosmngr_publish_object(ctx);
 	if (ret)
 		goto out;
+#endif
 
         memset(&bbfdm_ctx, 0, sizeof(struct bbfdm_context));
         bbfdm_ubus_set_service_name(&bbfdm_ctx, "qosmngr");
@@ -154,7 +161,7 @@ int main(int argc, char **argv)
 	/* Main loop of qosmngr */
 	uloop_run();
  out:
-	bbfdm_ubus_regiter_free(&bbfdm_ctx);;
+	bbfdm_ubus_regiter_free(&bbfdm_ctx);
 	ubus_free(ctx);
 	uloop_done();
 
diff --git a/src/qos_bbf.c b/src/qos_bbf.c
index e35b4c1..e717ada 100644
--- a/src/qos_bbf.c
+++ b/src/qos_bbf.c
@@ -117,6 +117,22 @@ static void qos_update_order(const char *order, bool is_del)
 	}
 }
 
+static int get_QoSQueueStats_value(struct qos_stats *stats, char *intf, char *queue)
+{
+	char *queue_str = queue;
+	if (queue && *queue && DM_STRLEN(queue) > 2 && intf && *intf) {
+		char queue_id[8] = {0};
+
+		snprintf(queue_id, sizeof(queue_id), "%c", queue_str[2]);
+		int qid = (int) DM_STRTOL(queue_id);
+
+		if (!prepare_stats_blob(NULL, stats, NULL, intf, qid)) {
+			return 0;
+		}
+	}
+	return 1;
+}
+
 /*************************************************************
  * ENTRY METHOD
 *************************************************************/
@@ -179,11 +195,28 @@ static int browseQoSQueueInst(struct dmctx *dmctx, DMNODE *parent_node, void *pr
 
 static int browseQoSQueueStatsInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
 {
-	struct dm_data curr_data = {0};
 	struct uci_section *s = NULL;
 	char *inst = NULL;
 
 	uci_path_foreach_sections(bbfdm, "dmmap_qstats", "queue_stats", s) {
+		struct dm_data curr_data = {0};
+
+		char *queue = NULL, *intf = NULL, *enabled = NULL;
+	        struct qos_stats stats = {0};
+
+		enabled = dmuci_get_value_by_section_fallback_def(s, "enabled", "0");
+
+		// if enabled is not 0
+		if (DM_STRNCMP(enabled, "0", DM_STRLEN("0"))) {
+			dmuci_get_value_by_section_string(s, "queue", &queue);
+			dmuci_get_value_by_section_string(s, "interface", &intf);
+
+			if (!get_QoSQueueStats_value(&stats, intf, queue)) {
+				curr_data.additional_data = (void *)(&stats);
+			} else {
+				curr_data.additional_data = NULL;
+			}
+		}
 
 		curr_data.config_section = s;
 
@@ -1873,60 +1906,36 @@ static int set_QoSQueueStats_Interface(char *refparam, struct dmctx *ctx, void *
 	return 0;
 }
 
-static int get_QoSQueueStats_value(void *data, char *option, char **value)
+static int get_QoSQueueStats_OutputPackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	char *queue_link = NULL, *intf_link = NULL;
-
-	*value = "0";
-	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "queue", &queue_link);
-	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "interface", &intf_link);
-
-	if (queue_link && *queue_link && DM_STRLEN(queue_link) > 2 && intf_link && *intf_link) {
-		char queue_id[8] = {0};
-
-		snprintf(queue_id, sizeof(queue_id), "%c", queue_link[2]);
-		int qid = (int) DM_STRTOL(queue_id);
-	        struct qos_stats stats = {0};
-
-		if (!prepare_stats_blob(NULL, &stats, NULL, intf_link, qid)) {
-			char val_buf[65] = {0};
-
-			if (!DM_STRNCMP(option, "tx_packets", DM_STRLEN("tx_packets"))) {
-				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_packets);
-				*value = dmstrdup(val_buf);
-			} else if (!DM_STRNCMP(option, "tx_bytes", DM_STRLEN("tx_bytes"))) {
-				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_bytes);
-				*value = dmstrdup(val_buf);
-			} else if (!DM_STRNCMP(option, "tx_dropped_packets", DM_STRLEN("tx_dropped_packets"))) {
-				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_dropped_packets);
-				*value = dmstrdup(val_buf);
-			} else if (!DM_STRNCMP(option, "tx_dropped_bytes", DM_STRLEN("tx_dropped_bytes"))) {
-				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_dropped_bytes);
-				*value = dmstrdup(val_buf);
-			}
-		}
+	if (((struct dm_data *)data)->additional_data) {
+		dmasprintf(value, "%llu", ((struct qos_stats *)((struct dm_data *)data)->additional_data)->tx_packets);
 	}
 	return 0;
 }
 
-static int get_QoSQueueStats_OutputPackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
-{
-	return get_QoSQueueStats_value(data, "tx_packets", value);
-}
-
 static int get_QoSQueueStats_OutputBytes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	return get_QoSQueueStats_value(data, "tx_bytes", value);
+	if (((struct dm_data *)data)->additional_data) {
+		dmasprintf(value, "%llu", ((struct qos_stats *)((struct dm_data *)data)->additional_data)->tx_bytes);
+	}
+	return 0;
 }
 
 static int get_QoSQueueStats_DroppedPackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	return get_QoSQueueStats_value(data, "tx_dropped_packets", value);
+	if (((struct dm_data *)data)->additional_data) {
+		dmasprintf(value, "%llu", ((struct qos_stats *)((struct dm_data *)data)->additional_data)->tx_dropped_packets);
+	}
+	return 0;
 }
 
 static int get_QoSQueueStats_DroppedBytes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	return get_QoSQueueStats_value(data, "tx_dropped_bytes", value);
+	if (((struct dm_data *)data)->additional_data) {
+		dmasprintf(value, "%llu", ((struct qos_stats *)((struct dm_data *)data)->additional_data)->tx_dropped_bytes);
+	}
+	return 0;
 }
 
 static int get_QoSShaper_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
diff --git a/src/qosmngr.c b/src/qosmngr.c
index c5250fa..7ff70dd 100644
--- a/src/qosmngr.c
+++ b/src/qosmngr.c
@@ -353,8 +353,7 @@ int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
 		q_stat->tx_bytes = stats->tx_bytes;
 		q_stat->tx_dropped_packets = stats->tx_dropped_packets;
 		q_stat->tx_dropped_bytes = stats->tx_dropped_bytes;
-	}
-	else {
+	} else {
 		q_stat->tx_packets += stats->tx_packets;
 		q_stat->tx_bytes += stats->tx_bytes;
 		q_stat->tx_dropped_packets += stats->tx_dropped_packets;
@@ -381,6 +380,7 @@ int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
 	return ret;
 }
 
+#ifdef UBUS_SUPPORT
 /**
  *  get_stats_by_ifname function for getting specific interface stats
  *  @param b output parameter pointer to blob_buf
@@ -578,3 +578,4 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 	blob_buf_free(&b);
 	return ret;
 }
+#endif
-- 
GitLab


From ad1e84553fecf0e7dbde9c4f347424ec85116863 Mon Sep 17 00:00:00 2001
From: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
Date: Mon, 7 Apr 2025 21:10:32 +0530
Subject: [PATCH 4/6] qosmngr: use BBF api for logging, instead of syslog

---
 include/qosmngr.h |  2 +-
 src/main.c        | 10 ++++-----
 src/qos_bbf.c     |  4 ++++
 src/qosmngr.c     | 52 +++++++++++++++++++++++------------------------
 4 files changed, 36 insertions(+), 32 deletions(-)

diff --git a/include/qosmngr.h b/include/qosmngr.h
index b64c21c..e846b1a 100644
--- a/include/qosmngr.h
+++ b/include/qosmngr.h
@@ -30,7 +30,7 @@
 #include <qos.h>
 
 /* logging though syslog */
-#include <syslog.h>
+#include <libbbfdm-api/dmcommon.h>
 
 /* UCI definitions, used to parse the config files at their right location */
 #define UCI_CONFIG_QOS   "qos"
diff --git a/src/main.c b/src/main.c
index 0d85e90..17235e4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -68,7 +68,7 @@ static int qosmngr_publish_object(struct ubus_context *context)
 	int ret;
 	ret = ubus_add_object(context, &test_object);
 	if (ret) {
-		syslog(LOG_ERR, "Failed to add 'qos' ubus object: %s\n",
+		BBF_ERR("Failed to add 'qos' ubus object: %s\n",
 			ubus_strerror(ret));
 	}
 
@@ -83,7 +83,7 @@ static int qosmngr_publish_object(struct ubus_context *context)
  */
 void qosmngr_version(void)
 {
-	syslog(LOG_ERR, "version       : %s.%s\n", qosmngr_base_version, qosmngr_xtra_version);
+	BBF_ERR("version       : %s.%s\n", qosmngr_base_version, qosmngr_xtra_version);
 }
 
 /**
@@ -96,7 +96,7 @@ int main(int argc, char **argv)
 {
 	int ch;
 	int num_of_q = QOS_MIN_Q_NUM_PER_PORT;
-        int log_level = 6; // default LOG_INFO
+        int log_level = 7; // default LOG_DEBUG
 
 
 	/* Logging to syslog */
@@ -133,7 +133,7 @@ int main(int argc, char **argv)
 	uloop_init();
 	ctx = ubus_connect(ubus_socket);
 	if (!ctx) {
-		syslog(LOG_ERR, "Failed to connect to ubus\n");
+		BBF_ERR("Failed to connect to ubus\n");
 		return -1;
 	}
 
@@ -152,7 +152,7 @@ int main(int argc, char **argv)
         bbfdm_ubus_load_data_model(tDynamicObj);
 
 	if (bbfdm_ubus_regiter_init(&bbfdm_ctx)) {
-		syslog(LOG_ERR, "Failed to register ubus");
+		BBF_ERR("Failed to register ubus");
 		goto out;
 	}
 
diff --git a/src/qos_bbf.c b/src/qos_bbf.c
index e717ada..67fcb1f 100644
--- a/src/qos_bbf.c
+++ b/src/qos_bbf.c
@@ -126,6 +126,10 @@ static int get_QoSQueueStats_value(struct qos_stats *stats, char *intf, char *qu
 		snprintf(queue_id, sizeof(queue_id), "%c", queue_str[2]);
 		int qid = (int) DM_STRTOL(queue_id);
 
+		// the function name is prepare_stats_blob
+		// but when the first argument is NULL
+		// it does not populate the blob
+		// and only the stats are updated
 		if (!prepare_stats_blob(NULL, stats, NULL, intf, qid)) {
 			return 0;
 		}
diff --git a/src/qosmngr.c b/src/qosmngr.c
index 7ff70dd..fa4a174 100644
--- a/src/qosmngr.c
+++ b/src/qosmngr.c
@@ -71,7 +71,7 @@ static int get_no_queues(const char *ifname)
 
        uci_load(uci_ctx, "qos", &uci_pkg);
        if (!uci_pkg) {
-               syslog(LOG_ERR, "Failed to load configuration\n");
+               BBF_ERR("Failed to load configuration\n");
                queues = -1;
                goto done;
        }
@@ -138,7 +138,7 @@ static int init_interface(const char *ifname, size_t index)
 	data->q_stat = (struct qos_stats *)calloc(queues,
 			sizeof(struct qos_stats));
 	if (data->q_stat == NULL) {
-		syslog(LOG_ERR, "Initialization failed during memory allocation.\n");
+		BBF_ERR("Initialization failed during memory allocation.\n");
 		free(interfaces);
 		return -1;
 	}
@@ -154,7 +154,7 @@ int init_qstat(void)
 {
 	int ret = 0;
 
-	syslog(LOG_ERR, "Initializing global stat structure.\n");
+	BBF_ERR("Initializing global stat structure.\n");
 
 	interface_count = 0;
 	long int size;
@@ -172,7 +172,7 @@ int init_qstat(void)
 	unsigned int buffer_size = 0;
 	/* Allocate memory for entire content */
 	if (size < 0) {
-		syslog(LOG_ERR, "file read size < 0");
+		BBF_ERR("file read size < 0");
 		fclose(fp);
 		return -1;
 	} else {
@@ -181,14 +181,14 @@ int init_qstat(void)
 
 	buffer = calloc(1, buffer_size + 1);
 	if (buffer == NULL) {
-		syslog(LOG_ERR, "memory allocation to read buffer failed");
+		BBF_ERR("memory allocation to read buffer failed");
 		fclose(fp);
 		return -1;
 	}
 
 	/* Copy the file into the buffer */
 	if (fread(buffer, buffer_size, 1, fp) != 1) {
-		syslog(LOG_ERR, "read from board.json file failed");
+		BBF_ERR("read from board.json file failed");
 		free(buffer);
 		fclose(fp);
 		return -1;
@@ -196,7 +196,7 @@ int init_qstat(void)
 
 	struct json_object *board_json = json_tokener_parse(buffer);
 	if (board_json == NULL) {
-		syslog(LOG_ERR, "failed to read board.json as json");
+		BBF_ERR("failed to read board.json as json");
 		free(buffer);
 		fclose(fp);
 		return -1;
@@ -204,7 +204,7 @@ int init_qstat(void)
 
 	struct json_object *network = NULL;
 	if (!json_object_object_get_ex(board_json, "network", &network)) {
-		syslog(LOG_ERR, "network object not found in board.json");
+		BBF_ERR("network object not found in board.json");
 		ret = -1;
 		json_object_put(board_json);
 		goto free_and_return;
@@ -212,7 +212,7 @@ int init_qstat(void)
 
 	struct json_object *lan = NULL;
 	if (!json_object_object_get_ex(network, "lan", &lan)) {
-		syslog(LOG_ERR, "lan object not found in board.json");
+		BBF_ERR("lan object not found in board.json");
 		json_object_put(board_json);
 		ret = -1;
 		goto free_and_return;
@@ -225,7 +225,7 @@ int init_qstat(void)
 	// its not necessary that board.json has wan section at all
 	if (json_object_object_get_ex(network, "wan", &wan)) {
 		if (!json_object_object_get_ex(wan, "device", &wan_device)) {
-			syslog(LOG_ERR, "wan device object not found in board.json");
+			BBF_ERR("wan device object not found in board.json");
 			ret = -1;
 			json_object_put(board_json);
 			goto free_and_return;
@@ -236,9 +236,9 @@ int init_qstat(void)
 
 	struct json_object *lan_ports = NULL;
 	if (!json_object_object_get_ex(lan, "ports", &lan_ports)) {
-		syslog(LOG_INFO, "lan ports object not found in board.json");
+		BBF_INFO("lan ports object not found in board.json");
 		if (!json_object_object_get_ex(lan, "device", &lan_ports)) {
-			syslog(LOG_INFO, "lan device object not found in board.json");
+			BBF_INFO("lan device object not found in board.json");
 			ret = -1;
 			json_object_put(board_json);
 			goto free_and_return;
@@ -256,7 +256,7 @@ int init_qstat(void)
         interfaces = (qos_interface_data *)calloc(interface_count,
 	                                          sizeof(qos_interface_data));
 	if (interfaces == NULL) {
-		syslog(LOG_ERR, "Initialization failed during memory allocation.");
+		BBF_ERR("Initialization failed during memory allocation.");
 		ret = -1;
 		json_object_put(board_json);
 		goto free_and_return;
@@ -267,7 +267,7 @@ int init_qstat(void)
 		for (i = 0; i < json_object_array_length(lan_ports); i++) {
 			struct json_object *l_port_name = json_object_array_get_idx(lan_ports, i);
 			if (!l_port_name) {
-				syslog(LOG_ERR, "cannot read lan ports array");
+				BBF_ERR("cannot read lan ports array");
 				ret = -1;
 				json_object_put(board_json);
 				free(interfaces);
@@ -277,7 +277,7 @@ int init_qstat(void)
 			ret = init_interface(json_object_get_string(l_port_name), i);
 
 			if (ret < 0) {
-				syslog(LOG_ERR, "cannot int lan ports qos");
+				BBF_ERR("cannot int lan ports qos");
 				json_object_put(board_json);
 				free(interfaces);
 				goto free_and_return;
@@ -287,7 +287,7 @@ int init_qstat(void)
 	} else {
 		ret = init_interface(json_object_get_string(lan_ports), i);
 		if (ret < 0) {
-			syslog(LOG_ERR, "cannot int lan device qos");
+			BBF_ERR("cannot int lan device qos");
 			json_object_put(board_json);
 			free(interfaces);
 			goto free_and_return;
@@ -327,20 +327,20 @@ int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
 
 	ret = qos_get_stats(ifname, qid, stats, &is_read_and_reset);
 	if (ret != 0) {
-		syslog(LOG_ERR, "blob_get_status: ret %d\n", ret);
+		BBF_ERR("blob_get_status: ret %d\n", ret);
 		return ret;
 	}
 
 	index = get_interface_index(ifname);
 	if (index < 0 || index >= interface_count) {
-		syslog(LOG_ERR, "Invalid interface index %d (out of %zu) for interface %s",
+		BBF_ERR("Invalid interface index %d (out of %zu) for interface %s",
 		       index, interface_count, ifname);
 		return -1;
 	}
 
 	iface = &interfaces[index];
 	if (qid < 0 || qid >= iface->q_count) {
-		syslog(LOG_ERR, "Invalid queue index %d (out of %zu)",
+		BBF_ERR("Invalid queue index %d (out of %zu)",
 		       qid, iface->q_count);
 		return -1;
 	}
@@ -433,7 +433,7 @@ static int get_stats_for_all_intf(struct blob_buf *b, struct qos_stats *stats, v
 				cur->if_name, QOS_QUEUE_ANY);
 
 		if (ret != 0) {
-			syslog(LOG_ERR, "get_stats_by_ifname failed: ret %d", ret);
+			BBF_ERR("get_stats_by_ifname failed: ret %d", ret);
 			continue;
 		}
 	}
@@ -471,7 +471,7 @@ static int validate_keys(char *req_json)
 
 			if (!(!strncmp(key, PARAM1, strlen(PARAM1)) ||
 					!strncmp(key, PARAM2, strlen(PARAM2)))) {
-				syslog(LOG_ERR, "ERROR :: unknown parameter : %s\n", key);
+				BBF_ERR("ERROR :: unknown parameter : %s\n", key);
 				return -1;
 			}
 		}
@@ -521,7 +521,7 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 	/* Validate requested parameters, i.e., ifname and qid */
 	ret = validate_request(msg);
 	if (ret) {
-		syslog(LOG_ERR, "validate_request failed : ret %d\n", ret);
+		BBF_ERR("validate_request failed : ret %d\n", ret);
 		return UBUS_STATUS_INVALID_ARGUMENT;
 	}
 
@@ -546,10 +546,10 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 	if (init_flag) {
 		ret = init_qstat();
 		if (ret) {
-			syslog(LOG_ERR, "Failed to initialize gobal q_stat");
+			BBF_ERR("Failed to initialize gobal q_stat");
 			return ret;
 		}
-		syslog(LOG_INFO, "Initialized gobal q_stat successfully");
+		BBF_INFO("Initialized gobal q_stat successfully");
 	}
 
 	blob_buf_init(&b, 0);
@@ -559,13 +559,13 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 	if (tb[QOS_POLICY_IFNAME]) {
 		ret = get_stats_by_ifname(&b, &stats, &dd, ifname, qid);
 		if (ret != 0) {
-			syslog(LOG_ERR, "get_stats_by_ifname : ret %d\n", ret);
+			BBF_ERR("get_stats_by_ifname : ret %d\n", ret);
 			goto fail_get_status;
 		}
 	} else {
 		ret = get_stats_for_all_intf(&b, &stats, &dd);
 		if (ret != 0) {
-			syslog(LOG_ERR, "get_stats_for_all_intf : ret %d\n", ret);
+			BBF_ERR("get_stats_for_all_intf : ret %d\n", ret);
 			goto fail_get_status;
 		}
 	}
-- 
GitLab


From 12ab6e2a4549accc5b81b076a5fa7473c094155e Mon Sep 17 00:00:00 2001
From: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
Date: Tue, 8 Apr 2025 05:29:59 +0530
Subject: [PATCH 5/6] qosmngr: add deprecation warning for ubus call

---
 src/qosmngr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/qosmngr.c b/src/qosmngr.c
index fa4a174..7f4c1ef 100644
--- a/src/qosmngr.c
+++ b/src/qosmngr.c
@@ -510,6 +510,8 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 	       struct ubus_request_data *req, const char *method,
 	       struct blob_attr *msg)
 {
+	BBF_ERR("Warning: qos ubus object has been deprecated, please use bbfdm to fetch the stats!\n");
+
 	int ret = 0;
 	int qid = QOS_QUEUE_ANY;
 	char ifname[IFNAMSIZ] = {0};
-- 
GitLab


From 83aa4a3a355700ea86490941ea9b244c39fb9519 Mon Sep 17 00:00:00 2001
From: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
Date: Fri, 11 Apr 2025 10:50:28 +0530
Subject: [PATCH 6/6] cleanup

---
 .gitlab-ci.yml                    |  34 +----
 Makefile                          |  58 --------
 Makefile.diag.inc                 |   1 -
 common.mk                         |  10 --
 gitlab-ci/build.sh                |   2 +-
 gitlab-ci/functional-test.sh      |  23 ---
 src/Makefile                      |  28 ++++
 src/main.c                        | 117 ++++++++-------
 src/qos_bbf.c                     |  25 +---
 src/qosmngr.c                     |  89 +++--------
 {include => src}/qosmngr.h        |   8 +-
 test/cmocka/Makefile              |  26 ----
 test/cmocka/functional_test_qos.c | 240 ------------------------------
 13 files changed, 128 insertions(+), 533 deletions(-)
 delete mode 100644 Makefile
 delete mode 100644 Makefile.diag.inc
 delete mode 100644 common.mk
 delete mode 100755 gitlab-ci/functional-test.sh
 create mode 100644 src/Makefile
 rename {include => src}/qosmngr.h (94%)
 delete mode 100644 test/cmocka/Makefile
 delete mode 100644 test/cmocka/functional_test_qos.c

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6c92acc..a1b0995 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,24 +1,21 @@
 include:
   - project: 'iopsys/gitlab-ci-pipeline'
     file: '/static-code-analysis.yml'
-    ref: '0.31'
+    ref: '1.2'
+
+variables:
+  DEBUG: 'TRUE'
+  SOURCE_FOLDER: "src"
+  CPPCHECK_OPTIONS: "--suppress=cert-STR05-C"
 
 stages:
     - static_code_analysis
     - compile_test
-    - unit_test
-    - functional_test
     - api_test
 
-variables:
-  COMMON_IMAGE: "dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:0.31"
-  DEBUG: 'TRUE'
-  SOURCE_FOLDER: "src"
-  RUN_CPPCHECK: "cppcheck --enable=all --error-exitcode=1 --suppress=missingInclude --suppress=unusedFunction --suppress=unreadVariable --suppress=variableScope --suppress=redundantInitialization --suppress=unusedLabel --suppress=unusedStructMember --suppress=knownConditionTrueFalse --suppress=unmatchedSuppression --force"
-
 run_compile_test:
     stage: compile_test
-    image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
+    image: ${COMMON_IMAGE}
     allow_failure: false
     script:
         - "./gitlab-ci/install-dependencies.sh"
@@ -26,7 +23,7 @@ run_compile_test:
 
 run_api_test:
     stage: api_test
-    image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
+    image: ${COMMON_IMAGE}
     allow_failure: false
     script:
         - "./gitlab-ci/install-dependencies.sh"
@@ -41,18 +38,3 @@ run_api_test:
             - api-test-coverage.xml
             - api-test-memory-report.xml
             - timestamp.log
-
-run_functional_test:
-    stage: functional_test
-    image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
-    allow_failure: false
-    script:
-        - "./gitlab-ci/install-dependencies.sh"
-        - "./gitlab-ci/setup.sh"
-        - "./gitlab-ci/functional-test.sh"
-
-    artifacts:
-        when: always
-        paths:
-            - functional-test-coverage.xml
-            - timestamp.log
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 1593044..0000000
--- a/Makefile
+++ /dev/null
@@ -1,58 +0,0 @@
-# Makefile for qosmngr
-include common.mk
-
--include Makefile.diag.inc
-
-GCOV=gcov
-SRC_DIR = src
-
-CODECOVERAGE_SRC = $(addprefix $(SRC_DIR)/, qosmngr.c )
-PROG = $(PROJECT_TOPLEVEL)/qosmngr
-OBJS = $(addprefix $(SRC_DIR)/, main.o qosmngr.o qos_bbf.o)
-
-PROG_CFLAGS = $(CFLAGS) -I$(INCLUDE_DIR) $(DIAG_CFLAGS) -Werror -fstrict-aliasing
-PROG_LDFLAGS = $(LDFLAGS) -lbbfdm-ubus -lbbfdm-api
-PROG_LIBS = $(COMMON_LDFLAGS) -lgcov
-
-# MUSL has the following issue in snprintf, so it is ignored:
-PROG_CFLAGS += -Wno-format-nonliteral
-
-.PHONY: all clean
-
-all: version $(PROG)
-
-$(PROG): $(INCLUDE_DIR)/version.h $(OBJS)
-	$(CC) -o $@ $^ $(PROG_LDFLAGS) $(PROG_LIBS)
-
-version: $(INCLUDE_DIR)/version.h
-
-$(INCLUDE_DIR)/version.h: $(PROJECT_TOPLEVEL)/VERSION
-	@(dirty=$(shell (git status --porcelain | grep -q .) && echo -dirty); \
-	[ -f $(PROJECT_TOPLEVEL)/VERSION ] && basever=$(shell cat $(PROJECT_TOPLEVEL)/VERSION) || \
-		basever=Unknown; \
-	xver=$(shell date +'%y%V%u-%H%M'); \
-	echo "const char *qosmngr_base_version = \"$$basever\";" > $@; \
-	echo "const char *qosmngr_xtra_version = \"$$xver$$dirty\";" >> $@; \
-	)
-
-test: $(PROG)
-
-coverage: CFLAGS += -g -O0 -fprofile-arcs -ftest-coverage -fPIC -DBBF_VENDOR_PREFIX='"X_IOWRT_EU"'
-coverage: LDFLAGS += --coverage
-coverage: test $(PROG)
-	$(foreach testprog, $(CODECOVERAGE_SRC), $(GCOV) $(testprog);)
-
-functional-test: test
-	$(MAKE) -C test/cmocka functional-test
-
-%.o: %.c
-	$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
-
-clean:
-	rm -f *.o $(PROG) $(INCLUDE_DIR)/version.h
-	rm -f *.xml *.html
-	find -name '*.gcda' -exec rm {} -fv \;
-	find -name '*.gcno' -exec rm {} -fv \;
-	find -name '*.gcov' -exec rm {} -fv \;
-	make -C test/cmocka clean
-
diff --git a/Makefile.diag.inc b/Makefile.diag.inc
deleted file mode 100644
index 7729cbb..0000000
--- a/Makefile.diag.inc
+++ /dev/null
@@ -1 +0,0 @@
-DIAG_CFLAGS = -Wall -Wshadow -Wdouble-promotion -Wformat=2 -Wundef -fno-common -Wconversion -Wstrict-prototypes -Wno-declaration-after-statement
diff --git a/common.mk b/common.mk
deleted file mode 100644
index 2069d99..0000000
--- a/common.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# Useful to refer to headers not located in the same directory as the source files being compiled
-PROJECT_TOPLEVEL := $(dir $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
-INCLUDE_DIR = $(PROJECT_TOPLEVEL)/include
-
-# Common compiler options
-CC=gcc # gcc || clang
-
-COMMON_LDFLAGS = -luci -lubus -lubox -ljson-c -lblobmsg_json -lnl-genl-3 -lnl-3 -lqos
-QOSMNGR_LIB_DIR	?= $(shell dirname $(PWD))
-QOSMNGR_LDFLAGS	= -lqosmngr -L$(QOSMNGR_LIB_DIR)
diff --git a/gitlab-ci/build.sh b/gitlab-ci/build.sh
index aa28e04..20d23f4 100755
--- a/gitlab-ci/build.sh
+++ b/gitlab-ci/build.sh
@@ -2,4 +2,4 @@
 set -e
 echo "build stage"
 pwd
-make CFLAGS='-DBBF_VENDOR_PREFIX=\"X_IOPSYS_EU_\"'
+make -C ./src CFLAGS='-DBBF_VENDOR_PREFIX=\"X_IOPSYS_EU_\"'
diff --git a/gitlab-ci/functional-test.sh b/gitlab-ci/functional-test.sh
deleted file mode 100755
index f5231f6..0000000
--- a/gitlab-ci/functional-test.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-echo "Functional Test"
-pwd
-
-make coverage -C ./
-supervisorctl status all
-supervisorctl update
-sleep 3
-supervisorctl status all
-
-make functional-test -C ./
-
-supervisorctl stop all
-supervisorctl status
-
-#report part
-#GitLab-CI output
-gcovr -r .
-# Artefact
-gcovr -r . --xml -o ./functional-test-coverage.xml
-date +%s > timestamp.log
-
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..ef3e7b7
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,28 @@
+PROG = qosmngr
+OBJS = main.o qosmngr.o qos_bbf.o
+
+PROG_CFLAGS = $(CFLAGS) -Wall -Werror
+PROG_LDFLAGS = $(LDFLAGS) -lbbfdm-ubus -lbbfdm-api -luci -lubus -lubox -ljson-c
+PROG_LDFLAGS += -lblobmsg_json -lnl-genl-3 -lnl-3 -lqos
+
+ifeq ($(filter -DBBF_VENDOR_PREFIX=%,$(PROG_CFLAGS)),)
+PROG_CFLAGS += -DBBF_VENDOR_PREFIX=\"X_IOWRT_EU_\"
+endif
+
+.PHONY: all clean
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+	$(CC) -o $@ $^ $(PROG_LDFLAGS)
+
+%.o: %.c
+	$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
+
+clean:
+	rm -f *.o $(PROG)
+	rm -f *.xml *.html
+	find -name '*.gcda' -exec rm {} -fv \;
+	find -name '*.gcno' -exec rm {} -fv \;
+	find -name '*.gcov' -exec rm {} -fv \;
+
diff --git a/src/main.c b/src/main.c
index 17235e4..625523e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,15 +28,13 @@
 #include <libbbfdm-ubus/bbfdm-ubus.h>
 
 #include "qosmngr.h"
-#include "version.h"
-
 #include "qos_bbf.h"
 
-const char *ubus_socket;
+#define PROTOCOLS_FILE "/etc/protocols"
+
+protocol_list_t g_protocol_maps;
 
-struct ubus_context *ctx = NULL;
 extern DM_MAP_OBJ tDynamicObj[];
-static struct bbfdm_context bbfdm_ctx = {0};
 
 #ifdef UBUS_SUPPORT
 const struct blobmsg_policy get_status_policy[NUM_QOS_POLICY] = {
@@ -76,33 +74,56 @@ static int qosmngr_publish_object(struct ubus_context *context)
 }
 #endif
 
-/**
- *  To get the qosmngr version
- *  @param : none
- *  return : none
- */
-void qosmngr_version(void)
+static int init_protocol_numbers()
 {
-	BBF_ERR("version       : %s.%s\n", qosmngr_base_version, qosmngr_xtra_version);
+	char line[256] = {0};
+	protocol_list_t *pentry;
+
+	INIT_LIST_HEAD(&g_protocol_maps.list);
+
+	// cppcheck-suppress cert-MSC24-C
+	FILE *file = fopen(PROTOCOLS_FILE, "r");
+	if (!file)
+		return -1;
+
+	while (fgets(line, sizeof(line), file)) {
+		if (line[0] == '#' || line[0] == '\n')
+			continue;
+
+		char name[32] = {0};
+		int number = 0;
+		if (sscanf(line, "%31s %d", name, &number) == 2) {
+			pentry = (protocol_list_t *) calloc(1, sizeof(protocol_list_t));
+			if (pentry) {
+				pentry->proto_num = number;
+				snprintf(pentry->proto_name, sizeof(name), "%s", name);
+				list_add_tail(&pentry->list, &g_protocol_maps.list);
+			}
+		}
+	}
+
+	fclose(file);
+	return 0;
 }
 
-/**
- *  Main function for qosmngr, everything starts here
- *  @param argc input number of input arguments
- *  @param argv input double pointer array of optional command line arguments
- *  retrun integer value 0 on success and -1 on failure
- */
-int main(int argc, char **argv)
+int cleanup()
 {
-	int ch;
-	int num_of_q = QOS_MIN_Q_NUM_PER_PORT;
-        int log_level = 7; // default LOG_DEBUG
+	protocol_list_t *entry = NULL, *tmp = NULL;
 
+	list_for_each_entry_safe(entry, tmp, &g_protocol_maps.list, list) {
+		list_del(&entry->list);
+		free(entry);
+	}
+	return 0;
+}
 
-	/* Logging to syslog */
-	openlog("qosmngr", LOG_PID|LOG_CONS, LOG_LOCAL1);
+int main(int argc, char **argv)
+{
+	int ch;
+        int log_level = 7;
+	struct bbfdm_context bbfdm_ctx = {0};
 
-	while ((ch = getopt(argc, argv, "lvsq:e:")) != -1) {
+	while ((ch = getopt(argc, argv, "l:q:")) != -1) {
 		switch (ch) {
 		case 'l':
 			if (optarg) {
@@ -110,16 +131,10 @@ int main(int argc, char **argv)
 			}
 
 			if (log_level < 0 || log_level > 7)
-				log_level = 6;
-			break;
-		case 'v':
-			qosmngr_version();
-			exit(0);
-		case 's':
-			ubus_socket = optarg;
+				log_level = 7;
 			break;
 		case 'q':
-			num_of_q = get_no_of_q_per_port(argv[argc-1]);
+			int num_of_q = get_no_of_q_per_port(argv[argc-1]);
 			printf("%d", num_of_q);
 			exit(0);
 		default:
@@ -127,43 +142,31 @@ int main(int argc, char **argv)
 		}
 	}
 
-	argc -= optind;
-	argv += optind;
-
-	uloop_init();
-	ctx = ubus_connect(ubus_socket);
-	if (!ctx) {
-		BBF_ERR("Failed to connect to ubus\n");
-		return -1;
-	}
-
-	ubus_add_uloop(ctx);
-
-#ifdef UBUS_SUPPORT
-	int ret;
-	ret = qosmngr_publish_object(ctx);
-	if (ret)
-		goto out;
-#endif
-
         memset(&bbfdm_ctx, 0, sizeof(struct bbfdm_context));
         bbfdm_ubus_set_service_name(&bbfdm_ctx, "qosmngr");
         bbfdm_ubus_set_log_level(log_level);
         bbfdm_ubus_load_data_model(tDynamicObj);
 
+	openlog("qosmngr", LOG_PID|LOG_CONS, LOG_LOCAL1);
+
 	if (bbfdm_ubus_regiter_init(&bbfdm_ctx)) {
-		BBF_ERR("Failed to register ubus");
+		BBF_ERR("Failed to register bbfdm.qosmngr ubus");
 		goto out;
 	}
 
+#ifdef UBUS_SUPPORT
+	if (qosmngr_publish_object(&bbfdm_ctx.ubus_ctx)) {
+		BBF_ERR("Failed to register qos object");
+		goto out;
+	}
+#endif
+
 	init_qstat();
+	init_protocol_numbers();
 
-	/* Main loop of qosmngr */
 	uloop_run();
  out:
 	bbfdm_ubus_regiter_free(&bbfdm_ctx);
-	ubus_free(ctx);
-	uloop_done();
-
+	cleanup();
 	return 0;
 }
diff --git a/src/qos_bbf.c b/src/qos_bbf.c
index 67fcb1f..6e40051 100644
--- a/src/qos_bbf.c
+++ b/src/qos_bbf.c
@@ -13,7 +13,7 @@
 #include "libbbfdm_api.h"
 #include "qosmngr.h"
 
-#define PROTOCOLS_FILE "/etc/protocols"
+extern protocol_list_t g_protocol_maps;
 
 /*************************************************************
 * COMMON FUNCTIONS
@@ -31,26 +31,13 @@ static int is_numeric(const char *str)
 
 static int lookup_protocol_number(const char *protocol)
 {
-	FILE *file = fopen(PROTOCOLS_FILE, "r");
-	if (!file)
-		return -1;
-
-	char line[256];
-	while (fgets(line, sizeof(line), file)) {
-		if (line[0] == '#' || line[0] == '\n')
-			continue;
-
-		char name[32] = {0};
-		int number = 0;
-		if (sscanf(line, "%31s %d", name, &number) == 2) {
-			if (strcasecmp(name, protocol) == 0) {
-				fclose(file);
-				return number;
-			}
+	protocol_list_t *entry = NULL;
+
+	list_for_each_entry(entry, &g_protocol_maps.list, list) {
+		if (strcasecmp(entry->proto_name, protocol) == 0) {
+			return entry->proto_num;
 		}
 	}
-
-	fclose(file);
 	return -1;
 }
 
diff --git a/src/qosmngr.c b/src/qosmngr.c
index 7f4c1ef..498b1f4 100644
--- a/src/qosmngr.c
+++ b/src/qosmngr.c
@@ -42,15 +42,15 @@
 #define PARAM1 "ifname"
 #define PARAM2 "qid"
 
+#define BOARD_JSON_FILE "/etc/board.json"
+
 /** Container for single interface data (with multiple queues) */
 typedef struct qos_interface_data {
-	char              if_name[IFNAMSIZ];     /**< Cached interface name */
 	size_t            q_count;               /**< Cached number of queues */
 	struct qos_stats *q_stat;                /**< Cached queue statistics */
+	char              if_name[IFNAMSIZ];     /**< Cached interface name */
 } qos_interface_data;
 
-static int init_flag = 1;
-
 /** Number of interfaces currently cached by qosmngr */
 static size_t interface_count = 0;
 /** Array of interfaces cached by qosmngr */
@@ -127,21 +127,23 @@ static int get_interface_index(const char *ifname)
 	return -1;
 }
 
-static int init_interface(const char *ifname, size_t index)
+static int init_interface_queues(const char *ifname, qos_interface_data *data)
 {
-	qos_interface_data *data = &interfaces[index];
-
 	size_t queues = (size_t)get_no_queues(ifname);
 
+	if (data == NULL) {
+		BBF_ERR("Null interface entry");
+		return -1;
+	}
+
 	strncpy(data->if_name, ifname, IFNAMSIZ);
 	data->q_count = queues;
-	data->q_stat = (struct qos_stats *)calloc(queues,
-			sizeof(struct qos_stats));
+	data->q_stat = (struct qos_stats *)calloc(queues, sizeof(struct qos_stats));
 	if (data->q_stat == NULL) {
 		BBF_ERR("Initialization failed during memory allocation.\n");
-		free(interfaces);
 		return -1;
 	}
+
 	return 0;
 }
 
@@ -154,51 +156,10 @@ int init_qstat(void)
 {
 	int ret = 0;
 
-	BBF_ERR("Initializing global stat structure.\n");
-
 	interface_count = 0;
-	long int size;
-	FILE *fp = NULL;
-	char *buffer = NULL;
-
-	fp = fopen("/etc/board.json","r");
-	if (fp == NULL)
-		return -1;
-
-	fseek(fp, 0L, SEEK_END);
-	size = ftell(fp);
-	rewind(fp);
-
-	unsigned int buffer_size = 0;
-	/* Allocate memory for entire content */
-	if (size < 0) {
-		BBF_ERR("file read size < 0");
-		fclose(fp);
-		return -1;
-	} else {
-		buffer_size = (unsigned int)size;
-	}
-
-	buffer = calloc(1, buffer_size + 1);
-	if (buffer == NULL) {
-		BBF_ERR("memory allocation to read buffer failed");
-		fclose(fp);
-		return -1;
-	}
-
-	/* Copy the file into the buffer */
-	if (fread(buffer, buffer_size, 1, fp) != 1) {
-		BBF_ERR("read from board.json file failed");
-		free(buffer);
-		fclose(fp);
-		return -1;
-	}
-
-	struct json_object *board_json = json_tokener_parse(buffer);
+	struct json_object *board_json = json_object_from_file(BOARD_JSON_FILE);
 	if (board_json == NULL) {
 		BBF_ERR("failed to read board.json as json");
-		free(buffer);
-		fclose(fp);
 		return -1;
 	}
 
@@ -274,8 +235,7 @@ int init_qstat(void)
 				goto free_and_return;
 			}
 
-			ret = init_interface(json_object_get_string(l_port_name), i);
-
+			ret = init_interface_queues(json_object_get_string(l_port_name), &interfaces[i]);
 			if (ret < 0) {
 				BBF_ERR("cannot int lan ports qos");
 				json_object_put(board_json);
@@ -285,7 +245,7 @@ int init_qstat(void)
 
 		}
 	} else {
-		ret = init_interface(json_object_get_string(lan_ports), i);
+		ret = init_interface_queues(json_object_get_string(lan_ports), &interfaces[i]);
 		if (ret < 0) {
 			BBF_ERR("cannot int lan device qos");
 			json_object_put(board_json);
@@ -295,15 +255,13 @@ int init_qstat(void)
 		i++;
 	}
 
-	if (wan_device)
-		ret = init_interface(json_object_get_string(wan_device), i);
+	if (wan_device) {
+		ret = init_interface_queues(json_object_get_string(wan_device), &interfaces[i]);
+	}
 
 	json_object_put(board_json);
-	init_flag = 0;
 
 free_and_return:
-	free(buffer);
-	fclose(fp);
 	return ret;
 }
 
@@ -510,8 +468,6 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 	       struct ubus_request_data *req, const char *method,
 	       struct blob_attr *msg)
 {
-	BBF_ERR("Warning: qos ubus object has been deprecated, please use bbfdm to fetch the stats!\n");
-
 	int ret = 0;
 	int qid = QOS_QUEUE_ANY;
 	char ifname[IFNAMSIZ] = {0};
@@ -520,6 +476,7 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 	struct blob_buf b = {0};
 	struct qos_stats stats = {0};
 
+	BBF_WARNING("Warning: qos ubus object has been deprecated, please use bbfdm to fetch the stats!\n");
 	/* Validate requested parameters, i.e., ifname and qid */
 	ret = validate_request(msg);
 	if (ret) {
@@ -544,16 +501,6 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 	if (tb[QOS_POLICY_QID] && !tb[QOS_POLICY_IFNAME])
 		return UBUS_STATUS_INVALID_ARGUMENT;
 
-	// Initialize global q_stat global struct
-	if (init_flag) {
-		ret = init_qstat();
-		if (ret) {
-			BBF_ERR("Failed to initialize gobal q_stat");
-			return ret;
-		}
-		BBF_INFO("Initialized gobal q_stat successfully");
-	}
-
 	blob_buf_init(&b, 0);
 
 	d = blobmsg_open_array(&b, "queues");
diff --git a/include/qosmngr.h b/src/qosmngr.h
similarity index 94%
rename from include/qosmngr.h
rename to src/qosmngr.h
index e846b1a..9784af2 100644
--- a/include/qosmngr.h
+++ b/src/qosmngr.h
@@ -58,11 +58,17 @@ extern const struct blobmsg_policy get_status_policy[NUM_QOS_POLICY];
 
 /* A QoS queue. */
 struct qos_queue {
-	char name[IFNAMSIZ];
 	bool enable;
 	struct qos_queue_config config;
+	char name[IFNAMSIZ];
 };
 
+typedef struct protocol_list {
+	struct list_head list;
+	int proto_num;
+	char proto_name[32];
+} protocol_list_t;
+
 int init_qstat(void);
 int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 		       struct ubus_request_data *req, const char *method,
diff --git a/test/cmocka/Makefile b/test/cmocka/Makefile
deleted file mode 100644
index 0051154..0000000
--- a/test/cmocka/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-include ../../common.mk
-
-QOSMNGR_LIB_DIR = $(PROJECT_TOPLEVEL)
-CMOCKA_LIB	= -lcmocka
-LIBS		= $(QOSMNGR_LDFLAGS) $(CMOCKA_LIB) -lpthread $(COMMON_LDFLAGS) -ljson-validator -ljson-schema-validator -ljson-editor
-CFLAGS		= -g -Wall -O0 -fPIC -I$(INCLUDE_DIR)
-LDFLAGS		= $(LIBS) -Wl,-rpath=$(QOSMNGR_LIB_DIR) -I$(QOSMNGR_LIB_DIR) --coverage
-FUNCTIONAL_TESTS = functional_test_qos
-
-VALGRIND	= valgrind --leak-check=full --show-reachable=no \
-	--show-leak-kinds=all --errors-for-leak-kinds=all \
-	--error-exitcode=1 --track-origins=yes
-
-%.o: %.c
-	$(CC) $(CFLAGS) $(FPIC) -c -o $@ $<
-
-functional_test_qos: functional_test_qos.o
-	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
-
-functional-test: $(FUNCTIONAL_TESTS)
-	$(foreach testprog, $(FUNCTIONAL_TESTS), sudo $(VALGRIND) ./$(testprog);)
-
-.PHONY: clean
-
-clean:
-	rm $(FUNCTIONAL_TESTS) *.o *.gcno *.gcda -fv
diff --git a/test/cmocka/functional_test_qos.c b/test/cmocka/functional_test_qos.c
deleted file mode 100644
index 2f15f64..0000000
--- a/test/cmocka/functional_test_qos.c
+++ /dev/null
@@ -1,240 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <errno.h>
-#include <cmocka.h>
-
-#include <libubus.h>
-#include <libubox/blobmsg_json.h>
-#include <libubox/blobmsg.h>
-
-#include <json-validator.h>
-#include <json-c/json.h>
-#include <json-editor.h>
-#include <json-c/json_tokener.h>
-
-#include "qosmngr.h"
-
-#define UBUS_OUTPUT_FILE "/tmp/qosmngr_ubus_output.txt"
-
-struct json_object *json_output = NULL;
-
-/**
- *  group_setup function to setup the test modules
- *  @param state input parameter pointer to a pointer to test state
- */
-static int group_setup(void **state)
-{
-	// Start ubusd if it is not running
-	system("pidof ubusd || ubusd &");
-
-	// Restart qosmngr
-	system("kill $(pidof qosmngr) 2>/dev/null; ../../qosmngr &");
-
-	return 0;
-}
-
-/**
- *  group_teardown function to cleanup the test modules
- *  @param state input parameter pointer to a pointer to test state
- */
-static int group_teardown(void **state)
-{
-	// Stop qosmngr
-	system("kill $(pidof qosmngr) 2>/dev/null");
-
-	// Delete test logs
-	unlink(UBUS_OUTPUT_FILE);
-
-	return 0;
-}
-
-/**
- *  teardown function to cleanup the test modules
- *  @param state input parameter pointer to a pointer to test state
- */
-static int teardown(void **state)
-{
-	if (json_output) {
-		json_object_put(json_output); // Free the output JSON object
-		json_output = NULL;
-	}
-
-	return 0;
-}
-
-/**
- *  validate_queues function to validate all queues received under queues
- *  @param queues input parameter pointer to json_object containg all queues to
- *  be validated
- */
-static void validate_queues(struct json_object *queues)
-{
-	int i;
-	int len;
-
-	assert_non_null(queues);
-	len = json_object_array_length(queues);
-
-	// Assert on length as well, should be greater than 0
-	assert_true(len >= 0);
-
-	for (i = 0; i < len; i++) {
-		struct json_object *queue = json_object_array_get_idx(queues, i);
-		json_object_object_foreach(queue, key, val) {
-			int val_type = json_object_get_type(val);
-			switch(val_type) {
-			case json_type_int:
-				assert_true(json_object_get_int(val) >= 0);
-				break;
-			case json_type_string:
-				assert_true(!strncmp(json_object_get_string(val),
-						   "eth", strlen("eth")));
-				break;
-			}
-		}
-	}
-}
-
-/**
- *  validate_stats function to validate json_object received under json_obj
- *  @param json_obj input parameter pointer to json_object containg ubus output
- */
-static void validate_stats(struct json_object *json_obj)
-{
-        assert_non_null(json_obj);
-
-	json_object_object_foreach(json_obj, key, val) {
-		int val_type = json_object_get_type(val);
-
-		if (val_type == json_type_array) {
-			switch (val_type) {
-			case json_type_array:
-				validate_queues(val);
-				break;
-			}
-		}
-	}
-}
-
-/**
- *  get_ubus_call_output function to fill global json output variable with ubus call output
- *  @param ubus_cmd input parameter pointer to char string containg ubus call
- *  @param negative_case input parameter of type bool to identify negative scenarios
- */
-static void get_ubus_call_output(const char *ubus_cmd, bool negative_case)
-{
-	char cmd[256];
-	int fd = -1;
-	char *str = NULL;
-
-	// Put the output of ubus call into a string
-	snprintf(cmd, sizeof(cmd), "%s > %s", ubus_cmd, UBUS_OUTPUT_FILE);
-	int rc = system(cmd);
-	assert_return_code(rc, errno);
-
-	fd = open(UBUS_OUTPUT_FILE, O_RDONLY);
-	assert_return_code(fd, errno);
-
-	struct stat st;
-	rc = fstat(fd, &st);
-
-	if(negative_case) {
-		assert_false(rc == 0 && st.st_size > 0);
-		return;
-	} else
-		assert_true(rc == 0 && st.st_size > 0);
-
-	str = calloc(1, (size_t)st.st_size + 1);
-	assert_non_null(str);
-
-	ssize_t read_len = read(fd, str, (size_t)st.st_size);
-	assert_int_equal((int)read_len, (int)st.st_size);
-
-	// Parse the string to a json_object
-	//printf("JSON_OBJECT GET : %s\n", str);
-	json_output = json_tokener_parse(str);
-
-	if (fd >= 0)
-		close(fd);
-	if (str)
-		free(str);
-}
-
-/**
- *  test_qos_stats_no_param function to test qos_stats without any parameter
- *  @param state input parameter pointer to a pointer to test state
- */
-static void test_qos_stats_no_param(void **state)
-{
-	get_ubus_call_output("ubus call qos queue_stats", false);
-	validate_stats(json_output);
-}
-
-/**
- *  test_qos_stats_one_param function to test qos_stats with just ifname
- *  @param state input parameter pointer to a pointer to test state
- */
-static void test_qos_stats_one_param(void **state)
-{
-	get_ubus_call_output("ubus call qos queue_stats '{\"ifname\":\"eth0\"}'", false);
-	validate_stats(json_output);
-}
-
-/**
- *  test_qos_stats_all_param function to test qos_stats with all valid params
- *  @param state input parameter pointer to a pointer to test state
- */
-static void test_qos_stats_all_param(void **state)
-{
-	get_ubus_call_output("ubus call qos queue_stats '{\"ifname\":\"eth0\", \"qid\":0}'", false);
-	validate_stats(json_output);
-}
-
-/**
- *  test_qos_stats_missing_param_ifname function to test missing parameter i.e., ifname
- *  @param state input parameter pointer to a pointer to test state
- */
-static void test_qos_stats_missing_param_ifname(void **state)
-{
-	get_ubus_call_output("ubus call qos queue_stats '{\"qid\":0}'", true);
-}
-
-/**
- *  test_qos_stats_invalid_param_port function to test invalid parameter as port
- *  @param state input parameter pointer to a pointer to test state
- */
-static void test_qos_stats_invalid_param_port(void **state)
-{
-	get_ubus_call_output("ubus call qos queue_stats '{\"port\":\"eth0\"}'", true);
-}
-
-/**
- *  test_qos_stats_invalid_param_pid function to test invalid parameter as pid
- *  @param state input parameter pointer to a pointer to test state
- */
-static void test_qos_stats_invalid_param_pid(void **state)
-{
-	get_ubus_call_output("ubus call qos queue_stats '{\"ifname\":\"eth0\", \"pid\":0}'", true);
-}
-
-int main(void)
-{
-	const struct CMUnitTest tests[] = {
-		cmocka_unit_test_teardown(test_qos_stats_no_param, teardown),
-		cmocka_unit_test_teardown(test_qos_stats_one_param, teardown),
-		cmocka_unit_test_teardown(test_qos_stats_all_param, teardown),
-
-		// -ve scenarios
-		cmocka_unit_test_teardown(test_qos_stats_missing_param_ifname, teardown),
-		cmocka_unit_test_teardown(test_qos_stats_invalid_param_port, teardown),
-		cmocka_unit_test_teardown(test_qos_stats_invalid_param_pid, teardown),
-	};
-
-	return cmocka_run_group_tests(tests, group_setup, group_teardown);
-}
-- 
GitLab