///////////////////////////////////////////////////////////
//  OperationManager.cpp
//  Implementation of the Class OperationManager
//  Created on:      08-9-2008 16:50:36
//  Original author: Stanley Sun
///////////////////////////////////////////////////////////

#include <iostream>
#include <pthread.h>
#include "ace/Thread.h"
#include "ace/Synch.h"
#include <time.h>
#include "rsa.h"
#include "StudentMgr.h"
#include "RegMgr.h"
#include <IntfData.h>
#include "RequBase.h"
#include "RequFactory.h"
#include "verify.h"
#include <IPCTeacherDaemonAPI.h>
#include <seslib.h>
#include "SESPublishService.h"
#include "DetectIP.h"
#include "libsesdata.h"
#include "TSDCommon.h"
#include <ace/SSL/SSL_Context.h>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include "genrsa.h"
#include "PolicySettingData.h"
#include "OperationManager.h"
#include <iterator>
#include <list>
#include <string>
#include "TeacherPolicySettingData.h"
#include "TabNavigationData.h"
#include "LibSESDataCommon.h"
using namespace std;
using namespace IPCAPI;
using namespace LibSESData;

/**************************************************************************************************
 * Function Name	: COperationManager
 * Description		: COperationManager
 * Date				: 08/09/09
 * Parameter			:
 * Return Code		:
 * Author				:
 **************************************************************************************************/
COperationManager::COperationManager()
{
	CSESLog::WriteLine("COperationManager::COperationManager>>Start");
	m_iPort = 8888; //default port
	m_iDownloadCAPort = 8889;//default port

	myStudentManager = CStudentMgr::instance();
	myStudentManager->RegisterCOperationManager(this);

	myRequFactory = new RequFactory();

	myRegMgr = RegMgr::instance();
	myRegMgr->RegisterCOperationManager(this);

	IPCAPIBase* newObj = NULL;
	InitializeSESLibrary(SES_API_FOR_TEACHER_DAEMON, &newObj);
	// Start teacher dbus api
	TeacherDaemonAPI = dynamic_cast<IPCTeacherDaemonAPI*> (newObj);

	Publisher = new CSESPublishService();
	m_DetectIP = new DetectIP();
	isStarted = false;

	OP_List_lock = new ACE_Thread_Mutex();

	int err;
	err = pthread_create(&SESDetectIPThreadID, NULL, DetectIPChanged,
			(void*) this);
	if (0 != err)
	{
		CSESLog::WriteLine("CSESPublishService::start error<<pthread_create");
	}
	CSESLog::WriteLine("COperationManager::COperationManager<<End");

}

/**************************************************************************************************
 * Function Name	: ~COperationManager
 * Description		: ~COperationManager
 * Date				: 08/09/09
 * Parameter			:
 * Return Code		:
 * Author				:
 **************************************************************************************************/
COperationManager::~COperationManager()
{

	CSESLog::WriteLine("COperationManager::~COperationManager>>Start");
	pthread_join(SESDetectIPThreadID, NULL);
	if (NULL != Publisher)
	{
		Publisher->stop();
		delete (Publisher);
	}
	delete (myStudentManager);
	delete (myRequFactory);
	delete (myRegMgr);
	delete (TeacherDaemonAPI);
	delete (OP_List_lock);
	delete (m_DetectIP);

	CSESLog::WriteLine("COperationManager::~COperationManager<<End");
}
void* COperationManager::DetectIPChanged(void * arg)
{
	COperationManager* pThis = (COperationManager*) arg;
	while (1)
	{
		if (true == pThis->isStarted)
		{
			if (true == pThis->m_DetectIP->PollingIP())
			{
				CSESLog::WriteLine("COperationManager::DetectIP<<IPChange");
				usleep(1000000 * 5);
				pThis->Publisher->stop();
				usleep(1000000 * 1);
				//				delete pThis->Publisher;
				//				pThis->Publisher = NULL;
				//				pThis->Publisher = new CSESPublishService();
				pThis->Publisher->UpdateServiceInfo(pThis->ControllerName,
						pThis->ControllerDescription, pThis->m_iPort,
						pThis->m_iDownloadCAPort);
				pThis->Publisher->start();
			}
		}
		usleep(1000000 * 1);
	}
	return NULL;
}
/**************************************************************************************************
 * Function Name	: StartController
 * Description		: StartController
 * Date				: 08/09/09
 * Parameter			:
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::StartController(CIntfData* localMsg)
{

	//	Publisher->UpdateServiceInfo(ControllerName, ControllerDescription);
	//	Publisher->start();
	//	Publisher->stop();
	CSESLog::WriteLine("COperationManager::StartController>>Start");
	localMsg->SetResult(SES_API_SUCCESS);
	//modify by chenwei
	int iReturn = SES_API_SUCCESS;
	LibSESData::CSESSystemSettingData sysSettingData;
	sysSettingData.LoadFromFile(CONFIG_FILE_DIR + SES_SYSTEM_SETTING);
	int iPort = sysSettingData.GetConnectionPort();
	int iDownloadCAPort = sysSettingData.GetDownloadCAPort();
	if ((iPort < 1025) || (iPort > 65535) || (1025 > iDownloadCAPort)
			|| (iDownloadCAPort > 65535))
	{
		localMsg->SetResult(SES_API_FAILURE);
		TeacherDaemonAPI->ReplyMsg(localMsg);
		return;
	}
	CSESLog::WriteLine(iPort, "COperationManager::StartController iPort");
	CSESLog::WriteLine(iDownloadCAPort,
			"COperationManager::StartController>> iDownloadCAPort");
	m_iPort = iPort;
	m_iDownloadCAPort = iDownloadCAPort;
	if (isStarted)
	{

		Publisher->stop();
		myRegMgr->StopAccept();
		CIntfData* netMsgbyebye = new CIntfData(BYE_BYE, 0, "0");
		myStudentManager->KickOffAllStudent(*netMsgbyebye);
		delete netMsgbyebye;
		myStudentManager->Close();
		do
		{
			if (!myStudentManager->Open())
			{
				myStudentManager->Close();
				iReturn = SES_API_FAILURE;
				break;
			}
			isStarted = false;
			int iAccerptReturn = myRegMgr->Accept(iPort, iDownloadCAPort);
			if (0 != iAccerptReturn)
			{
				if (ADDRESSINUSE == iAccerptReturn)
				{
					iReturn = SES_API_ACCERT_ADDRESSINUSE;
				}
				else
				{
					iReturn = SES_API_FAILURE;
				}
				myStudentManager->Close();
			}

			else
			{
				Publisher->UpdateServiceInfo(ControllerName,
						ControllerDescription, m_iPort, m_iDownloadCAPort);
				if (true != Publisher->start())
				{

					iReturn = SES_API_FAILURE;
					myRegMgr->StopAccept();
					myStudentManager->Close();

				}
				else
				{
					isStarted = true;
				}
			}
		} while (0);
	}
#ifdef _DEBUG
	cout << "TEACHER_STARTCONTROLLER\n";
#endif

	//bool bRet = true;

	else
	{
		do
		{
			if (!myStudentManager->Open())
			{
				myStudentManager->Close();
				iReturn = SES_API_FAILURE;
				break;
			}
			int iAccerptReturn = myRegMgr->Accept(iPort, iDownloadCAPort);
			if (0 != iAccerptReturn)
			{
				if (ADDRESSINUSE == iAccerptReturn)
				{
					iReturn = SES_API_ACCERT_ADDRESSINUSE;
				}
				else
				{
					iReturn = SES_API_FAILURE;
				}
				myStudentManager->Close();
			}
			else
			{
				Publisher->UpdateServiceInfo(ControllerName,
						ControllerDescription, m_iPort, m_iDownloadCAPort);
				if (true != Publisher->start())
				{
					//bRet = false;
					iReturn = SES_API_FAILURE;
					myRegMgr->StopAccept();
					myStudentManager->Close();

				}
				else
				{
					isStarted = true;
				}
			}
		} while (0);
	}
	localMsg->SetResult(iReturn);

	TeacherDaemonAPI->ReplyMsg(localMsg);
	//TeacherDaemonAPI->ReplyMsg(localMsg);


	CSESLog::WriteLine("COperationManager::StartController<<End");
	return;
}
void COperationManager::KickoffAllStudents()
{
	CIntfData* netMsg = new CIntfData(BYE_BYE, 0, "0");
	myStudentManager->KickOffAllStudent(*netMsg);
	delete netMsg;
	//	myStudentManager->RemoveHandleAll();
	//	myStudentManager->SendAll(*netMsg);
	//
	//	myStudentManager->Close();
	//	myStudentManager->Open();

}
/**************************************************************************************************
 * Function Name	: StopController
 * Description		: StopController
 * Date				: 08/09/09
 * Parameter			:
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::StopController(CIntfData* localMsg)
{
	CSESLog::WriteLine("COperationManager::StopController>>Start");
#ifdef _DEBUG
	cout << "stop controller" << endl;
#endif
	if (isStarted)
	{
		Publisher->stop();
		CIntfData* netMsg = new CIntfData(BYE_BYE, 0, "0");
		//	myStudentManager->RemoveHandleAll();
		//	myStudentManager->SendAll(*netMsg);
		myRegMgr->StopAccept();
		myStudentManager->KickOffAllStudent(*netMsg);

		delete netMsg;
		//send byebye to all connected student
		//	CIntfData cIntfData;
		//	myStudentManager->GetStudentList(cIntfData);
		//	std::list<StudentInfo_t> studentList;
		//	cIntfData.ParaXmlDoc.getStudentInfoList(studentList);
		//
		//	list<StudentInfo_t>::iterator ir;
		//	list<StudentInfo_t>::iterator para_begin = studentList.begin();
		//	list<StudentInfo_t>::iterator para_end = studentList.end();
		//
		//	CIntfData* netMsg = new CIntfData(BYE_BYE, 0, "0");
		//
		//	for (ir = para_begin; ir != para_end; ir++)
		//	{
		//		//netMsg->SetStudentID((ir->studentID));
		//		myStudentManager->RemoveHandleAll();
		//		myStudentManager->SendAll(*netMsg);
		//	}
		//	delete (netMsg);

		myStudentManager->Close();

		isStarted = false;

		localMsg->SetResult(SES_API_SUCCESS);
	}
	else
	{
		localMsg->SetResult(SES_API_FAILURE);
	}
	TeacherDaemonAPI->ReplyMsg(localMsg);
	CSESLog::WriteLine("COperationManager::StopController<<End");
	return;
}

/**************************************************************************************************
 * Function Name	: CancelOperation
 * Description		: CancelOperation
 * Date				: 08/09/09
 * Parameter			:
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::CancelOperation(CIntfData* localMsg)
{
	CSESLog::WriteLine("COperationManager::CancelOperation>>Start");

	CSESLog::WriteLine(CSESLogData::LOG_TEACHER_PROGRAMSEARCH,
			"COperationManager::CancelOperation >>Start");

	int iOID;
	localMsg->ParaXmlDoc.getInt("OID", iOID);
	int iReturn = SES_API_INVALID_ARGS;

#ifdef _DEBUG
	cout << "cancel operation,ID=" << iOID << endl;
#endif

	OP_List_lock->acquire();
	list<RequBase*>::iterator ir;
	list<RequBase*>::iterator list_begin = requestList.begin();
	list<RequBase*>::iterator list_end = requestList.end();

	for (ir = list_begin; ir != list_end; ir++)
	{

		if (iOID == (*ir)->GetOperationID())
		{
#ifdef _DEBUG
			cout << "find ID" << endl;
#endif
			(*ir)->CancelOperation(iOID);
			delete (*ir);
			requestList.erase(ir);
			iReturn = SES_API_SUCCESS;
			break;
		}
	}
	OP_List_lock->release();

	localMsg->SetResult(iReturn);
	localMsg->ParaXmlDoc.clear();
	localMsg->ParaXmlDoc.setInt("errCode", iReturn);
	CSESLog::WriteLine(CSESLogData::LOG_TEACHER_PROGRAMSEARCH,
			"COperationManager::CancelOperation--Send Msg to DBus >>Start");
	TeacherDaemonAPI->ReplyMsg(localMsg);
	CSESLog::WriteLine(CSESLogData::LOG_TEACHER_PROGRAMSEARCH,
			"COperationManager::CancelOperation--Send Msg to DBus >>End");

	CSESLog::WriteLine(CSESLogData::LOG_TEACHER_PROGRAMSEARCH,
			"COperationManager::CancelOperation >>End");
	CSESLog::WriteLine("COperationManager::CancelOperation<<End");
	return;
}

/**************************************************************************************************
 * Function Name	: work
 * Description		: work
 * Date				: 08/09/09
 * Parameter			:
 * Return Code		:
 * Author				:
 **************************************************************************************************/
