/*
 * uspagent_dm.c - Library for USPAgent datamodel
 *
 * Copyright (C) 2024, IOPSYS Software Solutions AB.
 *
 * Author Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
 *
 * See LICENSE file for license related information.
 *
 */

#include "uspagent_dm.h"
#include "vendor_defs.h"

/********************************
 * Browse functions
 *******************************/
static int browse_usp_agent_mtp(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.MTP.";
	json_object *mtp_ob = NULL;

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s\" | grep -v CMD_", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	mtp_ob = json_object_new_object();
	if (mtp_ob == NULL) {
		delete_cmd_result(&result_list);
		return 0;
	}

	convert_list_to_json(mtp_ob, &result_list);
	delete_cmd_result(&result_list);

	json_object *obj = dmjson_get_obj(mtp_ob, 3, "Device", "LocalAgent", "MTP");

	if (obj && json_object_is_type(obj, json_type_array)) {
		int idx = 0;
		int mtp_count = json_object_array_length(obj);

		for (idx = 0; idx < mtp_count; idx++) {
			json_object *curr = json_object_array_get_idx(obj, idx);
			if (curr == NULL) {
				continue;
			}

			char path[MAX_PATH_LEN] = {0};
			snprintf(path, sizeof(path), "Device.LocalAgent.MTP.%d", idx+1);

			struct dm_data data = {0};
			data.json_object = curr;
			data.additional_data = (void *)dmstrdup(path);

			char *inst = handle_instance_without_section(dmctx, parent_node, idx+1);
			if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
				break;
		}
	}

	if (mtp_ob != NULL) {
		json_object_put(mtp_ob);
		mtp_ob = NULL;
	}

	return 0;
}

static int browse_usp_agent_controller(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.Controller.";
	json_object *cont_ob = NULL;

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s\" | grep -v CMD_", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	cont_ob = json_object_new_object();
	if (cont_ob == NULL) {
		delete_cmd_result(&result_list);
		return 0;
	}

	convert_list_to_json(cont_ob, &result_list);
	delete_cmd_result(&result_list);

	json_object *obj = dmjson_get_obj(cont_ob, 3, "Device", "LocalAgent", "Controller");

	if (obj && json_object_is_type(obj, json_type_array)) {
		int idx = 0;
		int con_count = json_object_array_length(obj);

		for (idx = 0; idx < con_count; idx++) {
			json_object *curr = json_object_array_get_idx(obj, idx);
			if (curr == NULL) {
				continue;
			}

			char path[MAX_PATH_LEN] = {0};
			snprintf(path, sizeof(path), "Device.LocalAgent.Controller.%d", idx+1);

			struct dm_data data = {0};
			data.json_object = curr;
			data.additional_data = (void *)dmstrdup(path);

			char *inst = handle_instance_without_section(dmctx, parent_node, idx+1);
			if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
				break;
		}
	}

	if (cont_ob != NULL) {
		json_object_put(cont_ob);
		cont_ob = NULL;
	}

	return 0;
}

#ifndef REMOVE_DEVICE_SECURITY
static int browse_usp_agent_certificate(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.Certificate.";
	json_object *cert_ob = NULL;

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s\" | grep -v CMD_", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	cert_ob = json_object_new_object();
	if (cert_ob == NULL) {
		delete_cmd_result(&result_list);
		return 0;
	}

	convert_list_to_json(cert_ob, &result_list);
	delete_cmd_result(&result_list);

	json_object *obj = dmjson_get_obj(cert_ob, 3, "Device", "LocalAgent", "Certificate");

	if (obj && json_object_is_type(obj, json_type_array)) {
		int idx = 0;
		int cert_count = json_object_array_length(obj);

		for (idx = 0; idx < cert_count; idx++) {
			json_object *curr = json_object_array_get_idx(obj, idx);
			if (curr == NULL) {
				continue;
			}

			char path[MAX_PATH_LEN] = {0};
			snprintf(path, sizeof(path), "Device.LocalAgent.Certificate.%d", idx+1);

			struct dm_data data = {0};
			data.json_object = curr;
			data.additional_data = (void *)dmstrdup(path);

			char *inst = handle_instance_without_section(dmctx, parent_node, idx+1);
			if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
				break;
		}
	}

	if (cert_ob != NULL) {
		json_object_put(cert_ob);
		cert_ob = NULL;
	}

	return 0;
}
#endif

static int browse_uspagent_controller_mtp(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	struct dm_data *data = (struct dm_data *)prev_data;

	if (data == NULL)
		return 0;

	char *dm_path = (char *)data->additional_data;
	json_object *cont_obj = data->json_object;
	json_object *obj = dmjson_get_obj(cont_obj, 1, "MTP");

	if (dm_path && obj && json_object_is_type(obj, json_type_array)) {
		int idx = 0;
		int mtp_count = json_object_array_length(obj);

		for (idx = 0; idx < mtp_count; idx++) {
			json_object *curr = json_object_array_get_idx(obj, idx);
			if (curr == NULL) {
				continue;
			}

			char path[MAX_PATH_LEN] = {0};
			snprintf(path, sizeof(path), "%s.MTP.%d", dm_path, idx+1);

			struct dm_data data = {0};
			data.json_object = curr;
			data.additional_data = (void *)dmstrdup(path);

			char *inst = handle_instance_without_section(dmctx, parent_node, idx+1);
			if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
				break;
		}
	}

	return 0;
}

static int browse_uspagent_trustrole(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.ControllerTrust.Role.";
	json_object *trustrole_ob = NULL;

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s\" | grep -v CMD_", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	trustrole_ob = json_object_new_object();
	if (trustrole_ob == NULL) {
		delete_cmd_result(&result_list);
		return 0;
	}

	convert_list_to_json(trustrole_ob, &result_list);
	delete_cmd_result(&result_list);

	json_object *obj = dmjson_get_obj(trustrole_ob, 4, "Device", "LocalAgent", "ControllerTrust", "Role");

	if (obj && json_object_is_type(obj, json_type_array)) {
		int idx = 0;
		int role_count = json_object_array_length(obj);

		for (idx = 0; idx < role_count; idx++) {
			json_object *curr = json_object_array_get_idx(obj, idx);
			if (curr == NULL) {
				continue;
			}

			char path[MAX_PATH_LEN] = {0};
			snprintf(path, sizeof(path), "Device.LocalAgent.ControllerTrust.Role.%d", idx+1);

			struct dm_data data = {0};
			data.json_object = curr;
			data.additional_data = (void *)dmstrdup(path);

			char *inst = handle_instance_without_section(dmctx, parent_node, idx+1);
			if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
				break;
		}
	}

	if (trustrole_ob != NULL) {
		json_object_put(trustrole_ob);
		trustrole_ob = NULL;
	}

	return 0;
}

static int browse_uspagent_credential(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.ControllerTrust.Credential.";
	json_object *cred_ob = NULL;

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s\" | grep -v CMD_", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	cred_ob = json_object_new_object();
	if (cred_ob == NULL) {
		delete_cmd_result(&result_list);
		return 0;
	}

	convert_list_to_json(cred_ob, &result_list);
	delete_cmd_result(&result_list);

	json_object *obj = dmjson_get_obj(cred_ob, 4, "Device", "LocalAgent", "ControllerTrust", "Credential");

	if (obj && json_object_is_type(obj, json_type_array)) {
		int idx = 0;
		int cred_count = json_object_array_length(obj);

		for (idx = 0; idx < cred_count; idx++) {
			json_object *curr = json_object_array_get_idx(obj, idx);
			if (curr == NULL) {
				continue;
			}

			char path[MAX_PATH_LEN] = {0};
			snprintf(path, sizeof(path), "Device.LocalAgent.ControllerTrust.Credential.%d", idx+1);

			struct dm_data data = {0};
			data.json_object = curr;
			data.additional_data = (void *)dmstrdup(path);

			char *inst = handle_instance_without_section(dmctx, parent_node, idx+1);
			if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
				break;
		}
	}

	if (cred_ob != NULL) {
		json_object_put(cred_ob);
		cred_ob = NULL;
	}

	return 0;
}

