/*
 * IPRPC - Inter Process Remote Procedure Call
 *
 * Copyright (C) 2012-2013 by Hiroyuki KAJIURA. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *     1:Redistributions of source code must retain the above copyright notice, 
 *       this list of conditions and the following disclaimer.
 *     2:Redistributions in binary form must reproduce the above copyright notice, 
 *       this list of conditions and the following disclaimer in the documentation 
 *       and/or other materials provided with the distribution.
 *     3:Neither the name of copyright owner nor the names of its contributors 
 *       may be used to endorse or promote products derived from this software 
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include	<stdio.h>

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include	"ipcInfo.h"
#include	"ipcType.h"
#include	"rpcFunc.h"
#include	"ipcSyscall.h"
#include	"ipcLog.h"
#include	"ipcLib.h"
#include	"ipcQue.h"
#include	"ipcShmDB.h"
#include	"ipcStub.h"
#include	"ipcSkelton.h"
#include	"ipcMarshal.h"
#include	"ipcInit.h"
#include	"ipcRendezv.h"

#include	"ipcTest.h"

//#define	MULTICAST_TEST
#undef	MULTICAST_TEST

RpcResult_t queTest(RpcBool_t globalFlag);
RpcResult_t shmTest(void);
RpcResult_t marshalTest(void);
RpcResult_t RendezvTest(RpcBool_t IpcFlag);

#define			NUM_OF_TEST_PROGRAM	(4)
#define			TEST_PROGRAM		"./ipcTest.out"

int main(int argc,char *argv[]) {
	RpcResult_t ret;RpcBool_t masterProcess;uint32_t inArg;
	uint32_t process[NUM_OF_TEST_PROGRAM];
	RpcResult_t (*skelFunc[NUM_OF_TEST_PROGRAM])(void);
	uint32_t skelFuncID[NUM_OF_TEST_PROGRAM];
	uint32_t errCode;int i;RpcBool_t useSkelton;RpcBool_t useStub;
	char *procArg[NUM_OF_TEST_PROGRAM][3];
	uint32_t queId;	struct timeval sleepTime;

	if(argc != 4) {
		fprintf(stdout,"USAGE:%s Master[1/0] UseSkelton[1/0] UseStub[1/0]\n",argv[0]);
		fprintf(stdout,"      Master:0 - SLAVE PROCESS\n");
		fprintf(stdout,"      Master:1 - MASTER PROCESS\n");
		return 1;
	}
	sscanf(argv[1],"%d",&inArg);
	if(inArg == 0)
		masterProcess = RPC_FALSE;
	else
		masterProcess = RPC_TRUE;
	sscanf(argv[2],"%d",&inArg);
	if(inArg == 0)
		useSkelton = RPC_FALSE;
	else
		useSkelton = RPC_TRUE;
	sscanf(argv[3],"%d",&inArg);
	if(inArg == 0)
		useStub = RPC_FALSE;
	else
		useStub = RPC_TRUE;

	fprintf(stdout,"%s PID:0x%x; masterProcess:%d; useSkelton:%d; useStub:%d;\n",
		argv[0],RPC_GetPid(),masterProcess,useSkelton, useStub);
	if((ret = IPC_InitIprpc(masterProcess,useSkelton, useStub, RPC_LOG_LEVEL_INFO)) != RPC_SUCCESS) {
		return 1;
	}
//	(void)RPC_LogPrintInfo();
#if	0
	if((ret = queTest(RPC_FALSE)) != RPC_SUCCESS) {
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR IN QUEUE TEST ret:0x%x", ret);
		return 1;
	}
#endif	/* 0 */
#if	0
	if((ret = shmTest()) != RPC_SUCCESS) {
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR IN SHM TEST ret:0x%x", ret);
		return 1;
	}
#endif	/* 0 */
#if	0
	if((ret = marshalTest()) != RPC_SUCCESS) {
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR IN MARSHAL TEST ret'0x%x",ret);
		return 1;
	}
#endif	/* 0 */
#if	0
	if((ret = DBTest()) != RPC_SUCCESS) {
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR IN DB TEST ret'0x%x",ret);
		return 1;		
	}
#endif	/* 0 */
#ifdef	USE_RENDEZVOUS
#if	0
	if((ret = RendezvTest(RPC_TRUE)) != RPC_SUCCESS) {
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR IN RENDEZVOUS TEST ret'0x%x",ret);
		return 1;		
	}
//	if((ret = RendezvTest(RPC_FALSE)) != RPC_SUCCESS) {
//		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR IN RENDEZVOUS TEST ret'0x%x",ret);
//		return 1;		
//	}
#endif	/* 0 */
#endif	/* RENDEZVOUS */
#if	1
	skelFunc[1] = SkeltonTest1;
	skelFunc[2] = SkeltonTest2;
	skelFunc[3] = SkeltonTest3;
	skelFunc[0] = StubTestA;
	skelFuncID[1] = IPC_SKEL_FUNC_A_FUNC_ID;
	skelFuncID[2] = IPC_SKEL_FUNC_B_FUNC_ID;
	skelFuncID[3] = IPC_SKEL_FUNC_C_FUNC_ID;
	skelFuncID[0] = IPC_STUB_FUNC_A_FUNC_ID;
	if(masterProcess) {uint32_t errCode;char *cmdArg[10];char *envArg[] = {NULL};
		for(i = 0;i < NUM_OF_TEST_PROGRAM;i++) {
			procArg[i][0] = "0";	/* SLAVE PROCESS */
			if(i == 0)
				procArg[i][1] = "0";	/* NOT USE SKELTON */
			else
				procArg[i][1] = "1";	/* USE SKELTON */
			procArg[i][2] = "1";	/* USE STUB */
		}
		for(i = 0;i < NUM_OF_TEST_PROGRAM;i++) {
			if(ret = RPC_Fork(&(process[i]),&errCode) != RPC_SUCCESS) {
				RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR CAN NOT CREATE PROCESS ret:0x%x;",ret);
				exit(-1);
			}
			if(process[i] == 0) {	/* child process */
				cmdArg[0] = TEST_PROGRAM;
				cmdArg[1] = procArg[i][0];
				cmdArg[2] = procArg[i][1];
				cmdArg[3] = procArg[i][2];
				cmdArg[4] = NULL;
				RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"NOW EXEC TEST PROGRAM PID:0x%x; --- CHILD --- ARG1:%s; ARG2:%s; ARG3:%s;",
					RPC_GetPid(), cmdArg[1], cmdArg[2], cmdArg[3]);
				if(RPC_Exec(TEST_PROGRAM,cmdArg,envArg,&errCode) != RPC_SUCCESS) {
					RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR: CAN NOT EXEC %s RET:0x%x;",cmdArg[0],errCode);
					exit(1);
				}
				exit(0);	/* NEVER COME */
			}
			else if(process[i] > 0) { /* parent process */
				RPC_LogPrintNomark(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"CREATED PROCESS PID:0x%x; AND NOW REGISTER SKELTON MAIN FUNCTION FUNCID:0x%x; FUNC:0x%x; ...",process[i],skelFuncID[i],skelFunc[i]);
				if(IPC_RegisterFuncDBEntry(skelFuncID[i], process[i], skelFunc[i], NULL) != RPC_SUCCESS) {
					RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR: CAN NOT REGISTER SKELTON MAIN FUNC ID:0x%x; PID:0x%x; FUNC:0x%x; RET:%s;",
						skelFuncID[i], process[i], skelFunc[i], RPC_LogConvertResultCode(ret));
				}
				RPC_LogPrintNomark(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1," ...DONE\n");
			}
			else {
				RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR CAN NOT CREATE PROCESS ret:0x%x; RET:0x%x;",ret,errCode);
				exit(-1);
			}
		}
