diff --git a/bbfdmd/ubus/bbfdmd.c b/bbfdmd/ubus/bbfdmd.c
index 1d3b9037404cd3c5569ce29c3e5a3fcfdae017b4..455f19a9fbe4c0600c91814a24c003b6d9fac4fc 100644
--- a/bbfdmd/ubus/bbfdmd.c
+++ b/bbfdmd/ubus/bbfdmd.c
@@ -38,6 +38,7 @@ static int bbfdm_handler_async(struct ubus_context *ctx, struct ubus_object *obj
 {
 	struct blob_attr *tb[__BBFDM_MAX];
 	service_entry_t *service = NULL;
+	unsigned int requested_proto = BBFDMD_BOTH;
 
 	if (blobmsg_parse(bbfdm_policy, __BBFDM_MAX, tb, blob_data(msg), blob_len(msg))) {
 		BBFDM_ERR("Failed to parse input message");
@@ -76,7 +77,7 @@ static int bbfdm_handler_async(struct ubus_context *ctx, struct ubus_object *obj
 		ubus_register_event_handler(ctx, &context->linker_handler, "bbfdm.linker.response");
 	}
 
-	unsigned int requested_proto = get_proto_type_option_value(tb[BBFDM_INPUT]);
+	fill_optional_input(tb[BBFDM_INPUT], &requested_proto, &context->raw_format);
 
 	ubus_defer_request(ctx, req, &context->request_data);
 
@@ -102,6 +103,8 @@ static int bbfdm_handler_sync(struct ubus_context *ctx, struct ubus_object *obj,
 	struct blob_attr *tb[__BBFDM_MAX];
 	service_entry_t *service = NULL;
 	char requested_path[MAX_PATH_LENGTH];
+	unsigned int requested_proto = BBFDMD_BOTH;
+	bool raw_format = false;
 	struct blob_buf bb = {0};
 
 	if (blobmsg_parse(bbfdm_policy, __BBFDM_MAX, tb, blob_data(msg), blob_len(msg))) {
@@ -121,7 +124,7 @@ static int bbfdm_handler_sync(struct ubus_context *ctx, struct ubus_object *obj,
 	memset(&bb, 0, sizeof(struct blob_buf));
 	blob_buf_init(&bb, 0);
 
-	unsigned int requested_proto = get_proto_type_option_value(tb[BBFDM_INPUT]);
+	fill_optional_input(tb[BBFDM_INPUT], &requested_proto, &raw_format);
 
 	list_for_each_entry(service, &registered_services, list) {
 
diff --git a/bbfdmd/ubus/cli.c b/bbfdmd/ubus/cli.c
index 8fad9ee299bd22f827adcf1afe588dc142b17ce0..473731c3c81c730b35bdff023503424a282c2b6d 100644
--- a/bbfdmd/ubus/cli.c
+++ b/bbfdmd/ubus/cli.c
@@ -70,21 +70,6 @@ static int bbfdm_ubus_invoke(const char *obj, const char *method, struct blob_at
 	return rc;
 }
 
-static struct blob_attr *get_results_array(struct blob_attr *msg)
-{
-	struct blob_attr *tb[1] = {0};
-	const struct blobmsg_policy p[1] = {
-			{ "results", BLOBMSG_TYPE_ARRAY }
-	};
-
-	if (msg == NULL)
-		return NULL;
-
-	blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
-
-	return tb[0];
-}
-
 static void __ubus_callback(struct ubus_request *req, int msgtype __attribute__((unused)), struct blob_attr *msg)
 {
 	struct blob_attr *cur = NULL;
@@ -160,6 +145,10 @@ static int cli_exec_cmd(cli_data_t *cli_data, const char *path, const char *valu
 	blobmsg_add_string(&b, "path", path);
 	blobmsg_add_string(&b, "value", value ? value : "");
 
+	void *table = blobmsg_open_table(&b, "optional");
+	blobmsg_add_string(&b, "format", "raw");
+	blobmsg_close_table(&b, table);
+
 	int e = bbfdm_ubus_invoke(BBFDM_UBUS_OBJECT, cli_data->cmd, b.head, __ubus_callback, cli_data);
 
 	if (e < 0) {
diff --git a/bbfdmd/ubus/common.c b/bbfdmd/ubus/common.c
index deae68cd2c2a73f56b047f9b394da4ffa6336003..a906dbd3bbbf9a0fdf364c0a0e6d414ba6723407 100644
--- a/bbfdmd/ubus/common.c
+++ b/bbfdmd/ubus/common.c
@@ -32,25 +32,60 @@ unsigned int get_proto_type(const char *proto)
 	return type;
 }
 
-unsigned int get_proto_type_option_value(struct blob_attr *msg)
+static bool is_raw_format_type(const char *format)
 {
-	struct blob_attr *tb[1] = {0};
-	const struct blobmsg_policy p[1] = {
-			{ "proto", BLOBMSG_TYPE_STRING }
+	bool raw_format = false;
+
+	if (format) {
+		if (strcmp(format, "raw") == 0)
+			raw_format = true;
+		else
+			raw_format = false;
+	}
+
+	return raw_format;
+}
+
+void fill_optional_input(struct blob_attr *msg, unsigned int *proto, bool *raw_format)
+{
+	struct blob_attr *tb[2] = {0};
+	const struct blobmsg_policy p[2] = {
+			{ "proto", BLOBMSG_TYPE_STRING },
+			{ "format", BLOBMSG_TYPE_STRING }
 	};
-	int proto = BBFDMD_BOTH;
+
+	*proto = BBFDMD_BOTH;
+	*raw_format = false;
 
 	if (!msg)
-		return proto;
+		return;
 
-	blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
+	blobmsg_parse(p, 2, tb, blobmsg_data(msg), blobmsg_len(msg));
 
 	if (tb[0]) {
 		const char *val = blobmsg_get_string(tb[0]);
-		proto = get_proto_type(val);
+		*proto = get_proto_type(val);
 	}
 
-	return proto;
+	if (tb[1]) {
+		const char *val = blobmsg_get_string(tb[1]);
+		*raw_format = is_raw_format_type(val);
+	}
+}
+
+struct blob_attr *get_results_array(struct blob_attr *msg)
+{
+	struct blob_attr *tb[1] = {0};
+	const struct blobmsg_policy p[1] = {
+			{ "results", BLOBMSG_TYPE_ARRAY }
+	};
+
+	if (msg == NULL)
+		return NULL;
+
+	blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
+
+	return tb[0];
 }
 
 bool proto_matches(unsigned int dm_type, const enum bbfdmd_type_enum type)
diff --git a/bbfdmd/ubus/common.h b/bbfdmd/ubus/common.h
index 3d1d42bb2838c762211ce7c93904d67c31e48e21..f9830d6fc6117ef3a52a123772ffa393e289b8f4 100644
--- a/bbfdmd/ubus/common.h
+++ b/bbfdmd/ubus/common.h
@@ -30,7 +30,11 @@ enum bbfdmd_type_enum {
 };
 
 unsigned int get_proto_type(const char *proto);
-unsigned int get_proto_type_option_value(struct blob_attr *msg);
+
+void fill_optional_input(struct blob_attr *msg, unsigned int *proto, bool *raw_format);
+
+struct blob_attr *get_results_array(struct blob_attr *msg);
+
 bool proto_matches(unsigned int dm_type, const enum bbfdmd_type_enum type);
 
 char *get_reference_data(const char *path, const char *method_name);
diff --git a/bbfdmd/ubus/get.c b/bbfdmd/ubus/get.c
index 82078af7bdeea1e5735f3560b734e684b917c065..3e6a6ef4015aa3ed3ddf9efe4e78540fe7d9b431 100644
--- a/bbfdmd/ubus/get.c
+++ b/bbfdmd/ubus/get.c
@@ -15,6 +15,7 @@
 #include "common.h"
 #include "service.h"
 #include "get.h"
+#include "pretty_print.h"
 
 extern int g_log_level;
 
@@ -161,23 +162,23 @@ static void resolve_reference_path(struct async_request_context *ctx, struct blo
 static void prepare_and_send_response(struct async_request_context *ctx)
 {
 	struct blob_attr *attr = NULL;
-	struct blob_buf bb = {0};
-	int remaining = 0;
+	struct blob_buf bb_raw = {0};
+	size_t remaining = 0;
 
 	if (!ctx)
 		return;
 
-	memset(&bb, 0, sizeof(struct blob_buf));
-	blob_buf_init(&bb, 0);
+	memset(&bb_raw, 0, sizeof(struct blob_buf));
+	blob_buf_init(&bb_raw, 0);
 
-	void *array = blobmsg_open_array(&bb, "results");
+	void *array = blobmsg_open_array(&bb_raw, "results");
 
 	if (ctx->path_matched == false) {
-		void *table = blobmsg_open_table(&bb, NULL);
-		blobmsg_add_string(&bb, "path", ctx->requested_path);
-		blobmsg_add_u32(&bb, "fault", 9005);
-		blobmsg_add_string(&bb, "fault_msg", "Invalid parameter name");
-		blobmsg_close_table(&bb, table);
+		void *table = blobmsg_open_table(&bb_raw, NULL);
+		blobmsg_add_string(&bb_raw, "path", ctx->requested_path);
+		blobmsg_add_u32(&bb_raw, "fault", 9005);
+		blobmsg_add_string(&bb_raw, "fault_msg", "Invalid parameter name");
+		blobmsg_close_table(&bb_raw, table);
 	} else {
 		blobmsg_for_each_attr(attr, ctx->tmp_bb.head, remaining) {
 
@@ -195,20 +196,33 @@ static void prepare_and_send_response(struct async_request_context *ctx)
 				if (is_reference_value(fields[3])) {
 					char data[MAX_VALUE_LENGTH] = {0};
 					resolve_reference_path(ctx, fields[1], data, sizeof(data));
-					fill_blob_param(&bb, fields[0], data, fields[2], fields[3]);
+					fill_blob_param(&bb_raw, fields[0], data, fields[2], fields[3]);
 				} else {
-					blobmsg_add_blob(&bb, attr);
+					blobmsg_add_blob(&bb_raw, attr);
 				}
 			} else {
-				blobmsg_add_blob(&bb, attr);
+				blobmsg_add_blob(&bb_raw, attr);
 			}
 		}
 	}
 
-	blobmsg_close_array(&bb, array);
+	blobmsg_close_array(&bb_raw, array);
 
-	ubus_send_reply(ctx->ubus_ctx, &ctx->request_data, bb.head);
-	blob_buf_free(&bb);
+	if (strcmp(ctx->ubus_method, "get") == 0 && ctx->raw_format == false) { // Pretty Format
+		struct blob_buf bb_pretty = {0};
+
+		memset(&bb_pretty, 0, sizeof(struct blob_buf));
+		blob_buf_init(&bb_pretty, 0);
+
+		prepare_pretty_response(ctx->requested_path, bb_raw.head, &bb_pretty);
+
+		ubus_send_reply(ctx->ubus_ctx, &ctx->request_data, bb_pretty.head);
+		blob_buf_free(&bb_pretty);
+	} else { // Raw Format
+		ubus_send_reply(ctx->ubus_ctx, &ctx->request_data, bb_raw.head);
+	}
+
+	blob_buf_free(&bb_raw);
 }
 
 void send_response(struct async_request_context *ctx)
@@ -226,21 +240,6 @@ void send_response(struct async_request_context *ctx)
 	BBFDM_FREE(ctx);
 }
 
-static struct blob_attr *get_results_array(struct blob_attr *msg)
-{
-	struct blob_attr *tb[1] = {0};
-	const struct blobmsg_policy p[1] = {
-			{ "results", BLOBMSG_TYPE_ARRAY }
-	};
-
-	if (msg == NULL)
-		return NULL;
-
-	blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
-
-	return tb[0];
-}
-
 static void append_response_data(struct ubus_request_tracker *tracker, struct blob_attr *msg)
 {
 	struct blob_attr *attr = NULL;
diff --git a/bbfdmd/ubus/get.h b/bbfdmd/ubus/get.h
index 4350d1a51d8fcc6e6428a631d5dde97f18b17f3e..9933d6bc55a6f7109710c25d1fffc8cafdc974bf 100644
--- a/bbfdmd/ubus/get.h
+++ b/bbfdmd/ubus/get.h
@@ -33,6 +33,7 @@ struct async_request_context {
 	struct blob_buf tmp_bb;
 	bool service_list_processed;
 	bool path_matched;
+	bool raw_format;
 	int pending_requests;
 	char requested_path[MAX_PATH_LENGTH];
 	char ubus_method[32];
diff --git a/bbfdmd/ubus/pretty_print.c b/bbfdmd/ubus/pretty_print.c
new file mode 100644
index 0000000000000000000000000000000000000000..5032bf51c3c2c73fa1b9cc157a98b6aeba5600c5
--- /dev/null
+++ b/bbfdmd/ubus/pretty_print.c
@@ -0,0 +1,590 @@
+/*
+ * Copyright (C) 2025 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: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
+ *
+ */
+
+#include <regex.h>
+#include <sys/param.h>
+#include <libubus.h>
+#include <libubox/blobmsg_json.h>
+
+#include "common.h"
+
+#define MAX_KEY_LENGTH 256
+#define DELIM '.'
+#define GLOB_CHAR "[*]+"
+
+struct pvNode {
+	char *param;
+	char *val;
+	char *type;
+	struct list_head list;
+};
+
+struct resultstack {
+	void *cookie;
+	char *key;
+	struct list_head list;
+};
+
+enum dmt_type_enum {
+	DMT_STRING,
+	DMT_UNINT,
+	DMT_INT,
+	DMT_UNLONG,
+	DMT_LONG,
+	DMT_BOOL,
+	DMT_TIME,
+	DMT_HEXBIN,
+	DMT_BASE64,
+	DMT_COMMAND,
+	DMT_EVENT,
+	__DMT_INVALID
+};
+
+static void strncpyt(char *dst, const char *src, size_t n)
+{
+	if (dst == NULL || src == NULL)
+		return;
+
+	if (n > 1) {
+		strncpy(dst, src, n - 1);
+		dst[n - 1] = 0;
+	}
+}
+
+static void add_pv_list(const char *para, const char *val, const char *type, struct list_head *pv_list)
+{
+	struct pvNode *node = NULL;
+
+	node = (struct pvNode *)calloc(1, sizeof(*node));
+
+	if (!node) {
+		BBFDM_ERR("Out of memory!");
+		return;
+	}
+
+	INIT_LIST_HEAD(&node->list);
+	list_add_tail(&node->list, pv_list);
+
+	node->param = (para) ? strdup(para) : strdup("");
+	node->val = (val) ? strdup(val) : strdup("");
+	node->type = (type) ? strdup(type) : strdup("");
+}
+
+static void free_pv_list(struct list_head *pv_list)
+{
+	struct pvNode *iter = NULL, *node = NULL;
+
+	list_for_each_entry_safe(iter, node, pv_list, list) {
+		BBFDM_FREE(iter->param);
+		BBFDM_FREE(iter->val);
+		BBFDM_FREE(iter->type);
+
+		list_del(&iter->list);
+		BBFDM_FREE(iter);
+	}
+}
+
+static bool match(const char *string, const char *pattern, size_t nmatch, regmatch_t pmatch[])
+{
+	regex_t re;
+
+	if (!string || !pattern)
+		return 0;
+
+	if (regcomp(&re, pattern, REG_EXTENDED) != 0)
+		return 0;
+
+	int status = regexec(&re, string, nmatch, pmatch, 0);
+
+	regfree(&re);
+
+	return (status != 0) ? false : true;
+}
+
+static bool is_node_instance(const char *path)
+{
+	if (!path)
+		return false;
+
+	if (strtol(path, NULL, 10))
+		return true;
+
+	return false;
+}
+
+static int count_consecutive_digits(char *p)
+{
+	int num_digits = 0;
+	char c;
+
+	if (!p)
+		return 0;
+
+	c = *p++;
+	while ((c >= '0') && (c <= 9)) {
+		num_digits++;
+		c = *p++;
+	}
+
+	return num_digits;
+}
+
+static int compare_path(const void *arg1, const void *arg2)
+{
+	const struct pvNode *pv1 = (const struct pvNode *)arg1;
+	const struct pvNode *pv2 = (const struct pvNode *)arg2;
+
+	char *s1 = pv1->param;
+	char *s2 = pv2->param;
+
+	char c1, c2;
+	int num_digits_s1;
+	int num_digits_s2;
+	int delta;
+
+	// Skip all characters which are the same
+	while (true) {
+		c1 = *s1;
+		c2 = *s2;
+
+		// Exit if reached the end of either string
+		if ((c1 == '\0') || (c2 == '\0')) {
+			// NOTE: The following comparision puts s1 before s2, if s1 terminates before s2 (and vice versa)
+			return (int)c1 - (int)c2;
+		}
+
+		// Exit if the characters do not match
+		if (c1 != c2) {
+			break;
+		}
+
+		// As characters match, move to next characters
+		s1++;
+		s2++;
+	}
+
+	// If the code gets here, then we have reached a character which is different
+	// Determine the number of digits in the rest of the string (this may be 0 if the first character is not a digit)
+	num_digits_s1 = count_consecutive_digits(s1);
+	num_digits_s2 = count_consecutive_digits(s2);
+
+	// Determine if the number of digits in s1 is greater than in s2 (if so, s1 comes after s2)
+	delta = num_digits_s1 - num_digits_s2;
+	if (delta != 0) {
+		return delta;
+	}
+
+	// If the code gets here, then the strings contain either no digits, or the same number of digits,
+	// so just compare the characters (this also works if the characters are digits)
+	return (int)c1 - (int)c2;
+}
+
+static struct pvNode *sort_pv_path(struct list_head *pv_list, size_t pv_count)
+{
+	if (!pv_list || pv_count == 0)
+		return NULL;
+
+	if (list_empty(pv_list))
+		return NULL;
+
+	struct pvNode *arr = (struct pvNode *)calloc(pv_count, sizeof(struct pvNode));
+	if (arr == NULL)
+		return NULL;
+
+	struct pvNode *pv = NULL;
+	size_t i = 0;
+
+	list_for_each_entry(pv, pv_list, list) {
+		if (i == pv_count)
+			break;
+
+		memcpy(&arr[i], pv, sizeof(struct pvNode));
+		i++;
+	}
+
+	qsort(arr, pv_count, sizeof(struct pvNode), compare_path);
+
+	return arr;
+}
+
+static bool is_leaf_element(char *path)
+{
+	char *ptr = NULL;
+
+	if (!path)
+		return true;
+
+	ptr = strchr(path, DELIM);
+
+	return (ptr == NULL);
+}
+
+static bool get_next_element(char *path, char *param)
+{
+	char *ptr = NULL;
+	size_t len = 0;
+
+	if (!path)
+		return false;
+
+	len = strlen(path);
+	ptr = strchr(path, DELIM);
+	if (ptr)
+		strncpyt(param, path, (size_t)labs(ptr - path) + 1);
+	else
+		strncpyt(param, path, len + 1);
+
+	return true;
+}
+
+static bool is_same_group(char *path, char *group)
+{
+	return (strncmp(path, group, strlen(group)) == 0);
+}
+
+static int get_dm_type(char *dm_type)
+{
+	if (dm_type == NULL)
+		return DMT_STRING;
+
+	if (strcmp(dm_type, "xsd:string") == 0)
+		return DMT_STRING;
+	else if (strcmp(dm_type, "xsd:unsignedInt") == 0)
+		return DMT_UNINT;
+	else if (strcmp(dm_type, "xsd:int") == 0)
+		return DMT_INT;
+	else if (strcmp(dm_type, "xsd:unsignedLong") == 0)
+		return DMT_UNLONG;
+	else if (strcmp(dm_type, "xsd:long") == 0)
+		return DMT_LONG;
+	else if (strcmp(dm_type, "xsd:boolean") == 0)
+		return DMT_BOOL;
+	else if (strcmp(dm_type, "xsd:dateTime") == 0)
+		return DMT_TIME;
+	else if (strcmp(dm_type, "xsd:hexBinary") == 0)
+		return DMT_HEXBIN;
+	else if (strcmp(dm_type, "xsd:base64") == 0)
+		return DMT_BASE64;
+	else if (strcmp(dm_type, "xsd:command") == 0)
+		return DMT_COMMAND;
+	else if (strcmp(dm_type, "xsd:event") == 0)
+		return DMT_EVENT;
+	else
+		return DMT_STRING;
+
+	return DMT_STRING;
+}
+
+bool get_boolean_string(char *value)
+{
+	if (!value)
+		return false;
+
+	if (strncasecmp(value, "true", 4) == 0 ||
+	    value[0] == '1' ||
+	    strncasecmp(value, "on", 2) == 0 ||
+	    strncasecmp(value, "yes", 3) == 0 ||
+	    strncasecmp(value, "enabled", 7) == 0)
+		return true;
+
+	return false;
+}
+
+static void add_data_blob(struct blob_buf *bb, char *param, char *value, char *type)
+{
+	if (param == NULL || value == NULL || type == NULL)
+		return;
+
+	switch (get_dm_type(type)) {
+	case DMT_UNINT:
+		blobmsg_add_u64(bb, param, (uint32_t)strtoul(value, NULL, 10));
+		break;
+	case DMT_INT:
+		blobmsg_add_u32(bb, param, (int)strtol(value, NULL, 10));
+		break;
+	case DMT_LONG:
+		blobmsg_add_u64(bb, param, strtoll(value, NULL, 10));
+		break;
+	case DMT_UNLONG:
+		blobmsg_add_u64(bb, param, (uint64_t)strtoull(value, NULL, 10));
+		break;
+	case DMT_BOOL:
+		if (get_boolean_string(value))
+			blobmsg_add_u8(bb, param, true);
+		else
+			blobmsg_add_u8(bb, param, false);
+		break;
+	default: //"xsd:hexbin" "xsd:dateTime" "xsd:string"
+		blobmsg_add_string(bb, param, value);
+		break;
+	}
+}
+
+static void add_result_node(struct list_head *rlist, char *key, char *cookie)
+{
+	struct resultstack *rnode = NULL;
+
+	rnode = (struct resultstack *)calloc(1, sizeof(*rnode));
+	if (!rnode) {
+		BBFDM_ERR("Out of memory!");
+		return;
+	}
+
+	INIT_LIST_HEAD(&rnode->list);
+	list_add(&rnode->list, rlist);
+
+	rnode->key = (key) ? strdup(key) : strdup("");
+	rnode->cookie = cookie;
+}
+
+static void free_result_node(struct resultstack *rnode)
+{
+	if (rnode) {
+		BBFDM_FREE(rnode->key);
+
+		list_del(&rnode->list);
+		BBFDM_FREE(rnode);
+	}
+}
+
+static void free_result_list(struct list_head *head)
+{
+	struct resultstack *iter = NULL, *node = NULL;
+
+	list_for_each_entry_safe(iter, node, head, list) {
+		BBFDM_FREE(iter->key);
+
+		list_del(&iter->list);
+		BBFDM_FREE(iter);
+	}
+}
+
+static bool add_paths_to_stack(struct blob_buf *bb, char *path, size_t begin,
+			       struct pvNode *pv, struct list_head *result_stack)
+{
+	char key[MAX_KEY_LENGTH], param[MAX_PATH_LENGTH], *ptr;
+	size_t parsed_len = 0;
+	void *c;
+	char *k;
+
+	ptr = path + begin;
+	if (is_leaf_element(ptr)) {
+		add_data_blob(bb, ptr, pv->val, pv->type);
+		return true;
+	}
+
+	while (get_next_element(ptr, key)) {
+		parsed_len += strlen(key) + 1;
+		ptr += strlen(key) + 1;
+		if (is_leaf_element(ptr)) {
+			strncpyt(param, path, begin + parsed_len + 1);
+			if (is_node_instance(key))
+				c = blobmsg_open_table(bb, NULL);
+			else
+				c = blobmsg_open_table(bb, key);
+
+			k = param;
+			add_result_node(result_stack, k, c);
+			add_data_blob(bb, ptr, pv->val, pv->type);
+			break;
+		}
+		strncpyt(param, pv->param, begin + parsed_len + 1);
+		if (is_node_instance(ptr))
+			c = blobmsg_open_array(bb, key);
+		else
+			c = blobmsg_open_table(bb, key);
+
+		k = param;
+		add_result_node(result_stack, k, c);
+	}
+
+	return true;
+}
+
+static size_t list_length(struct list_head *head)
+{
+	struct list_head *pos;
+	size_t count = 0;
+
+	list_for_each(pos, head) {
+		count++;
+	}
+
+	return count;
+}
+
+static void prepare_result_blob(struct blob_buf *bb, struct list_head *pv_list)
+{
+	struct resultstack *rnode = NULL;
+	size_t pv_count = 0;
+
+	if (!bb || !pv_list)
+		return;
+
+	if (list_empty(pv_list))
+		return;
+
+	pv_count = list_length(pv_list);
+
+	struct pvNode *sortedPV = sort_pv_path(pv_list, pv_count);
+	if (sortedPV == NULL)
+		return;
+
+	LIST_HEAD(result_stack);
+
+	for (size_t i = 0; i < pv_count; i++) {
+		struct pvNode *pv = &sortedPV[i];
+		char *ptr = pv->param;
+		if (list_empty(&result_stack)) {
+			BBFDM_DEBUG("stack empty Processing (%s)", ptr);
+			add_paths_to_stack(bb, pv->param, 0, pv, &result_stack);
+		} else {
+			bool is_done = false;
+
+			while (is_done == false) {
+				rnode = list_entry(result_stack.next, struct resultstack, list);
+				if (is_same_group(ptr, rnode->key)) {
+					size_t len = strlen(rnode->key);
+					ptr = ptr + len;
+
+					BBFDM_DEBUG("GROUP (%s), ptr(%s), len(%zu)", pv->param, ptr, len);
+					add_paths_to_stack(bb, pv->param, len, pv, &result_stack);
+					is_done = true;
+				} else {
+					// Get the latest entry before deleting it
+					BBFDM_DEBUG("DIFF GROUP pv(%s), param(%s)", pv->param, ptr);
+					blobmsg_close_table(bb, rnode->cookie);
+					free_result_node(rnode);
+					if (list_empty(&result_stack)) {
+						add_paths_to_stack(bb, pv->param, 0, pv, &result_stack);
+						is_done = true;
+					}
+				}
+			}
+		}
+	}
+
+	BBFDM_FREE(sortedPV);
+
+	// Close the stack entry if left
+	list_for_each_entry(rnode, &result_stack, list) {
+		blobmsg_close_table(bb, rnode->cookie);
+	}
+
+	free_result_list(&result_stack);
+}
+
+static bool is_res_required(const char *str, size_t s_len, size_t *start, size_t *len)
+{
+	if (match(str, GLOB_CHAR, 0, NULL)) {
+		char *star = strchr(str, '*');
+
+		*start = (star) ? (size_t)labs(star - str) : s_len;
+		*len = 1;
+		return true;
+	}
+
+	*start = s_len;
+	return false;
+}
+
+static size_t get_glob_len(const char *path)
+{
+	char temp_name[MAX_KEY_LENGTH] = {'\0'};
+	char *end = NULL;
+	size_t m_index = 0, m_len = 0, ret = 0;
+	size_t plen = strlen(path);
+
+	if (is_res_required(path, plen, &m_index, &m_len)) {
+		if (m_index <= MAX_KEY_LENGTH)
+			snprintf(temp_name, m_index, "%s", path);
+
+		end = strrchr(temp_name, DELIM);
+		if (end != NULL)
+			ret = m_index - strlen(end);
+	} else {
+		char name[MAX_KEY_LENGTH] = {'\0'};
+
+		if (plen == 0)
+			return ret;
+
+		if (path[plen - 1] == DELIM) {
+			if (plen <= MAX_KEY_LENGTH)
+				snprintf(name, plen, "%s", path);
+		} else {
+			ret = 1;
+			if (plen < MAX_KEY_LENGTH)
+				snprintf(name, plen + 1, "%s", path);
+		}
+
+		end = strrchr(name, DELIM);
+		if (end == NULL)
+			return ret;
+
+		ret = ret + strlen(path) - strlen(end);
+
+		if (is_node_instance(end + 1)) {
+			int copy_len = plen - strlen(end);
+			if (copy_len <= MAX_KEY_LENGTH)
+				snprintf(temp_name, copy_len, "%s", path);
+			end = strrchr(temp_name, DELIM);
+			if (end != NULL)
+				ret = ret - strlen(end);
+		}
+	}
+
+	return(ret);
+}
+
+void prepare_pretty_response(const char *path, struct blob_attr *msg, struct blob_buf *bb_pretty)
+{
+	struct blob_attr *cur = NULL;
+	size_t rem = 0;
+
+	if (!path || !msg || !bb_pretty)
+		return;
+
+	struct blob_attr *raw_attr = get_results_array(msg);
+	if (!raw_attr)
+		return;
+
+	LIST_HEAD(pv_local);
+
+	size_t plen = get_glob_len(path);
+
+	blobmsg_for_each_attr(cur, raw_attr, rem) {
+		struct blob_attr *tb[4] = {0};
+		const struct blobmsg_policy p[4] = {
+				{ "path", BLOBMSG_TYPE_STRING },
+				{ "data", BLOBMSG_TYPE_STRING },
+				{ "type", BLOBMSG_TYPE_STRING },
+				{ "fault", BLOBMSG_TYPE_INT32 },
+		};
+
+		blobmsg_parse(p, 4, tb, blobmsg_data(cur), blobmsg_len(cur));
+
+		if (tb[3]) {
+			blobmsg_add_blob(bb_pretty, cur);
+			return;
+		}
+
+		char *name = tb[0] ? blobmsg_get_string(tb[0]) : "";
+		char *data = tb[1] ? blobmsg_get_string(tb[1]) : "";
+		char *type = tb[2] ? blobmsg_get_string(tb[2]) : "";
+
+		add_pv_list(name + plen, data, type, &pv_local);
+	}
+
+	prepare_result_blob(bb_pretty, &pv_local);
+
+	free_pv_list(&pv_local);
+}
+
diff --git a/bbfdmd/ubus/pretty_print.h b/bbfdmd/ubus/pretty_print.h
new file mode 100644
index 0000000000000000000000000000000000000000..a61fcc2064758d2aa42135f44940a58b02a058d1
--- /dev/null
+++ b/bbfdmd/ubus/pretty_print.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2025 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: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
+ *
+ */
+
+#ifndef BBFDMD_PRETTY_PRINT_H
+#define BBFDMD_PRETTY_PRINT_H
+
+void prepare_pretty_response(const char *path, struct blob_attr *msg, struct blob_buf *bb_pretty);
+
+#endif /* BBFDMD_PRETTY_PRINT_H */
diff --git a/test/funl/validation/bbf.validation.json b/test/funl/validation/bbf.validation.json
index 20fdfc868f5b72f2b39408d230dfe9514dda77f1..809aa5d045cc78c185d2cebc66046e2c48ef61ff 100644
--- a/test/funl/validation/bbf.validation.json
+++ b/test/funl/validation/bbf.validation.json
@@ -17,6 +17,38 @@
             },
             "rc": 0
         },
+		{
+		    "method": "get",
+		    "args": {
+		        "path": "Device.DeviceInfo.Manufacturer",
+		        "optional": {"format":"raw", "proto":"usp"}
+		    },
+		    "rc": 0
+		},
+		{
+		    "method": "get",
+		    "args": {
+		        "path": "Device.DeviceInfo.Manufacturer",
+		        "optional": {"format":"raw", "proto":"cwmp"}
+		    },
+		    "rc": 0
+		},
+		{
+		    "method": "get",
+		    "args": {
+		        "path": "Device.DeviceInfo.Manufacturer",
+		        "optional": {"format":"pretty", "proto":"usp"}
+		    },
+		    "rc": 0
+		},
+		{
+		    "method": "get",
+		    "args": {
+		        "path": "Device.DeviceInfo.Manufacturer",
+		        "optional": {"format":"pretty", "proto":"cwmp"}
+		    },
+		    "rc": 0
+		},
         {
             "method": "get",
             "args": {
diff --git a/test/python/validate_device.py b/test/python/validate_device.py
index 05056744b377042a01b9d27d2b2cdb375210e5fb..ee5e13ace8a9bc279effdcc2f503550ff7864902 100755
--- a/test/python/validate_device.py
+++ b/test/python/validate_device.py
@@ -15,11 +15,14 @@ if sock.exists():
 else:
     assert ubus.connect()
 
-out = ubus.call('bbfdm', 'get', {"path":"Device."})
-assert isinstance(out[0]["results"][0], dict), "FAIL: get Device."
+out = ubus.call('bbfdm', 'get', {"path":"Device.", "optional":{"format":"raw"}})
+assert isinstance(out[0]["results"][0], dict), "FAIL: get Device. on bbfdm with raw format"
+
+out = ubus.call('bbfdm', 'get', {"path":"Device", "optional":{"format":"raw"}})
+assert out[0]["results"][0]["fault"] == 9005, "FAIL: get Device on bbfdm with raw format"
 
-out = ubus.call('bbfdm', 'get', {"path":"Device"})
-assert out[0]["results"][0]["fault"] == 9005, "FAIL: get Device"
+out = ubus.call('bbfdm', 'get', {"path":"Device."})
+assert isinstance(out[0]['Device'], dict), "FAIL: get Device. on bbfdm with pretty format"
 
 ubus.disconnect()
 print("PASS: " + TEST_NAME)