int COperationManager::work()
{
	ProcessTimeOutRequest();
	//CSESLog::WriteLine("COperationManager::work>>Start");
	//polling IP;
	//reading local msg
	CIntfData* localMsg = new CIntfData();
	//add by chenwei
	int iReturn = 1;
	if (NULL == localMsg)
	{

		iReturn = 0;
		return iReturn;
	}
	//
	if (SES_API_SUCCESS != TeacherDaemonAPI->ReceiveMsg(*localMsg))
	{
		//		localMsg->SetMessage("asdfasdfasdf");
		//		myStudentManager->SendAll(*localMsg);
		delete (localMsg);
		iReturn = 0;
		return iReturn;
	}

	//dispatch request
	string type;
	localMsg->GetMessage(type);

	string tempMsg;
	localMsg->toString(tempMsg);
	CSESLog::WriteLine("------------------------");
	CSESLog::WriteLine(tempMsg);
	CSESLog::WriteLine("-------------------------");
	//cout << "got local MSG :" << tempMsg << endl;


	if (0 == type.compare(TEACHER_STARTCONTROLLER))
	{

		StartController(localMsg);

	}
	else if (0 == type.compare("Message_Set_Keystore_Passwd"))
	{//TODO : I believe this message is necessary - Stanley

	}
	else if (0 == type.compare(TEACHER_UPDATETEACHERINFO))
	{
		string temp;
		localMsg->ParaXmlDoc.getString("teacherInfoXML", temp);
		LibSESData::CTeacherInfoData* pTeacher =
				new LibSESData::CTeacherInfoData();
		if (0 == pTeacher->LoadFromString(temp))
		{
			ControllerName = pTeacher->GetTeacherName();
			ControllerDescription = pTeacher->GetCourse();
			Publisher->UpdateServiceInfo(ControllerName, ControllerDescription,
					m_iPort, m_iDownloadCAPort);
			localMsg->SetResult(SES_API_SUCCESS);
#ifdef _DEBUG
			cout << "teacher updated" << ControllerName << endl;
#endif
		}
		else
		{
			localMsg->SetResult(SES_API_FAILURE);
#ifdef _DEBUG
			cout << "teacher update failed" << endl;
#endif
		}
		TeacherDaemonAPI->ReplyMsg(localMsg);
		delete pTeacher;
		//disconnect all students
		//KickoffAllStudents();
	}
	else if (0 == type.compare(TEACHER_VERIFYCERTIFICATE))
	{
		string path;
		localMsg->ParaXmlDoc.getString("path", path);
		if (SES_API_SUCCESS == Verifycertificate(path))
		{
			localMsg->SetResult(SES_API_SUCCESS);
		}
		else
		{
			localMsg->SetResult(SES_API_FAILURE);
		}
		TeacherDaemonAPI->ReplyMsg(localMsg);
	}
	else if (0 == type.compare(TEACHER_VERIFYPASSWORD))
	{
		string path;
		localMsg->ParaXmlDoc.getString("path", path);
		string password;
		localMsg->ParaXmlDoc.getString("Password", password);
		localMsg->ParaXmlDoc.getString("path", path);
		if (SES_API_SUCCESS == VerifyPassword(password, path))
		{
			localMsg->SetResult(SES_API_SUCCESS);
		}
		else
		{
			localMsg->SetResult(SES_API_FAILURE);
		}
		TeacherDaemonAPI->ReplyMsg(localMsg);
	}
	else if (0 == type.compare(TEACHER_IMPORTCERTIFICATE))
	{
		string path;
		localMsg->ParaXmlDoc.getString("Path", path);
		int iResult = 0;
		if (isStarted)
		{
			iResult = ImportCertificate(path, NEWCAPATH);

		}
		else
		{
			iResult = ImportCertificate(path, SESPATH);
		}
		localMsg->SetResult(iResult);

		TeacherDaemonAPI->ReplyMsg(localMsg);
	}

	else if (!isStarted)
	{
#ifdef _DEBUG
		cout << "controller not started" << endl;
#endif
		localMsg->SetResult(SES_API_FAILURE);
		if (TeacherDaemonAPI->IsBlock())
		{
			TeacherDaemonAPI->ReplyMsg(localMsg);
		}
		else
		{
			//			TeacherDaemonAPI->SendMsg(localMsg);
		}
	}
	else if (0 == type.compare(TEACHER_STOPCONTROLLER))
	{
		StopController(localMsg);
	}
	else if (0 == type.compare(TEACHER_GETSTUDENTLIST))
	{

		myStudentManager->GetStudentList(*localMsg);
		localMsg->SetResult(SES_API_SUCCESS);
		TeacherDaemonAPI->ReplyMsg(localMsg);
	}

	else if (0 == type.compare(TEACHER_CANCELOPERATION))
	{
		CancelOperation(localMsg);
	}
	else if (0 == type.compare(TEACHER_KICKOFFSTUDENT))
	{
		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_KICKOFFSTUDENT,
				"COperationManager::Work TEACHER_KICKOFFSTUDENT Start");
		string SID;
		localMsg->GetStudentID(SID);
		CIntfData* netMsg = new CIntfData(BYE_BYE, 0, SID);
		myStudentManager->Send(*netMsg);
		delete (netMsg);

		myStudentManager->WillDelStudent(SID);
		localMsg->SetMessage(TEACHER_KICKOFFSTUDENTCALLBACK);
		localMsg->SetResult(SES_API_SUCCESS);
		TeacherDaemonAPI->SendMsg(localMsg);

		NotifyStudentStatusChanged(SID, SES_STU_DISCONNECT);
		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_KICKOFFSTUDENT,
				"COperationManager::Work TEACHER_KICKOFFSTUDENT End");
	}
	else if (0 == type.compare(TEACHER_KICKOFFSTUDENTLIST))
	{
		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_KICKOFFSTUDENT,
				"COperationManager::Work TEACHER_KICKOFFSTUDENTLIST Start");
		list<string> liststr;
		localMsg->ParaXmlDoc.getListPara(liststr);
		CIntfData bybCIntfData;
		bybCIntfData.SetMessage(BYE_BYE);
		myStudentManager->KickOffStudentList(bybCIntfData, liststr);
		//for chenw.
		//There is no "NotifyStudentStatusChanged(SID, SES_STU_DISCONNECT);" now
		list<string>::iterator itBegin;
		list<string>::iterator itEnd;
		//list<string>
		//list<string>::iterator itEnd;
		itBegin = liststr.begin();
		itEnd = liststr.end();
		for (; itBegin != itEnd; ++itBegin)
		{
			NotifyStudentStatusChanged(*itBegin, SES_STU_DISCONNECT);
		}
		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_KICKOFFSTUDENT,
				"COperationManager::Work TEACHER_KICKOFFSTUDENTLIST end");
	}
	else if (0 == type.compare(TEACHER_KICKOFFALLSTUDENT))
	{

		//for chenw.
		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_KICKOFFSTUDENT,
				"COperationManager::Work TEACHER_KICKOFFALLSTUDENT start");
		CIntfData bybCIntfData;
		std::vector<std::string> vectorID;
		myStudentManager->GetStudentIDVector(vectorID);
		bybCIntfData.SetMessage(BYE_BYE);
		myStudentManager->KickOffAllStudent(bybCIntfData);
		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_KICKOFFSTUDENT,
				"COperationManager::Work TEACHER_KICKOFFALLSTUDENT ed");
		int iVectorSize = vectorID.size();
		for (int i = 0; i < iVectorSize; i++)
		{
			NotifyStudentStatusChanged(vectorID[i], SES_STU_DISCONNECT);
		}
		//There is no "NotifyStudentStatusChanged(SID, SES_STU_DISCONNECT);" now
	}
	else if (0 == type.compare(TEACHER_CONTROLNEWSTUDENTCONNECT))
	{
		CSESLog::WriteLine(CSESLogData::LOG_STUDENT_CONNECTTEACHER,
				"COperationManager::Work TEACHER_CONTROLNEWSTUDENTCONNECT Get msg from DBus ");
		string SID;
		string allow;
		localMsg->GetStudentID(SID);

#ifdef _DEBUG
		cout << "tsd TEACHER_CONTROLNEWSTUDENTCONNECT " << SID << endl;
#endif

		if (localMsg->ParaXmlDoc.getString("allow", allow))
		{
			if (allow.compare(METHOD_TRUE) == 0)
			{
				//myRegMgr->ControlNewStudent(SID, true, *localMsg);
				if (true == myStudentManager->IsStudentExist(SID))
				{
					CSESLog::WriteLine(CSESLogData::LOG_STUDENT_CONNECTTEACHER,
							"COperationManager::Work Begin send allow to network");
					myStudentManager->ControlNewStudent(SID, true, *localMsg);
					CSESLog::WriteLine(CSESLogData::LOG_STUDENT_CONNECTTEACHER,
							"COperationManager::Work Begin send allow to network");

					this->RequirePolicySchedule(SID);
					this->SetStudentTime(SID);
					//not notify CONNECT status to teacher

					//NotifyStudentStatusChanged(SID, SES_STU_CONNECT);
				}
				else
				{
					NotifyStudentStatusChanged(SID, SES_STU_DISCONNECT);
				}
			}
			else
			{
				CSESLog::WriteLine(CSESLogData::LOG_STUDENT_CONNECTTEACHER,
						"COperationManager::Work Begin send no allow to network");
				//myRegMgr->ControlNewStudent(SID, false, *localMsg);
				myStudentManager->ControlNewStudent(SID, false, *localMsg);
				CSESLog::WriteLine(CSESLogData::LOG_STUDENT_CONNECTTEACHER,
						"COperationManager::Work Begin send no allow to network");
				NotifyStudentStatusChanged(SID, SES_STU_DISCONNECT);
			}
			//continue to send request
			RegMgrCallback();
		}

	}
	else if (0 == type.compare(TEACHER_GETSTUDENTSTATUS))
	{
		string SID;
		localMsg->GetStudentID(SID);
		StudentInfo_t stuInfo;
		list<StudentInfo_t> stuList;

		APIResult hr = SES_API_FAILURE;
		if (myStudentManager->GetStudentDetailedInfo(SID, stuInfo))
		{
			hr = SES_API_SUCCESS;
		}
		else
		{
			CTeacherPolicySettingData data;
			data.LoadFromFile(CONFIG_FILE_DIR + TEACHERPOLICYSETTING);
			TeacherLockPolicyUpdateInfo tlpInfo;
			if (data.GetInfo(SID, tlpInfo))
			{
				stuInfo.deployerName = tlpInfo.deployerName;
				stuInfo.lastUpdateTime = tlpInfo.UpdateTime;
				stuInfo.status = SES_STU_DISCONNECT;
				hr = SES_API_SUCCESS;
			}
		}
		localMsg->SetResult(hr);
		if (SES_API_SUCCESS == hr)
		{
			localMsg->ParaXmlDoc.clear();
			stuList.push_back(stuInfo);
			localMsg->ParaXmlDoc.setStudentInfoList(stuList);
		}
		TeacherDaemonAPI->ReplyMsg(localMsg);
	}
	else if (0 == type.compare(TEACHER_GETSTUDENTLOCKPOLICY))
	{
		string SID;
		localMsg->GetStudentID(SID);

		string lockPolicy("");

		if (myStudentManager->GetLockPolicy(SID, lockPolicy))
		{
			localMsg->SetResult(SES_API_SUCCESS);
			localMsg->ParaXmlDoc.clear();
			localMsg->ParaXmlDoc.setString("lockPolicy", lockPolicy);
		}
		else
		{
			localMsg->SetResult(SES_API_FAILURE);
		}
		TeacherDaemonAPI->ReplyMsg(localMsg);
	}
	//	else if(0 == type.compare(TEACHER_CANCELOPERATION))
	//	{
	//		int OID = 0;
	//		localMsg->ParaXmlDoc.getInt("OID",OID);
	//		localMsg->SetResult(SES_API_FAILURE);
	//		for(list<RequBase*>::iterator iter = requestList.begin(); iter != requestList.end() ; iter++)
	//		{
	//			RequBase * pRequest = *iter;
	//			if( (NULL != pRequest) && (OID == pRequest->GetOperationID()))
	//			{
	//				if(pRequest->CancelOperation(OID))
	//				{
	//					localMsg->SetResult(SES_API_SUCCESS);
	//				}
	//			}
	//		}
	//		TeacherDaemonAPI->ReplyMsg(localMsg);
	//	}

	else if (0 == type.compare(TEACHER_CHANGEPASSWORD))
	{
		string OldPassword, NewPassword;
		localMsg->ParaXmlDoc.getString("OldPassword", OldPassword);
		localMsg->ParaXmlDoc.getString("NewPassword", NewPassword);
		if (SES_API_SUCCESS == ChangePassword(OldPassword, NewPassword))
		{
			localMsg->SetResult(SES_API_SUCCESS);
		}
		else
		{
			localMsg->SetResult(SES_API_FAILURE);
		}
		TeacherDaemonAPI->ReplyMsg(localMsg);
	}
	else if (0 == type.compare(TEACHER_DEPLOYSCHEDULEPOLICYLIST))
	{
		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_DEPLOYSCHDULE,
				"COperationManager::work Get Msg from dbus!");

		std::list<std::string> studentList;
		localMsg->ParaXmlDoc.getListPara(studentList);
		std::string schedulePolicyXML;
		localMsg->ParaXmlDoc.getString("schedulePolicyXML", schedulePolicyXML);

		int iOID = 0;
		localMsg->GetOperationID(iOID);

		if ((0 != studentList.size()) && (true != schedulePolicyXML.empty()))
		{
			string teacherpolicyupdatedatapath = CONFIG_FILE_DIR
					+ TEACHERPOLICYSETTING;
			CTeacherPolicySettingData teacherpolicyupdatedata;
			teacherpolicyupdatedata.LoadFromFile(teacherpolicyupdatedatapath);

			CIntfData cIntfData;
			cIntfData.SetMessage(TEACHER_DEPLOYSCHEDULEPOLICY);
			cIntfData.ParaXmlDoc.setString("schedulePolicyXML",
					schedulePolicyXML);
			cIntfData.SetOperationID(iOID);
			list<std::string>::iterator ir;
			list<std::string>::iterator para_begin = studentList.begin();
			list<std::string>::iterator para_end = studentList.end();

			for (ir = para_begin; ir != para_end; ir++)
			{
				cIntfData.SetStudentID((*ir));
				myStudentManager->Send(cIntfData);

				teacherpolicyupdatedata.UpdateInfo(*ir, this->ControllerName);
			}

			teacherpolicyupdatedata.Save2File(teacherpolicyupdatedatapath);
		}

		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_DEPLOYSCHDULE,
				"COperationManager::work Deploy finished!");
	}

	//	else if (0 == type.compare(TEACHER_DEPLOYTABNAVPOLICYLIST))
	//	{
	//		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_DEPLOYTABNAV,
	//				"COperationManager::work Get Msg from dbus!");
	//
	//		std::list<std::string> studentList;
	//		localMsg->ParaXmlDoc.getListPara(studentList);
	//		std::string tabNavPolicyXML;
	//		//		localMsg->ParaXmlDoc.getString("tabNavPolicyXML", tabNavPolicyXML);
	//
	//		LibSESData::CTabNavigationData tabnavData;
	//		tabnavData.LoadFromFile(LibSESData::CONFIG_FILE_DIR
	//				+ LibSESData::TAB_NAVIGATION);
	//		tabnavData.Save2String(tabNavPolicyXML);
	//
	//		if ((0 != studentList.size()) && (true != tabNavPolicyXML.empty()))
	//		{
	//			string teacherpolicyupdatedatapath = CONFIG_FILE_DIR
	//					+ TEACHERPOLICYSETTING;
	//			CTeacherPolicySettingData teacherpolicyupdatedata;
	//			teacherpolicyupdatedata.LoadFromFile(teacherpolicyupdatedatapath);
	//
	//			CIntfData cIntfData;
	//			cIntfData.SetMessage(TEACHER_DEPLOYTABNAVPOLICY);
	//			cIntfData.ParaXmlDoc.setString("tabNavPolicyXML", tabNavPolicyXML);
	//			list<std::string>::iterator ir;
	//			list<std::string>::iterator para_begin = studentList.begin();
	//			list<std::string>::iterator para_end = studentList.end();
	//
	//			for (ir = para_begin; ir != para_end; ir++)
	//			{
	//				cIntfData.SetStudentID((*ir));
	//				myStudentManager->Send(cIntfData);
	//
	//				teacherpolicyupdatedata.UpdateInfo(*ir, this->ControllerName);
	//			}
	//
	//			teacherpolicyupdatedata.Save2File(teacherpolicyupdatedatapath);
	//		}
	//
	//		CSESLog::WriteLine(CSESLogData::LOG_TEACHER_DEPLOYTABNAV,
	//				"COperationManager::work Deploy finished!");
	//
	//	}

	else //call factory to build the process

	{
		RequBase* myRequest = myRequFactory->Create(type);
		myRequest->SetIPCTeacherDaemonAPI(TeacherDaemonAPI);
		if ((NULL != myRequest) && (true == myRequest->SendRequ(*localMsg)))
		{
			OP_List_lock->acquire();
			requestList.push_back(myRequest);
			OP_List_lock->release();
		}
		else
		{
			delete myRequest;
#ifdef _DEBUG
			cout << "invalide message recieved from DBUS" << endl;
#endif
		}

	}

	delete (localMsg);
	CSESLog::WriteLine("COperationManager::work<<End");
	return iReturn;
}