#if	defined(USE_MULTICAST_RPC)&&defined(MULTICAST_TEST)
		{
		sleepTime.tv_sec = 0;
		sleepTime.tv_usec = 100*1000;
		(void)RPC_TaskSleep(&sleepTime,NULL);
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"NOW REGISTER AND SIGNUP MULTICAST FUNCTION");
		if(IPC_RegisterMulticastFunc(IPC_FUNC_ID_MLTCST_TST_1) != RPC_SUCCESS) {
			RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR CAN NOT REGISTER MULTICAST FUNCTION ID:0x%x;",IPC_FUNC_ID_MLTCST_TST_1);
			exit(-1);
		}
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"REGISTER MULTICAST ID:0x%x;",IPC_FUNC_ID_MLTCST_TST_1);
		}
#endif	/* USE_MULTICAST_RPC MULTICAST_TEST */
//		sleep(10);
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"NOW WAIT CHILD PROCESS TO EXIT PID:0x%x;",RPC_GetPid());
		for(i = 0;i < NUM_OF_TEST_PROGRAM;i++) {int32_t pid;int status;
			if(RPC_Wait(&pid,&status,&errCode) != RPC_SUCCESS) {
				RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR: ERROR IN WAIT RET:0x%x;",errCode);
			}
			RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"RETURN FROM WAIT PID:0x%x; STATUS:0x%x;",pid,status);
		}
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"END WAIT CHILD PROCESS TO EXIT PID:0x%x;",RPC_GetPid());
	}
	else {int32_t pid,skelPid;RpcResult_t (*skelFunction)(void);RpcResult_t (*skelCancel)(void);
		sleepTime.tv_sec = 0;
		sleepTime.tv_usec =100*1000;
		(void)RPC_TaskSleep(&sleepTime,NULL);
		pid = RPC_GetPid();
		for(i = 0;i < NUM_OF_TEST_PROGRAM;i++ ) {
			if(IPC_SerachProcessIdFromFuncDB(skelFuncID[i],&skelPid) == RPC_SUCCESS) {
				if(pid != skelPid)
					continue;
				else if(IPC_SearchFunctionFromFuncDB(skelFuncID[i],&skelFunction,&skelCancel) == RPC_SUCCESS) {
					RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"NOW CALL SkeltonTest PID:0x%x; SkeltonFunc:0x%x; ",pid, skelFunction);
					if((ret = skelFunction()) != RPC_SUCCESS) {
						RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR IN TEST PROCESS PID:0x%x; ret:0x%x",skelPid,ret);
						return 1;		
					}
					RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"RETURN SkeltonTest PID:0x%x;",skelPid);
					break;
				}
				else {
					RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR: CAN NOT FIND SKELTON FUNC PID:0x%x, FUNCID:0x%x;RET:%s;",
						skelPid, skelFuncID[i],RPC_LogConvertResultCode(ret));
					return 1;		
				}
			}
		}
		if(i >= NUM_OF_TEST_PROGRAM) {
			RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"NOT FOUND THE EXEC FUNCTION PID:0x%x;",pid);
		}
	}
#endif	/* 0 */
	RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_DEBUG1,"NOW PROCESS IS EXITED PID:0x%x; MASTER:%d; SKELTON:%d; STUB:%d;",RPC_GetPid(),masterProcess,useSkelton,useStub);
	return 0;
}

/* ----- SKELTON TEST ROUTINES ----- */

static RpcResult_t skeltonFuncA(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut);
static RpcResult_t skeltonFuncCancelA(uint32_t processId, uint32_t seqNum);
static RpcResult_t skeltonFuncB(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut);
static RpcResult_t skeltonFuncCancelB(uint32_t processId, uint32_t seqNum);
static RpcResult_t skeltonFuncC(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut);
static RpcResult_t skeltonFuncCancelC(uint32_t processId, uint32_t seqNum);

static RpcResult_t FunctionA(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet);
static RpcResult_t FunctionB(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet);
static RpcResult_t FunctionC(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet);

static RpcResult_t setSkeltonParam(uint32_t retVal, char *fromRet, char *toRet, RpcParamData_t *retParam, void **outData, int32_t *outSize);

