Mdm_set_automatic_time() returned status -13 and not set the time

I have:

Device: Samsung Galaxy Watch Active (SM-R500);

Tizen version (API): 4.0;

Knox Tizen SDK for Wearables version: 2.4;

On the Knox Partner portal I have found active KPE Standart key and then implemented it into my code.

I get the privilege to set time functions (http://developer.samsung.com/tizen/privilege/mdm.datetime) with ppm_check_permission function:

...

const char *privileges[] =
{
	"http://tizen.org/privilege/mediastorage",
	"http://tizen.org/privilege/location",
	"http://tizen.org/privilege/healthinfo",
	"http://developer.samsung.com/tizen/privilege/mdm.admin",
	"http://developer.samsung.com/tizen/privilege/mdm.datetime",
	"http://developer.samsung.com/tizen/privilege/mdm.location",
};

...

static void _ppm_request_response_cb(ppm_call_cause_e cause, ppm_request_result_e result, const char *privilege, void *user_data)
{
	if (cause == PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR)
	{
		LOG_PRINT(DLOG_DEBUG, "Error request response!");
		/* Log and handle errors */
		return;
	}

	switch (result)
	{
	case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_ALLOW_FOREVER:
		/* Update UI and start accessing protected functionality */
		LOG_PRINT(DLOG_DEBUG, "PPM request result: allow forever");
		break;
	case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_FOREVER:
		/* Show a message and terminate the application */
		LOG_PRINT(DLOG_DEBUG, "PPM request result: deny forever");
		ui_app_exit();
		break;
	case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE:
		/* Show a message with explanation */
		LOG_PRINT(DLOG_DEBUG, "PPM request result: deny once");
		ui_app_exit();
		break;
	}
}

...

static bool _create_cb(void *data)
{
	int i = 0;
	int ret = PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE;
	ppm_check_result_e result = PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW;

	int size = sizeof(privileges) / sizeof(char *);

	setlocale(LC_ALL, "en_US.UTF-8");

	for (i = 0; i < size; i++)
	{
		ret = ppm_check_permission(privileges[i], &result);
		if (ret == PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE)
		{
			switch (result)
			{
			case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW:
				LOG_PRINT(DLOG_DEBUG, "PPM request response: allow");
				break;
			case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY:
				LOG_PRINT(DLOG_DEBUG, "PPM error request response: deny");
				ui_app_exit();
				break;
			case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK:
				ret = ppm_request_permission(privileges[i], _ppm_request_response_cb, NULL);
				LOG_PRINT(DLOG_DEBUG, "[ppm_request_permission] return %d", (int)ret);
				break;
			}
		}
	}

    file_logger_init(pfl, PATH_LOGS, CURRENT_VERSION, LOGGER_ROTATE_BY_SIZE | LOGGER_ROTATE_PER_HOUR, 8);

	if (!g_init())
	{
		LOG_PRINT(DLOG_ERROR, "GNSS is not working!");
	}

	me_init();

	gui_create_base();

	c_set_state(ST_WIZARD_STEP1);

	elm_run();
	return true;
}

...

int main(int argc, char *argv[])
{
	int ret = 0;
	app_data_t app_data = { 0, };
	ui_app_lifecycle_callback_s event_callback = { 0, };
	app_event_handler_h handlers[5] = { NULL, };
	pfl = &fl;

	feedback_initialize();

	event_callback.create = _create_cb;
	event_callback.terminate = _terminate_cb;
	event_callback.pause = _pause_cb;
	event_callback.resume = _resume_cb;
	event_callback.app_control = _app_control_cb;

	device_add_callback(DEVICE_CALLBACK_BATTERY_CHARGING, _device_changed_cb, NULL);

	ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY],
			APP_EVENT_LOW_BATTERY, _app_event_low_battery_cb, &app_data);
	ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY],
			APP_EVENT_LOW_MEMORY, _app_event_low_memory_cb, &app_data);
	ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED],
			APP_EVENT_DEVICE_ORIENTATION_CHANGED, _app_event_device_orientation_changed_cb, &app_data);
	ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED],
			APP_EVENT_LANGUAGE_CHANGED, _app_event_language_changed_cb, &app_data);
	ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED],
			APP_EVENT_REGION_FORMAT_CHANGED, _app_event_region_format_changed_cb, &app_data);

	ret = ui_app_main(argc, argv, &event_callback, &app_data);
	if (ret != APP_ERROR_NONE)
	{
		LOG_PRINT(DLOG_ERROR, "[ui_app_main] return %d.", ret);
	}
	return ret;
}