#ifndef REMOVE_DEVICE_SECURITY
static int browse_uspagent_challenge(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.ControllerTrust.Challenge.";
	json_object *chal_ob = NULL;

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s\" | grep -v CMD_", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	chal_ob = json_object_new_object();
	if (chal_ob == NULL) {
		delete_cmd_result(&result_list);
		return 0;
	}

	convert_list_to_json(chal_ob, &result_list);
	delete_cmd_result(&result_list);

	json_object *obj = dmjson_get_obj(chal_ob, 4, "Device", "LocalAgent", "ControllerTrust", "Challenge");

	if (obj && json_object_is_type(obj, json_type_array)) {
		int idx = 0;
		int chal_count = json_object_array_length(obj);

		for (idx = 0; idx < chal_count; idx++) {
			json_object *curr = json_object_array_get_idx(obj, idx);
			if (curr == NULL) {
				continue;
			}

			char path[MAX_PATH_LEN] = {0};
			snprintf(path, sizeof(path), "Device.LocalAgent.ControllerTrust.Challenge.%d", idx+1);

			struct dm_data data = {0};
			data.json_object = curr;
			data.additional_data = (void *)dmstrdup(path);

			char *inst = handle_instance_without_section(dmctx, parent_node, idx+1);
			if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
				break;
		}
	}

	if (chal_ob != NULL) {
		json_object_put(chal_ob);
		chal_ob = NULL;
	}

	return 0;
}
#endif

static int browse_uspagent_trustrole_permis(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	struct dm_data *data = (struct dm_data *)prev_data;

	if (data == NULL)
		return 0;

	char *dm_path = (char *)data->additional_data;
	json_object *cont_obj = data->json_object;
	json_object *obj = dmjson_get_obj(cont_obj, 1, "Permission");

	if (dm_path && obj && json_object_is_type(obj, json_type_array)) {
		int idx = 0;
		int per_count = json_object_array_length(obj);

		for (idx = 0; idx < per_count; idx++) {
			json_object *curr = json_object_array_get_idx(obj, idx);
			if (curr == NULL) {
				continue;
			}

			char path[MAX_PATH_LEN] = {0};
			snprintf(path, sizeof(path), "%s.Permission.%d", dm_path, idx+1);

			struct dm_data data = {0};
			data.json_object = curr;
			data.additional_data = (void *)dmstrdup(path);

			char *inst = handle_instance_without_section(dmctx, parent_node, idx+1);
			if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
				break;
		}
	}

	return 0;
}

/********************************
 * GET functions
 *******************************/
static int get_uspagent_endpoint_id(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.EndpointID";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

static int get_uspagent_software_version(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.SoftwareVersion";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

static int get_uspagent_uptime(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.UpTime";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

static int get_uspagent_supported_protocols(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.SupportedProtocols";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

#ifndef REMOVE_DEVICE_SECURITY
static int get_uspagent_supported_fingerprints(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.SupportedFingerprintAlgorithms";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}
#endif

static int get_uspagent_mtp_number_of_entries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.MTPNumberOfEntries";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

static int get_uspagent_controller_number_of_entries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.ControllerNumberOfEntries";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

#ifndef REMOVE_DEVICE_SECURITY
static int get_uspagent_certificate_number_of_entries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.CertificateNumberOfEntries";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}
#endif

static int get_uspagent_subscription_number_of_entries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.SubscriptionNumberOfEntries";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

static int get_uspagent_mtp_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Alias");
	return 0;
}

static int get_uspagent_mtp_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Enable");
	return 0;
}

static int get_uspagent_mtp_status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Status");
	return 0;
}

static int get_uspagent_mtp_protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Protocol");
	return 0;
}

#ifndef DISABLE_STOMP
static int get_uspagent_mtp_stomp_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "STOMP", "Reference");
	return 0;
}

static int get_uspagent_mtp_stomp_destination(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "STOMP", "Destination");
	return 0;
}

static int get_uspagent_mtp_stomp_destination_from_server(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "STOMP", "DestinationFromServer");
	return 0;
}
#endif

#ifdef ENABLE_COAP
static int get_uspagent_mtp_coap_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "CoAP", "Port");
	return 0;
}

static int get_uspagent_mtp_coap_path(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "CoAP", "Path");
	return 0;
}

static int get_uspagent_mtp_coap_encryption(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "CoAP", "EnableEncryption");
	return 0;
}
#endif

#ifdef ENABLE_WEBSOCKETS
static int get_uspagent_mtp_ws_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "Port");
	return 0;
}

static int get_uspagent_mtp_ws_path(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "Path");
	return 0;
}

static int get_uspagent_mtp_ws_enable_encryption(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "EnableEncryption");
	return 0;
}

static int get_uspagent_mtp_ws_keepalive_interval(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "KeepAliveInterval");
	return 0;
}
#endif

#ifdef ENABLE_MQTT
static int get_uspagent_mtp_mqtt_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "MQTT", "Reference");
	return 0;
}

static int get_uspagent_mtp_mqtt_topic_configured(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "MQTT", "ResponseTopicConfigured");
	return 0;
}

static int get_uspagent_mtp_mqtt_topic_discovered(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "MQTT", "ResponseTopicDiscovered");
	return 0;
}

static int get_uspagent_mtp_mqtt_qos(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "MQTT", "PublishQoS");
	return 0;
}
#endif

#ifdef ENABLE_UDS
static int get_uspagent_mtp_uds_sock_ref(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "UDS", "UnixDomainSocketRef");
	return 0;
}
#endif

static int get_uspagent_controller_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Alias");
	return 0;
}

static int get_uspagent_controller_endpoint_id(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "EndpointID");
	return 0;
}

static int get_uspagent_controller_code(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "ControllerCode");
	return 0;
}

static int get_uspagent_controller_provcode(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "ProvisioningCode");
	return 0;
}

static int get_uspagent_controller_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Enable");
	return 0;
}

static int get_uspagent_controller_assigned_role(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	const char *valid_value = "Device.LocalAgent.ControllerTrust.Role.";
	struct dm_data *ob_data = (struct dm_data *)data;

	char *tmp = dmjson_get_value(ob_data->json_object, 1, "AssignedRole");

	if (DM_STRLEN(tmp) && DM_STRNCMP(tmp, valid_value, DM_STRLEN(valid_value)) == 0) {
		char val[MAX_PATH_LEN] = {0};
		tmp = tmp + DM_STRLEN("Device.LocalAgent.");
		snprintf(val, sizeof(val), "Device.USPAgent.%s", tmp);
		*value = dmstrdup(val);
	}

	return 0;
}

static int get_uspagent_controller_inherited_role(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	const char *valid_value = "Device.LocalAgent.ControllerTrust.Role.";
	struct dm_data *ob_data = (struct dm_data *)data;

	char *tmp = dmjson_get_value(ob_data->json_object, 1, "InheritedRole");

	if (DM_STRLEN(tmp) && DM_STRNCMP(tmp, valid_value, DM_STRLEN(valid_value)) == 0) {
		char val[MAX_PATH_LEN] = {0};
		tmp = tmp + DM_STRLEN("Device.LocalAgent.");
		snprintf(val, sizeof(val), "Device.USPAgent.%s", tmp);
		*value = dmstrdup(val);
	}

	return 0;
}