void COperationManager::ProcessTimeOutRequest()
{
	time_t nowtime;
	time(&nowtime);
	OP_List_lock->acquire();

	if (!requestList.empty())
	{
		list<RequBase*>::iterator list_begin = requestList.begin();

		long int iTimeOutPoint = (*list_begin)->GetTimeOutPoint();
		if (nowtime >= iTimeOutPoint)
		{
			(*list_begin)->CancelOperation((*list_begin)->GetOperationID());
			delete (*list_begin);
			requestList.erase(list_begin);
		}
	}
	OP_List_lock->release();
}

bool COperationManager::RequirePolicySchedule(std::string SID)
{
	CSESLog::WriteLine("COperationManager::RequirePolicySchedule >>Start");
	//TODO high del?
	CIntfData* netMsg = new CIntfData(TEACHER_REQUIRELOCKSCHEDULE, 0, SID);
	myStudentManager->Send(*netMsg);
	delete (netMsg);

	CSESLog::WriteLine("COperationManager::RequirePolicySchedule <<End");
	return true;
}

bool COperationManager::SavePolicySchedule(IPCAPI::CIntfData* localMsg)
{
	CSESLog::WriteLine("COperationManager::SavePolicySchedule >>Start");
	if (NULL != localMsg)
	{
		string strID;
		localMsg->GetStudentID(strID);
		string lockPolicy("");
		if (localMsg->ParaXmlDoc.getString("lockPolicy", lockPolicy))
		{
			//			CSESLog::WriteLine(
			//					"COperationManager::SavePolicySchedule --lockPolict = "
			//							+ lockPolicy);
			this->myStudentManager->UpdateLockPolicy(strID, lockPolicy);
		}
	}
	CSESLog::WriteLine("COperationManager::SavePolicySchedule <<End");
	return true;
}