RpcResult_t SkeltonTest1(void) {
	struct timeval sleepTime;RpcResult_t ret;uint32_t pid;
#ifdef	MULTICAST_TEST
	sleepTime.tv_sec = 1;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
#endif	/* MULTICAST_TEST */
	pid = RPC_GetPid();
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN SkeltonTest1 PID:0x%x;",pid);
	if((ret = IPC_RegisterFuncDBEntry(IPC_FUNCTION_A_FUNC_ID, pid, skeltonFuncA,skeltonFuncCancelA)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_RegisterFuncDBEntry RET:%s",RPC_LogConvertResultCode(ret));
	}
#ifdef	USE_MULTICAST_RPC
	if(IPC_SignupMulticastFunc(IPC_FUNC_ID_MLTCST_TST_1,IPC_FUNCTION_A_FUNC_ID) != RPC_SUCCESS) {
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR CAN NOT SIGNUP MULTICAST FUNCTION ID:0x%x; FUNC:0x%x;",IPC_FUNC_ID_MLTCST_TST_1,IPC_FUNCTION_A_FUNC_ID);
	}
#endif	/* USE_MULTICAST_RPC */
	sleepTime.tv_sec = 20;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT SkeltonTest1 PID:0x%x;",RPC_GetPid());	
	return RPC_SUCCESS;
}

RpcResult_t SkeltonTest2(void) {
	struct timeval sleepTime;RpcResult_t ret;uint32_t pid;

#ifdef	MULTICAST_TEST
	sleepTime.tv_sec = 1;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
#endif	/* MULTICAST_TEST */
	pid = RPC_GetPid();
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN SkeltonTest2 PID:0x%x;",pid);
	if((ret = IPC_RegisterFuncDBEntry(IPC_FUNCTION_B_FUNC_ID, pid, skeltonFuncB,skeltonFuncCancelB)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_RegisterFuncDBEntry RET:%s",RPC_LogConvertResultCode(ret));
	}
#ifdef	USE_MULTICAST_RPC
	if(IPC_SignupMulticastFunc(IPC_FUNC_ID_MLTCST_TST_1,IPC_FUNCTION_B_FUNC_ID) != RPC_SUCCESS) {
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR CAN NOT SIGNUP MULTICAST FUNCTION ID:0x%x; FUNC:0x%x;",IPC_FUNC_ID_MLTCST_TST_1,IPC_FUNCTION_B_FUNC_ID);
	}
#endif	/* USE_MULTICAST_RPC */
	sleepTime.tv_sec = 20;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT SkeltonTest2 PID:0x%x;",RPC_GetPid());	
	return RPC_SUCCESS;
}

RpcResult_t SkeltonTest3(void) {
	struct timeval sleepTime;RpcResult_t ret;uint32_t pid;

#ifdef	MULTICAST_TEST
	sleepTime.tv_sec = 1;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
#endif	/* MULTICAST_TEST */
	pid = RPC_GetPid();
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN SkeltonTest3 PID:0x%x;",pid);
	if((ret = IPC_RegisterFuncDBEntry(IPC_FUNCTION_C_FUNC_ID, pid, skeltonFuncC,skeltonFuncCancelC)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_RegisterFuncDBEntry RET:%s",RPC_LogConvertResultCode(ret));
	}
#ifdef	USE_MULTICAST_RPC
	if(IPC_SignupMulticastFunc(IPC_FUNC_ID_MLTCST_TST_1,IPC_FUNCTION_C_FUNC_ID) != RPC_SUCCESS) {
		RPC_LogPrint(RPC_LOG_MODULE_MAIN,RPC_LOG_LEVEL_ERROR,"ERROR CAN NOT SIGNUP MULTICAST FUNCTION ID:0x%x; FUNC:0x%x;",IPC_FUNC_ID_MLTCST_TST_1,IPC_FUNCTION_C_FUNC_ID);
	}
#endif	/* USE_MULTICAST_RPC */
	sleepTime.tv_sec = 20;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT SkeltonTest3 PID:0x%x;",RPC_GetPid());	
	return RPC_SUCCESS;
}

static RpcResult_t skeltonFuncA(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut) {
	uint32_t fromPid;
	uint8_t inParam[1024*10];RpcResult_t ret;
	uint32_t count; char fromProcess[1024],toProcess[1024]; uint32_t retVal;char fromRet[1024],toRet[1024];
	RpcParamData_t retParam[4];

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN skeltonFuncA PID:0x%x; seqNum:0x%x; inData:0x%x; inSize:0x%x, outData:0x%x; outSize:0x%x; timeOut:%d;",
		processId, seqNum, inData, inSize, outData, outSize, timeOut);
	if((ret = IPC_Unmarshal(inData, inSize, inParam, 1024*10)) != RPC_SUCCESS) {
		IPC_FreeMarshaledSharedData(inData);
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
		if((ret = setSkeltonParam(0xFFFFFFFF,"", "", retParam, outData, outSize)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
			return RPC_FATAL_ERROR;
		}
		return RPC_FATAL_ERROR;
	}
	fromPid = *((uint32_t*)((RpcParamData_t*)inParam)[0].paramData);
	count = *((uint32_t*)((RpcParamData_t*)inParam)[1].paramData);
	memcpy(fromProcess,((RpcParamData_t*)inParam)[2].paramData,((RpcParamData_t*)inParam)[2].paramSpec.paramLeng);
	fromProcess[((RpcParamData_t*)inParam)[2].paramSpec.paramLeng] = 0;
	memcpy(toProcess, ((RpcParamData_t*)inParam)[3].paramData, ((RpcParamData_t*)inParam)[3].paramSpec.paramLeng);
	toProcess[((RpcParamData_t*)inParam)[3].paramSpec.paramLeng] = 0;
//	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"  From PARAM fromPid:0x%x; count:%d; fromProcess:%s; toProcess:%s;",
//		fromPid, count, fromProcess, toProcess);	
	if((ret = FunctionA(count,fromProcess, toProcess,  &retVal, fromRet, toRet)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN FunctionA RET:%s;",RPC_LogConvertResultCode(ret));
		if((ret = setSkeltonParam(0xFFFFFFFF,"", "", retParam, outData, outSize)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
			return RPC_FATAL_ERROR;
		}
		return RPC_FATAL_ERROR;
	}
	if((ret = setSkeltonParam(retVal, fromRet, toRet, retParam, outData, outSize)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
		return RPC_FATAL_ERROR;
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT skeltonFuncA PID:0x%x; seqNum:0x%x;",processId, seqNum);
	return RPC_SUCCESS;
}

static RpcResult_t skeltonFuncCancelA(uint32_t processId, uint32_t seqNum) {
	struct timeval sleepTime;;

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN skeltonFuncCancelA PID:0x%x; seqNum:0x%x;",processId, seqNum);
	sleepTime.tv_sec = 3;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT skeltonFuncCancelA PID:0x%x; seqNum:0x%x;",processId, seqNum);
	return RPC_SUCCESS;
}


static RpcResult_t skeltonFuncB(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut) {
	uint32_t fromPid;
	uint8_t inParam[1024*10];RpcResult_t ret;
	uint32_t count; char fromProcess[1024],toProcess[1024]; uint32_t retVal;char fromRet[1024],toRet[1024];
	RpcParamData_t retParam[4];

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN skeltonFuncB PID:0x%x; seqNum:0x%x; inData:0x%x; inSize:0x%x, outData:0x%x; outSize:0x%x; timeOut:%d;",
		processId, seqNum, inData, inSize, outData, outSize, timeOut);
	if((ret = IPC_Unmarshal(inData, inSize, inParam, 1024*10)) != RPC_SUCCESS) {
		IPC_FreeMarshaledSharedData(inData);
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
		if((ret = setSkeltonParam(0xFFFFFFFF,"", "", retParam, outData, outSize)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
			return RPC_FATAL_ERROR;
		}
		return RPC_FATAL_ERROR;
	}
	fromPid = *((uint32_t*)((RpcParamData_t*)inParam)[0].paramData);
	count = *((uint32_t*)((RpcParamData_t*)inParam)[1].paramData);
	memcpy(fromProcess,((RpcParamData_t*)inParam)[2].paramData,((RpcParamData_t*)inParam)[2].paramSpec.paramLeng);
	fromProcess[((RpcParamData_t*)inParam)[2].paramSpec.paramLeng] = 0;
	memcpy(toProcess, ((RpcParamData_t*)inParam)[3].paramData, ((RpcParamData_t*)inParam)[3].paramSpec.paramLeng);
	toProcess[((RpcParamData_t*)inParam)[3].paramSpec.paramLeng] = 0;
//	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"  From PARAM fromPid:0x%x; count:%d; fromProcess:%s; toProcess:%s;",
//		fromPid, count, fromProcess, toProcess);	
	if((ret = FunctionB(count,fromProcess, toProcess,  &retVal, fromRet, toRet)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN FunctionA RET:%s;",RPC_LogConvertResultCode(ret));
		if((ret = setSkeltonParam(0xFFFFFFFF,"", "", retParam, outData, outSize)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
			return RPC_FATAL_ERROR;
		}
		return RPC_FATAL_ERROR;
	}
	if((ret = setSkeltonParam(retVal, fromRet, toRet, retParam, outData, outSize)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
		return RPC_FATAL_ERROR;
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT skeltonFuncB PID:0x%x; seqNum:0x%x;",processId, seqNum);
	return RPC_SUCCESS;
}

static RpcResult_t skeltonFuncCancelB(uint32_t processId, uint32_t seqNum) {
	struct timeval sleepTime;

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN skeltonFuncCancelB PID:0x%x; seqNum:0x%x;",processId, seqNum);
	sleepTime.tv_sec = 3;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT skeltonFuncCancelB PID:0x%x; seqNum:0x%x;",processId, seqNum);
	return RPC_SUCCESS;
}

static RpcResult_t skeltonFuncC(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut) {
	uint32_t fromPid;
	uint8_t inParam[1024*10];RpcResult_t ret;
	uint32_t count; char fromProcess[1024],toProcess[1024]; uint32_t retVal;char fromRet[1024],toRet[1024];
	RpcParamData_t retParam[4];

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN skeltonFuncC PID:0x%x; seqNum:0x%x; inData:0x%x; inSize:0x%x, outData:0x%x; outSize:0x%x; timeOut:%d;",
		processId, seqNum, inData, inSize, outData, outSize, timeOut);
	if((ret = IPC_Unmarshal(inData, inSize, inParam, 1024*10)) != RPC_SUCCESS) {
		IPC_FreeMarshaledSharedData(inData);
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
		if((ret = setSkeltonParam(0xFFFFFFFF,"", "", retParam, outData, outSize)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
			return RPC_FATAL_ERROR;
		}
		return RPC_FATAL_ERROR;
	}
	fromPid = *((uint32_t*)((RpcParamData_t*)inParam)[0].paramData);
	count = *((uint32_t*)((RpcParamData_t*)inParam)[1].paramData);
	memcpy(fromProcess,((RpcParamData_t*)inParam)[2].paramData,((RpcParamData_t*)inParam)[2].paramSpec.paramLeng);
	fromProcess[((RpcParamData_t*)inParam)[2].paramSpec.paramLeng] = 0;
	memcpy(toProcess, ((RpcParamData_t*)inParam)[3].paramData, ((RpcParamData_t*)inParam)[3].paramSpec.paramLeng);
	toProcess[((RpcParamData_t*)inParam)[3].paramSpec.paramLeng] = 0;
//	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"  From PARAM fromPid:0x%x; count:%d; fromProcess:%s; toProcess:%s;",
//		fromPid, count, fromProcess, toProcess);	
	if((ret = FunctionC(count,fromProcess, toProcess,  &retVal, fromRet, toRet)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN FunctionA RET:%s;",RPC_LogConvertResultCode(ret));
		if((ret = setSkeltonParam(0xFFFFFFFF,"", "", retParam, outData, outSize)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
			return RPC_FATAL_ERROR;
		}
		return RPC_FATAL_ERROR;
	}
	if((ret = setSkeltonParam(retVal, fromRet, toRet, retParam, outData, outSize)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN setSkeltonParam RET:%s;",RPC_LogConvertResultCode(ret));
		return RPC_FATAL_ERROR;
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT skeltonFuncC PID:0x%x; seqNum:0x%x;",processId, seqNum);
	return RPC_SUCCESS;
}

static RpcResult_t skeltonFuncCancelC(uint32_t processId, uint32_t seqNum) {
	struct timeval sleepTime;

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN skeltonFuncCancelC PID:0x%x; seqNum:0x%x;",processId, seqNum);
	sleepTime.tv_sec = 3;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT skeltonFuncCancelC PID:0x%x; seqNum:0x%x;",processId, seqNum);
	return RPC_SUCCESS;
}

static RpcResult_t FunctionA(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet) {
	RpcResult_t ret = RPC_SUCCESS;char newFrom[1024]; char newTo[1024];
	struct timeval sleepTime;

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN FunctionA PID:0x%x; count:%d; fromProcess:%s; toProcess:%s;",RPC_GetPid(),count, fromProcess, toProcess);
	count--;
	if(count > 0) {
		sleepTime.tv_sec = 1;
		sleepTime.tv_usec = 0;
		(void)RPC_TaskSleep(&sleepTime,NULL);

		strcpy(newFrom,"SkeltonTest1");
		strcpy(newTo,"SkeltonTest2");
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," NOW CALL FunctionStubA count:%d; from:%s; to:%s;",
			count, newFrom, newTo);
		if((ret = FunctionStubA(count, newFrom, newTo, retVal,fromRet, toRet)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR," ERROR IN FunctionStubA RET:0x%x;",ret);
			return ret;
		}
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," RETURN FunctionStubA retVal:%d; fromRet:%s; toRet:%s;",
			*retVal, fromRet, toRet);
	}
	else {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," ##### OK COUNT IS 0, SO FINISH IN FunctionA PID:0x%x; #####",RPC_GetPid());
		sleepTime.tv_sec = 2;
		sleepTime.tv_usec = 0;
		(void)RPC_TaskSleep(&sleepTime,NULL);
	}
	*retVal = 0xA;
	strcpy(fromRet,"SkeltonTest1");
	strcpy(toRet, fromProcess);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT FunctionA PID:0x%x; RET:0x%x;",RPC_GetPid(), ret);
	return ret;
}

static RpcResult_t FunctionB(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet) {
	RpcResult_t ret = RPC_SUCCESS;char newFrom[1024]; char newTo[1024];
	struct timeval sleepTime;

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN FunctionB PID:0x%x; count:%d; fromProcess:%s; toProcess:%s;",RPC_GetPid(),count, fromProcess, toProcess);
	count--;
	if(count > 0) {
		sleepTime.tv_sec = 1;
		sleepTime.tv_usec = 0;
		(void)RPC_TaskSleep(&sleepTime,NULL);

		strcpy(newFrom,"SkeltonTest2");
		strcpy(newTo,"SkeltonTest3");
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," NOW CALL FunctionStubB count:%d; from:%s; to:%s;",
			count, newFrom, newTo);
		if((ret = FunctionStubB(count, newFrom, newTo, retVal,fromRet, toRet)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR," ERROR IN FunctionStubB RET:0x%x;",ret);
			return ret;
		}
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," RETURN FunctionStubB retVal:%d; fromRet:%s; toRet:%s;",
			*retVal, fromRet, toRet);
	}
	else {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," ##### OK COUNT IS 0, SO FINISH IN FunctionB PID:0x%x; #####",RPC_GetPid());
		sleepTime.tv_sec = 2;
		sleepTime.tv_usec = 0;
		(void)RPC_TaskSleep(&sleepTime,NULL);
	}
	*retVal = 0xB;
	strcpy(fromRet,"SkeltonTest2");
	strcpy(toRet, fromProcess);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT FunctionB PID:0x%x; RET:0x%x;",RPC_GetPid(), ret);
	return ret;
}

static RpcResult_t FunctionC(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet) {
	RpcResult_t ret = RPC_SUCCESS;char newFrom[1024]; char newTo[1024];
	struct timeval sleepTime;

	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"IN FunctionC PID:0x%x; count:%d; fromProcess:%s; toProcess:%s;",RPC_GetPid(),count, fromProcess, toProcess);
	count--;
	if(count > 0) {
		sleepTime.tv_sec = 1;
		sleepTime.tv_usec = 0;
		(void)RPC_TaskSleep(&sleepTime,NULL);

		strcpy(newFrom,"SkeltonTest3");
		strcpy(newTo,"SkeltonTest1");
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," NOW CALL FunctionStubC count:%d; from:%s; to:%s;",
			count, newFrom, newTo);
		if((ret = FunctionStubC(count, newFrom, newTo, retVal,fromRet, toRet)) != RPC_SUCCESS) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR," ERROR IN FunctionStubC RET:0x%x;",ret);
			return ret;
		}
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," RETURN FunctionStubC retVal:%d; fromRet:%s; toRet:%s;",
			*retVal, fromRet, toRet);
	}
	else {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1," ##### OK COUNT IS 0, SO FINISH IN FunctionC PID:0x%x; #####",RPC_GetPid());
		sleepTime.tv_sec = 2;
		sleepTime.tv_usec = 0;
		(void)RPC_TaskSleep(&sleepTime,NULL);
	}
	*retVal = 0xC;
	strcpy(fromRet,"SkeltonTest3");
	strcpy(toRet, fromProcess);
	(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_DEBUG1,"OUT FunctionC PID:0x%x; RET:0x%x;",RPC_GetPid(), ret);
	return ret;
}

static RpcResult_t setSkeltonParam(uint32_t retVal, char *fromRet, char *toRet, RpcParamData_t *retParam, void **outData, int32_t *outSize) {
	RpcResult_t ret;

	retParam[0].paramSpec.paramType = RPC_UINT_TYPE;
	retParam[0].paramSpec.paramLeng = 4;
	retParam[0].paramData = (uint8_t*)&retVal;
	retParam[1].paramSpec.paramType = RPC_STRING_TYPE;
	retParam[1].paramSpec.paramLeng = strlen(fromRet);
	retParam[1].paramData = (uint8_t*)fromRet;
	retParam[2].paramSpec.paramType = RPC_STRING_TYPE;
	retParam[2].paramSpec.paramLeng = strlen(toRet);
	retParam[2].paramData = (uint8_t*)toRet;
	retParam[3].paramSpec.paramType = RPC_TYPE_UNKNOWN;
	retParam[3].paramSpec.paramLeng = 0;
	retParam[3].paramData = (uint8_t*)NULL;
	if((ret = IPC_Marshal(retParam, outData,outSize)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_SKELTON,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Marshal RET:%s",RPC_LogConvertResultCode(ret));
		return ret;
	}
	return ret;
}

/* ----- STUB TEST ROUTINES----- */

static RpcResult_t setStubParam(RpcParamData_t *inData, uint32_t pid, uint32_t count, char *fromProcess, char *toProcess,void **outData,uint32_t *outSize);
static void RpcStubFuncACallback(uint32_t seqNum,void *outData,uint32_t outSize,uint32_t errCode);
static void * StubSyncTestA(void *arg);
#ifdef	USE_MULTICAST_RPC
static void multicastCallback(uint32_t seqNum,uint32_t numOfRet,IpcMulticastRetData_t *retData,uint32_t errCode);
#endif	/* USE_MULTICAST_RPC */

RpcResult_t StubTestA(void) {
	struct timeval sleepTime;uint32_t errCode;RpcResult_t ret;uint32_t pid;
	uint32_t count;uint32_t seqNum;
	char *fromProcess;char *toProcess;
	uint32_t retVal;char fromRet[1024]; char toRet[1024];

	pid = RPC_GetPid();
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"IN StubTestA PID:0x%x;",pid);
#ifdef	MULTICAST_TEST
	sleepTime.tv_sec = 2;
#else	/* MULTICAST_TEST */
	sleepTime.tv_sec = 1;
#endif	/* MULTICAST_TEST */
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
#ifdef	MULTICAST_TEST
	count = 2;
#else	/* MULTICAST_TEST */
	count = 15;
#endif	/* MULTICAST_TEST */
	fromProcess = "StubTest1";
	toProcess = "SkeltonTest2";
//	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"  NOW CALL FunctionStubA");
#if	0
	if((ret = FunctionStubA(count, fromProcess, toProcess, &retVal, fromRet, toRet)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN FunctionStubA RET:%s",RPC_LogConvertResultCode(ret));
		return RPC_FATAL_ERROR;
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1," ##### OK SUCCESS TO RETURN SYNC FUNC RET-VAL:0x%x; fromRet:%s; toRet:%s; #####",retVal, fromRet, toRet);
#else	/* 0 */
#if	0	/* CANCEL TEST FOR SYNC CALL */
	{RpcTaskID_t taskId;RpcTaskAttribute_t taskAttr;void *retVal;
	RPC_TaskAttrInit(&taskAttr);
	RPC_CreateTask(&taskId,&taskAttr,StubSyncTestA,(void*)NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1," OK CREATE A TASK ID:0x%x;",taskId);
	sleepTime.tv_sec = 3;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1," OK NOW CANCEL TASK ID:0x%x;",taskId);
	ret = RPC_StubSyncCancel(taskId,&errCode);
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1," RETURN FROM THE CANCEL TASKID:0x%x; RET:%d; errCode:%s;",
		taskId,RPC_LogConvertResultCode(ret),RPC_LogConvertErrCode(errCode));
	RPC_JoinTask(taskId,&retVal);
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1," OK JOIN THE CREATED TASK ID:0x%x;",taskId);
	}
#else	/* 0 */	/* TEST FOR ASYNC CALL */
	if((ret = FunctionStubAAsync(count, fromProcess, toProcess,&seqNum )) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN FunctionStubA RET:%s",RPC_LogConvertResultCode(ret));
		return RPC_FATAL_ERROR;
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1," ##### OK SUCCESS TO RETURN ASYNC FUNC #####");
#endif	/* 0 */
#endif	/* 0 */
#if	1
	sleepTime.tv_sec = 8;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
#else	/* 0 */	/* CANCEL TEST FOR ASYNC CALL */
	sleepTime.tv_sec = 1;
	sleepTime.tv_usec = 0;	/* 300msec */
	(void)RPC_TaskSleep(&sleepTime,NULL);
	if((ret = RPC_StbuAsyncCancel(seqNum,&errCode)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR,"ERROR IN RPC_StbuAsyncCancel RET-CODE:%s; ERR-CODE:%s;",
			RPC_LogConvertResultCode(ret),RPC_LogConvertErrCode(errCode));
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"OUT StubTestA PID:0x%x;",RPC_GetPid());	
		return RPC_FATAL_ERROR;
	}
	sleepTime.tv_sec = 8;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
#endif	/* 0 */
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"OUT StubTestA PID:0x%x;",RPC_GetPid());	
	return RPC_SUCCESS;
}