I try set time with next code:

#include <logger_ext.h>
#include "mdm_ext.h"
#include "main.h"

#include <mdm.h>
#include <knox_custom.h>
#include <tizen.h>
#include <app_preference.h>

/* Registration keys */
#ifndef KEY
	#define KEY "KLM09-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"
#endif

static const char *old_licenses[] =
{
"KLM09-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
"KLM09-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
"KLM06-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
};

static void _date_time_cb(int oper, void *cb_data, void *user_data);
static void _mdm_client_cb(int oper, void *cb_data, void *user_data);

static void _date_time_cb(int oper, void *cb_data, void *user_data)
{
	/*mdm_license_callback_t *ldata = (mdm_license_callback_t *)cb_data;
	switch (oper)
	{
		case MDM_CB_LICENSE_DEACTIVATE_KNOX:
			break;
		default:
			break;
	}*/
}

static void _mdm_client_cb(int oper, void *cb_data, void *user_data)
{
	if (!cb_data)
	{
		LOG_PRINT(DLOG_DEBUG, "cb_data == NULL");
		return;
	}
	const mdm_license_callback_t *ldata = (mdm_license_callback_t *) cb_data;
	if (!ldata || !ldata->license_info)
	{
		LOG_PRINT(DLOG_DEBUG, "ldata == NULL");
		return;
	}

	switch (oper)
	{
	case MDM_CB_LICENSE_ACTIVATE:
		if (ldata->license_info->error_code == 0)
		{
			LOG_PRINT(DLOG_INFO, "Success");
		}
		else
		{
			LOG_PRINT(DLOG_ERROR, "Fail: %s", ldata->license_info->error_desc);
		}
		break;
	case MDM_CB_LICENSE_ACTIVATE_KNOX:
		if (ldata->license_info->error_code == 0)
		{
			LOG_PRINT(DLOG_INFO, "Success");
		}
		else
		{
			LOG_PRINT(DLOG_ERROR, "Fail: %s", ldata->license_info->error_desc);
		}
		break;
	case MDM_CB_LICENSE_DEACTIVATE_KNOX:
		if (ldata->license_info->error_code == 0)
		{
			LOG_PRINT(DLOG_INFO, "Success");
		}
		else
		{
			LOG_PRINT(DLOG_ERROR, "Fail: %s", ldata->license_info->error_desc);
		}
		break;
	case MDM_CB_LICENSE_VALIDATE_RESULT:
		if (ldata->license_info->error_code == 0)
		{
			LOG_PRINT(DLOG_INFO, "Success");
		}
		else
		{
			LOG_PRINT(DLOG_ERROR, "Fail: %s", ldata->license_info->error_desc);
		}
		break;
	case MDM_CB_LICENSE_KNOX_VALIDATE_RESULT:
		if (ldata->license_info->error_code == 0)
		{
			LOG_PRINT(DLOG_INFO, "Success");
		}
		else
		{
			LOG_PRINT(DLOG_ERROR, "Fail: %s", ldata->license_info->error_desc);
		}
		break;
	default:
		break;
	}
}