bool COperationManager::UpdatePolicyInfo(IPCAPI::CIntfData* localMsg)
{
	CSESLog::WriteLine("COperationManager::UpdatePolicyInfo >>Start");
	if (NULL != localMsg)
	{
		string strContent;
		string studentID;
		localMsg->GetStudentID(studentID);
		localMsg->ParaXmlDoc.getString("PolicySettingData", strContent);
		LibSESData::CPolicySettingData data;
		data.LoadFromString(strContent);
		this->myStudentManager->UpdateLockPolicyData(studentID,
				data.GetTimeOriginal(), data.GetDeployerName());
	}
	CSESLog::WriteLine("COperationManager::UpdatePolicyInfo <<End");
	return true;
}

/**************************************************************************************************
 * Function Name	: RegMgrCallback
 * Description		:
 * Date				: 08/09/15
 * Parameter			: CIntfData& netMsg
 * Return Code		:
 * Author				:
 **************************************************************************************************/
//void COperationManager::RegMgrCallback(CIntfData& netMsg)
//{
//
//	CSESLog::WriteLine("COperationManager::RegMgrCallback>>Start");
//	string temp;
//	bool bNew = false;
//	netMsg.GetMessage(temp);
//	list<StudentInfo_t> stuInfoList;
//	string SID;
//	netMsg.GetStudentID(SID);
//	if (0 == temp.compare(TEACHER_CONTROLNEWSTUDENTCONNECTCALLBACK))
//	{
//		if ((netMsg.ParaXmlDoc.getStudentInfoList(stuInfoList))
//				&& (!stuInfoList.empty()))
//		{
//			int iTime;
//			time((time_t*) &iTime);
//			stuInfoList.front().start_time = iTime;
//
//			//send student connection callback
//			netMsg.ParaXmlDoc.clear();
//			netMsg.ParaXmlDoc.setStudentInfoList(stuInfoList);
//			netMsg.SetResult(SES_API_SUCCESS);
//			TeacherDaemonAPI->SendMsg(&netMsg);
//
//			//modify by chenwei
//
//
//			bNew = true;
//			cout << "allow connection" << endl;
//		}
//	}
//	myRegMgr->UpdateStudent(SID, stuInfoList.front(), bNew);
//	CSESLog::WriteLine("COperationManager::RegMgrCallback<<End");
//	return;
//}
#ifdef AUTO_CONNECT_DISCONNECT
int i = 0;
#endif
void COperationManager::RegMgrCallback()
{
	CSESLog::WriteLine("COperationManager::RegMgrCallback>>Start");
	StudentInfo_t stStudentInfo;
	bool hasNotify =
			myStudentManager->GetStudentforNotifyTeacher(stStudentInfo);
	if (hasNotify == true)
	{
		//		list<StudentInfo_t> stuInfoList;
		//		stuInfoList.push_back(stStudentInfo);
		//		CIntfData netMsg;
		//		//netMsg.SetOperationID(TeacherDaemonAPI->GetOPID());
		//		netMsg.SetMessage(TEACHER_CONTROLNEWSTUDENTCONNECTCALLBACK);
		//		netMsg.ParaXmlDoc.setStudentInfoList(stuInfoList);
		//		netMsg.SetResult(SES_API_SUCCESS);
		//		CSESLog::WriteLine(CSESLogData::LOG_STUDENT_CONNECTTEACHER,
		//				"COperationManager::RegMgrCallback TeacherDaemonAPI->SendMsg start");
		//		TeacherDaemonAPI->SendMsg(&netMsg);

		TeacherDaemonAPI->NewStudentCallBack(stStudentInfo);

		CSESLog::WriteLine(CSESLogData::LOG_STUDENT_CONNECTTEACHER,
				"COperationManager::RegMgrCallback TeacherDaemonAPI->SendMsg end");
#ifdef AUTO_CONNECT_DISCONNECT
		CSESLog::WriteLine(i++, "COperationManager::RegMgrCallback :::::::::");
#endif
	}
	CSESLog::WriteLine("COperationManager::RegMgrCallback<<End");
}
/**************************************************************************************************
 * Function Name	: NotifyStudentStatusChanged
 * Description		: NotifyStudentStatusChanged
 * Date				: 08/09/09
 * Parameter			: const string& SID,int iStatus
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::NotifyStudentStatusChanged(const string& SID,
		int iStatus)
{//TODO str wrong handle
	CSESLog::WriteLine("COperationManager::NotifyStudentStatusChanged>>Start");
	//	CIntfData* noticeMsg =
	//			new CIntfData(TEACHER_NOTIFYSTUDENTSTATUSCHANGED, 0, SID);
	CSESLog::WriteLine(CSESLogData::LOG_DEFAULT,
			"COperationManager::NotifyStudentStatusChanged start");
	//	CIntfData noticeMsg;
	//	noticeMsg.SetMessage("TEACHER_NOTIFYSTUDENTSTATUSCHANGED");
	//	noticeMsg.SetStudentID(SID);
	//	noticeMsg.ParaXmlDoc.setInt("iStatus", iStatus);
	//	TeacherDaemonAPI->SendMsg(&noticeMsg);
	TeacherDaemonAPI->NotifyStudentStatusChanged(SID, iStatus);
	CSESLog::WriteLine(CSESLogData::LOG_DEFAULT,
			"COperationManager::NotifyStudentStatusChanged finish send msg to dbus");
	//delete (noticeMsg);

	CSESLog::WriteLine("COperationManager::NotifyStudentStatusChanged<<End");
	return;
}

/**************************************************************************************************
 * Function Name	: StuMgrCallback
 * Description		:
 * Date				: 08/09/15
 * Parameter			: CIntfData& netMsg
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::StuMgrCallback(CIntfData& netMsg)
{
	CSESLog::WriteLine("COperationManager::StuMgrCallback>>Start");
	string type;
	netMsg.GetMessage(type);

#ifdef _DEBUG
	cout << "network callback:COperationManager::StuMgrCallback:type:" << type
	<< endl;
#endif
	string studentID;
	netMsg.GetStudentID(studentID);
	string log = "COperationManager::StuMgrCallback message:";
	log.append(type);
	log.append(" networkStuId:");
	log.append(studentID);
	CSESLog::WriteLine(log);
	if (0 == type.compare(BYE_BYE))
	{
		string SID;
		netMsg.GetStudentID(SID);
		StuMgrDisconnectCallback(SID);
		//NotifyStudentStatusChanged(SID, SES_STU_DISCONNECT);
		//myStudentManager->DelStudent(SID);
	}
	if (0 == type.compare(STUDENT_SAVESTUDENTINFO))
	{
		string strXML("");
		netMsg.ParaXmlDoc.getString("strXML", strXML);
		string SID;
		netMsg.GetStudentID(SID);
		StuMgrChangeStdInfoCallback(SID, strXML);
	}
	else if (0 == type.compare(STUDENT_HEARTBEAT))
	{
		//add by chenwei
		HandleSTUDENT_HEARTBEAT(netMsg);

		//add end

	}
	else if (0 == type.compare(TEACHER_REQUIRELOCKSCHEDULECALLBACK))
	{
		SavePolicySchedule(&netMsg);
	}
	else if (0 == type.compare(STUDENT_POLICYUPDATE))
	{
		UpdatePolicyInfo(&netMsg);
	}
	//	else if (0 == type.compare(TEACHER_ROOTCA))
	//	{
	//		//add by chenwei
	//		string buff;
	//		ifstream finRootCaFile;
	//		finRootCaFile.open(CAROOT, ios::binary);
	//
	//		if (finRootCaFile.good())
	//		{
	//			char ch;
	//			//			char acha[1024] ="";
	//			//			char* pch=acha;
	//			while (finRootCaFile.get(ch))
	//			{
	//				//pch=&ch;
	//				buff.append(1, ch);
	//			}
	//			cout << endl << endl << buff << endl;
	//			netMsg.ParaXmlDoc.setString(TEACHER_ROOTCA, buff);
	//			myStudentManager->Send(netMsg);
	//			finRootCaFile.close();
	//		}

	//add end

	//}

	else
	{
		if (0 == type.compare(STUDENT_HEARTBEAT))
		{
			CSESLog::WriteLine("COperationManager::STUDENT_HEARTBEAT");
		}
		HandleByRequestList(netMsg);
	}

	CSESLog::WriteLine("COperationManager::StuMgrCallback<<End");

	return;
}

/**************************************************************************************************
 * Function Name	: HandleByRequestList
 * Description		:
 * Date				: 08/09/09
 * Parameter			: CIntfData& netMsg
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::HandleByRequestList(CIntfData& netMsg)
{
	CSESLog::WriteLine("COperationManager::HandleByRequestList>>Start");
	int iReplyID;
	netMsg.GetOperationID(iReplyID);

#ifdef _DEBUG
	cout << "reply ID =" << iReplyID << endl;
#endif

	//handle request list when receiving message
	OP_List_lock->acquire();
	list<RequBase*>::iterator ir;
	list<RequBase*>::iterator list_begin = requestList.begin();
	list<RequBase*>::iterator list_end = requestList.end();

	for (ir = list_begin; ir != list_end; ir++)
	{

		if (iReplyID == (*ir)->GetOperationID())
		{
			bool bFinished = (*ir)->RecvResp(netMsg);

			/*			bool needLog = true;
			 CSESLogData::FunctionTag Tag;
			 {
			 string strOPName;
			 netMsg.GetMessage(strOPName);
			 if (strOPName.compare(TEACHER_SEARCHPROGRAMCALLBACK) == 0)
			 {
			 Tag = CSESLogData::LOG_TEACHER_PROGRAMSEARCH;
			 }
			 else
			 {
			 needLog = false;
			 }

			 if (needLog)
			 {
			 CSESLog::WriteLine(Tag,
			 "IPCTeacherDaemonAPI::SendMsg --Send Msg to Dbus >>Start!");
			 }
			 }
			 */
			TeacherDaemonAPI->SendMsg(&netMsg);
			/*
			 if (needLog)
			 {
			 CSESLog::WriteLine(Tag,
			 "IPCTeacherDaemonAPI::SendMsg --Send Msg to Dbus >>End!");
			 }

			 */
			if (true == bFinished)
			{
				delete (*ir);
				requestList.erase(ir);
			}
			break;
		}
	}
	OP_List_lock->release();
	CSESLog::WriteLine("COperationManager::HandleByRequestList<<End");
	return;
}