static void *StubSyncTestA(void *arg) {
	struct timeval sleepTime;RpcResult_t ret;uint32_t pid;
	uint32_t count;uint32_t seqNum;
	char *fromProcess;char *toProcess;
	uint32_t retVal;char fromRet[1024]; char toRet[1024];

	pid = RPC_GetPid();
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"IN StubSyncTestA PID:0x%x; TASKID:0x%x;",pid,RPC_TaskSelf());
	sleepTime.tv_sec = 1;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	count = 6;
	fromProcess = "StubSyncTestA";
	toProcess = "SkeltonTest2";
//	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"  NOW CALL FunctionStubA");
	if((ret = FunctionStubA(count, fromProcess, toProcess, &retVal, fromRet, toRet)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN FunctionStubA RET:%s",RPC_LogConvertResultCode(ret));
		return (void*)NULL;
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1," ##### OK SUCCESS TO RETURN SYNC FUNC RET-VAL:0x%x; fromRet:%s; toRet:%s; #####",retVal, fromRet, toRet);
	sleepTime.tv_sec = 2;
	sleepTime.tv_usec = 0;
	(void)RPC_TaskSleep(&sleepTime,NULL);
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"OUT StubSyncTestA PID:0x%x; TASKID:0x%x;",RPC_GetPid(),RPC_TaskSelf());	
	return (void*)NULL;
}