static int get_uspagent_controller_notifinterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "PeriodicNotifInterval");
	return 0;
}

static int get_uspagent_controller_notiftime(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "PeriodicNotifTime");
	return 0;
}

static int get_uspagent_multiplier(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "USPNotifRetryIntervalMultiplier");
	return 0;
}

static int get_uspagent_mininterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "USPNotifRetryMinimumWaitInterval");
	return 0;
}

static int get_uspagent_controller_mtp_count(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "MTPNumberOfEntries");
	return 0;
}

static int get_uspagent_controller_send_onboard(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	dmasprintf(value, "0");
	return 0;
}

static int get_uspagent_controller_mtp_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Alias");
	return 0;
}

static int get_uspagent_controller_mtp_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Enable");
	return 0;
}

static int get_uspagent_controller_mtp_protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Protocol");
	return 0;
}

#ifndef DISABLE_STOMP
static int get_uspagent_controller_mtp_stomp_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "STOMP", "Reference");
	return 0;
}

static int get_uspagent_controller_mtp_stomp_destination(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "STOMP", "Destination");
	return 0;
}
#endif

#ifdef ENABLE_COAP
static int get_uspagent_controller_mtp_coap_host(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "CoAP", "Host");
	return 0;
}

static int get_uspagent_controller_mtp_coap_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "CoAP", "Port");
	return 0;
}

static int get_uspagent_controller_mtp_coap_path(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "CoAP", "Path");
	return 0;
}

static int get_uspagent_controller_mtp_coap_encryption(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "CoAP", "EnableEncryption");
	return 0;
}
#endif

#ifdef ENABLE_WEBSOCKETS
static int get_uspagent_controller_mtp_ws_host(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "Host");
	return 0;
}

static int get_uspagent_controller_mtp_ws_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "Port");
	return 0;
}

static int get_uspagent_controller_mtp_ws_path(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "Path");
	return 0;
}

static int get_uspagent_controller_mtp_ws_encryption(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "EnableEncryption");
	return 0;
}

static int get_uspagent_controller_mtp_ws_keepalive(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "KeepAliveInterval");
	return 0;
}

static int get_uspagent_controller_mtp_ws_retry_count(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "CurrentRetryCount");
	return 0;
}

static int get_uspagent_controller_mtp_ws_mutiplier(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "SessionRetryIntervalMultiplier");
	return 0;
}

static int get_uspagent_controller_mtp_ws_minwait(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "WebSocket", "SessionRetryMinimumWaitInterval");
	return 0;
}
#endif

#ifdef ENABLE_MQTT
static int get_uspagent_controller_mtp_mqtt_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "MQTT", "Reference");
	return 0;
}

static int get_uspagent_controller_mtp_mqtt_topic(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "MQTT", "Topic");
	return 0;
}
#endif

#ifdef ENABLE_UDS
static int get_uspagent_controller_mtp_uds_sock_ref(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "UDS", "UnixDomainSocketRef");
	return 0;
}

#ifndef REMOVE_USP_BROKER
static int get_uspagent_controller_mtp_uds_usp_serv_ref(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 2, "UDS", "USPServiceRef");
	return 0;
}
#endif
#endif

#ifndef REMOVE_DEVICE_SECURITY
static int get_uspagent_certificate_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Alias");
	return 0;
}

static int get_uspagent_certificate_issuer(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Issuer");
	return 0;
}

static int get_uspagent_certificate_serial(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "SerialNumber");
	return 0;
}
#endif

static int get_uspagent_trust_role_count(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.ControllerTrust.RoleNumberOfEntries";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

static int get_uspagent_trust_credential_count(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.ControllerTrust.CredentialNumberOfEntries";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}

#ifndef REMOVE_DEVICE_SECURITY
static int get_uspagent_trust_challenge_count(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	char cmd[MAX_CMD_LEN] = {0};
	const char *dm_path = "Device.LocalAgent.ControllerTrust.ChallengeNumberOfEntries";

	LIST_HEAD(result_list);
	snprintf(cmd, sizeof(cmd), "%s %s | grep \"%s =>\"", PROG_CMD_GET, dm_path, dm_path);
	exec_cmd(cmd, &result_list);

	collect_value(dm_path, &result_list, value);
	delete_cmd_result(&result_list);

	return 0;
}
#endif

static int get_uspagent_trustrole_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Alias");
	return 0;
}

static int get_uspagent_trustrole_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Enable");
	return 0;
}

static int get_uspagent_trustrole_name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Name");
	return 0;
}

static int get_uspagent_trustrole_permis_count(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "PermissionNumberOfEntries");
	return 0;
}

static int get_uspagent_trustrole_permis_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Alias");
	return 0;
}

static int get_uspagent_trustrole_permis_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Enable");
	return 0;
}

static int get_uspagent_trustrole_permis_order(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Order");
	return 0;
}

static int get_uspagent_trustrole_permis_targets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Targets");
	return 0;
}

static int get_uspagent_trustrole_permis_param(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Param");
	return 0;
}

static int get_uspagent_trustrole_permis_obj(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Obj");
	return 0;
}

static int get_uspagent_trustrole_permis_instobj(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "InstantiatedObj");
	return 0;
}

static int get_uspagent_trustrole_permis_cmdevent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "CommandEvent");
	return 0;
}

static int get_uspagent_credential_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Alias");
	return 0;
}

static int get_uspagent_credential_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Enable");
	return 0;
}

static int get_uspagent_credential_role(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	const char *valid_value = "Device.LocalAgent.ControllerTrust.Role.";
	struct dm_data *ob_data = (struct dm_data *)data;

	char *tmp = dmjson_get_value(ob_data->json_object, 1, "Role");

	if (DM_STRLEN(tmp) && DM_STRNCMP(tmp, valid_value, DM_STRLEN(valid_value)) == 0) {
		char val[MAX_PATH_LEN] = {0};
		tmp = tmp + DM_STRLEN("Device.LocalAgent.");
		snprintf(val, sizeof(val), "Device.USPAgent.%s", tmp);
		*value = dmstrdup(val);
	}

	return 0;
}

static int get_uspagent_credential_credential(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	const char *valid_value = "Device.LocalAgent.Certificate.";
	struct dm_data *ob_data = (struct dm_data *)data;

	char *tmp = dmjson_get_value(ob_data->json_object, 1, "Credential");

	if (DM_STRLEN(tmp) && DM_STRNCMP(tmp, valid_value, DM_STRLEN(valid_value)) == 0) {
		char val[MAX_PATH_LEN] = {0};
		tmp = tmp + DM_STRLEN("Device.LocalAgent.");
		snprintf(val, sizeof(val), "Device.USPAgent.%s", tmp);
		*value = dmstrdup(val);
	}

	return 0;
}

static int get_uspagent_credential_uses(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "AllowedUses");
	return 0;
}

#ifndef REMOVE_DEVICE_SECURITY
static int get_uspagent_challenge_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Alias");
	return 0;
}

static int get_uspagent_challenge_desc(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Description");
	return 0;
}

static int get_uspagent_challenge_role(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	const char *valid_value = "Device.LocalAgent.ControllerTrust.Role.";
	struct dm_data *ob_data = (struct dm_data *)data;

	char *tmp = dmjson_get_value(ob_data->json_object, 1, "Role");

	if (DM_STRLEN(tmp) && DM_STRNCMP(tmp, valid_value, DM_STRLEN(valid_value)) == 0) {
		char val[MAX_PATH_LEN] = {0};
		tmp = tmp + DM_STRLEN("Device.LocalAgent.");
		snprintf(val, sizeof(val), "Device.USPAgent.%s", tmp);
		*value = dmstrdup(val);
	}

	return 0;
}

static int get_uspagent_challenge_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Enable");
	return 0;
}