/**************************************************************************************************
 * Function Name	: StuMgrDisconnectCallback
 * Description		:
 * Date				: 08/09/15
 * Parameter			: std::string & studentID
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::StuMgrDisconnectCallback(std::string & studentID)
{
	CSESLog::WriteLine("COperationManager::StuMgrDisconnectCallback>>Start");

	//remove request list when student disconnect.
	OP_List_lock->acquire();
	list<RequBase*>::iterator ir;
	list<RequBase*>::iterator list_begin = requestList.begin();
	list<RequBase*>::iterator list_end = requestList.end();

	CSESLog::WriteLine("COperationManager::StuMgrDisconnectCallback>>Start for");
	for (ir = list_begin; ir != list_end; ir++)
	{

		if (true == (*ir)->isSameStudent(studentID))
		{
			CSESLog::WriteLine("isSameStudent");
			bool bFinished = (*ir)->Disconnect(studentID);

#ifdef _DEBUG
			string temp;
			netMsg.toString(temp);
			cout << "find ID ,message: "<<temp << endl;
#endif

			if (true == bFinished)
			{
				delete (*ir);
				requestList.erase(ir);
				CSESLog::WriteLine("erase");
				//maybe list is changed by erase operation. reassign parameter.
				list_begin = requestList.begin();
				list_end = requestList.end();
				ir = list_begin;
				ir--;
			}
		}
	}
	CSESLog::WriteLine("COperationManager::StuMgrDisconnectCallback>>End for");
	OP_List_lock->release();

	NotifyStudentStatusChanged(studentID, SES_STU_DISCONNECT);
	myStudentManager->WillDelStudent(studentID);

	//continue to find new request if student timeout
	RegMgrCallback();
	CSESLog::WriteLine("COperationManager::StuMgrDisconnectCallback<<End");
	return;

}

/**************************************************************************************************
 * Function Name	: StuMgrChangeStdInfoCallback
 * Description		:
 * Date				: 08/09/15
 * Parameter			: std::string & studentID
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::StuMgrChangeStdInfoCallback(std::string & studentID,
		std::string & strXML)
{
	CSESLog::WriteLine("COperationManager::StuMgrChangeStdInfoCallback>>Start");

	LibSESData::CStudentInfoData cStudentInfo;
	if (cStudentInfo.LoadFromString(strXML) != (-1))
	{
		//		CIntfData data;
		//		data.SetMessage(TEACHER_NOTIFYSTUDENTINFOCHANGED);
		string NewStudentID = cStudentInfo.GetStudentID();
		//
		//		data.ParaXmlDoc.setString("OldStudentID", studentID);
		//		data.ParaXmlDoc.setString("NewStudentID", NewStudentID);
		//		data.ParaXmlDoc.setString("NewStudentName",
		//				cStudentInfo.GetStudentName());
		bool bNeedDelete = true;
		if (!this->myStudentManager->IsStudentExist(NewStudentID))
		{
			//			data.ParaXmlDoc.setString("bNeedDelete", METHOD_FALSE);
			//			this->StuMgrDisconnectCallback(studentID);
			bNeedDelete = false;
		}
		//		else
		//		{
		//			data.ParaXmlDoc.setString("bNeedDelete", METHOD_TRUE);
		//			//			this->myStudentManager->DelStudent(studentID);
		//		}
		//		NotifyStudentStatusChanged(studentID, SES_STU_DISCONNECT);
		//		this->TeacherDaemonAPI->SendMsg(&data);
		this->TeacherDaemonAPI->NotifyStudentInfoChanged(studentID,
				NewStudentID, cStudentInfo.GetStudentName(), bNeedDelete);
	}

	CSESLog::WriteLine("COperationManager::StuMgrChangeStdInfoCallback<<End");
	return;

}

/**************************************************************************************************
 * Function Name	: CheckOperationTimeOut
 * Description		: CheckOperationTimeOut
 * Date				: 08/09/09
 * Parameter			:
 * Return Code		: bool
 * Author				:
 **************************************************************************************************/
