/* ------------------------------------------------------------- */
bool tlcNotifyEvent(uint32_t eventType)
{
	bool ret = false;
	enum mc_result result;

	if (NULL == pDci) {
		pr_debug("ERROR tlcNotifyEvent: DCI has not been set up properly - exiting\n");
		return false;
	}

	/* Wait for previous notification to be acknowledged */
	while (pDci->nwdNotif != NOT_TUI_NONE) {
		pr_debug("TLC waiting for previous notification ack\n");
		usleep_range(10000, 10000);
	};

	/* Prepare notification message in DCI */
	pr_debug("tlcNotifyEvent: eventType = %d\n", eventType);
	pDci->nwdNotif = eventType;

	/* Signal the Driver */
	pr_debug("DCI EVENT NOTIFY CORE\n");
	result = mc_notify(&drSessionHandle);
	if (MC_DRV_OK != result) {
		pr_debug("ERROR tlcNotifyEvent: mcNotify failed: %d\n", result);
		ret = false;
	} else {
		ret = true;
	}

	return ret;
}
Example #2
0
void secwidevinemdw_listenDci(void)
{
    enum mc_result mc_ret = MC_DRV_OK;
    u32 cmdId;

    MSG(INFO, "%s: DCI listener.\n", __func__);

    for (;;) {

        MSG(INFO, "%s: Waiting for notification\n", __func__);

        /* Wait for notification from SWd */
        mc_ret = mc_wait_notification(&secwidevinemdwdr_session, MC_INFINITE_TIMEOUT);
        if (mc_ret != MC_DRV_OK) {
            MSG(ERR, "%s: mcWaitNotification failed, mc_ret=%d\n", __func__, mc_ret);
            break;
        }

        cmdId = secwidevinemdw_dci->command;
        u32 currentversion = secwidevinemdw_dci->request.currenthdcpversion;
        u32 requiredversion = secwidevinemdw_dci->request.requiredhdcpversion;
        MSG(INFO, "%s: wait notification done!! cmdId = 0x%x, current = 0x%x, required = 0x%x\n",
                __func__, cmdId, currentversion, requiredversion);
        /* Received exception. */
        mc_ret = secwidevinemdw_execute(cmdId);

        /* Notify the STH*/
        mc_ret = mc_notify(&secwidevinemdwdr_session);
        if (mc_ret != MC_DRV_OK) {
            MSG(ERR, "%s: mcNotify returned: %d\n", __func__, mc_ret);
            break;
        }
    }
}
/* ------------------------------------------------------------- */
bool tlc_notify_event(uint32_t event_type)
{
    bool ret = false;
    enum mc_result result;

    if (NULL == dci) {
        pr_debug("ERROR tlc_notify_event: DCI has not been set up "\
                 "properly - exiting\n");
        return false;
    }

    /* Prepare notification message in DCI */
    pr_debug("tlc_notify_event: event_type = %d\n", event_type);
    dci->nwd_notif = event_type;

    /* Signal the Driver */
    pr_debug("DCI EVENT NOTIFY CORE\n");
    result = mc_notify(&dr_session_handle);
    if (MC_DRV_OK != result) {
        pr_debug("ERROR tlc_notify_event: mc_notify failed: %d\n",
                 result);
        ret = false;
    } else {
        ret = true;
    }

    return ret;
}
Example #4
0
// return 0 for success and -1 for error
static int set_tplay_handle_addr_request(void)
{
    int ret = 0;
    enum mc_result mcRet = MC_DRV_OK;

    DDPDBG("[SVP] set_tplay_handle_addr_request \n");

    open_tplay_driver_connection();
    if (tplaySessionHandle.session_id == 0)
    {
        DDPERR("[SVP] invalid tplay session \n");
        return -1;
    }

    DDPDBG("[SVP] handle_pa=0x%pa \n", &handle_pa);
    /* set other TCI parameter */
    pTplayTci->tplay_handle_low_addr = (uint32_t)handle_pa;
    pTplayTci->tplay_handle_high_addr = (uint32_t)(handle_pa >> 32);
    /* set TCI command */
    pTplayTci->cmd.header.commandId = CMD_TPLAY_REQUEST;

    /* notify the trustlet */
    DDPDBG("[SVP] notify Tlsec trustlet CMD_TPLAY_REQUEST \n");
    mcRet = mc_notify(&tplaySessionHandle);
    if (MC_DRV_OK != mcRet)
    {
        DDPERR("[SVP] mc_notify failed: %d @%s line %d\n", mcRet, __func__, __LINE__);
        ret = -1;
        goto _notify_to_trustlet_fail;
    }

    /* wait for response from the trustlet */
	mcRet = mc_wait_notification(&tplaySessionHandle, MC_INFINITE_TIMEOUT);
    if (MC_DRV_OK != mcRet)
    {
        DDPERR("[SVP] mc_wait_notification failed: %d @%s line %d\n", mcRet, __func__, __LINE__);
        ret = -1;
        goto _notify_from_trustlet_fail;
    }

    DDPDBG("[SVP] CMD_TPLAY_REQUEST result=%d, return code=%d\n", pTplayTci->result, pTplayTci->rsp.header.returnCode);

_notify_from_trustlet_fail:
_notify_to_trustlet_fail:
    close_tplay_driver_connection();

    return ret;
}
Example #5
0
int32_t cmdq_sec_execute_session_unlocked(struct mc_session_handle *pSessionHandle,
					  CMDQ_IWC_STATE_ENUM *pIwcState, int32_t timeout_ms)
{
	enum mc_result mcRet;
	int32_t status = 0;
	const int32_t secureWoldTimeout_ms = (0 < timeout_ms) ?
										(timeout_ms) :
										(MC_INFINITE_TIMEOUT);

	CMDQ_PROF_START("CMDQ_SEC_EXE");

	do {
		/* notify to secure world */
		mcRet = mc_notify(pSessionHandle);
		if (MC_DRV_OK != mcRet) {
			CMDQ_ERR("[SEC]EXEC: mc_notify err[0x%x]\n", mcRet);
			status = -1;
			break;
		} else {
			CMDQ_MSG("[SEC]EXEC: mc_notify ret[0x%x]\n", mcRet);
		}
		(*pIwcState) = IWC_SES_TRANSACTED;


		/* wait respond */
		mcRet = mc_wait_notification(pSessionHandle, secureWoldTimeout_ms);
		if (MC_DRV_ERR_TIMEOUT == mcRet) {
			CMDQ_ERR
			    ("[SEC]EXEC: mc_wait_notification timeout, err[0x%x], secureWoldTimeout_ms[%d]\n",
			     mcRet, secureWoldTimeout_ms);
			status = -ETIMEDOUT;
			break;
		}

		if (MC_DRV_OK != mcRet) {
			CMDQ_ERR("[SEC]EXEC: mc_wait_notification err[0x%x]\n", mcRet);
			status = -1;
			break;
		} else {
			CMDQ_MSG("[SEC]EXEC: mc_wait_notification err[%d]\n", mcRet);
		}
		(*pIwcState) = IWC_SES_ON_TRANSACTED;
	} while (0);

	CMDQ_PROF_END("CMDQ_SEC_EXE");

	return status;
}
Example #6
0
static int dump_tplay_physcial_addr(void)
{
    DDPDBG("[SVP] dump_tplay_physcial_addr \n");
    int ret = 0;   
    enum mc_result mcRet = MC_DRV_OK;
    open_tplay_driver_connection();
    if (tplaySessionHandle.session_id == 0)
    {
        DDPERR("[SVP] invalid tplay session \n");
        return -1;
    }

    /* set TCI command */
    pTplayTci->cmd.header.commandId = CMD_TPLAY_DUMP_PHY; 
   
    /* notify the trustlet */        
    DDPMSG("[SVP] notify Tlsec trustlet CMD_TPLAY_DUMP_PHY \n");
    mcRet = mc_notify(&tplaySessionHandle);        
    if (MC_DRV_OK != mcRet)        
    {            
        DDPERR("[SVP] mc_notify failed: %d @%s line %d\n", mcRet, __func__, __LINE__); 
        ret = -1;
        goto _notify_to_trustlet_fail;
    }

    /* wait for response from the trustlet */
    mcRet = mc_wait_notification(&tplaySessionHandle, MC_INFINITE_TIMEOUT);
    if (MC_DRV_OK != mcRet)
    {            
        DDPERR("[SVP] mc_wait_notification failed: %d @%s line %d\n", mcRet, __func__, __LINE__);
        ret = -1;
        goto _notify_from_trustlet_fail;
    }

    DDPDBG("[SVP] CMD_TPLAY_DUMP_PHY result=%d, return code=%d\n", pTplayTci->result, pTplayTci->rsp.header.returnCode);

_notify_from_trustlet_fail:
_notify_to_trustlet_fail:
    close_tplay_driver_connection();

    return ret;
}
/* ------------------------------------------------------------- */
static void tlcProcessCmd(void)
{
	uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR;
	uint32_t commandId = CMD_TUI_SW_NONE;

	if (NULL == pDci) {
		pr_debug("ERROR tlcProcessCmd: DCI has not been set up properly - exiting\n");
		return;
	} else {
		commandId = pDci->cmdNwd.id;
	}

	/* Warn if previous response was not acknowledged */
	if (CMD_TUI_SW_NONE == commandId) {
		pr_debug("ERROR tlcProcessCmd: Notified without command\n");
		return;
	} else {
		if (pDci->nwdRsp.id != CMD_TUI_SW_NONE)
			pr_debug("tlcProcessCmd: Warning, previous response not ack\n");
	}

	/* Handle command */
	switch (commandId) {
	case CMD_TUI_SW_OPEN_SESSION:
		pr_debug("tlcProcessCmd: CMD_TUI_SW_OPEN_SESSION.\n");

		/* Start android TUI activity */
		ret = sendCmdToUser(TLC_TUI_CMD_START_ACTIVITY);
		if (TUI_DCI_OK == ret) {

			/* allocate TUI frame buffer */
			if (!allocateTuiBuffer(pDci))
				ret = TUI_DCI_ERR_INTERNAL_ERROR;
		}

		break;

	case CMD_TUI_SW_STOP_DISPLAY:
		pr_debug("tlcProcessCmd: CMD_TUI_SW_STOP_DISPLAY.\n");

#ifndef CONFIG_SOC_EXYNOS5420
		/* Set linux TUI flag */
		trustedui_set_mask(TRUSTEDUI_MODE_TUI_SESSION);
#endif
		trustedui_blank_set_counter(0);
#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
		blank_framebuffer(1);
		disable_irq(gpio_to_irq(190));
#endif

		trustedui_set_mask(TRUSTEDUI_MODE_VIDEO_SECURED|TRUSTEDUI_MODE_INPUT_SECURED);

		ret = TUI_DCI_OK;
		break;
		
	case CMD_TUI_SW_CLOSE_SESSION:
		pr_debug("tlcProcessCmd: CMD_TUI_SW_CLOSE_SESSION.\n");

		freeTuiBuffer();
		// Protect NWd
		trustedui_clear_mask(TRUSTEDUI_MODE_VIDEO_SECURED|TRUSTEDUI_MODE_INPUT_SECURED);

#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
		pr_info("Unblanking");
		enable_irq(gpio_to_irq(190));
		unblank_framebuffer(1);
#endif

		/* Clear linux TUI flag */
		trustedui_set_mode(TRUSTEDUI_MODE_OFF);

#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
		pr_info("Unsetting TUI flag (blank counter=%d)", trustedui_blank_get_counter());
		if (0 < trustedui_blank_get_counter()) {
			blank_framebuffer(0);		
		}
#endif

		/* Stop android TUI activity */
		ret = sendCmdToUser(TLC_TUI_CMD_STOP_ACTIVITY);
		break;

	default:
		pr_debug("ERROR tlcProcessCmd: Unknown command %d\n",
				commandId);
		break;
	}

	/* Fill in response to SWd, fill ID LAST */
	pr_debug("tlcProcessCmd: return 0x%08x to cmd 0x%08x\n",
			ret, commandId);
	pDci->nwdRsp.returnCode = ret;
	pDci->nwdRsp.id = RSP_ID(commandId);

	/* Acknowledge command */
	pDci->cmdNwd.id = CMD_TUI_SW_NONE;

	/* Notify SWd */
	pr_debug("DCI RSP NOTIFY CORE\n");
	ret = mc_notify(&drSessionHandle);
	if (MC_DRV_OK != ret)
		pr_debug("ERROR tlcProcessCmd: Notify failed: %d\n", ret);
}
/* DO NOT invoke this function unless you get HACC lock */
int tee_secure_request(unsigned int user, unsigned char *data, unsigned int data_size,
		       unsigned int direction, unsigned char *seed, unsigned int seed_size)
{
	int ret = SEC_OK;
	struct mc_bulk_map dataMapInfo;
	struct mc_bulk_map seedMapInfo;
	char *databuf = NULL;
	char *seedbuf = NULL;
	enum mc_result mcRet = 0;

	/* allocate data buffer to be sent to TEE */
	databuf = vmalloc(data_size);
	if (databuf == NULL) {
		pr_debug("NWD HACC: vmalloc fail for data buffer");
		ret = ERR_HACC_ALLOCATE_BUFFER_FAIL;
		goto _allocate_data_buf_err;
	}
	memcpy(databuf, data, data_size);

	if (seed_size != 0) {
		/* allocate seed buffer to be sent to TEE */
		seedbuf = vmalloc(seed_size);
		if (seedbuf == NULL) {
			pr_debug("NWD HACC: vmalloc fail for seed buffer");
			ret = ERR_HACC_ALLOCATE_BUFFER_FAIL;
			goto _allocate_seed_buf_err;
		}
		memcpy(seedbuf, seed, seed_size);
	}

	/* map TCI virtual address for data buffer */
	ret = mc_map(&drSessionHandle, databuf, data_size, &dataMapInfo);
	if (MC_DRV_OK != ret) {
		pr_debug("NWD HACC: mcMap failed of data buffer: %d", ret);
		ret = ERR_HACC_MCMAP_BUFFER_FAIL;
		goto _mcmap_data_fail;
	}
	pTci->data_addr = (uint32_t) dataMapInfo.secure_virt_addr;
	pTci->data_len = data_size;

	if (seed_size != 0) {
		/* map TCI virtual address for seed buffer */
		ret = mc_map(&drSessionHandle, seedbuf, seed_size, &seedMapInfo);
		if (MC_DRV_OK != ret) {
			pr_debug("NWD HACC: mcMap failed of seed buffer: %d", ret);
			ret = ERR_HACC_MCMAP_BUFFER_FAIL;
			goto _mcmap_seed_fail;
		}
		pTci->seed_addr = (uint32_t) seedMapInfo.secure_virt_addr;
		pTci->seed_len = seed_size;
	} else {
		pTci->seed_addr = 0;
		pTci->seed_len = 0;
	}

	/* set other TCI parameter */
	pTci->hacc_user = user;
	pTci->direction = direction;

	/* set TCI command */
	pTci->cmd.header.commandId = CMD_HACC_REQUEST;

	/* notify the trustlet */
	pr_debug("NWD HACC: prepare notify\n");
	mcRet = mc_notify(&drSessionHandle);
	if (MC_DRV_OK != mcRet) {
		pr_debug("NWD HACC IRQ fail: mc_notify returned: %d\n", mcRet);
		ret = ERR_HACC_NOTIFY_TO_TRUSTLET_FAIL;
		goto _notify_to_trustlet_fail;
	}

	/* wait for response from the trustlet */
	mcRet = mc_wait_notification(&drSessionHandle, /*MC_INFINITE_TIMEOUT */ 20000);
	if (MC_DRV_OK != mcRet) {
		pr_debug("NWD HACC IRQ fail: mc_wait_notification 20s timeout: %d\n", mcRet);
		ret = ERR_HACC_NOTIFY_FROM_TRUSTLET_FAIL;
		goto _notify_from_trustlet_fail;
	}

	if (pTci->result != 0) {
		pr_debug("NWD HACC Request Fail!!!!!!!!(ret:%d, err:%d)\n", pTci->result,
			 pTci->rsp.header.returnCode);
	} else {
		pr_debug("NWD HACC Request Success!!!!!!!!\n");
		/* update result from secure buffer */
		memcpy(data, databuf, data_size);
	}

_notify_from_trustlet_fail:
_notify_to_trustlet_fail:
	if (seed_size != 0)
		mc_unmap(&drSessionHandle, seedbuf, &seedMapInfo);
_mcmap_seed_fail:
	mc_unmap(&drSessionHandle, databuf, &dataMapInfo);
_mcmap_data_fail:
	if (seed_size != 0)
		vfree(seedbuf);
_allocate_seed_buf_err:
	vfree(databuf);
_allocate_data_buf_err:

	return ret;
}
/* ------------------------------------------------------------- */
static void tlc_process_cmd(void)
{
    uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR;
    uint32_t command_id = CMD_TUI_SW_NONE;
#if defined(CONFIG_SECURE_OS_BOOSTER_API)
    int ret_val = 0;
    u8 retry_cnt = 0;
#endif

    if (NULL == dci) {
        pr_debug("ERROR %s: DCI has not been set up properly - exiting"\
                 "\n", __func__);
        return;
    } else {
        command_id = dci->cmd_nwd.id;
    }

    /* Warn if previous response was not acknowledged */
    if (CMD_TUI_SW_NONE == command_id) {
        pr_debug("ERROR %s: Notified without command\n", __func__);
        return;
    } else {
        if (dci->nwd_rsp.id != CMD_TUI_SW_NONE)
            pr_debug("%s: Warning, previous response not ack\n",
                     __func__);
    }

    /* Handle command */
    switch (command_id) {
    case CMD_TUI_SW_OPEN_SESSION:
        pr_debug("%s: CMD_TUI_SW_OPEN_SESSION.\n", __func__);
#if defined(CONFIG_SECURE_OS_BOOSTER_API)
        pr_info("%s TUI_CPU_SPEEDUP ON retry: %d\n",
                __func__, retry_cnt);
        do {
            ret_val = secos_booster_start(MAX_PERFORMANCE);
            retry_cnt++;
            if (ret_val) {
                pr_err("%s: booster start failed. (%d) retry: %d\n"
                       , __func__, ret_val, retry_cnt);
                if (retry_cnt < 7)
                    usleep_range(500, 510);
            }
        } while (ret_val && retry_cnt < 7);
#endif

        /* Start android TUI activity */
        ret = send_cmd_to_user(TLC_TUI_CMD_START_ACTIVITY);
        if (TUI_DCI_OK != ret)
            break;

        /* allocate TUI frame buffer */
        ret = hal_tui_alloc(dci->nwd_rsp.alloc_buffer,
                            dci->cmd_nwd.payload.alloc_data.alloc_size,
                            dci->cmd_nwd.payload.alloc_data.num_of_buff);

        if (TUI_DCI_OK != ret) {
            pr_err("%s: hal_tui_alloc error : %d\n", __func__ ,ret);
            /* no need to call tui_i2c_reset, because there will be no TUI
             * session */
            //tui_i2c_reset();
            send_cmd_to_user(TLC_TUI_CMD_STOP_ACTIVITY);
            break;
        }

        /* Deactivate linux UI drivers */
        ret = hal_tui_deactivate();

        if (TUI_DCI_OK != ret) {
            pr_err("%s: hal_tui_deactivate error : %d\n", __func__ ,ret);
            hal_tui_free();
            send_cmd_to_user(TLC_TUI_CMD_STOP_ACTIVITY);
            break;
        }
        break;

    case CMD_TUI_SW_CLOSE_SESSION:
        pr_debug("%s: CMD_TUI_SW_CLOSE_SESSION.\n", __func__);

        /* Activate linux UI drivers */
        ret = hal_tui_activate();

        hal_tui_free();

#if defined(CONFIG_SECURE_OS_BOOSTER_API)
        ret_val = secos_booster_stop();
        if (ret_val)
            pr_err("%s: booster stop failed. (%d)\n"
                   , __func__, ret_val);
#endif
        /* Stop android TUI activity */
        ret = send_cmd_to_user(TLC_TUI_CMD_STOP_ACTIVITY);
        break;

    default:
        pr_debug("ERROR %s: Unknown command %d\n",
                 __func__, command_id);
        break;
    }

    /* Fill in response to SWd, fill ID LAST */
    pr_debug("%s: return 0x%08x to cmd 0x%08x\n",
             __func__, ret, command_id);
    dci->nwd_rsp.return_code = ret;
    dci->nwd_rsp.id = RSP_ID(command_id);

    /* Acknowledge command */
    dci->cmd_nwd.id = CMD_TUI_SW_NONE;

    /* Notify SWd */
    pr_debug("DCI RSP NOTIFY CORE\n");
    ret = mc_notify(&dr_session_handle);
    if (MC_DRV_OK != ret)
        pr_debug("ERROR %s: Notify failed: %d\n", __func__, ret);
}
/* ------------------------------------------------------------- */
static void tlcProcessCmd(void)
{
	uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR;
	uint32_t commandId = CMD_TUI_SW_NONE;

	pDci->cmdNwd.payload.allocData.numOfBuff = TUI_BUFFER_NUM;

	if (NULL == pDci) {
		pr_debug("ERROR tlcProcessCmd: DCI has not been set up properly - exiting\n");
		return;
	} else {
		commandId = pDci->cmdNwd.id;
	}

	/* Warn if previous response was not acknowledged */
	if (CMD_TUI_SW_NONE == commandId) {
		pr_debug("ERROR tlcProcessCmd: Notified without command\n");
		return;
	} else {
		if (pDci->nwdRsp.id != CMD_TUI_SW_NONE)
			pr_debug("tlcProcessCmd: Warning, previous response not ack\n");
	}

	/* Handle command */
	switch (commandId) {
	case CMD_TUI_SW_OPEN_SESSION:
		printk(KERN_ERR "tlcProcessCmd: CMD_TUI_SW_OPEN_SESSION.\n");

		/* Start android TUI activity */
		ret = sendCmdToUser(TLC_TUI_CMD_START_ACTIVITY);
		if (TUI_DCI_OK == ret) {

			/* allocate TUI frame buffer */
			ret = hal_tui_alloc(&pDci->nwdRsp.allocBuffer[MAX_DCI_BUFFER_NUMBER],
					pDci->cmdNwd.payload.allocData.allocSize,
					pDci->cmdNwd.payload.allocData.numOfBuff);

			printk(KERN_ERR "tlcProcessCmd: CMD_TUI_SW_OPEN_SESSION & disable_irq(%d);.\n",tsp_irq_num);
			disable_irq(tsp_irq_num);
			msleep(100); // temp code
		}
		hal_tui_video_space_alloc();

		pDci->nwdRsp.allocBuffer[0].pa = g_sec_tuiMemPool.pa;
		pDci->nwdRsp.allocBuffer[1].pa = (g_sec_tuiMemPool.pa + g_sec_tuiMemPool.size/2);

		pDci->cmdNwd.payload.allocData.allocSize = g_sec_tuiMemPool.size;

		break;

	case CMD_TUI_SW_STOP_DISPLAY:
		printk(KERN_ERR "tlcProcessCmd: CMD_TUI_SW_STOP_DISPLAY.\n");

		/* Deactivate linux UI drivers */
		ret = hal_tui_deactivate();

		break;

	case CMD_TUI_SW_CLOSE_SESSION:
		printk(KERN_ERR "tlcProcessCmd: CMD_TUI_SW_CLOSE_SESSION & enable_irq(%d).\n", tsp_irq_num);

		disable_irq(pwr_irq_num);
		/* Activate linux UI drivers */
		ret = hal_tui_activate();
		tui_i2c_reset();
		enable_irq(tsp_irq_num);
		hal_tui_free();
		enable_irq(pwr_irq_num);

		/* Stop android TUI activity */
		ret = sendCmdToUser(TLC_TUI_CMD_STOP_ACTIVITY);
		break;

	default:
		pr_debug("ERROR tlcProcessCmd: Unknown command %d\n",
				commandId);
		break;
	}

	/* Fill in response to SWd, fill ID LAST */
	pr_debug("tlcProcessCmd: return 0x%08x to cmd 0x%08x\n",
			ret, commandId);
	pDci->nwdRsp.returnCode = ret;
	pDci->nwdRsp.id = RSP_ID(commandId);

	/* Acknowledge command */
	pDci->cmdNwd.id = CMD_TUI_SW_NONE;

	/* Notify SWd */
	pr_debug("DCI RSP NOTIFY CORE\n");
	ret = mc_notify(&drSessionHandle);
	if (MC_DRV_OK != ret)
		pr_debug("ERROR tlcProcessCmd: Notify failed: %d\n", ret);
}