RpcResult_t FunctionStubAAsync(uint32_t count, char *fromProcess, char *toProcess, uint32_t *seqNum) {
	uint32_t errCode;RpcParamData_t inData[5];uint32_t pid;void *outData;uint32_t outSize;RpcResult_t ret;
	uint32_t retSize;uint32_t timeOut;

	pid = RPC_GetPid();
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "IN FunctioncStubAAsync PID:0x%x;, count:%d; fromProcess:%s; toProcess:%s;",
		pid, count, fromProcess, toProcess);
	if((ret = setStubParam(inData, pid, count, fromProcess, toProcess, &outData, &outSize)) != RPC_SUCCESS) {
		return ret;
	}
	timeOut = 1000*20;
//	timeOut = 1000*5;	/* TIMEOUT TEST FOR ASYNC CALL */
#if	defined(USE_MULTICAST_RPC)&&defined(MULTICAST_TEST)
	{
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"NOW CALL IPC_CallStubAsyncMulticast FUNC-ID:0x%x;",IPC_FUNC_ID_MLTCST_TST_1);
	if((ret = IPC_CallStubAsyncMulticast(IPC_FUNC_ID_MLTCST_TST_1,outData,outSize,timeOut,multicastCallback,seqNum,&errCode)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_CallStubAsyncMulticast FUNCID:0x%x; RET:%s; ERR-CODE:%s",
			IPC_FUNC_ID_MLTCST_TST_1,RPC_LogConvertResultCode(ret),RPC_LogConvertErrCode(errCode));
		return ret;
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "OUT FunctioncStubAAsync PID:0x%x; SEQ-NUM:0x%x; ERR-CODE:%s",
		pid,*seqNum,RPC_LogConvertErrCode(errCode));

	}