bool COperationManager::CheckOperationTimeOut()
{
	return false;
}

/**************************************************************************************************
 * Function Name	: StuMgrDisconnectCallback
 * Description		:
 * Date				: 08/09/15
 * Parameter			: CIntfData& netMsg
 * Return Code		:
 * Author				:
 **************************************************************************************************/
void COperationManager::HandleSTUDENT_HEARTBEAT(CIntfData& netMsg)
{
	CSESLog::WriteLine("COperationManager::HandleSTUDENT_HEARTBEAT>>Start");
	CSESLog::WriteLine(CSESLogData::LOG_TEACHER_DEPLOYSCHDULE,
			"COperationManager::LOG_TEACHER_DEPLOYSCHDULE got Network msg start");
	std::string studentID;
	int iStatus;
	int bLocked;

	netMsg.GetStudentID(studentID);

	StudentInfo_t existStudentInfo_t;

	myStudentManager->GetStudentDetailedInfo(studentID, existStudentInfo_t);
	//TODO HandleSTUDENT_HEARTBEAT
	if (netMsg.ParaXmlDoc.getInt("iStatus", iStatus)
			&& netMsg.ParaXmlDoc.getInt("bLocked", bLocked))
	{
		myStudentManager->UpdateStudentStatus(studentID, bLocked, iStatus);
		//		cout << "heart beat:" << studentID << "lock:" << bLocked << "status:"
		//				<< iStatus << endl;
		NotifyStudentStatusChanged(studentID, iStatus);
		this->RequirePolicySchedule(studentID);
	}
	else
	{
		CSESLog::WriteLine("COperationManager::HandleSTUDENTHEARTBEAT invalid");
	}
	CSESLog::WriteLine(CSESLogData::LOG_TEACHER_DEPLOYSCHDULE,
			"COperationManager::LOG_TEACHER_DEPLOYSCHDULE got Network msg start");
	CSESLog::WriteLine("COperationManager::HandleSTUDENT_HEARTBEAT<<End");
	return;
}