static int get_uspagent_challenge_type(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Type");
	return 0;
}

static int get_uspagent_challenge_value(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	return 0;
}

static int get_uspagent_challenge_valuetype(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "ValueType");
	return 0;
}

static int get_uspagent_challenge_instruction(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Instruction");
	return 0;
}

static int get_uspagent_challenge_instructiontype(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "InstructionType");
	return 0;
}

static int get_uspagent_challenge_retries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "Retries");
	return 0;
}

static int get_uspagent_challenge_lockout(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	struct dm_data *ob_data = (struct dm_data *)data;

	*value = dmjson_get_value(ob_data->json_object, 1, "LockoutPeriod");
	return 0;
}
#endif

/*****************************************
 * SET functions
 ****************************************/
static int set_uspagent_mtp_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Alias", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Enable", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	char *sup_proto = NULL;
	bool valid_value = false;
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		get_uspagent_supported_protocols(refparam, ctx, data, instance, &sup_proto);
		if (DM_STRLEN(sup_proto) == 0) {
			ret = FAULT_9007;
			break;
		}

		char *tmp = strtok(sup_proto, ",");
		while (tmp) {
			remove_whitespaces(tmp);
			if (DM_STRCMP(tmp, value) == 0) {
				valid_value = true;
				break;
			}

			tmp = strtok(NULL, ",");
		}

		if (!valid_value) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Protocol", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

#ifndef DISABLE_STOMP
static int set_uspagent_mtp_stomp_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_reference reference = {0};
	int ret = FAULT_9002;
	char *allowed_objects[] = {
			"Device.STOMP.Connection.",
			NULL
		};

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	bbfdm_get_reference_linker(ctx, value, &reference);

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, reference.path, -1, 1024, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.STOMP.Reference", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_stomp_destination(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.STOMP.Destination", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