#else	/* USE_MULTICAST_RPC MULTICAST_TEST */
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"NOW CALL IPC_CallStubAsync");
	if((ret = IPC_CallStubAsync(IPC_FUNCTION_B_FUNC_ID, outData, outSize, timeOut,RpcStubFuncACallback, seqNum,&errCode)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_CallStubSync FUNCID:0x%x; ERR-CODE:%s",IPC_FUNCTION_B_FUNC_ID,RPC_LogConvertErrCode(errCode));
		return ret;
	}
#endif	/* USE_MULTICAST_RPC MULTICAST_TEST */
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "OUT FunctioncStubAAsync PID:0x%x; seqNum:0x%x;",
		pid, *seqNum);
	return ret;
}

#ifdef	USE_MULTICAST_RPC
static void multicastCallback(uint32_t seqNum,uint32_t numOfRet,IpcMulticastRetData_t *retData,uint32_t errCode) {
	int i;	uint8_t retParam[1024*10]; uint32_t retParamSize = 1024*10;uint32_t retVal;char fromRet[256],toRet[256];
	RpcResult_t ret;

	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"IN multicastCallback PID:0x%x; seqNum:0x%x; numOfRet:%d; retData:0x%x; errCode:%s;",
		RPC_GetPid(),seqNum,numOfRet,retData,RPC_LogConvertErrCode(errCode));
	if(retData != (IpcMulticastRetData_t*)NULL) {
		for(i = 0;i < numOfRet;i++) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "   RESULT PID:0x%x; RET-SIZE:%d; RET-DATA:0x%x;ERR-CODE:%s",
				retData[i].resPid,retData[i].retParamSize,retData[i].retParam,RPC_LogConvertErrCode(retData[i].errCode));
			if(retData[i].retParam != (void*)NULL) {
				if((ret = IPC_Unmarshal(retData[i].retParam, retData[i].retParamSize, retParam, retParamSize)) != RPC_SUCCESS) {
					IPC_FreeMarshaledSharedData(retData[i].retParam);
					(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
					return;
				}
				retVal = *((uint32_t*)((RpcParamData_t*)retParam)[0].paramData);
				memcpy(fromRet,((RpcParamData_t*)retParam)[1].paramData,((RpcParamData_t*)retParam)[1].paramSpec.paramLeng);
				fromRet[((RpcParamData_t*)retParam)[1].paramSpec.paramLeng] = 0;
				memcpy(toRet, ((RpcParamData_t*)retParam)[2].paramData, ((RpcParamData_t*)retParam)[2].paramSpec.paramLeng);
				toRet[((RpcParamData_t*)retParam)[2].paramSpec.paramLeng] = 0;
				(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "   OUT PARAMS RET-CODE:0x%x; from:%s; to:%s;",
					retVal,fromRet, toRet);
			}
		}
		IPC_FreeMulticastOutParams(retData);
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "OUT multicastCallback PID:0x%x;",RPC_GetPid());
}
#endif	/* USE_MULTICAST_RPC */


RpcResult_t FunctionStubA(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet) {
	uint32_t errCode;RpcParamData_t inData[5];uint32_t pid;void *outData;uint32_t outSize;RpcResult_t ret;
	void *retData;uint32_t retSize;uint32_t timeOut;
	uint8_t retParam[1024*10]; uint32_t retParamSize = 1024*10;
#if	0
	int32_t (*func)(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut, uint32_t *errCode);
	int32_t (*cancelFunc)(uint32_t processId, uint32_t seqNum, uint32_t *errCode);
#endif	/* 0 */

	pid = RPC_GetPid();
	*retVal = 0xFFFFFFFF;
	strcpy(fromRet,"ERROR");
	strcpy(toRet, "ERROR");
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "IN FunctioncStubA PID:0x%x;, count:%d; fromProcess:%s; toProcess:%s;",
		pid, count, fromProcess, toProcess);