bool COperationManager::SetStudentTime(string SID)
{
	CSESLog::WriteLine("COperationManager::SetStudentTime >>Start");

	time_t t;
	time(&t);
	CSESLog::WriteLine("COperationManager::SetStudentTime --Time:"
			+ IPCCommonUtil::ParseInt2String(t));
	std::string str = "";
	{
		stringstream strStream("");
		strStream << t;

		if (strStream.good())
		{
			str.append(strStream.str());
		}
		else
		{
			CSESLog::WriteLine(
					"COperationManager::SetStudentTime --stringstream error!",
					CSESLog::ERROR);
			return false;

		}
	}
	CSESLog::WriteLine("COperationManager::SetStudentTime --String :" + str);

	CIntfData* netMsg = new CIntfData(TEACHER_SETSTUDENTTIME, 0, SID);
	netMsg->ParaXmlDoc.setString("Time", str);
	myStudentManager->Send(*netMsg);
	delete (netMsg);

	CSESLog::WriteLine("COperationManager::SetStudentTime <<End");
	return true;
}

/**************************************************************************************************
 * Function Name	: Verifycertificate
 * Description		:
 * Date				: 08/09/15
 * Parameter		:
 * Return Code		: 1:success;0 :failuer
 * Author			: chenwei
 **************************************************************************************************/

int COperationManager::Verifycertificate(const string& path)
{//
	CSESLog::WriteLine("COperationManager::Verifycertificate>> Start");
	int iReturn = SES_API_SUCCESS;
	string serverCert;
	string serverKey;
	string cacert;
	if (path.size() > 0)
	{
		//#define CACERT "/cacert.pem"
		//#define SERVERKEY "/sslserverkey.pem"
		//#define SERVERCERT "/sslservercert.pem"
		serverCert.append(path);
		serverCert.append(SERVERCERT);
		serverKey.append(path);
		serverKey.append(SERVERKEY);
		cacert.append(path);
		cacert.append(CACERT);

	}
	else
	{
		serverCert.append(CERTIFICATE);
		serverKey.append(PRIVATE_KEY);
		cacert.append(CAROOT);
	}
	char* p_cCacert = NULL;
	char* p_cServercert = NULL;
	do
	{
		//		if (m_pContext->certificate(serverCert.c_str(), SSL_FILETYPE_PEM) < 0)
		//		{
		//			CSESLog::WriteLine("Verifycertificate", CSESLog::ERROR);
		//			CSESLog::WriteLine(ACE_OS_String::strerror(errno), CSESLog::WARNING);
		//			iReturn = SES_API_FAILURE;
		//			break;
		//		}
		X509 *x = NULL;
		BIO *b = NULL;

		b = BIO_new_file(serverCert.c_str(), "r");
		if (NULL == b)
		{
			iReturn = SES_API_FAILURE;

			break;
		}
		x = PEM_read_bio_X509(b, NULL, NULL, NULL);
		if (NULL == x)
		{
			iReturn = SES_API_FAILURE;
			BIO_free(b);

			break;
		}
		//	int iReturn = 1;
		//	X509 * server_cert;
		char * str;
		string strSubj;
		str = X509_NAME_oneline(X509_get_subject_name(x), 0, 0);
		if (str != NULL)
		{
			CSESLog::WriteLine(str);
			strSubj.append(str);
			if (strSubj.find(SESSUBJ) < 0)
			{
				iReturn = SES_API_FAILURE;
				BIO_free(b);
				X509_free(x);
				OPENSSL_free(str);
				break;
			}

			OPENSSL_free(str);
		}

		str = X509_NAME_oneline(X509_get_issuer_name(x), 0, 0);
		if (str != NULL)
		{
			//printf(" issuer: [%s]\n", str);
			CSESLog::WriteLine(str);
			strSubj.clear();
			strSubj.append(str);
			if (strSubj.find(SESSUBJ) < 0)
			{
				iReturn = SES_API_FAILURE;

				OPENSSL_free(str);
				break;
			}
			OPENSSL_free(str);
		}
		BIO_free(b);
		X509_free(x);
		///////////////
		X509 *x1 = NULL;
		BIO *b1 = NULL;

		b1 = BIO_new_file(cacert.c_str(), "r");
		x1 = PEM_read_bio_X509(b1, NULL, NULL, NULL);
		if (NULL == b1)
		{
			iReturn = SES_API_FAILURE;
			break;
		}
		if (NULL == x1)
		{
			BIO_free(b1);

			iReturn = SES_API_FAILURE;
			break;
		}
		//	int iReturn = 1;
		//	X509 * server_cert;
		char * str1;
		string strSubj1;
		str1 = X509_NAME_oneline(X509_get_subject_name(x1), 0, 0);
		if (str1 != NULL)
		{
			printf(" subject: [%s]\n", str1);
			strSubj1.append(str1);
			if (strSubj1.find(SESSUBJ) < 0)
			{
				iReturn = SES_API_FAILURE;
				BIO_free(b1);
				X509_free(x1);
				OPENSSL_free(str1);

				break;
			}

			OPENSSL_free(str1);
		}

		str1 = X509_NAME_oneline(X509_get_issuer_name(x1), 0, 0);
		if (str1 != NULL)
		{
			printf(" issuer: [%s]\n", str1);
			strSubj.clear();
			strSubj.append(str1);
			if (strSubj.find(SESSUBJ) < 0)
			{
				iReturn = SES_API_FAILURE;
				BIO_free(b1);
				X509_free(x1);
				OPENSSL_free(str1);
				break;
			}
			OPENSSL_free(str1);
		}
		BIO_free(b1);
		X509_free(x1);
		/////////////////
		ifstream ifKey;
		ifKey.open(serverKey.c_str());
		if (ifKey.fail())
		{
			CSESLog::WriteLine("PRIVATE_KEY doesn't exit", CSESLog::ERROR);
			iReturn = SES_API_FAILURE;
			break;
		}
		ifKey.close();
		const int iacArg1 = 4;

		try
		{
			p_cCacert = new char[cacert.size() + 1];
			p_cServercert = new char[serverCert.size() + 1];
		} catch (...)
		{
			break;
		}
		memset(p_cCacert, 0, cacert.size() + 1);
		memset(p_cServercert, 0, serverCert.size() + 1);
		memcpy(p_cCacert, cacert.c_str(), cacert.size());
		memcpy(p_cServercert, serverCert.c_str(), serverCert.size());
		char arrVerify[7] =
		{ 'v', 'e', 'r', 'i', 'f', 'y', '\0' };
		char CAfile[8] =
		{ '-', 'C', 'A', 'f', 'i', 'l', 'e', '\0' };

		char* acArg1[iacArg1] =
		{ arrVerify, CAfile, p_cCacert, p_cServercert };

		if (0 == Verify(iacArg1, acArg1))
		{
			iReturn = SES_API_FAILURE;

		}
		//Verify(iacArg1,acArg1);
		delete p_cCacert;
		delete p_cServercert;
	} while (0);

	CSESLog::WriteLine(iReturn, "COperationManager::Verifycertificate<< End:");
	return iReturn;
}

/**************************************************************************************************
 * Function Name	: Verifycertificate
 * Description		:
 * Date				: 08/09/15
 * Parameter		:
 * Return Code		: 1:success;0 :failuer
 * Author			: chenwei
 **************************************************************************************************/