void me_init(void)
{
	int ret = MDM_RESULT_SUCCESS;
	mdm_data_t *mdm_data = NULL;
	mdm_result_t mdm_result = MDM_RESULT_SUCCESS;
	mdm_status_t mdm_status = MDM_TRUE;
	int size = sizeof(old_licenses) / sizeof(char *);
	int i = 0;

	ret = mdm_register_client(PACKAGE);
	switch (ret)
	{
	case MDM_RESULT_SERVICE_NOT_ENABLED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_SERVICE_NOT_ENABLED");
		break;
	case MDM_RESULT_ACCESS_DENIED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_ACCESS_DENIED");
		break;
	case MDM_RESULT_INVALID_PARAM:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_INVALID_PARAM");
		break;
	case MDM_RESULT_NOT_SUPPORTED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_NOT_SUPPORTED");
		break;
	case MDM_RESULT_FAIL:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_FAIL");
		break;
	case MDM_RESULT_SUCCESS:
		LOG_PRINT(DLOG_INFO, "MDM_RESULT_SUCCESS");
		break;
	case MDM_NOT_AN_OWNER:
		LOG_PRINT(DLOG_ERROR, "MDM_NOT_AN_OWNER");
		break;
	default:
		LOG_PRINT(DLOG_ERROR, "[mdm_register_client] return %d", ret);
		break;
	}

	mdm_result = mdm_get_service();
	if (mdm_result != MDM_RESULT_SUCCESS)
	{
		LOG_PRINT(DLOG_ERROR, "[mdm_get_service] return %d", mdm_result);
		mdm_release_service();
		return;
	}

	ret = mdm_register_client_callback(MDM_LICENSE_CB, _mdm_client_cb, NULL, NULL);
	if (ret != MDM_RESULT_SUCCESS)
	{
		LOG_PRINT(DLOG_ERROR, "[mdm_register_client_callback] return %d", ret);
		mdm_release_service();
		return;
	}

	for (i = 0; i < size; i++)
	{
		mdm_data = mdm_deactivate_knox_license(PACKAGE, old_licenses[i]);
		if (mdm_data != NULL)
		{
			mdm_free_data(mdm_data);
		}
		else
		{
			LOG_PRINT(DLOG_ERROR, "[mdm_deactivate_knox_license] return NULL");
		}
	}
	
	mdm_data = mdm_activate_knox_license(PACKAGE, KEY);
	if (mdm_data->ret == MDM_RESULT_SUCCESS)
	{
		LOG_PRINT(DLOG_INFO, "License Activated");
	}
	else
	{
		LOG_PRINT(DLOG_ERROR, "[mdm_activate_knox_license] return %d", (int)mdm_data->ret);
	}
	mdm_free_data(mdm_data);

	mdm_status = mdm_is_client_registered(PACKAGE);
	if (mdm_status != MDM_TRUE)
	{
		LOG_PRINT(DLOG_ERROR, "[mdm_is_client_registered] return %d", (int)mdm_status);
		
		mdm_data = mdm_activate_knox_license(PACKAGE, KEY);
		if (mdm_data->ret == MDM_RESULT_SUCCESS)
		{
			LOG_PRINT(DLOG_INFO, "MDM_RESULT_SUCCESS");
		}
		else
		{
			LOG_PRINT(DLOG_ERROR, "[mdm_activate_knox_license] return %d", (int)mdm_data->ret);
		}

		mdm_free_data(mdm_data);
	}
	else
	{
		LOG_PRINT(DLOG_INFO, "Client Registered");
	}

	mdm_release_service();
}


void me_disable_automatic_time(void)
{
	int ret = MDM_RESULT_SUCCESS;
	mdm_result_t mdm_result = MDM_RESULT_SUCCESS;

	ret = mdm_register_client(PACKAGE);
	switch (ret)
	{
	case MDM_RESULT_SERVICE_NOT_ENABLED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_SERVICE_NOT_ENABLED");
		break;
	case MDM_RESULT_ACCESS_DENIED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_ACCESS_DENIED");
		break;
	case MDM_RESULT_INVALID_PARAM:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_INVALID_PARAM");
		break;
	case MDM_RESULT_NOT_SUPPORTED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_NOT_SUPPORTED");
		break;
	case MDM_RESULT_FAIL:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_FAIL");
		break;
	case MDM_RESULT_SUCCESS:
		LOG_PRINT(DLOG_INFO, "MDM_RESULT_SUCCESS");
		break;
	case MDM_NOT_AN_OWNER:
		LOG_PRINT(DLOG_ERROR, "MDM_NOT_AN_OWNER");
		break;
	default:
		LOG_PRINT(DLOG_ERROR, "[mdm_register_client] return %d", ret);
		break;
	}

	mdm_result = mdm_get_service();
	if (mdm_result != MDM_RESULT_SUCCESS)
	{
		LOG_PRINT(DLOG_ERROR, "[mdm_get_service] return %d", mdm_result);
		mdm_release_service();
		return;
	}

	mdm_result = mdm_set_automatic_time(MDM_FALSE);
    if (mdm_result != MDM_RESULT_SUCCESS)
    {
    	LOG_PRINT(DLOG_ERROR, "[mdm_set_automatic_time] return %d", mdm_result);
    }

	mdm_release_service();
}