#if	0
	if((ret = RPC_searchFuncDBFromFunction(IPC_FUNCTION_B_FUNC_ID,&func,&cancelFunc,&errCode)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN RPC_searchFuncDBFromFunction FUNCID:0x%x,ERR-CODE:%s",IPC_FUNCTION_B_FUNC_ID,RPC_LogConvertErrCode(errCode));
		return ret;
	}
#endif	/* 0 */
	if((ret = setStubParam(inData, pid, count, fromProcess, toProcess, &outData, &outSize)) != RPC_SUCCESS) {
		return ret;
	}
	timeOut = 1000*20;
#if	defined(USE_MULTICAST_RPC)&&defined(MULTICAST_TEST)
	{uint32_t numOfRet;IpcMulticastRetData_t *outParams;int i;
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1,"NOW CALL IPC_CallStubSyncMulticast FUNC-ID:0x%x;",IPC_FUNC_ID_MLTCST_TST_1);
	if((ret = IPC_CallStubSyncMulticast(IPC_FUNC_ID_MLTCST_TST_1,outData,outSize,&numOfRet,&outParams,timeOut,&errCode)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_CallStubSyncMulticast FUNCID:0x%x; RET:%s; ERR-CODE:%s",
			IPC_FUNC_ID_MLTCST_TST_1,RPC_LogConvertResultCode(ret),RPC_LogConvertErrCode(errCode));
		return ret;
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "RETURN FROM MULTICAST NUM-OF-RET:%d; RET-DATA:0x%x; ERR-CODE:%s",
		numOfRet,outParams,RPC_LogConvertErrCode(errCode));
	if(outParams != (IpcMulticastRetData_t*)NULL) {
		for(i = 0;i < numOfRet;i++) {
			(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "   RESULT PID:0x%x; RET-SIZE:%d; RET-DATA:0x%x;ERR-CODE:%s",
				outParams[i].resPid,outParams[i].retParamSize,outParams[i].retParam,RPC_LogConvertErrCode(outParams[i].errCode));
			if(outParams[i].retParam != (void*)NULL) {
				if((ret = IPC_Unmarshal(outParams[i].retParam, outParams[i].retParamSize, retParam, retParamSize)) != RPC_SUCCESS) {
					IPC_FreeMarshaledSharedData(outParams[i].retParam);
					(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
					return ret;
				}
				*retVal = *((uint32_t*)((RpcParamData_t*)retParam)[0].paramData);
				memcpy(fromRet,((RpcParamData_t*)retParam)[1].paramData,((RpcParamData_t*)retParam)[1].paramSpec.paramLeng);
				fromRet[((RpcParamData_t*)retParam)[1].paramSpec.paramLeng] = 0;
				memcpy(toRet, ((RpcParamData_t*)retParam)[2].paramData, ((RpcParamData_t*)retParam)[2].paramSpec.paramLeng);
				toRet[((RpcParamData_t*)retParam)[2].paramSpec.paramLeng] = 0;
				(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "   OUT PARAMS RET-CODE:0x%x; from:%s; to:%s;",
					*retVal,fromRet, toRet);
			}
		}
		IPC_FreeMulticastOutParams(outParams);
	}
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "OUT FunctioncStubA PID:0x%x;",
		pid);
	}
#else	/* USE_MULTICAST_RPC MULTICAST_TEST */
	if((ret = IPC_CallStubSync(IPC_FUNCTION_B_FUNC_ID, outData, outSize, &retData, &retSize,timeOut, &errCode)) != RPC_SUCCESS) {
		if(retData != (void*)NULL) {
			IPC_FreeMarshaledSharedData(retData);
		}
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_CallStubSync FUNCID:0x%x; ERR-CODE:%s",IPC_FUNCTION_B_FUNC_ID,RPC_LogConvertErrCode(errCode));
		return ret;
	}
	if(retData == (void*)NULL) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "SOMTHING WRONG IN STUB CALL\n");
		return RPC_FATAL_ERROR;
	}
	if((ret = IPC_Unmarshal(retData, retSize, retParam, retParamSize)) != RPC_SUCCESS) {
		IPC_FreeMarshaledSharedData(retData);
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
		return ret;
	}
	*retVal = *((uint32_t*)((RpcParamData_t*)retParam)[0].paramData);
	memcpy(fromRet,((RpcParamData_t*)retParam)[1].paramData,((RpcParamData_t*)retParam)[1].paramSpec.paramLeng);
	fromRet[((RpcParamData_t*)retParam)[1].paramSpec.paramLeng] = 0;
	memcpy(toRet, ((RpcParamData_t*)retParam)[2].paramData, ((RpcParamData_t*)retParam)[2].paramSpec.paramLeng);
	toRet[((RpcParamData_t*)retParam)[2].paramSpec.paramLeng] = 0;
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "OUT FunctioncStubA PID:0x%x; RET-CODE:0x%x; from:%s; to:%s;",
		pid,*retVal,fromRet, toRet);
#endif	/* USE_MULTICAST_RPC MULTICAST_TEST */
	return ret;
}

RpcResult_t FunctionStubB(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet) {
	uint32_t errCode;RpcParamData_t inData[5];uint32_t pid;void *outData;uint32_t outSize;RpcResult_t ret;
	int32_t (*func)(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut, uint32_t *errCode);
	int32_t (*cancelFunc)(uint32_t processId, uint32_t seqNum, uint32_t *errCode);
	void *retData;uint32_t retSize;uint32_t timeOut;
	uint8_t retParam[1024*10]; uint32_t retParamSize = 1024*10;

	pid = RPC_GetPid();
	*retVal = 0xFFFFFFFF;
	strcpy(fromRet,"ERROR");
	strcpy(toRet, "ERROR");
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "IN FunctioncStubB PID:0x%x;, count:%d; fromProcess:%s; toProcess:%s;",
		pid, count, fromProcess, toProcess);
#if	0
	if((ret = RPC_searchFuncDBFromFunction(IPC_FUNCTION_C_FUNC_ID,&func,&cancelFunc,&errCode)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN RPC_searchFuncDBFromFunction FUNCID:0x%x,ERR-CODE:%s",IPC_FUNCTION_C_FUNC_ID,RPC_LogConvertErrCode(errCode));
		return ret;
	}
#endif	/* 0 */
	if((ret = setStubParam(inData, pid, count, fromProcess, toProcess, &outData, &outSize)) != RPC_SUCCESS) {
		return ret;
	}
	timeOut = 1000*20;
//	timeOut = 1000*3;	/* TIMEOUT TEST FOR SYNC CALL */
	if((ret = IPC_CallStubSync(IPC_FUNCTION_C_FUNC_ID, outData, outSize, &retData, &retSize,timeOut, &errCode)) != RPC_SUCCESS) {
		if(retData != (void*)NULL) {
			IPC_FreeMarshaledSharedData(retData);
		}
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_CallStubSync FUNCID:0x%x; RET-CODE:%s; ERR-CODE:%s",IPC_FUNCTION_C_FUNC_ID,RPC_LogConvertResultCode(ret),RPC_LogConvertErrCode(errCode));
		return ret;
	}
	if(retData == (void*)NULL) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "SOMTHING WRONG IN STUB CALL\n");
		return RPC_FATAL_ERROR;
	}
	if((ret = IPC_Unmarshal(retData, retSize, retParam, retParamSize)) != RPC_SUCCESS) {
		IPC_FreeMarshaledSharedData(retData);
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
		return ret;
	}
	*retVal = *((uint32_t*)((RpcParamData_t*)retParam)[0].paramData);
	memcpy(fromRet,((RpcParamData_t*)retParam)[1].paramData,((RpcParamData_t*)retParam)[1].paramSpec.paramLeng);
	fromRet[((RpcParamData_t*)retParam)[1].paramSpec.paramLeng] = 0;
	memcpy(toRet, ((RpcParamData_t*)retParam)[2].paramData, ((RpcParamData_t*)retParam)[2].paramSpec.paramLeng);
	toRet[((RpcParamData_t*)retParam)[2].paramSpec.paramLeng] = 0;
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "OUT FunctioncStubB PID:0x%x; RET-CODE:0x%x; from:%s; to:%s;",
		pid,*retVal,fromRet, toRet);
	return ret;
}