#ifdef ENABLE_COAP
static int set_uspagent_mtp_coap_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","65535"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.CoAP.Port", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_coap_path(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.CoAP.Path", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_coap_encryption(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.CoAP.EnableEncryption", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

#ifdef ENABLE_WEBSOCKETS
static int set_uspagent_mtp_ws_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","65535"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.Port", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_ws_path(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.Path", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_ws_enable_encryption(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.EnableEncryption", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_ws_keepalive_interval(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1",NULL}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.KeepAliveInterval", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

#ifdef ENABLE_MQTT
static int set_uspagent_mtp_mqtt_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_reference reference = {0};
	int ret = FAULT_9002;
	char *allowed_objects[] = {
			"Device.MQTT.Client.",
			NULL
		};

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	bbfdm_get_reference_linker(ctx, value, &reference);

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, reference.path, -1, 1024, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.MQTT.Reference", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_mqtt_topic_configured(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 65535, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.MQTT.ResponseTopicConfigured", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mtp_mqtt_qos(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","2"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.MQTT.PublishQoS", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

#ifdef ENABLE_UDS
static int set_uspagent_uds_sock_ref(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;
	struct dm_reference reference = {0};
	char *allowed_objects[] = {
			"Device.UnixDomainSockets.UnixDomainSocket.",
			NULL
		};

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	bbfdm_get_reference_linker(ctx, value, &reference);

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, reference.path, -1, 1024, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.UDS.UnixDomainSocketRef", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

static int set_uspagent_controller_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Alias", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_endpoint_id(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.EndpointID", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_code(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 128, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.ControllerCode", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_provcode(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.ProvisioningCode", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Enable", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int uspagent_set_param_role(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action, const char *param_name)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;
	char val[MAX_PATH_LEN] = {0};
	char *tmp = NULL;
	const char *allowed_object = "Device.USPAgent.ControllerTrust.Role.";

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0 || DM_STRLEN(param_name) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 1024, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		if (DM_STRNCMP(value, allowed_object, DM_STRLEN(allowed_object)) != 0) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		tmp = value + DM_STRLEN("Device.USPAgent.");
		snprintf(val, sizeof(val), "Device.LocalAgent.%s", tmp);
		snprintf(param_path, sizeof(param_path), "%s.%s", dm_path, param_name);

		ret = set_succeed(param_path, val);
	}

	return ret;
}

static int set_uspagent_controller_assigned_role(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	return uspagent_set_param_role(refparam, ctx, data, instance, value, action, "AssignedRole");
}

static int set_uspagent_controller_notifinterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1",NULL}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.PeriodicNotifInterval", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_notiftime(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_dateTime(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.PeriodicNotifTime", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_multiplier(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1000","65535"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.USPNotifRetryIntervalMultiplier", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_mininterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","65535"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.USPNotifRetryMinimumWaitInterval", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_send_onboard(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	char cmd[MAX_CMD_LEN] = {0};
	int ret = FAULT_9002;
	bool val = false;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		string_to_bool(value, &val);

		if (val) {
			LIST_HEAD(result_list);
			snprintf(param_path, sizeof(param_path), "%s.SendOnBoardRequest()", dm_path);
			snprintf(cmd, sizeof(cmd), "%s \"%s\" &", PROG_CMD_OPERATE, param_path);
			exec_cmd(cmd, &result_list);
			delete_cmd_result(&result_list);
		}

		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Alias", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Enable", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;
	char *sup_proto = NULL;
	bool valid_value = false;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		get_uspagent_supported_protocols(refparam, ctx, data, instance, &sup_proto);
		if (DM_STRLEN(sup_proto) == 0) {
			break;
		}

		char *tmp = strtok(sup_proto, ",");
		while (tmp) {
			remove_whitespaces(tmp);
			if (DM_STRCMP(tmp, value) == 0) {
				valid_value = true;
				break;
			}

			tmp = strtok(NULL, ",");
		}

		if (!valid_value) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Protocol", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

#ifndef DISABLE_STOMP
static int set_uspagent_controller_mtp_stomp_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;
	struct dm_reference reference = {0};
	char *allowed_objects[] = {
			"Device.STOMP.Connection.",
			NULL
		};

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	bbfdm_get_reference_linker(ctx, value, &reference);

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, reference.path, -1, 1024, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.STOMP.Reference", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_stomp_destination(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.STOMP.Destination", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

#ifdef ENABLE_COAP
static int set_uspagent_controller_mtp_coap_host(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 256, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.CoAP.Host", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_coap_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","65535"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.CoAP.Port", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_coap_path(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.CoAP.Path", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_coap_encryption(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.CoAP.EnableEncryption", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

#ifdef ENABLE_WEBSOCKETS
static int set_uspagent_controller_mtp_ws_host(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 256, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.Host", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_ws_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","65535"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.Port", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_ws_path(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.Path", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_ws_encryption(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.EnableEncryption", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_ws_keepalive(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1",NULL}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.KeepAliveInterval", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_ws_multiplier(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1000","65535"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.SessionRetryIntervalMultiplier", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_ws_minwait(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","65535"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.WebSocket.SessionRetryMinimumWaitInterval", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

#ifdef ENABLE_MQTT
static int set_uspagent_controller_mtp_mqtt_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;
	struct dm_reference reference = {0};
	char *allowed_objects[] = {
			"Device.MQTT.Client.",
			NULL
		};

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	bbfdm_get_reference_linker(ctx, value, &reference);

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, reference.path, -1, 1024, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.MQTT.Reference", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_controller_mtp_mqtt_topic(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 65535, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.MQTT.Topic", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

#ifndef REMOVE_DEVICE_SECURITY
static int set_uspagent_certificate_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Alias", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

static int set_uspagent_trustrole_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Alias", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Enable", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_name(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Name", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_permis_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Alias", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_permis_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Enable", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_permis_order(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"NULL","NULL"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Order", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_permis_targets(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Targets", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int validate_permission_value(struct dmctx *ctx, char *value)
{
	if (bbfdm_validate_string(ctx, value, 4, 4, NULL, NULL)) {
		return FAULT_9007;
	}

	if ((value[0] != 'r' && value[0] != '-') || (value[1] != 'w' && value[1] != '-') ||
	    (value[2] != 'x' && value[2] != '-') || (value[3] != 'n' && value[3] != '-')) {
		return FAULT_9007;
	}

	return 0;
}

static int set_uspagent_trustrole_permis_param(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		ret = validate_permission_value(ctx, value);
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Param", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_permis_obj(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		ret = validate_permission_value(ctx, value);
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Obj", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_permis_instobj(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		ret = validate_permission_value(ctx, value);
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.InstantiatedObj", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_trustrole_permis_cmdevent(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		ret = validate_permission_value(ctx, value);
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.CommandEvent", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_credential_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Alias", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_credential_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Enable", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_credential_role(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;
	char val[MAX_PATH_LEN] = {0};
	char *tmp = NULL;
	const char *allowed_object = "Device.USPAgent.ControllerTrust.Role.";

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 1024, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		if (DM_STRNCMP(value, allowed_object, DM_STRLEN(allowed_object)) != 0) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		tmp = value + DM_STRLEN("Device.USPAgent.");
		snprintf(val, sizeof(val), "Device.LocalAgent.%s", tmp);
		snprintf(param_path, sizeof(param_path), "%s.Role", dm_path);

		ret = set_succeed(param_path, val);
	}

	return ret;
}

static int set_uspagent_credential_credential(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;
	char val[MAX_PATH_LEN] = {0};
	char *tmp = NULL;
	const char *allowed_object = "Device.USPAgent.Certificate.";

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 1024, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		if (DM_STRNCMP(value, allowed_object, DM_STRLEN(allowed_object)) != 0) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		tmp = value + DM_STRLEN("Device.USPAgent.");
		snprintf(val, sizeof(val), "Device.LocalAgent.%s", tmp);
		snprintf(param_path, sizeof(param_path), "%s.Credential", dm_path);

		ret = set_succeed(param_path, val);
		break;
	}

	return ret;
}

static int set_uspagent_credential_uses(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char *AllowedUses[] = {"MTP-only", "MTP-and-USP", "MTP-and-broker", NULL};
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, AllowedUses, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.AllowedUses", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

#ifndef REMOVE_DEVICE_SECURITY
static int set_uspagent_challenge_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Alias", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_challenge_desc(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Description", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_challenge_role(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	return uspagent_set_param_role(refparam, ctx, data, instance, value, action, "Role");
}

static int set_uspagent_challenge_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_boolean(ctx, value)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Enable", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_challenge_type(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char *Type[] = {"Passphrase", NULL};
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, Type, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Type", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int validate_base64_value(char *value)
{
	int val_len = DM_STRLEN(value);

	if ((val_len % 4) != 0) {
		return FAULT_9007;
	}

	while (val_len > 0) {
		if ((value[val_len-1] >= 'A' && value[val_len-1] <= 'Z') ||
		    (value[val_len-1] >= 'a' && value[val_len-1] <= 'z') ||
		    (value[val_len-1] >= '0' && value[val_len-1] <= '9') ||
		    (value[val_len-1] == '/') || (value[val_len-1] == '+') ||
		    (value[val_len-1] == '=')) {
			val_len--;
			continue;
		}

		return FAULT_9007;
	}

	return 0;
}

static int set_uspagent_challenge_value(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		ret = validate_base64_value(value);
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Value", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_challenge_valuetype(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char *Type[] = {"text/plain", "image/jpeg", NULL};
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, Type, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.ValueType", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_challenge_instruction(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		ret = validate_base64_value(value);
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Instruction", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_challenge_instructiontype(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char *Type[] = {"text/plain", "image/jpeg", "text/html", NULL};
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_string(ctx, value, -1, -1, Type, NULL)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.InstructionType", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_challenge_retries(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"NULL","NULL"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.Retries", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}

static int set_uspagent_challenge_lockout(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	char param_path[MAX_PATH_LEN] = {0};
	int ret = FAULT_9002;

	struct dm_data *ob_data = (struct dm_data *)data;
	char *dm_path = (char *)ob_data->additional_data;

	if (DM_STRLEN(dm_path) == 0) {
		return ret;
	}

	switch (action) {
	case VALUECHECK:
		if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"0","NULL"}}, 1)) {
			ret = FAULT_9007;
			break;
		}

		ret = 0;
		break;
	case VALUESET:
		snprintf(param_path, sizeof(param_path), "%s.LockoutPeriod", dm_path);
		ret = set_succeed(param_path, value);
		break;
	}

	return ret;
}
#endif

/*******************************
 * ADD/DEL functions
 ******************************/
static int add_usp_agent_mtp(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
	char param_path[MAX_PATH_LEN] = {0};

	snprintf(param_path, sizeof(param_path), "Device.LocalAgent.MTP.");
	return get_instance_number(param_path, instance);
}

static int del_usp_agent_mtp(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	switch (del_action) {
		case DEL_INST:
			snprintf(param_path, sizeof(param_path), "%s.", (char *)p->additional_data);
			break;
		case DEL_ALL:
			snprintf(param_path, sizeof(param_path), "Device.LocalAgent.MTP.*.");
			break;
	}

	return deletion_succeed(param_path);
}

static int add_usp_agent_controller(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
	char param_path[MAX_PATH_LEN] = {0};

	snprintf(param_path, sizeof(param_path), "Device.LocalAgent.Controller.");
	return get_instance_number(param_path, instance);
}

static int del_usp_agent_controller(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	switch (del_action) {
		case DEL_INST:
			snprintf(param_path, sizeof(param_path), "%s.", (char *)p->additional_data);
			break;
		case DEL_ALL:
			snprintf(param_path, sizeof(param_path), "Device.LocalAgent.Controller.*.");
			break;
	}

	return deletion_succeed(param_path);
}

static int add_uspagent_controller_mtp(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	snprintf(param_path, sizeof(param_path), "%s.MTP.", (char *)p->additional_data);
	return get_instance_number(param_path, instance);
}

static int del_uspagent_controller_mtp(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	switch (del_action) {
		case DEL_INST:
			snprintf(param_path, sizeof(param_path), "%s.", (char *)p->additional_data);
			break;
		case DEL_ALL:
			snprintf(param_path, sizeof(param_path), "%s.MTP.*.", (char *)p->additional_data);
			break;
	}

	return deletion_succeed(param_path);
}

static int add_uspagent_trustrole(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
	char param_path[MAX_PATH_LEN] = {0};

	snprintf(param_path, sizeof(param_path), "Device.LocalAgent.ControllerTrust.Role.");
	return get_instance_number(param_path, instance);
}

static int del_uspagent_trustrole(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	switch (del_action) {
		case DEL_INST:
			snprintf(param_path, sizeof(param_path), "%s.", (char *)p->additional_data);
			break;
		case DEL_ALL:
			snprintf(param_path, sizeof(param_path), "Device.LocalAgent.ControllerTrust.Role.*.");
			break;
	}

	return deletion_succeed(param_path);
}

static int add_uspagent_credential(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
	char param_path[MAX_PATH_LEN] = {0};

	snprintf(param_path, sizeof(param_path), "Device.LocalAgent.ControllerTrust.Credential.");
	return get_instance_number(param_path, instance);
}

static int del_uspagent_credential(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	switch (del_action) {
		case DEL_INST:
			snprintf(param_path, sizeof(param_path), "%s.", (char *)p->additional_data);
			break;
		case DEL_ALL:
			snprintf(param_path, sizeof(param_path), "Device.LocalAgent.ControllerTrust.Credential.*.");
			break;
	}

	return deletion_succeed(param_path);
}

#ifndef REMOVE_DEVICE_SECURITY
static int add_uspagent_challenge(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
	char param_path[MAX_PATH_LEN] = {0};

	snprintf(param_path, sizeof(param_path), "Device.LocalAgent.ControllerTrust.Challenge.");
	return get_instance_number(param_path, instance);
}

static int del_uspagent_challenge(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	switch (del_action) {
		case DEL_INST:
			snprintf(param_path, sizeof(param_path), "%s.", (char *)p->additional_data);
			break;
		case DEL_ALL:
			snprintf(param_path, sizeof(param_path), "Device.LocalAgent.ControllerTrust.Challenge.*.");
			break;
	}

	return deletion_succeed(param_path);
}
#endif

static int add_uspagent_trustrole_permis(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	snprintf(param_path, sizeof(param_path), "%s.Permission.", (char *)p->additional_data);
	return get_instance_number(param_path, instance);
}

static int del_uspagent_trustrole_permis(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
	char param_path[MAX_PATH_LEN] = {0};
	struct dm_data *p = (struct dm_data *)data;

	switch (del_action) {
		case DEL_INST:
			snprintf(param_path, sizeof(param_path), "%s.", (char *)p->additional_data);
			break;
		case DEL_ALL:
			snprintf(param_path, sizeof(param_path), "%s.Permission.*.", (char *)p->additional_data);
			break;
	}

	return deletion_succeed(param_path);
}

/**********************************************************************************************************************************
*                                            OBJ & PARAM DEFINITION
***********************************************************************************************************************************/
/*** Device.USPAgent. ***/
DMOBJ tUSPAgentObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
{"MTP", &DMWRITE, add_usp_agent_mtp, del_usp_agent_mtp, NULL, browse_usp_agent_mtp, NULL, NULL, tUSPAgentMTPObj, tUSPAgentMTPParams, NULL, BBFDM_CWMP, NULL},
{"Controller", &DMWRITE, add_usp_agent_controller, del_usp_agent_controller, NULL, browse_usp_agent_controller, NULL, NULL, tUSPAgentControllerObj, tUSPAgentControllerParams, NULL, BBFDM_CWMP, NULL},
#ifndef REMOVE_DEVICE_SECURITY
{"Certificate", &DMREAD, NULL, NULL, NULL, browse_usp_agent_certificate, NULL, NULL, NULL, tUSPAgentCertificateParams, NULL, BBFDM_CWMP, NULL},
#endif
{"ControllerTrust", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentControllerTrustObj, tUSPAgentControllerTrustParams, NULL, BBFDM_CWMP, NULL},
{0}
};

DMLEAF tUSPAgentParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"EndpointID", &DMREAD, DMT_STRING, get_uspagent_endpoint_id, NULL, BBFDM_CWMP},
{"SoftwareVersion", &DMREAD, DMT_STRING, get_uspagent_software_version, NULL, BBFDM_CWMP},
{"UpTime", &DMREAD, DMT_UNINT, get_uspagent_uptime, NULL, BBFDM_CWMP},
{"SupportedProtocols", &DMREAD, DMT_STRING, get_uspagent_supported_protocols, NULL, BBFDM_CWMP},
#ifndef REMOVE_DEVICE_SECURITY
{"SupportedFingerprintAlgorithms", &DMREAD, DMT_STRING, get_uspagent_supported_fingerprints, NULL, BBFDM_CWMP},
#endif
{"MTPNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_mtp_number_of_entries, NULL, BBFDM_CWMP},
{"ControllerNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_controller_number_of_entries, NULL, BBFDM_CWMP},
#ifndef REMOVE_DEVICE_SECURITY
{"CertificateNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_certificate_number_of_entries, NULL, BBFDM_CWMP},
#endif
{"SubscriptionNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_subscription_number_of_entries, NULL, BBFDM_CWMP},
{0}
};

/*** Device.LocalAgent. ***/
DMLEAF tLocalAgentParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"SubscriptionNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_subscription_number_of_entries, NULL, BBFDM_CWMP},
{0}
};

/*** Device.USPAgent.MTP. ***/
DMOBJ tUSPAgentMTPObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
#ifndef DISABLE_STOMP
{"STOMP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentMTPSTOMPParams, NULL, BBFDM_CWMP, NULL},
#endif

#ifdef ENABLE_COAP
{"CoAP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentMTPCoAPParams, NULL, BBFDM_CWMP, NULL},
#endif

#ifdef ENABLE_WEBSOCKETS
{"WebSocket", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentMTPWebSocketParams, NULL, BBFDM_CWMP, NULL},
#endif

#ifdef ENABLE_MQTT
{"MQTT", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentMTPMQTTParams, NULL, BBFDM_CWMP, NULL},
#endif

#ifdef ENABLE_UDS
{"UDS", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentMTPUDSParams, NULL, BBFDM_CWMP, NULL},
#endif

{0}
};

DMLEAF tUSPAgentMTPParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_uspagent_mtp_alias, set_uspagent_mtp_alias, BBFDM_CWMP},
{"Enable", &DMWRITE, DMT_STRING, get_uspagent_mtp_enable, set_uspagent_mtp_enable, BBFDM_CWMP},
{"Status", &DMREAD, DMT_STRING, get_uspagent_mtp_status, NULL, BBFDM_CWMP},
{"Protocol", &DMWRITE, DMT_STRING, get_uspagent_mtp_protocol, set_uspagent_mtp_protocol, BBFDM_CWMP},
{0}
};

#ifndef DISABLE_STOMP
DMLEAF tUSPAgentMTPSTOMPParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Reference", &DMWRITE, DMT_STRING, get_uspagent_mtp_stomp_reference, set_uspagent_mtp_stomp_reference, BBFDM_CWMP},
{"Destination", &DMWRITE, DMT_STRING, get_uspagent_mtp_stomp_destination, set_uspagent_mtp_stomp_destination, BBFDM_CWMP},
{"DestinationFromServer", &DMREAD, DMT_STRING, get_uspagent_mtp_stomp_destination_from_server, NULL, BBFDM_CWMP},
{0}
};
#endif

#ifdef ENABLE_COAP
DMLEAF tUSPAgentMTPCoAPParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Port", &DMWRITE, DMT_UNINT, get_uspagent_mtp_coap_port, set_uspagent_mtp_coap_port, BBFDM_CWMP},
{"Path", &DMWRITE, DMT_STRING, get_uspagent_mtp_coap_path, set_uspagent_mtp_coap_path, BBFDM_CWMP},
{"EnableEncryption", &DMREAD, DMT_BOOL, get_uspagent_mtp_coap_encryption, set_uspagent_mtp_coap_encryption, BBFDM_CWMP},
{0}
};
#endif

#ifdef ENABLE_WEBSOCKETS
DMLEAF tUSPAgentMTPWebSocketParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Port", &DMWRITE, DMT_UNINT, get_uspagent_mtp_ws_port, set_uspagent_mtp_ws_port, BBFDM_CWMP},
{"Path", &DMWRITE, DMT_STRING, get_uspagent_mtp_ws_path, set_uspagent_mtp_ws_path, BBFDM_CWMP},
{"EnableEncryption", &DMWRITE, DMT_BOOL, get_uspagent_mtp_ws_enable_encryption, set_uspagent_mtp_ws_enable_encryption, BBFDM_CWMP},
{"KeepAliveInterval", &DMWRITE, DMT_UNINT, get_uspagent_mtp_ws_keepalive_interval, set_uspagent_mtp_ws_keepalive_interval, BBFDM_CWMP},
{0}
};
#endif

#ifdef ENABLE_MQTT
DMLEAF tUSPAgentMTPMQTTParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Reference", &DMWRITE, DMT_STRING, get_uspagent_mtp_mqtt_reference, set_uspagent_mtp_mqtt_reference, BBFDM_CWMP},
{"ResponseTopicConfigured", &DMWRITE, DMT_STRING, get_uspagent_mtp_mqtt_topic_configured, set_uspagent_mtp_mqtt_topic_configured, BBFDM_CWMP},
{"ResponseTopicDiscovered", &DMREAD, DMT_STRING, get_uspagent_mtp_mqtt_topic_discovered, NULL, BBFDM_CWMP},
{"PublishQoS", &DMWRITE, DMT_UNINT, get_uspagent_mtp_mqtt_qos, set_uspagent_mtp_mqtt_qos, BBFDM_CWMP},
{0}
};
#endif

#ifdef ENABLE_UDS
DMLEAF tUSPAgentMTPUDSParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"UnixDomainSocketRef", &DMWRITE, DMT_STRING, get_uspagent_mtp_uds_sock_ref, set_uspagent_uds_sock_ref, BBFDM_CWMP},
{0}
};
#endif