bool me_set_date_time(int year, int month, int day, int hour, int minute, int second)
{
	int _ret = MDM_RESULT_SUCCESS;
	bool ret = false;
	mdm_result_t res = MDM_RESULT_SUCCESS;

	LOG_PRINT(DLOG_DEBUG, "-> %4d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second);

	_ret = mdm_register_client(PACKAGE);
	switch (_ret)
	{
	case MDM_RESULT_SERVICE_NOT_ENABLED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_SERVICE_NOT_ENABLED");
		break;
	case MDM_RESULT_ACCESS_DENIED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_ACCESS_DENIED");
		break;
	case MDM_RESULT_INVALID_PARAM:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_INVALID_PARAM");
		break;
	case MDM_RESULT_NOT_SUPPORTED:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_NOT_SUPPORTED");
		break;
	case MDM_RESULT_FAIL:
		LOG_PRINT(DLOG_ERROR, "MDM_RESULT_FAIL");
		break;
	case MDM_RESULT_SUCCESS:
		LOG_PRINT(DLOG_INFO, "MDM_RESULT_SUCCESS");
		break;
	case MDM_NOT_AN_OWNER:
		LOG_PRINT(DLOG_ERROR, "MDM_NOT_AN_OWNER");
		break;
	default:
		LOG_PRINT(DLOG_ERROR, "[mdm_register_client] return %d", ret);
		break;
	}

	res = mdm_get_service();
	if (res != MDM_RESULT_SUCCESS)
	{
		LOG_PRINT(DLOG_ERROR, "[mdm_get_service] return %d", (int)res);
		return ret;
	}

	mdm_register_client_callback(MDM_DATE_TIME_CB, _date_time_cb, NULL, NULL);

	res = mdm_set_date_time_change_enabled(true);
	if (res != MDM_RESULT_SUCCESS)
	{
		mdm_release_service();
		LOG_PRINT(DLOG_ERROR, "[mdm_set_date_time_change_enabled] return %d", (int)res);
		return ret;
	}

	res = mdm_set_date_time(day, month, year, hour, minute, second);
	if (res != MDM_RESULT_SUCCESS)
	{
		mdm_release_service();
		LOG_PRINT(DLOG_ERROR, "[mdm_set_date_time] return %d", (int)res);
		return ret;
	}

	res = mdm_set_date_time_change_enabled(false);
	if (res != MDM_RESULT_SUCCESS)
	{
		mdm_release_service();
		LOG_PRINT(DLOG_ERROR, "[mdm_set_date_time_change_enabled] return %d", (int)res);
		return ret;
	}

	ret = true;

	mdm_release_service();

	LOG_PRINT(DLOG_INFO, "Time sync completed");

	return ret;
}

The procedure for calling features:

...

me_init();
me_disable_automatic_time();
me_set_date_time(2020, 3, 31, 16, 54, 1);

...

MY ISSUE:

For function mdm_set_automatic_time() returned status -13 with my commercial key, but at the same time status for mdm_activate_knox_license() is MDM_RESULT_SUCCESS.

BUT it fine working and the error is not repeated for several devices, it’s 2-3 out of 42 devices. For these devices, the application has been uploaded with console Knox Configure.


What kind of actions can I do wrong?

Hello dpr1585674273,
Welcome to the community!
We would like to recommend you to reach out https://support.samsungknox.com for further guidance.

Thank you.