RpcResult_t FunctionStubC(uint32_t count, char *fromProcess, char *toProcess, uint32_t *retVal, char *fromRet, char *toRet) {
	uint32_t errCode;RpcParamData_t inData[5];uint32_t pid;void *outData;uint32_t outSize;RpcResult_t ret;
	int32_t (*func)(uint32_t processId, uint32_t seqNum, void *inData ,uint32_t inSize, void **outData, int32_t *outSize, uint32_t timeOut, uint32_t *errCode);
	int32_t (*cancelFunc)(uint32_t processId, uint32_t seqNum, uint32_t *errCode);
	void *retData;uint32_t retSize;uint32_t timeOut;
	uint8_t retParam[1024*10]; uint32_t retParamSize = 1024*10;

	pid = RPC_GetPid();
	*retVal = 0xFFFFFFFF;
	strcpy(fromRet,"ERROR");
	strcpy(toRet, "ERROR");
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "IN FunctioncStubC PID:0x%x;, count:%d; fromProcess:%s; toProcess:%s;",
		pid, count, fromProcess, toProcess);
#if	0
	if((ret = RPC_searchFuncDBFromFunction(IPC_FUNCTION_A_FUNC_ID,&func,&cancelFunc,&errCode)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN RPC_searchFuncDBFromFunction FUNCID:0x%x,ERR-CODE:%s",IPC_FUNCTION_A_FUNC_ID,RPC_LogConvertErrCode(errCode));
		return ret;
	}
#endif	/* 0 */
	if((ret = setStubParam(inData, pid, count, fromProcess, toProcess, &outData, &outSize)) != RPC_SUCCESS) {
		return ret;
	}
	timeOut = 1000*20;
	if((ret = IPC_CallStubSync(IPC_FUNCTION_A_FUNC_ID, outData, outSize, &retData, &retSize,timeOut, &errCode)) != RPC_SUCCESS) {
		if(retData != (void*)NULL) {
			IPC_FreeMarshaledSharedData(retData);
		}
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_CallStubSync FUNCID:0x%x; ERR-CODE:%s",IPC_FUNCTION_A_FUNC_ID,RPC_LogConvertErrCode(errCode));
		return ret;
	}
	if(retData == (void*)NULL) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "SOMTHING WRONG IN STUB CALL\n");
		return RPC_FATAL_ERROR;
	}
	if((ret = IPC_Unmarshal(retData, retSize, retParam, retParamSize)) != RPC_SUCCESS) {
		IPC_FreeMarshaledSharedData(retData);
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
		return ret;
	}
	*retVal = *((uint32_t*)((RpcParamData_t*)retParam)[0].paramData);
	memcpy(fromRet,((RpcParamData_t*)retParam)[1].paramData,((RpcParamData_t*)retParam)[1].paramSpec.paramLeng);
	fromRet[((RpcParamData_t*)retParam)[1].paramSpec.paramLeng] = 0;
	memcpy(toRet, ((RpcParamData_t*)retParam)[2].paramData, ((RpcParamData_t*)retParam)[2].paramSpec.paramLeng);
	toRet[((RpcParamData_t*)retParam)[2].paramSpec.paramLeng] = 0;
	(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_DEBUG1, "OUT FunctioncStubC PID:0x%x; RET-CODE:0x%x; from:%s; to:%s;",
		pid,*retVal,fromRet, toRet);
	return ret;
}

static RpcResult_t setStubParam(RpcParamData_t *inData, uint32_t pid, uint32_t count, char *fromProcess, char *toProcess,void **outData, uint32_t *outSize) {
	RpcResult_t ret;

	inData[0].paramSpec.paramType = RPC_UINT_TYPE;
	inData[0].paramSpec.paramLeng = 4;
	inData[0].paramData = (uint8_t*)&pid;
	inData[1].paramSpec.paramType = RPC_UINT_TYPE;
	inData[1].paramSpec.paramLeng = 4;
	inData[1].paramData = (uint8_t*)&count;
	inData[2].paramSpec.paramType = RPC_STRING_TYPE;
	inData[2].paramSpec.paramLeng = strlen(fromProcess);
	inData[2].paramData = (uint8_t*)fromProcess;
	inData[3].paramSpec.paramType = RPC_STRING_TYPE;
	inData[3].paramSpec.paramLeng = strlen(toProcess);
	inData[3].paramData = (uint8_t*)toProcess;
	inData[4].paramSpec.paramType = RPC_TYPE_UNKNOWN;
	inData[4].paramSpec.paramLeng = 0;
	inData[4].paramData = (uint8_t*)NULL;
	if((ret = IPC_Marshal(inData, outData,outSize)) != RPC_SUCCESS) {
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Marshal RET:%s",RPC_LogConvertResultCode(ret));
		return ret;
	}
	return ret;
}

void RpcStubFuncACallback(uint32_t seqNum,void *outData,uint32_t outSize,uint32_t errCode) {
	RpcResult_t ret;uint32_t retVal;char fromRet[1024];char toRet[1024];
	uint8_t retParam[1024*10]; uint32_t retParamSize = 1024*10;

	RPC_LogPrint(RPC_LOG_MODULE_STUB, RPC_LOG_LEVEL_DEBUG1,"IN RpcStubFuncACallback PID:0x%x; seqNum:0x%x; outData:0x%x outSize:%d; errCode:0x%x;",
		RPC_GetPid(), seqNum, outData, outSize, errCode);
	if(outData == (void*)NULL) {
		RPC_LogPrint(RPC_LOG_MODULE_STUB, RPC_LOG_LEVEL_DEBUG1, "OUT RpcStubFuncACallback OCCUR SOMETHING WRONG ERR-CODE:%s;",RPC_LogConvertErrCode(errCode));
		return;
	}
	if((ret = IPC_Unmarshal(outData, outSize, retParam, retParamSize)) != RPC_SUCCESS) {
		IPC_FreeMarshaledSharedData(outData);
		(void)RPC_LogPrint(RPC_LOG_MODULE_STUB,RPC_LOG_LEVEL_ERROR, "FAIL IN IPC_Unmarshal RET:%s",RPC_LogConvertResultCode(ret));
		return ;
	}
	retVal = *((uint32_t*)((RpcParamData_t*)retParam)[0].paramData);
	memcpy(fromRet,((RpcParamData_t*)retParam)[1].paramData,((RpcParamData_t*)retParam)[1].paramSpec.paramLeng);
	fromRet[((RpcParamData_t*)retParam)[1].paramSpec.paramLeng] = 0;
	memcpy(toRet, ((RpcParamData_t*)retParam)[2].paramData, ((RpcParamData_t*)retParam)[2].paramSpec.paramLeng);
	toRet[((RpcParamData_t*)retParam)[2].paramSpec.paramLeng] = 0;
	RPC_LogPrint(RPC_LOG_MODULE_STUB, RPC_LOG_LEVEL_DEBUG1, "OUT RpcStubFuncACallback retVal:0x%x; fromRet:%s; toRet:%s;",
		retVal, fromRet, toRet);
	return;
}