/*** Device.USPAgent.Controller. ***/
DMOBJ tUSPAgentControllerObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
{"MTP", &DMWRITE, add_uspagent_controller_mtp, del_uspagent_controller_mtp, NULL, browse_uspagent_controller_mtp, NULL, NULL, tUSPAgentControllerMTPObj, tUSPAgentControllerMTPParams, NULL, BBFDM_CWMP, NULL},
{0}
};

DMLEAF tUSPAgentControllerParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_uspagent_controller_alias, set_uspagent_controller_alias, BBFDM_CWMP},
{"EndpointID", &DMWRITE, DMT_STRING, get_uspagent_controller_endpoint_id, set_uspagent_controller_endpoint_id, BBFDM_CWMP},
{"ControllerCode", &DMWRITE, DMT_STRING, get_uspagent_controller_code, set_uspagent_controller_code, BBFDM_CWMP},
{"ProvisioningCode", &DMWRITE, DMT_STRING, get_uspagent_controller_provcode, set_uspagent_controller_provcode, BBFDM_CWMP},
{"Enable", &DMWRITE, DMT_BOOL, get_uspagent_controller_enable, set_uspagent_controller_enable, BBFDM_CWMP},
{"AssignedRole", &DMWRITE, DMT_STRING, get_uspagent_controller_assigned_role, set_uspagent_controller_assigned_role, BBFDM_CWMP},
{"InheritedRole", &DMREAD, DMT_STRING, get_uspagent_controller_inherited_role, NULL, BBFDM_CWMP},
{"PeriodicNotifInterval", &DMWRITE, DMT_UNINT, get_uspagent_controller_notifinterval, set_uspagent_controller_notifinterval, BBFDM_CWMP},
{"PeriodicNotifTime", &DMWRITE, DMT_TIME, get_uspagent_controller_notiftime, set_uspagent_controller_notiftime, BBFDM_CWMP},
{"USPNotifRetryIntervalMultiplier", &DMWRITE, DMT_UNINT, get_uspagent_multiplier, set_uspagent_multiplier, BBFDM_CWMP},
{"USPNotifRetryMinimumWaitInterval", &DMWRITE, DMT_UNINT, get_uspagent_mininterval, set_uspagent_mininterval, BBFDM_CWMP},
{"MTPNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_controller_mtp_count, NULL, BBFDM_CWMP},
{"SendOnBoardRequest", &DMWRITE, DMT_BOOL, get_uspagent_controller_send_onboard, set_uspagent_controller_send_onboard, BBFDM_CWMP},
{0}
};

DMOBJ tUSPAgentControllerMTPObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
#ifndef DISABLE_STOMP
{"STOMP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentControllerMTPSTOMPParams, NULL, BBFDM_CWMP, NULL},
#endif

#ifdef ENABLE_COAP
{"CoAP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentControllerMTPCoAPParams, NULL, BBFDM_CWMP, NULL},
#endif

#ifdef ENABLE_WEBSOCKETS
{"WebSocket", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentControllerMTPWebSocketParams, NULL, BBFDM_CWMP, NULL},
#endif

#ifdef ENABLE_MQTT
{"MQTT", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentControllerMTPMQTTParams, NULL, BBFDM_CWMP, NULL},
#endif

#ifdef ENABLE_UDS
{"UDS", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSPAgentControllerMTPUDSParams, NULL, BBFDM_CWMP, NULL},
#endif

{0}
};

DMLEAF tUSPAgentControllerMTPParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_alias, set_uspagent_controller_mtp_alias, BBFDM_CWMP},
{"Enable", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_enable, set_uspagent_controller_mtp_enable, BBFDM_CWMP},
{"Protocol", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_protocol, set_uspagent_controller_mtp_protocol, BBFDM_CWMP},
{0}
};

#ifndef DISABLE_STOMP
DMLEAF tUSPAgentControllerMTPSTOMPParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Reference", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_stomp_reference, set_uspagent_controller_mtp_stomp_reference, BBFDM_CWMP},
{"Destination", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_stomp_destination, set_uspagent_controller_mtp_stomp_destination, BBFDM_CWMP},
{0}
};
#endif

#ifdef ENABLE_COAP
DMLEAF tUSPAgentControllerMTPCoAPParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Host", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_coap_host, set_uspagent_controller_mtp_coap_host, BBFDM_CWMP},
{"Port", &DMWRITE, DMT_UNINT, get_uspagent_controller_mtp_coap_port, set_uspagent_controller_mtp_coap_port, BBFDM_CWMP},
{"Path", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_coap_path, set_uspagent_controller_mtp_coap_path, BBFDM_CWMP},
{"EnableEncryption", &DMWRITE, DMT_BOOL, get_uspagent_controller_mtp_coap_encryption, set_uspagent_controller_mtp_coap_encryption, BBFDM_CWMP},
{0}
};
#endif

#ifdef ENABLE_WEBSOCKETS
DMLEAF tUSPAgentControllerMTPWebSocketParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Host", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_ws_host, set_uspagent_controller_mtp_ws_host, BBFDM_CWMP},
{"Port", &DMWRITE, DMT_UNINT, get_uspagent_controller_mtp_ws_port, set_uspagent_controller_mtp_ws_port, BBFDM_CWMP},
{"Path", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_ws_path, set_uspagent_controller_mtp_ws_path, BBFDM_CWMP},
{"EnableEncryption", &DMWRITE, DMT_BOOL, get_uspagent_controller_mtp_ws_encryption, set_uspagent_controller_mtp_ws_encryption, BBFDM_CWMP},
{"KeepAliveInterval", &DMWRITE, DMT_UNINT, get_uspagent_controller_mtp_ws_keepalive, set_uspagent_controller_mtp_ws_keepalive, BBFDM_CWMP},
{"CurrentRetryCount", &DMREAD, DMT_UNINT, get_uspagent_controller_mtp_ws_retry_count, NULL, BBFDM_CWMP},
{"SessionRetryIntervalMultiplier", &DMWRITE, DMT_UNINT, get_uspagent_controller_mtp_ws_mutiplier, set_uspagent_controller_mtp_ws_multiplier, BBFDM_CWMP},
{"SessionRetryMinimumWaitInterval", &DMWRITE, DMT_UNINT, get_uspagent_controller_mtp_ws_minwait, set_uspagent_controller_mtp_ws_minwait, BBFDM_CWMP},
{0}
};
#endif