int COperationManager::VerifyPassword(const std::string& Password,
		const std::string& path)
{
	//ACE_SSL_Context *pContext =new ACE_SSL_Context();
	CSESLog::WriteLine("COperationManager::VerifyPassword>> Start");

	int iReturn = SES_API_SUCCESS;
	string serverCert;
	string serverKey;
	if (path.size() > 0)
	{
		serverCert.append(path);
		serverCert.append(SERVERCERT);
		serverKey.append(path);
		serverKey.append(SERVERKEY);
	}
	else
	{
		serverCert.append(CERTIFICATE);
		serverKey.append(PRIVATE_KEY);
	}

	ifstream fin(serverKey.c_str(), ios::binary);
	if (!fin.good())
	{
		CSESLog::WriteLine("COperationManager::VerifyPassword>> fin ERR");
		iReturn = SES_API_FAILURE;
	}

	fin.close();

	CSESLog::WriteLine(Password);
	SSL_METHOD *meth;
	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();
	meth = SSLv3_server_method();
	SSL_CTX *ctx = SSL_CTX_new(meth);

	SSL_CTX_set_default_passwd_cb_userdata(ctx, (void*) Password.c_str());
	//	pContext->context()->default_passwd_callback_userdata
	//			= (void*) Password.c_str();
	//SSL_CTX_set_default_passwd_cb(pContext->context(),(pem_password_cb*) Password.c_str());
	do
	{
		//		if (ctx->certificate(serverCert.c_str(), SSL_FILETYPE_PEM) < 0)
		//		{
		//			CSESLog::WriteLine("Verifycertificate", CSESLog::ERROR);
		//			CSESLog::WriteLine(ACE_OS_String::strerror(errno), CSESLog::WARNING);
		//			iReturn = SES_API_FAILURE;
		//			break;
		//		}
		//		if (pContext->private_key(serverKey.c_str(), SSL_FILETYPE_PEM) < 0)
		//		{
		//			CSESLog::WriteLine("context->private_key", CSESLog::ERROR);
		//			CSESLog::WriteLine(ACE_OS_String::strerror(errno), CSESLog::WARNING);
		//			iReturn = SES_API_FAILURE;
		//			break;
		//		}
		//		if (0 != pContext->verify_private_key())
		//		{
		//			CSESLog::WriteLine(pContext->verify_private_key(),
		//					"COperationManager::verify_private_key>>Err:",
		//					CSESLog::ERROR);
		//			CSESLog::WriteLine(errno, ACE_OS_String::strerror(errno));
		//			iReturn = SES_API_FAILURE;
		//		}
		if (SSL_CTX_use_certificate_file(ctx, serverCert.c_str(),
				X509_FILETYPE_PEM) < 1)
		{
			iReturn = SES_API_FAILURE;
			break;
		}
		if (SSL_CTX_use_PrivateKey_file(ctx, serverKey.c_str(),
				X509_FILETYPE_PEM) < 1)
		{
			iReturn = SES_API_FAILURE;
			break;
		}

	} while (0);
	//pContext->context()->default_passwd_callback_userdata = NULL;
	SSL_CTX_free(ctx);
	//	SSL_CTX_set_default_passwd_cb_userdata(context->context(),
	//				(void*) NULL);
	if (SES_API_SUCCESS == iReturn)
	{
		myRegMgr->setPassword(Password);
	}
	//SSL_CTX_set_default_passwd_cb_userdata(pContext->context(), NULL);
	//SSL_CTX_set_default_passwd_cb(pContext->context(), NULL);
	// pContext->~ACE_SSL_Context();;

	CSESLog::WriteLine(iReturn, "COperationManager::VerifyPassword end");
	return iReturn;
}
int COperationManager::ChangePassword(const std::string& OldPassword,
		const std::string& NewPassword)
{
	CSESLog::WriteLine("OldPasswordstart:");
	CSESLog::WriteLine(OldPassword);
	CSESLog::WriteLine("NewPasswordstart:");
	CSESLog::WriteLine(NewPassword);
	CSESLog::WriteLine("NewPasswordend:");
	int iReturn = SES_API_SUCCESS;

	do
	{

		if (SES_API_SUCCESS != VerifyPassword(OldPassword, ""))
		{

			iReturn = SES_API_FAILURE;
			break;
		}

		const int iacArg1 = 10;
		// q&a the max size
		char acPass[70];
		string passpassword("pass:");
		passpassword.append(OldPassword);
		strcpy(acPass, passpassword.c_str());
		//rsa -in privatekey.key -out
		//verify password
		char acPassNew[71];
		string passpasswordNew("pass:");
		passpasswordNew.append(NewPassword);
		strcpy(acPassNew, passpasswordNew.c_str());
		char rsa[] =
		{ 'r', 's', 'a', '\0' };
		char passin[] =
		{ '-', 'p', 'a', 's', 's', 'i', 'n', '\0' };
		char des3[] =
		{ '-', 'd', 'e', 's', '\0' };
		char in[] =
		{ '-', 'i', 'n', '\0' };
		char passout[] =
		{ '-', 'p', 'a', 's', 's', 'o', 'u', 't', '\0' };
		char out[] =
		{ '-', 'o', 'u', 't', '\0' };

		char* acArg1[iacArg1] =
		{ rsa, des3, passin, acPass, in, (char*) PRIVATE_KEY, passout,
				acPassNew, out, (char*) PRIVATE_KEY };
		char** ppcArg1;
		ppcArg1 = acArg1;
		Rsa(iacArg1, ppcArg1);
	} while (0);
	//	pContext->context()->default_passwd_callback_userdata = NULL;
	//	SSL_CTX_set_default_passwd_cb_userdata(pContext->context(),
	//					NULL);

	return iReturn;
}

int COperationManager::ImportCertificate(const std::string& fromPath,
		const std::string& newPath)
{
	CSESLog::WriteLine("CAToolUtil::ImportRootCA()>>Start");
	int iReturn = SES_API_SUCCESS;
	string pathSES;

	string outCA;
	string outPrivate_key;
	string outServercert;

	string rootCA(fromPath);
	rootCA.append(CACERT);
	string serverKey(fromPath);
	serverKey.append(SERVERKEY);
	string servercert(fromPath);
	servercert.append(SERVERCERT);

	outCA.append(newPath);
	outPrivate_key.append(newPath);
	outServercert.append(newPath);

	outCA.append(CACERT);
	outPrivate_key.append(SERVERKEY);
	outServercert.append(SERVERCERT);

	if (access(newPath.c_str(), R_OK ) != 0)
	{
		mkdir(newPath.c_str(), S_IRWXU);
	}

	do
	{
		//import rootca


		ifstream fin(rootCA.c_str(), ios::binary);
		if (!fin.good())
		{
			iReturn = SES_API_FAILURE;
			break;
		}

		char ch;
		string foutMsg;
		while (fin.get(ch))
		{
			foutMsg.append(1, ch);
		}
		fin.close();

		fstream fout;
		fout.open(outCA.c_str(), ios::trunc | ios::out | ios::binary | ios::in);
		if (!fout.good())
		{
			iReturn = SES_API_FAILURE;

			break;
		}

		fout << foutMsg;
		fout.close();

		//import serverkey


		fin.open(serverKey.c_str(), ios::binary);

		if (!fin.good())
		{
			iReturn = SES_API_FAILURE;
			break;
		}
		foutMsg.clear();
		while (fin.get(ch))
		{
			foutMsg.append(1, ch);
		}
		//filerootKey.append(SES);
		fin.close();
		fout.open(outPrivate_key.c_str(), ios::trunc | ios::out | ios::binary
				| ios::in);
		if (!fout.good())
		{
			iReturn = SES_API_FAILURE;

			break;
		}

		fout << foutMsg;

		fout.close();

		//import server cert


		fin.open(servercert.c_str(), ios::binary);

		if (!fin.good())
		{
			iReturn = SES_API_FAILURE;
			break;
		}

		foutMsg.clear();
		while (fin.get(ch))
		{
			foutMsg.append(1, ch);
		}
		fin.close();
		/////////////////

		//////////
		//filerootKey.append(SES);

		fout.open(outServercert.c_str(), ios::trunc | ios::out | ios::binary
				| ios::in);
		if (!fout.good())
		{
			iReturn = SES_API_FAILURE;

			break;
		}
		fout << foutMsg;
		fout.close();


	} while (0);
	CSESLog::WriteLine("CAToolUtil::ImportRootCA()<<End");
	return iReturn;

}