#ifdef ENABLE_MQTT
DMLEAF tUSPAgentControllerMTPMQTTParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Reference", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_mqtt_reference, set_uspagent_controller_mtp_mqtt_reference, BBFDM_CWMP},
{"Topic", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_mqtt_topic, set_uspagent_controller_mtp_mqtt_topic, BBFDM_CWMP},
{0}
};
#endif

#ifdef ENABLE_UDS
DMLEAF tUSPAgentControllerMTPUDSParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"UnixDomainSocketRef", &DMWRITE, DMT_STRING, get_uspagent_controller_mtp_uds_sock_ref, set_uspagent_uds_sock_ref, BBFDM_CWMP},
#ifndef REMOVE_USP_BROKER
{"USPServiceRef", &DMREAD, DMT_STRING, get_uspagent_controller_mtp_uds_usp_serv_ref, NULL, BBFDM_CWMP},
#endif
{0}
};
#endif

#ifndef REMOVE_DEVICE_SECURITY
/*** Device.USPAgent.Certificate. ***/
DMLEAF tUSPAgentCertificateParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_uspagent_certificate_alias, set_uspagent_certificate_alias, BBFDM_CWMP},
{"Issuer", &DMREAD, DMT_STRING, get_uspagent_certificate_issuer, NULL, BBFDM_CWMP},
{"SerialNumber", &DMREAD, DMT_STRING, get_uspagent_certificate_serial, NULL, BBFDM_CWMP},
{0}
};
#endif

/*** Device.USPAgent.ControllerTrust. ***/
DMOBJ tUSPAgentControllerTrustObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
{"Role", &DMWRITE, add_uspagent_trustrole, del_uspagent_trustrole, NULL, browse_uspagent_trustrole, NULL, NULL, tUSPAgentTrustRoleObj, tUSPAgentTrustRoleParams, NULL, BBFDM_CWMP, NULL},
{"Credential", &DMWRITE, add_uspagent_credential, del_uspagent_credential, NULL, browse_uspagent_credential, NULL, NULL, NULL, tUSPAgentCredentialParams, NULL, BBFDM_CWMP, NULL},
#ifndef REMOVE_DEVICE_SECURITY
{"Challenge", &DMWRITE, add_uspagent_challenge, del_uspagent_challenge, NULL, browse_uspagent_challenge, NULL, NULL, NULL, tUSPAgentChallengeParams, NULL, BBFDM_CWMP, NULL},
#endif
{0}
};

DMLEAF tUSPAgentControllerTrustParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"RoleNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_trust_role_count, NULL, BBFDM_CWMP},
{"CredentialNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_trust_credential_count, NULL, BBFDM_CWMP},
#ifndef REMOVE_DEVICE_SECURITY
{"ChallengeNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_trust_challenge_count, NULL, BBFDM_CWMP},
#endif
{0}
};

DMOBJ tUSPAgentTrustRoleObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
{"Permission", &DMWRITE, add_uspagent_trustrole_permis, del_uspagent_trustrole_permis, NULL, browse_uspagent_trustrole_permis, NULL, NULL, NULL, tUSPAgentTrustRolePermisParams, NULL, BBFDM_CWMP, NULL},
{0}
};

DMLEAF tUSPAgentTrustRoleParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_uspagent_trustrole_alias, set_uspagent_trustrole_alias, BBFDM_CWMP},
{"Enable", &DMWRITE, DMT_BOOL, get_uspagent_trustrole_enable, set_uspagent_trustrole_enable, BBFDM_CWMP},
{"Name", &DMWRITE, DMT_STRING, get_uspagent_trustrole_name, set_uspagent_trustrole_name, BBFDM_CWMP},
{"PermissionNumberOfEntries", &DMREAD, DMT_UNINT, get_uspagent_trustrole_permis_count, NULL, BBFDM_CWMP},
{0}
};

DMLEAF tUSPAgentTrustRolePermisParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_uspagent_trustrole_permis_alias, set_uspagent_trustrole_permis_alias, BBFDM_CWMP},
{"Enable", &DMWRITE, DMT_BOOL, get_uspagent_trustrole_permis_enable, set_uspagent_trustrole_permis_enable, BBFDM_CWMP},
{"Order", &DMWRITE, DMT_UNINT, get_uspagent_trustrole_permis_order, set_uspagent_trustrole_permis_order, BBFDM_CWMP},
{"Targets", &DMWRITE, DMT_STRING, get_uspagent_trustrole_permis_targets, set_uspagent_trustrole_permis_targets, BBFDM_CWMP},
{"Param", &DMWRITE, DMT_STRING, get_uspagent_trustrole_permis_param, set_uspagent_trustrole_permis_param, BBFDM_CWMP},
{"Obj", &DMWRITE, DMT_STRING, get_uspagent_trustrole_permis_obj, set_uspagent_trustrole_permis_obj, BBFDM_CWMP},
{"InstantiatedObj", &DMWRITE, DMT_STRING, get_uspagent_trustrole_permis_instobj, set_uspagent_trustrole_permis_instobj, BBFDM_CWMP},
{"CommandEvent", &DMWRITE, DMT_STRING, get_uspagent_trustrole_permis_cmdevent, set_uspagent_trustrole_permis_cmdevent, BBFDM_CWMP},
{0}
};

DMLEAF tUSPAgentCredentialParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_uspagent_credential_alias, set_uspagent_credential_alias, BBFDM_CWMP},
{"Enable", &DMWRITE, DMT_BOOL, get_uspagent_credential_enable, set_uspagent_credential_enable, BBFDM_CWMP},
{"Role", &DMWRITE, DMT_STRING, get_uspagent_credential_role, set_uspagent_credential_role, BBFDM_CWMP},
{"Credential", &DMWRITE, DMT_STRING, get_uspagent_credential_credential, set_uspagent_credential_credential, BBFDM_CWMP},
{"AllowedUses", &DMWRITE, DMT_STRING, get_uspagent_credential_uses, set_uspagent_credential_uses, BBFDM_CWMP},
{0}
};

#ifndef REMOVE_DEVICE_SECURITY
DMLEAF tUSPAgentChallengeParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_uspagent_challenge_alias, set_uspagent_challenge_alias, BBFDM_CWMP},
{"Description", &DMWRITE, DMT_STRING, get_uspagent_challenge_desc, set_uspagent_challenge_desc, BBFDM_CWMP},
{"Role", &DMWRITE, DMT_STRING, get_uspagent_challenge_role, set_uspagent_challenge_role, BBFDM_CWMP},
{"Enable", &DMWRITE, DMT_BOOL, get_uspagent_challenge_enable, set_uspagent_challenge_enable, BBFDM_CWMP},
{"Type", &DMWRITE, DMT_STRING, get_uspagent_challenge_type, set_uspagent_challenge_type, BBFDM_CWMP},
{"Value", &DMWRITE, DMT_BASE64, get_uspagent_challenge_value, set_uspagent_challenge_value, BBFDM_CWMP},
{"ValueType", &DMWRITE, DMT_STRING, get_uspagent_challenge_valuetype, set_uspagent_challenge_valuetype, BBFDM_CWMP},
{"Instruction", &DMWRITE, DMT_BASE64, get_uspagent_challenge_instruction, set_uspagent_challenge_instruction, BBFDM_CWMP},
{"InstructionType", &DMWRITE, DMT_STRING, get_uspagent_challenge_instructiontype, set_uspagent_challenge_instructiontype, BBFDM_CWMP},
{"Retries", &DMWRITE, DMT_UNINT, get_uspagent_challenge_retries, set_uspagent_challenge_retries, BBFDM_CWMP},
{"LockoutPeriod", &DMWRITE, DMT_INT, get_uspagent_challenge_lockout, set_uspagent_challenge_lockout, BBFDM_CWMP},
{0}
};
#endif
