www.pudn.com > lucent_softphone.rar > DirectoryNumber.cpp


// DirectoryNumber.cpp : Implementation of CDirectoryNumber 
#include "stdafx.h" 
#include "LucentCti.h" 
#include "MichelleCTI.h" 
#include "DirectoryNumber.h" 
 
///////////////////////////////////////////////////////////////////////////// 
// CDirectoryNumber 
 
extern BOOL B2C(BSTR bStr,char* pBuf,int nBufLen); 
extern BSTR C2B(const char *c); 
extern void WriteLog(char* pData); 
 
#define PROCESS (strcmp((char*)&m_deviceId,m_thisDevice.deviceID)==0) 
 
BOOL CALLBACK DialingDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
	if(uMsg==WM_COMMAND) { 
		if(LOWORD(wParam)==IDCANCEL) { 
			while(!::PostMessage(NULL, UM_CANCELDIAL, (WPARAM)0, (LPARAM)0)) 
				Sleep(100); 
		} 
		return(TRUE); 
	} 
	return(FALSE); 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::MakeCall(BSTR dn, LPKVLIST data) 
{ 
	// TODO: Add your implementation code here 
	 
	BOOL bRet=FALSE; 
	DeviceID_t callId; 
	WriteLog("Make call service."); 
	if (B2C(dn,(char*)&callId,sizeof(DeviceID_t))) 
	{ 
		RetCode_t ret=-1; 
 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
		if (data ) 
		{ 
			ATTPrivateData_t privateData; 
			memset(&privateData,0,sizeof(ATTPrivateData_t)); 
			ATTUserToUserInfo_t attData; 
			memset(&attData,0,sizeof(ATTUserToUserInfo_t )); 
			attData.type=UUI_IA5_ASCII; 
			 
			if (KVListToAppString(data,(char*)attData.data.value,sizeof(attData.data.value)-1)) 
			{ 
				attData.data.length=strlen((char*)attData.data.value); 
				ret=attV6MakeCall(&privateData,NULL,FALSE,&attData); 
				if (ret==0) 
					ret=cstaMakeCall(m_serverHandle,m_invokeId,&m_deviceId,&callId,(PrivateData_t*)&privateData); 
			} 
		} 
		if (ret!=0) 
			ret=cstaMakeCall(m_serverHandle,m_invokeId,&m_deviceId,&callId,NULL); 
		m_lErrCode=ERR_INI; 
		m_ErrMsg=""; 
		if (ACSPOSITIVE_ACK==ret) 
		{ 
			MSG msg; 
			BOOL bQuit=FALSE;//Quit the getmessage loop? 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					switch(msg.wParam) 
					{ 
					case UM_APIFAILED: 
						if (m_lErrCode==0||msg.wParam==CSTA_CONNECTION_CLEARED) 
						{ 
							m_lErrCode=LUCENT_MAKECALL_ERR; 
							m_ErrMsg="Make call failed."; 
						} 
						bQuit=TRUE; 
						ReleaseCall(NULL); 
						break; 
					case CSTA_ORIGINATED:	// null/initiated -> connected (LOCAL only) 
						bRet=OnCallDial(); 
						bQuit=TRUE; 
					} 
				} 
				if (bQuit) break; 
			} 
		}else 
		{ 
			m_lErrCode=ret; 
			m_ErrMsg="Make call return an error."; 
		} 
		m_bIsCmdMsg=bSave; 
	}else 
	{ 
		m_lErrCode=LUCENT_INVALID_PARAM; 
		m_ErrMsg="Invalid parameter."; 
	} 
 
	if (!bRet) 
	{ 
		char tep[300]={0}; 
		wsprintf((char*)&tep,"error:%s,code:%d",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return bRet; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::AnswerCall(BSTR connid) 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
	WriteLog("Answer cal service."); 
	if (!m_bConnect) 
	{ 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
		RetCode_t retCode=cstaAnswerCall(m_serverHandle,m_invokeId, 
											&m_activeConnId,NULL); 
		m_lErrCode=ERR_INI; 
		m_ErrMsg=""; 
		if (retCode==ACSPOSITIVE_ACK) 
		{ 
			MSG msg; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					if (msg.wParam==UM_APIFAILED||msg.wParam==CSTA_CONNECTION_CLEARED) 
					{ 
						if (m_lErrCode==ERR_INI) 
						{ 
							m_lErrCode=LUCENT_ANSWERCALL_ERR; 
							m_ErrMsg="Answercall failed."; 
						} 
						break; 
					} 
					else if (msg.wParam==CSTA_ESTABLISHED) 
					{ 
						ret=TRUE; 
						break; 
					} 
				} 
			} 
		}else 
		{ 
			m_lErrCode=ret; 
			m_ErrMsg="AnswerCall retun an error"; 
		} 
		m_bIsCmdMsg=bSave; 
	}else 
		ret=TRUE; 
	if (!ret) 
	{ 
		char tep[300]={0}; 
		wsprintf((char*)&tep,"error:%s,code:%d",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
BOOL CDirectoryNumber::Initialize(BSTR deviceId,ACSHandle_t serverHandle,InvokeID_t invokeId) 
{ 
	BOOL ret=FALSE; 
	DeviceID_t device; 
	WriteLog("Monitor device service."); 
	if (B2C(deviceId,device,sizeof(DeviceID_t))) 
	{ 
		strcpy(m_deviceId,device); 
		// now, attempt to put a device monitor on the specified device. No filtering is requested, 
		//  but the PBX may place filtering on the monitor. You will be notified of the filtering 
		//  placed on the monitor in the monitor confirmation event. 
		CSTAMonitorFilter_t noFilter; 
		noFilter.call = 0; 
		noFilter.feature = 0; 
		noFilter.agent = 0; 
		noFilter.maintenance = 0; 
		noFilter.privateFilter = 0; 
		// create a device record in the TSAPI window for this device. This device record will be 
		//  used to track all calls for this device and is also used to determine which window should 
		//  handle the TSAPI events that are received for each device. 
 
		//begin a inner message loop(not fire out) 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
		RetCode_t rc = cstaMonitorDevice(serverHandle, 
						invokeId, &device, &noFilter, NULL); 
		if (rc>=0) 
		{ 
			MSG msg; 
			BOOL bQuit=FALSE; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					switch (msg.wParam) 
					{ 
					case CSTA_MONITOR_CONF: 
						bQuit=TRUE; 
						ret=TRUE; 
						break; 
					case UM_APIFAILED: 
						bQuit=TRUE; 
						break; 
					} 
				} 
				if (bQuit) 
					break; 
			} 
			if (ret) 
			{ 
				m_invokeId=invokeId; 
				m_serverHandle=serverHandle; 
 
			} 
		}else 
		{ 
			m_lErrCode=rc; 
			m_ErrMsg="cstaMonitorDevice return an error."; 
		} 
		m_bIsCmdMsg=bSave; 
	}else 
	{ 
		m_lErrCode=LUCENT_INVALID_PARAM; 
		m_ErrMsg="Invalid parameter."; 
	} 
	if (!ret) 
	{ 
		char tep[300]={0}; 
		wsprintf((char*)&tep,"error:%s,code:%d",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
void CDirectoryNumber::Uninitialize() 
{ 
	if (m_monitorId)  
	{ 
		StopMonitor(m_monitorId); 
		m_invokeId=0; 
	} 
	if (m_splitMonitorId) 
	{ 
		StopMonitor(m_splitMonitorId); 
		m_splitMonitorId=0; 
	} 
	return ; 
} 
 
BOOL CDirectoryNumber::DefaultHandler(dnevent* pEvent) 
{ 
 
	BOOL notFire=FALSE; 
	if (pEvent) 
	{ 
		CSTAEvent_t* cstaEvent=pEvent->m_cstaEvent; 
		if (cstaEvent) 
		{ 
			switch(cstaEvent->eventHeader.eventClass) 
			{ 
			case ACSCONFIRMATION: 
				if (cstaEvent->eventHeader.eventType==ACS_UNIVERSAL_FAILURE_CONF) 
				{ 
					m_lErrCode=cstaEvent->event.cstaConfirmation.u.universalFailure.error; 
					m_ErrMsg="Monitor device failed."; 
					DNPostMessage(UM_CMDMSG,UM_APIFAILED,0); 
					char pTemp[100]={0}; 
					wsprintf(pTemp,"ACSCONFIRMATION error code:%d(dn)",m_lErrCode); 
					WriteLog(pTemp); 
				} 
				//This message will never be sent out 
				notFire=TRUE; 
				break; 
			case ACSUNSOLICITED: 
				m_lErrCode=cstaEvent->event.acsUnsolicited.u.failureEvent.error; 
				m_ErrMsg="acs unsolicited failed."; 
				DNPostMessage(UM_CMDMSG,UM_APIFAILED,0); 
				{ 
					char pTemp[100]={0}; 
					wsprintf(pTemp,"ACSUNSOLICITED error code:%d(dn)",m_lErrCode); 
					WriteLog(pTemp); 
				} 
				//This message will never be sent out 
				notFire=TRUE; 
				break; 
			case CSTACONFIRMATION: 
				//This message will never be sent out 
				notFire=TRUE; 
				switch(cstaEvent->eventHeader.eventType) 
				{ 
				case CSTA_UNIVERSAL_FAILURE_CONF: 
					 m_lErrCode=cstaEvent->event.cstaConfirmation.u.universalFailure.error; 
					 m_ErrMsg="CSTA_UNIVERSAL_FAILURE_CONF "; 
					 DNPostMessage(UM_CMDMSG,UM_APIFAILED,0); 
					 { 
						char pTemp[100]={0}; 
						wsprintf(pTemp,"CSTACONFIRMATION error code:%d(dn)",m_lErrCode); 
						WriteLog(pTemp); 
					 } 
					 break; 
				 case CSTA_MONITOR_CONF: 
					 // The monitor device confirmation, get the monitor cross ref id 
					 if (m_monitorId) 
					 {// this is the split monitor id 
						 m_splitMonitorId=cstaEvent->event.cstaConfirmation.u.monitorStart.monitorCrossRefID; 
					 }else 
					 {//This is the dn monitor id 
						 m_monitorId=cstaEvent->event.cstaConfirmation.u.monitorStart.monitorCrossRefID; 
						 //initialize the connecton id 
						 memset(&m_activeConnId,0,sizeof(ConnectionID_t)); 
						 strcpy((char*)&m_activeConnId.deviceID,(char*)&m_deviceId); 
						 memset(&m_holdConnId,0,sizeof(ConnectionID_t)); 
						 strcpy((char*)&m_holdConnId.deviceID,(char*)&m_deviceId); 
					 } 
					 while (!PostMessage(NULL,UM_CMDMSG,cstaEvent->eventHeader.eventType,0)) 
						 Sleep(100); 
					 break; 
				 case CSTA_QUERY_AGENT_STATE_CONF: 
					 switch (cstaEvent->event.cstaConfirmation.u.queryAgentState.agentState) 
					 { 
					 case AG_NULL: 
						 m_agentStat=AS_Logout; 
						 m_bLogged=FALSE; 
						 break; 
					 case AG_NOT_READY: 
						 m_agentStat=AS_NotReady; 
						 m_bLogged=TRUE; 
						 break; 
					 case AG_WORK_NOT_READY: 
						 m_bLogged=TRUE; 
						 m_agentStat=AS_AfterCallWork; 
						 break; 
					 case AG_READY: 
						 m_agentStat=AS_Ready; 
						 m_bLogged=TRUE; 
						 break; 
					 } 
					 DNPostMessage(UM_CMDMSG,cstaEvent->eventHeader.eventType,0); 
					 break; 
				 case CSTA_MAKE_CALL_CONF: 
				 case CSTA_CLEAR_CONNECTION_CONF: 
				 case CSTA_ANSWER_CALL_CONF: 
				 case CSTA_HOLD_CALL_CONF: 
				 case CSTA_RETRIEVE_CALL_CONF: 
				 case CSTA_CONFERENCE_CALL_CONF: 
				 case CSTA_TRANSFER_CALL_CONF:  
				 case CSTA_CLEAR_CALL: 
				 case CSTA_CONSULTATION_CALL_CONF: 
				 default://Post error message 
					 DNPostMessage(UM_CMDMSG,cstaEvent->eventHeader.eventType,0); 
					 break; 
				} 
				//This kind of message should not be fired 
				notFire=TRUE; 
				break; 
			case CSTAUNSOLICITED: 
				//This message may be sent out 
				notFire=FALSE; 
				switch(cstaEvent->eventHeader.eventType) 
				{ 
					case CSTA_FAILED: 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.failed); 
//						if (PROCESS) 
//						{ 
							//After connect to a call, connect to destinated dn failed 
							//It must not be a message from invoked csta api 
							m_lErrCode=cstaEvent->event.cstaUnsolicited.u.failed.cause; 
							m_ErrMsg="CSTAEventCause_t error"; 
							while (!PostMessage(NULL,UM_CMDMSG,UM_APIFAILED,0)) 
								Sleep(100); 
							{ 
								char pTemp[100]={0}; 
								wsprintf(pTemp,"CSTAUNSOLICITED CSTA_FAILED error code:%d(dn)",m_lErrCode); 
								WriteLog(pTemp); 
							 } 
//						} 
						notFire=TRUE; 
						break; 
					case CSTA_MONITOR_ENDED: 
						//It must not be a message from invoked csta api 
						while (!PostMessage(NULL,UM_CMDMSG,UM_APIFAILED,0)) 
							Sleep(100); 
						notFire=TRUE; 
						break; 
					case CSTA_SERVICE_INITIATED: // null -> initiated (LOCAL only) 
						//get the new connection id 
 
						//Because never receive other device's this event, it's not  
						//neccessary to get call info 
						m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.serviceInitiated.initiatedConnection.callID; 
						break; 
					case CSTA_ORIGINATED: // null/initiated -> connected (LOCAL only) 
						//get the new connection id 
						//Because never receive other device's this event, it's not  
						//neccessary to get call info 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.originated ); 
 
						if (PROCESS) 
						{ 
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.originated.originatedConnection.callID; 
							if (!m_bIsCmdMsg) 
							{//  
								ReplyMessage(0l); 
								m_bIsCmdMsg=TRUE; 
								OnCallDial(); 
								m_bIsCmdMsg=FALSE; 
							} 
						} 
						break; 
					case CSTA_DELIVERED: // null -> alerting 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.delivered); 
						if (PROCESS) 
						{ 
							//get the new connection id 
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.delivered.connection.callID; 
							 
							// if this event will be fired out, fill it out 
							if (!notFire) 
								FillEvent(pEvent); 
						} 
						break; 
					case CSTA_NETWORK_REACHED: // null -> connected (REMOTE only) 
						break; 
					case CSTA_ESTABLISHED:	// alerting/connected -> connected 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.established); 
						if (PROCESS) 
						{ 
							//get the new connection id 
							m_bConnect=TRUE; 
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.established.establishedConnection.callID; 
							 
							// if this event will be fired out, fill it out 
							if (!notFire) 
								FillEvent(pEvent); 
						} 
						break; 
					case CSTA_DIVERTED: // alerting -> null 
						break; 
					case CSTA_HELD: // connected -> held 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.held ); 
						if (PROCESS) 
						{ 
							m_holdConnId.callID=m_activeConnId.callID; 
							m_activeConnId.callID=0; 
							 
							// if this event will be fired out, fill it out 
							if (!notFire) 
								FillEvent(pEvent); 
						} 
						break; 
					case CSTA_RETRIEVED: // held -> connected 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.retrieved); 
 
						if (PROCESS) 
						{ 
							m_activeConnId.callID=m_holdConnId.callID; 
							m_holdConnId.callID=0; 
							m_bConnect=TRUE; 
							// if this event will be fired out, fill it out 
							if (!notFire) 
								FillEvent(pEvent); 
						} 
						break; 
					case CSTA_CONFERENCED: // held & connected -> connected (3 different connections) 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.conferenced); 
 
//						if (PROCESS) 
//						{ 
						m_holdConnId.callID=0; 
						if (cstaEvent->event.cstaUnsolicited.u.conferenced.conferenceConnections.count>0) 
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.conferenced.conferenceConnections.connection[0].party.callID; 
						else  
							m_activeConnId.callID=0; 
						m_bConnect=TRUE; 
//						} 
						break; 
					case CSTA_TRANSFERRED: // held & connected -> connected or null (3 different connections) 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.transferred); 
 
						if (PROCESS) 
						{//This connection is cleared 
							m_bConnect=FALSE; 
							m_holdConnId.callID=0; 
							m_activeConnId.callID=0; 
						}else 
						{//a new connection is built 
							m_holdConnId.callID=0; 
							if (cstaEvent->event.cstaUnsolicited.u.transferred.transferredConnections.count>0) 
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.transferred.transferredConnections.connection[0].party.callID; 
						} 
						break; 
					case CSTA_CALL_CLEARED: // * -> null (for all connections in call) 
						//clear the active connection id 
						//this message will never be recieved 
 
						m_bConnect=FALSE; 
						m_holdConnId.callID=0; 
						m_activeConnId.callID=0; 
						// if this event will be fired out, fill it out 
						if (!notFire) 
							FillEvent(pEvent); 
						break; 
					case CSTA_CONNECTION_CLEARED: // * -> null 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.connectionCleared); 
 
						if (PROCESS) 
						{ 
							m_activeConnId.callID=0; 
							m_bConnect=FALSE; 
							// if this event will be fired out, fill it out 
							if (!notFire) 
								FillEvent(pEvent); 
						} 
						break; 
					case CSTA_LOGGED_ON: 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.loggedOn); 
						if (PROCESS) 
							m_bLogged=TRUE; 
						break; 
					case CSTA_LOGGED_OFF: 
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.loggedOff); 
						if (PROCESS) 
							m_bLogged=FALSE; 
						break; 
				}//case CSTAUNSOLICITED 
				if (m_bIsCmdMsg) 
				{// This is all cmd message, and should not be fired 
					if (cstaEvent->eventHeader.eventType!=CSTA_FAILED  
						 || cstaEvent->eventHeader.eventType!=CSTA_MONITOR_ENDED) 
					{ 
						while (!PostMessage(NULL,UM_CMDMSG,cstaEvent->eventHeader.eventType,0)) 
							Sleep(100); 
					} 
					notFire=TRUE; 
				} 
				// If this device is ringing, fire this event out always 
				if (cstaEvent->eventHeader.eventClass==CSTAUNSOLICITED  
					&& cstaEvent->eventHeader.eventType==CSTA_DELIVERED 
					&& PROCESS) 
					notFire=FALSE; 
				break; 
			}//switch 
 
			{ 
				char temp[300]={0}; 
				wsprintf((char*)&temp,"DN receive event: eventClass:%d,eventType %d,MonitoerDeviece %s, EventDevice %s, notFire:%d", 
							cstaEvent->eventHeader.eventClass, 
							cstaEvent->eventHeader.eventType, 
							m_deviceId,m_thisDevice.deviceID , 
							notFire); 
				WriteLog((char*)&temp); 
			} 
		}//if (cstaEvent) 
	if (notFire) delete pEvent; 
	else ReplyMessage(0l); 
	}//if (pEvent) 
	return notFire; 
} 
 
 
BOOL CDirectoryNumber::KVListToAppString(IKVList* pkvlist, char* pAppString,UINT bufLen) 
{ 
	//Transform character: "/" 
	//	/k:  type : key 
	//	/s:	type: string 
	//	/i:	type: int 
	//	/b:	type: binary 
	//	/l:	type: binary length (/l23/l) 
	//sample:  /kRick/sMyname/kName/i100 
	BOOL bReturn=TRUE; 
 
	if (pkvlist) 
	{ 
		KVRESULTS res=pkvlist->InitScanLoop(); 
		if (KVR_Successful==res) 
		{ 
			IKVPair* pkvpair=NULL; 
			while (pkvpair=pkvlist->NextPair()) 
			{ 
				pkvpair->AddRef(); 
 
				BSTR key=NULL; 
				char* pKey=NULL; 
				if (SUCCEEDED(pkvpair->get_Key(&key))) 
				{ 
					if (GetAnsiFromBSTR(&pKey,key)) 
					{ 
//						ValidateString(pKey,bufLen); 
						if (strlen(pKey)+strlen(pAppString)+3<=bufLen) 
						{ 
							strcat(pAppString,"/k"); 
							strcat(pAppString,pKey); 
							key=NULL; 
							if (pKey)  
							{ 
								delete pKey; 
								pKey=NULL; 
							} 
							KVTYPES type; 
							if (SUCCEEDED(pkvpair->get_Type(&type))) 
							{ 
								int nVal=0; 
								switch (type) 
								{ 
								case KVT_String: 
									pkvpair->get_StringValue(&key); 
									if (GetAnsiFromBSTR(&pKey,key)) 
									{ 
//										ValidateString(pKey,bufLen); 
										if (strlen(pKey)+strlen(pAppString)+3<=bufLen) 
										{ 
											strcat(pAppString,"/s"); 
											strcat(pAppString,pKey); 
										}else 
											bReturn = FALSE; 
									}else 
									{ 
										bReturn = FALSE; 
									} 
									if (pKey) 
									{ 
										delete pKey; 
										pKey=NULL; 
									} 
									key=NULL; 
									break; 
								case KVT_Int: 
									pkvpair->get_IntValue(&nVal); 
									if (GetAnsiFromInt(&pKey,nVal)) 
									{ 
										if (strlen(pKey)+strlen(pAppString)+3<=bufLen) 
										{ 
											strcat(pAppString,"/i"); 
											strcat(pAppString,pKey); 
										}else 
											bReturn= FALSE; 
									}else 
										bReturn= FALSE; 
									if (pKey) 
									{ 
										delete pKey; 
										pKey=NULL; 
									} 
									break; 
								default: 
									bReturn=FALSE; 
								} 
							}else//pkvpair->Type 
							{ 
								bReturn =FALSE; 
							} 
						}else//LENGTH CHECK 
						{ 
							bReturn =FALSE; 
						} 
					}else//GetAnsiFromBSTR 
					{ 
						bReturn =FALSE; 
					} 
					if (pKey) 
					{ 
						delete pKey; 
						pKey=NULL; 
					} 
					key=NULL; 
				}else//pkvpair->Key 
				{ 
					bReturn = FALSE; 
				} 
 
				pkvpair->Release(); 
				pkvpair=NULL; 
			}//while 
		}else//KVR_Successful==res 
		{ 
			bReturn= FALSE; 
		} 
	}//if (pkvlist) 
	else 
	{ 
		bReturn =TRUE; 
	} 
	if (!bReturn )  
		ZeroMemory(pAppString, strlen(pAppString)); 
	return bReturn; 
} 
 
BOOL CDirectoryNumber::GetAnsiFromBSTR(char** dest, BSTR source) 
{ 
	BOOL ret=TRUE; 
	int nLength=WideCharToMultiByte(CP_ACP,0,source,-1,NULL,0,NULL,NULL); 
	if (nLength>0) 
	{ 
		char* pTemp=new char[nLength]; 
		if (pTemp) 
		{ 
			if (WideCharToMultiByte(CP_ACP,0,source,-1,pTemp,nLength,NULL,NULL)) 
			{ 
				*dest=new char[nLength*2]; 
				int nDestLen=0; 
				if (*dest) 
				{ 
					for (UINT i=0;i0) 
		memcpy((char*)backGroup,(char*)&m_agentGroup,sizeof(AgentGroup_t)); 
 
	if (B2C(AgentID,(char*)&m_agentId,sizeof(AgentID_t))  
		&& B2C(AgentPassword,(char*)&m_agentPwd,sizeof(AgentPassword_t))  
		&&B2C(ACDQ,(char*)&m_agentGroup,sizeof(AgentGroup_t))  
		&&strlen((char*)&m_agentGroup)>0) 
	{ 
		if (strcmp(m_agentGroup,backGroup)==0 && m_splitMonitorId!=0) 
		{//This acd group has been moniotred 
			bMonitored=TRUE; 
		}else// This split hasn't been monitored  
			if (m_splitMonitorId==0) 
				bMonitored=MonitorSplit(&m_agentGroup); 
			else  
			{// There is another split has been monitored 
				StopMonitor(m_splitMonitorId); 
				m_splitMonitorId=0; 
				bMonitored=MonitorSplit(&m_agentGroup); 
			} 
		if (bMonitored) 
		{ 
			BOOL bSave=m_bIsCmdMsg; 
			m_bIsCmdMsg=TRUE; 
			RetCode_t retCode; 
			ATTWorkMode_t workMode; 
			switch (mode) 
			{ 
			case AM_ManualIn: 
				workMode=WM_MANUAL_IN; 
				break; 
			case AM_AutoIn: 
				workMode=WM_AUTO_IN; 
				break; 
			case AM_AfterCallWork: 
				workMode=WM_AFTCAL_WK; 
				break; 
			case AM_AuxWork: 
				workMode=WM_AUX_WORK; 
				break; 
			default: 
				workMode=WM_AUX_WORK; 
				break; 
			} 
			ATTPrivateData_t privateData={0}; 
			retCode=attV6SetAgentState(&privateData, 
										workMode, 
										0,//reason code not available 
										FALSE); //not pending 
			if (retCode==ACSPOSITIVE_ACK) 
				retCode=cstaSetAgentState(m_serverHandle,m_invokeId,&m_deviceId, 
											AM_LOG_IN,//angent mode 
											&m_agentId,//agent id 
											&m_agentGroup,//agent group 
											&m_agentPwd,//agent password 
											(PrivateData_t*)&privateData); //private data 
			//Do default process 
			if (retCode!=ACSPOSITIVE_ACK) 
				retCode=cstaSetAgentState(m_serverHandle,m_invokeId,&m_deviceId, 
												AM_LOG_IN,//angent mode 
												&m_agentId,//agent id 
												&m_agentGroup,//agent group 
												&m_agentPwd,//agent password 
												NULL); //private data 
			m_lErrCode=ERR_INI; 
			m_ErrMsg=""; 
			if (retCode==ACSPOSITIVE_ACK) 
			{ 
				MSG msg; 
				while (GetMessage(&msg,NULL,0,0)) 
				{ 
					if (msg.message==UM_CMDMSG) 
					{ 
						if (msg.wParam==UM_APIFAILED) 
						{ 
							if (m_lErrCode==ERR_INI) 
							{ 
								m_lErrCode=LUCENT_AGENT_LOGIN_ERR; 
								m_ErrMsg="Agent login failed."; 
							}else 
							{ 
								switch (m_lErrCode) 
								{ 
								case GENERIC_UNSPECIFIED://The agent has logged in when you specified login 
									m_bLogged=FALSE; 
									m_lErrCode=ERR_INI; 
									bRet=TRUE; 
									break; 
								case GENERIC_OPERATION:// The agent has logged out when you specified logout 
									m_bLogged=TRUE; 
									m_lErrCode=ERR_INI; 
									bRet=TRUE; 
									break; 
								case INVALID_OBJECT_STATE: // The agent has logged in another split 
									m_bLogged=TRUE; 
									m_ErrMsg="This agent has logged in another split."; 
									bRet=FALSE; 
									break; 
								} 
							} 
							break; 
						} 
						else if (msg.wParam==CSTA_LOGGED_ON) 
						{ 
							bRet=TRUE; 
							break; 
						} 
					} 
				} 
			}else 
			{ 
				m_lErrCode=LUCENT_AGENT_LOGIN_ERR; 
				m_ErrMsg="Agent login return an error."; 
			} 
			m_bIsCmdMsg=bSave; 
		} 
	}else 
	{ 
		m_ErrMsg="Specified an error parameter."; 
		m_lErrCode=LUCENT_INVALID_PARAM; 
	} 
	if (bRet) 
	{ 
		m_bLogged=TRUE; 
	}else 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return bRet; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::AgentLogout() 
{ 
	// TODO: Add your implementation code here 
 
	BOOL bRet=FALSE; 
 
	BOOL bSave=m_bIsCmdMsg; 
	m_bIsCmdMsg=TRUE; 
 
	WriteLog("Agent logout service."); 
	RetCode_t	retCode=cstaSetAgentState(m_serverHandle,m_invokeId,&m_deviceId, 
										AM_LOG_OUT,//angent mode 
										&m_agentId,//agent id 
										&m_agentGroup,//agent group 
										&m_agentPwd,//agent password 
										NULL); //private data 
	m_lErrCode=ERR_INI; 
	m_ErrMsg=""; 
	if (retCode==ACSPOSITIVE_ACK) 
	{ 
		MSG msg; 
		while (GetMessage(&msg,NULL,0,0)) 
		{ 
			if (msg.message==UM_CMDMSG) 
			{ 
				if (msg.wParam==UM_APIFAILED) 
				{ 
					if (m_lErrCode==ERR_INI) 
					{ 
						m_lErrCode=LUCENT_AGENT_LOGOUT_ERR; 
						m_ErrMsg="Agent logout failed."; 
					}else 
					{ 
						switch (m_lErrCode) 
						{ 
						case GENERIC_UNSPECIFIED://The agent has logged in when you specified login 
							m_bLogged=FALSE; 
							m_lErrCode=ERR_INI; 
							bRet=TRUE; 
							break; 
						case GENERIC_OPERATION:// The agent has logged out when you specified logout 
							m_bLogged=TRUE; 
							m_lErrCode=ERR_INI; 
							bRet=TRUE; 
							break; 
						case INVALID_OBJECT_STATE: // The agent has logged in another split 
							m_bLogged=TRUE; 
							bRet=FALSE; 
							break; 
						} 
					} 
					break; 
				} 
				else if (msg.wParam==CSTA_LOGGED_OFF) 
				{ 
					bRet=TRUE; 
					break; 
				} 
			} 
		} 
	}else 
	{ 
		m_lErrCode=LUCENT_AGENT_LOGOUT_ERR; 
		m_ErrMsg="agent logout return an error."; 
	} 
	m_bIsCmdMsg=bSave; 
	if (bRet) 
	{ 
		m_bLogged=FALSE; 
	}else 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return bRet; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::CompleteConference() 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
 
	BOOL bSave=m_bIsCmdMsg; 
	m_bIsCmdMsg=TRUE; 
	WriteLog("Conference call service."); 
	RetCode_t retCode=cstaConferenceCall(m_serverHandle,m_invokeId, 
										&m_holdConnId,&m_activeConnId,NULL); 
	m_lErrCode=ERR_INI; 
	m_ErrMsg=""; 
	if (retCode==ACSPOSITIVE_ACK) 
	{ 
		MSG msg; 
		while (GetMessage(&msg,NULL,0,0)) 
		{ 
			if (msg.message==UM_CMDMSG) 
			{ 
				if (msg.wParam==UM_APIFAILED) 
				{ 
					if (m_lErrCode==ERR_INI) 
					{ 
						m_lErrCode=LUCENT_CONFERENCE_ERR; 
						m_ErrMsg="Conference call failed."; 
					} 
					ReconnectCall(); 
					break; 
				} 
				else if (msg.wParam==CSTA_CONFERENCED) 
				{ 
					ret=TRUE; 
					break; 
				}else if (msg.wParam==CSTA_CONNECTION_CLEARED) 
				{ 
					m_lErrCode=LUCENT_CALL_RELEASED; 
					m_ErrMsg="The call was released by the other party."; 
					RetrieveCall(NULL); 
					break; 
				} 
			} 
		} 
	}else 
	{ 
		m_lErrCode=retCode; 
		m_ErrMsg="conference return an error."; 
	} 
	m_bIsCmdMsg=bSave; 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::CompleteTransfer() 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
 
	BOOL bSave=m_bIsCmdMsg; 
	m_bIsCmdMsg=TRUE; 
	WriteLog("Transfer call service."); 
	RetCode_t retCode=cstaTransferCall(m_serverHandle,m_invokeId, 
										&m_holdConnId,&m_activeConnId,NULL); 
	m_lErrCode=ERR_INI; 
	m_ErrMsg=""; 
	if (retCode==ACSPOSITIVE_ACK) 
	{ 
		MSG msg; 
		while (GetMessage(&msg,NULL,0,0)) 
		{ 
			if (msg.message==UM_CMDMSG) 
			{ 
				if (msg.wParam==UM_APIFAILED) 
				{ 
					if (m_lErrCode==ERR_INI) 
					{ 
						m_lErrCode=LUCENT_TRANSFERCALL_ERR; 
						m_ErrMsg="Transfer call failed."; 
					} 
					ReconnectCall(); 
					break; 
				} 
				else if (msg.wParam==CSTA_TRANSFERRED) 
				{ 
					ret=TRUE; 
					break; 
				}else if (msg.wParam==CSTA_CONNECTION_CLEARED) 
				{ 
					m_lErrCode=LUCENT_CALL_RELEASED; 
					m_ErrMsg="The call was released by the other party."; 
					RetrieveCall(NULL); 
					break; 
				} 
			} 
		} 
	}else 
	{ 
		m_lErrCode=retCode; 
		m_ErrMsg="Transfer call return value"; 
	} 
	m_bIsCmdMsg=bSave; 
 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::HoldCall(BSTR connid) 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
 
	BOOL bSave=m_bIsCmdMsg; 
	m_bIsCmdMsg=TRUE; 
	WriteLog("Hold call service."); 
	RetCode_t retCode=cstaHoldCall(m_serverHandle,m_invokeId, 
										&m_activeConnId,TRUE,NULL); 
	m_lErrCode=ERR_INI; 
	m_ErrMsg=""; 
	if (retCode==ACSPOSITIVE_ACK) 
	{ 
		MSG msg; 
		while (GetMessage(&msg,NULL,0,0)) 
		{ 
			if (msg.message==UM_CMDMSG) 
			{ 
				if (msg.wParam==UM_APIFAILED ||msg.wParam==CSTA_CONNECTION_CLEARED) 
				{ 
					if (m_lErrCode==ERR_INI) 
					{ 
						m_lErrCode=LUCENT_HOLDCALL_ERR; 
						m_ErrMsg="Hold call failed."; 
					} 
					break; 
				} 
				else if (msg.wParam==CSTA_HELD) 
				{ 
					ret=TRUE; 
					break; 
				} 
			} 
		} 
	}else 
	{ 
		m_lErrCode=retCode; 
		m_ErrMsg="HoldCall return value"; 
	} 
	m_bIsCmdMsg=bSave; 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::InitConferenceCall(BSTR dn, LPKVLIST data) 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
 
	DeviceID_t calledDevice={0}; 
	RetCode_t code=-1; 
	if (B2C(dn,(char*)&calledDevice,sizeof(DeviceID_t))) 
	{ 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
		WriteLog("Consultation call service."); 
		if (data) 
		{ 
			ATTPrivateData_t privateData; 
			memset(&privateData,0,sizeof(ATTPrivateData_t)); 
			ATTUserToUserInfo_t attData; 
			memset(&attData,0,sizeof(ATTUserToUserInfo_t )); 
			attData.type=UUI_IA5_ASCII; 
			 
			if (KVListToAppString(data,(char*)attData.data.value,sizeof(attData.data.value)-1)) 
			{ 
				attData.data.length=strlen((char*)attData.data.value); 
				code=attV6ConsultationCall(&privateData,NULL,TRUE,&attData); 
				if (code==ACSPOSITIVE_ACK) 
				{ 
					code=cstaConsultationCall(m_serverHandle,m_invokeId, 
									&m_activeConnId,&calledDevice, 
									(PrivateData_t*)&privateData); 
				} 
			} 
		} 
		if (code!=ACSPOSITIVE_ACK) 
			code=cstaConsultationCall(m_serverHandle,m_invokeId, 
								&m_activeConnId,&calledDevice, 
								NULL); 
		m_lErrCode=ERR_INI; 
		m_ErrMsg=""; 
		if (code==ACSPOSITIVE_ACK) 
		{ 
			MSG msg; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					if (msg.wParam==UM_APIFAILED ||msg.wParam==CSTA_CONNECTION_CLEARED) 
					{ 
						if (m_lErrCode==ERR_INI) 
						{ 
							m_lErrCode=LUCENT_CONSULTATION_ERR; 
							m_ErrMsg="Consultation call failed."; 
						} 
						ReconnectCall(); 
						break; 
					} 
					else if (msg.wParam==CSTA_ORIGINATED) 
					{ 
						ret=OnConsultDial(); 
						break; 
					} 
				} 
			} 
		}else 
		{ 
			m_lErrCode=code; 
			m_ErrMsg="Consultation call return an error."; 
		} 
		m_bIsCmdMsg=bSave; 
	}else 
	{ 
		m_lErrCode=LUCENT_INVALID_PARAM; 
		m_ErrMsg="Invalid parameter."; 
	} 
 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::InitTransferCall(BSTR dn, LPKVLIST data) 
{ 
	// TODO: Add your implementation code here 
	return InitConferenceCall(dn,data); 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::ReleaseCall(BSTR connid, BOOL hangup) 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
 
	WriteLog("Clear connection service."); 
	BOOL bSave=m_bIsCmdMsg; 
	m_bIsCmdMsg=TRUE; 
	RetCode_t code=cstaClearConnection(m_serverHandle,m_invokeId,&m_activeConnId,NULL); 
	m_lErrCode=0; 
	if (code==ACSPOSITIVE_ACK) 
	{ 
		MSG msg; 
		while (GetMessage(&msg,NULL,0,0)) 
		{ 
			if (msg.message==UM_CMDMSG) 
			{ 
				if (msg.wParam==UM_APIFAILED) 
				{ 
					if (m_lErrCode==0) 
					{ 
						m_lErrCode=LUCENT_CLEARCALL_ERR; 
						m_ErrMsg="Clear call failed."; 
					} 
					break; 
				} 
				else if (/*msg.wParam==CSTA_CALL_CLEARED || */msg.wParam==CSTA_CONNECTION_CLEARED) 
				{ 
					ret=TRUE; 
					break; 
				} 
			} 
		} 
	}else 
	{ 
		m_lErrCode=code; 
		m_ErrMsg="Clear call return value."; 
	} 
	m_bIsCmdMsg=bSave; 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::RetrieveCall(BSTR connid) 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
 
	BOOL bSave=m_bIsCmdMsg; 
	m_bIsCmdMsg=TRUE; 
	WriteLog("Retreive call service."); 
	RetCode_t retCode=cstaRetrieveCall(m_serverHandle,m_invokeId, 
										&m_holdConnId,NULL); 
	m_lErrCode=ERR_INI; 
	m_ErrMsg=""; 
	if (retCode==ACSPOSITIVE_ACK) 
	{ 
		MSG msg; 
		while (GetMessage(&msg,NULL,0,0)) 
		{ 
			if (msg.message==UM_CMDMSG) 
			{ 
				if (msg.wParam==UM_APIFAILED||msg.wParam==CSTA_CONNECTION_CLEARED) 
				{ 
					if (m_lErrCode==ERR_INI) 
					{ 
						m_lErrCode=LUCENT_RETRIEVECALL_ERR; 
						m_ErrMsg="Retrieve call failed."; 
					} 
					break; 
				} 
				else if (msg.wParam==CSTA_RETRIEVED) 
				{ 
					ret=TRUE; 
					break; 
				} 
			} 
		} 
	}else 
	{ 
		m_lErrCode=retCode; 
		m_ErrMsg="Retrive call return an error."; 
	} 
	m_bIsCmdMsg=bSave; 
 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::SingleStepTransfer(BSTR dn, LPKVLIST data) 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
	DeviceID_t transDevice={0}; 
	RetCode_t retCode=-1; 
	WriteLog("Single step transfer call service."); 
	if (B2C(dn,(char*)&transDevice,sizeof(DeviceID_t))) 
	{ 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
		WriteLog("Consultation call service."); 
		if (data) 
		{ 
			ATTPrivateData_t privateData; 
			memset(&privateData,0,sizeof(ATTPrivateData_t )); 
			ATTUserToUserInfo_t attData; 
			memset(&attData,0,sizeof(ATTUserToUserInfo_t )); 
			attData.type=UUI_IA5_ASCII; 
			 
			if (KVListToAppString(data,(char*)attData.data.value,sizeof(attData.data.value)-1)) 
			{ 
				attData.data.length=strlen((char*)attData.data.value); 
				retCode=attV6ConsultationCall(&privateData,NULL,FALSE,&attData); 
				if (retCode==ACSPOSITIVE_ACK) 
				{ 
					retCode=cstaConsultationCall(m_serverHandle,m_invokeId, 
									&m_activeConnId,&transDevice, 
									(PrivateData_t*)&privateData); 
				} 
			} 
		} 
		if (retCode!=ACSPOSITIVE_ACK) 
			retCode=cstaConsultationCall(m_serverHandle,m_invokeId, 
								&m_activeConnId,&transDevice, 
								NULL); 
		m_lErrCode=ERR_INI; 
		m_ErrMsg=""; 
		if (retCode==ACSPOSITIVE_ACK) 
		{ 
			MSG msg; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					if (msg.wParam==UM_APIFAILED) 
					{ 
						if (m_lErrCode==ERR_INI ||msg.wParam==CSTA_RETRIEVED) 
						{ 
							m_lErrCode=LUCENT_CONSULTATION_ERR; 
							m_ErrMsg="Consultation call failed."; 
						} 
						ReconnectCall(); 
						break; 
					}else if (msg.wParam==CSTA_CONNECTION_CLEARED) 
					{ 
						m_lErrCode=LUCENT_CALL_RELEASED; 
						m_ErrMsg="The call was released by the other party."; 
						RetrieveCall(NULL); 
						break; 
					}else if (msg.wParam==CSTA_TRANSFERRED) 
					{//transfer call ok 
						ret=TRUE; 
						break; 
					}else if (msg.wParam==CSTA_DELIVERED/*CSTA_ESTABLISHED*/) 
					{//begin transfer the call nomatter the other party answer it or not 
						WriteLog("Transfer call service."); 
						retCode=cstaTransferCall(m_serverHandle,m_invokeId, 
											&m_holdConnId,&m_activeConnId,NULL); 
						if (retCode!=ACSPOSITIVE_ACK) 
						{ 
							m_lErrCode=LUCENT_TRANSFERCALL_ERR; 
							m_ErrMsg="Transfer call failed."; 
							ReconnectCall(); 
							break; 
						} 
					} 
				} 
			} 
		}else 
		{ 
			m_lErrCode=retCode; 
			m_ErrMsg="cstaConsultationCall return an error."; 
		} 
		m_bIsCmdMsg=bSave; 
	} 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
 
void CDirectoryNumber::DNPostMessage(UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
	while (!PostMessage(NULL,msg,wParam,lParam)) 
		Sleep(100); 
	return; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::ReconnectCall() 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
 
	BOOL bSave=m_bIsCmdMsg; 
	m_bIsCmdMsg=TRUE; 
	WriteLog("Reconnect call service."); 
	RetCode_t retCode=cstaReconnectCall(m_serverHandle,m_invokeId, 
							&m_activeConnId,&m_holdConnId,NULL); 
	m_lErrCode=ERR_INI; 
	m_ErrMsg=""; 
	if (retCode==ACSPOSITIVE_ACK) 
	{ 
		MSG msg; 
		while (GetMessage(&msg,NULL,0,0)) 
		{ 
			if (msg.message==UM_CMDMSG) 
			{ 
				if (msg.wParam==UM_APIFAILED) 
				{ 
					if (m_lErrCode==ERR_INI) 
					{ 
						m_lErrCode=LUCENT_RECONNECT_ERR; 
						m_ErrMsg="Reconnect call failed."; 
					} 
					break; 
				} 
				else if(msg.wParam==CSTA_RETRIEVED) 
				{ 
					ret=TRUE; 
					break; 
				} 
			} 
		} 
	}else 
	{ 
		m_lErrCode=retCode; 
		m_ErrMsg="Reconnect call return an error."; 
	} 
	m_bIsCmdMsg=bSave; 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
} 
 
BOOL CDirectoryNumber::FillEvent(dnevent* pEvent)//other DN 
{ 
	pEvent->ConnID=m_activeConnId.callID; 
	memcpy(&pEvent->ThisDN,&m_thisDevice.deviceID,sizeof(DeviceID_t)); 
	memcpy(&pEvent->OtherDN,&m_otherDevice.deviceID,sizeof(DeviceID_t)); 
	memcpy(&pEvent->AgentID,&m_agentId,sizeof(AgentID_t)); 
	memcpy(&pEvent->ANI,&m_ani,sizeof(AgentID_t)); 
	memcpy(&pEvent->DNIS,&m_dnis,sizeof(AgentID_t)); 
	pEvent->CallType=m_callType; 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::AgentSetNotReady(AGENTMODES mode) 
{ 
	// TODO: Add your implementation code here 
 
	BOOL bRet=FALSE; 
	WriteLog("Agent set not ready service."); 
	{ 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
/////////////MARK by rick --begin 
// 
//			ATTWorkMode_t workMode; 
//			switch (mode) 
//			{ 
//			case AM_ManualIn: 
//				workMode=WM_MANUAL_IN; 
//				break; 
//			case AM_AutoIn: 
//				workMode=WM_AUTO_IN; 
//				break; 
//			case AM_AfterCallWork: 
//				workMode=WM_AFTCAL_WK; 
//				break; 
//			case AM_AuxWork: 
//				workMode=WM_AUX_WORK; 
//				break; 
//			default: 
//				workMode=WM_AUX_WORK; 
//				break; 
//			} 
//			ATTPrivateData_t privateData={0}; 
//			RetCode_t retCode=attV6SetAgentState(&privateData, 
//										workMode, 
//										0,//reason code not available 
//										FALSE); //not pending 
//			if (retCode==ACSPOSITIVE_ACK) 
//				retCode=cstaSetAgentState(m_serverHandle,m_invokeId,&m_deviceId, 
//											AM_NOT_READY,//angent mode 
//											&m_agentId,//agent id 
//											&m_agentGroup,//agent group 
//											&m_agentPwd,//agent password 
//											(PrivateData_t*)&privateData); //private data 
//			if (retCode!=ACSPOSITIVE_ACK) 
//				if (mode==AM_AfterCallWork) 
//					retCode=cstaSetAgentState(m_serverHandle,m_invokeId,&m_deviceId, 
//											AM_WORK_NOT_READY,//angent mode 
//											&m_agentId,//agent id 
//											&m_agentGroup,//agent group 
//											&m_agentPwd,//agent password 
//											NULL); //private data 
//				else 
 
/////////////MARK --end 
		AgentMode_t workMode; 
		switch (mode) 
			{ 
			case AM_AfterCallWork: 
				workMode=AM_WORK_NOT_READY; 
				break; 
			case AM_AuxWork: 
				workMode=AM_NOT_READY; 
				break; 
			default: 
				workMode=AM_NOT_READY; 
				break; 
			} 
		RetCode_t	retCode=cstaSetAgentState(m_serverHandle,m_invokeId,&m_deviceId, 
											workMode,//angent mode 
											&m_agentId,//agent id 
											&m_agentGroup,//agent group 
											&m_agentPwd,//agent password 
											NULL); //private data 
		m_lErrCode=ERR_INI; 
		m_ErrMsg=""; 
		if (retCode==ACSPOSITIVE_ACK) 
		{ 
			MSG msg; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					if (msg.wParam==UM_APIFAILED) 
					{ 
						if (m_lErrCode==ERR_INI) 
						{ 
							m_lErrCode=LUCENT_AGENT_SETNOTREADY_ERR; 
							m_ErrMsg="Agent set notready failed."; 
						} 
						break; 
					} 
					else if (msg.wParam==CSTA_SET_AGENT_STATE_CONF) 
					{ 
						bRet=TRUE; 
						break; 
					} 
				} 
			} 
		}else 
		{ 
			m_lErrCode=retCode; 
			m_ErrMsg="cstaSetAgentState return an error,"; 
		} 
		m_bIsCmdMsg=bSave; 
	} 
	if (!bRet) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return bRet; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::AgentSetReady(AGENTMODES mode) 
{ 
	// TODO: Add your implementation code here 
	BOOL bRet=FALSE; 
	WriteLog("Agent set ready service."); 
	{ 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
 
			ATTWorkMode_t workMode; 
			switch (mode) 
			{ 
			case AM_ManualIn: 
				workMode=WM_MANUAL_IN; 
				break; 
			case AM_AutoIn: 
				workMode=WM_AUTO_IN; 
				break; 
			default: 
				workMode=WM_AUTO_IN; 
				break; 
			} 
			ATTPrivateData_t privateData={0}; 
			RetCode_t retCode=attV6SetAgentState(&privateData, 
										workMode, 
										0,//reason code not available 
										FALSE); //not pending 
			if (retCode==ACSPOSITIVE_ACK) 
				retCode=cstaSetAgentState(m_serverHandle,m_invokeId,&m_deviceId, 
											AM_READY,//angent mode 
											&m_agentId,//agent id 
											&m_agentGroup,//agent group 
											&m_agentPwd,//agent password 
											(PrivateData_t*)&privateData); //private data 
			if (retCode!=ACSPOSITIVE_ACK) 
				 retCode=cstaSetAgentState(m_serverHandle,m_invokeId,&m_deviceId, 
											AM_READY,//angent mode 
											&m_agentId,//agent id 
											&m_agentGroup,//agent group 
											&m_agentPwd,//agent password 
											NULL); //private data 
		m_lErrCode=ERR_INI; 
		m_ErrMsg=""; 
		if (retCode==ACSPOSITIVE_ACK) 
		{ 
			m_lErrCode=0; 
			MSG msg; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					if (msg.wParam==UM_APIFAILED) 
					{ 
						if (m_lErrCode==ERR_INI) 
						{ 
							m_lErrCode=LUCENT_AGENT_SETREADY_ERR; 
							m_ErrMsg="Agent set ready failed."; 
						} 
						break; 
					} 
					else if (msg.wParam==CSTA_SET_AGENT_STATE_CONF) 
					{ 
						bRet=TRUE; 
						break; 
					} 
				} 
			} 
		}else 
		{ 
			m_lErrCode=retCode; 
			m_ErrMsg="agentsetready return an error."; 
		} 
		m_bIsCmdMsg=bSave; 
	} 
	if (!bRet) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return bRet; 
} 
 
STDMETHODIMP CDirectoryNumber::get_AgentState(AGENTSTATES *pVal) 
{ 
	// TODO: Add your implementation code here 
	WriteLog("Agent get status service."); 
	if (strlen((char*)&m_agentId)>0) 
	{// There's a agent has logged in 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
		RetCode_t ret=-1; 
 
		ATTPrivateData_t privateData={0}; 
		ret=attQueryAgentState(&privateData,(DeviceID_t*)m_agentGroup); 
 
		if (ret==ACSPOSITIVE_ACK) 
			ret=cstaQueryAgentState(m_serverHandle,m_invokeId, 
									(DeviceID_t*)&m_agentId, 
									(PrivateData_t*)&privateData); 
		if (ret==ACSPOSITIVE_ACK) 
		{ 
			MSG msg; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message ==UM_CMDMSG) 
				{ 
					if (msg.wParam ==UM_APIFAILED) 
					{ 
						break; 
					}else if (msg.wParam ==CSTA_QUERY_AGENT_STATE_CONF) 
					{ 
						break; 
					}else if (msg.wParam ==CSTA_CONNECTION_CLEARED) 
					{ 
						break; 
					} 
				} 
			} 
		} 
		m_bIsCmdMsg=bSave; 
	} 
	*pVal=m_agentStat; 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_ErrCode(long *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal=m_lErrCode; 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_ErrMsg(BSTR *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal=C2B(m_ErrMsg.c_str()); 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_HoldID(long *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal=m_holdConnId.callID; 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_Logged(BOOL *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal=m_bLogged; 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_Registered(BOOL *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal=m_monitorId!=0; 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_ActiveID(long *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal=m_activeConnId.callID; 
	return S_OK; 
} 
 
 
 
STDMETHODIMP CDirectoryNumber::get_AgentID(BSTR *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal=C2B((char*)&m_agentId); 
	return S_OK; 
} 
 
 
BOOL CDirectoryNumber::GetCallInfo(CSTAHeldEvent_t* pHeldEvent) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pHeldEvent->holdingDevice,sizeof(SubjectDeviceID_t)); 
	return TRUE; 
}; 
 
BOOL CDirectoryNumber::GetCallInfo(CSTARetrievedEvent_t* pRetrieveEvent) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pRetrieveEvent->retrievingDevice,sizeof(SubjectDeviceID_t)); 
	return TRUE; 
} 
 
BOOL CDirectoryNumber::GetCallInfo(CSTAConferencedEvent_t* pConfer) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pConfer->confController,sizeof(SubjectDeviceID_t)); 
	return TRUE; 
} 
 
BOOL CDirectoryNumber::GetCallInfo(CSTALoggedOffEvent_t* pLogoff) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pLogoff->agentDevice,sizeof(SubjectDeviceID_t)); 
	return TRUE; 
} 
 
BOOL CDirectoryNumber::GetCallInfo(CSTATransferredEvent_t* pTransfer) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pTransfer->transferringDevice,sizeof(SubjectDeviceID_t)); 
	memcpy(&m_otherDevice,&pTransfer->transferredDevice,sizeof(SubjectDeviceID_t)); 
	return TRUE; 
} 
 
BOOL CDirectoryNumber::GetCallInfo(CSTADeliveredEvent_t* pDeliverEvent) 
{ 
	BOOL bIsMyAlart=FALSE; 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	if (strcmp((char*)&m_deviceId,(char*)&pDeliverEvent->alertingDevice.deviceID)!=0) 
		bIsMyAlart=FALSE; 
	else bIsMyAlart=TRUE; 
 
	if (bIsMyAlart) 
	{ 
		memcpy(&m_otherDevice,&pDeliverEvent->callingDevice,sizeof(CalledDeviceID_t)); 
		memcpy(&m_thisDevice,&pDeliverEvent->alertingDevice,sizeof(CalledDeviceID_t)); 
		memcpy(&m_ani,&pDeliverEvent->calledDevice.deviceID,sizeof(DeviceID_t)); 
		memcpy(&m_dnis,&m_deviceId,sizeof(DeviceID_t)); 
	}else 
	{ 
		memcpy(&m_otherDevice,&pDeliverEvent->calledDevice,sizeof(CalledDeviceID_t)); 
		memcpy(&m_thisDevice,&pDeliverEvent->callingDevice,sizeof(CalledDeviceID_t)); 
		memcpy(&m_dnis,&pDeliverEvent->alertingDevice.deviceID,sizeof(DeviceID_t)); 
		memcpy(&m_ani,&m_deviceId,sizeof(DeviceID_t)); 
	} 
 
	switch (m_otherDevice.deviceIDType) 
	{ 
	case IMPLICIT_PRIVATE : 
	case EXPLICIT_PRIVATE_UNKNOWN : 
    case EXPLICIT_PRIVATE_LEVEL3_REGIONAL_NUMBER : 
    case EXPLICIT_PRIVATE_LEVEL2_REGIONAL_NUMBER : 
    case EXPLICIT_PRIVATE_LEVEL1_REGIONAL_NUMBER : 
    case EXPLICIT_PRIVATE_PTN_SPECIFIC_NUMBER : 
    case EXPLICIT_PRIVATE_LOCAL_NUMBER : 
    case EXPLICIT_PRIVATE_ABBREVIATED : 
		m_callType=CT_Internal; 
		break; 
	default: 
		if (bIsMyAlart) 
			m_callType=CT_Inbound; 
		else  
			m_callType=CT_Outbound; 
		break; 
	} 
	{ 
		char temp[300]={0}; 
		wsprintf((char*)&temp,"Ringing: calledDevice %s, callingdevice %s, alertingDevice %s",pDeliverEvent->calledDevice.deviceID ,pDeliverEvent->callingDevice.deviceID ,pDeliverEvent->alertingDevice.deviceID  ); 
		WriteLog((char*)&temp); 
	} 
	return TRUE; 
} 
 
BOOL CDirectoryNumber::GetCallInfo(CSTALoggedOnEvent_t* pLogon) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pLogon->agentDevice,sizeof (SubjectDeviceID_t)); 
	return TRUE; 
} 
 
BOOL CDirectoryNumber:: GetCallInfo(CSTAOriginatedEvent_t* pOriginated) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pOriginated->callingDevice,sizeof (SubjectDeviceID_t)); 
	return TRUE; 
} 
 
BOOL CDirectoryNumber::GetCallInfo(CSTAFailedEvent_t* pFailed) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pFailed->failingDevice,sizeof (SubjectDeviceID_t)); 
	return TRUE; 
} 
 
BOOL CDirectoryNumber::GetCallInfo(CSTAConnectionClearedEvent_t* pConnclearEvnet) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	memcpy(&m_thisDevice,&pConnclearEvnet->releasingDevice,sizeof (SubjectDeviceID_t)); 
	return TRUE; 
} 
 
BOOL CDirectoryNumber::GetCallInfo(CSTAEstablishedEvent_t* pEstablishEvent) 
{ 
	memset(&m_otherDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_thisDevice,0,sizeof(ExtendedDeviceID_t)); 
	memset(&m_ani,0,sizeof(DeviceID_t)); 
	memset(&m_dnis,0,sizeof(DeviceID_t)); 
	m_callType=CT_Unknown; 
 
	BOOL bIsMyAnswer=FALSE; 
	if (strcmp((char*)&m_deviceId,(char*)&pEstablishEvent->answeringDevice.deviceID)!=0) 
		bIsMyAnswer=FALSE; 
	else bIsMyAnswer=TRUE; 
 
	if (bIsMyAnswer) 
	{ 
		memcpy(&m_otherDevice,&pEstablishEvent->callingDevice,sizeof(CalledDeviceID_t)); 
		memcpy(&m_thisDevice,&pEstablishEvent->answeringDevice,sizeof(CalledDeviceID_t)); 
		memcpy(&m_ani,&pEstablishEvent->calledDevice.deviceID,sizeof(DeviceID_t)); 
		memcpy(&m_dnis,&m_deviceId,sizeof(DeviceID_t)); 
	}else 
	{ 
		memcpy(&m_otherDevice,&pEstablishEvent->calledDevice,sizeof(CalledDeviceID_t)); 
		memcpy(&m_thisDevice,&pEstablishEvent->callingDevice,sizeof(CalledDeviceID_t)); 
		memcpy(&m_dnis,&pEstablishEvent->answeringDevice.deviceID,sizeof(DeviceID_t)); 
		memcpy(&m_ani,&m_deviceId,sizeof(DeviceID_t)); 
	} 
 
	switch (m_otherDevice.deviceIDType) 
	{ 
	case IMPLICIT_PRIVATE : 
	case EXPLICIT_PRIVATE_UNKNOWN : 
    case EXPLICIT_PRIVATE_LEVEL3_REGIONAL_NUMBER : 
    case EXPLICIT_PRIVATE_LEVEL2_REGIONAL_NUMBER : 
    case EXPLICIT_PRIVATE_LEVEL1_REGIONAL_NUMBER : 
    case EXPLICIT_PRIVATE_PTN_SPECIFIC_NUMBER : 
    case EXPLICIT_PRIVATE_LOCAL_NUMBER : 
    case EXPLICIT_PRIVATE_ABBREVIATED : 
		m_callType=CT_Internal; 
		break; 
	default: 
		if (bIsMyAnswer) 
			m_callType=CT_Inbound; 
		else  
			m_callType=CT_Outbound; 
		break; 
	} 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::MuteTransfer(BSTR dn, LPKVLIST data) 
{ 
	// TODO: Add your implementation code here 
	ATLASSERT(FALSE); 
	return TRUE; 
} 
 
//monitor the agent split 
BOOL CDirectoryNumber::MonitorSplit(AgentGroup_t* agentSplit) 
{ 
	BOOL bRet=FALSE; 
	WriteLog("Monitor split service."); 
	if (m_splitMonitorId==0) 
	{ 
		//  placed on the monitor in the monitor confirmation event. 
		CSTAMonitorFilter_t noFilter; 
		noFilter.call = 0; 
		noFilter.feature = 0; 
		noFilter.agent = 0; 
		noFilter.maintenance = 0; 
		noFilter.privateFilter = 0; 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
		RetCode_t retCode=cstaMonitorDevice(m_serverHandle,m_invokeId,agentSplit,&noFilter,NULL); 
		if (retCode>=0) 
		{ 
			MSG msg; 
			BOOL bQuit=FALSE; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					switch (msg.wParam) 
					{ 
					case CSTA_MONITOR_CONF: 
						bQuit=TRUE; 
						bRet=TRUE; 
						break; 
					case UM_APIFAILED: 
						bQuit=TRUE; 
						break; 
					} 
				} 
				if (bQuit) 
					break; 
			} 
		}else 
		{ 
			m_lErrCode=retCode; 
			m_ErrMsg="cstaMonitorDevice return an error."; 
		} 
		m_bIsCmdMsg=bSave; 
	}else 
	{ 
		bRet=TRUE; 
	} 
	if (!bRet) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return bRet; 
} 
 
void CDirectoryNumber::StopMonitor(CSTAMonitorCrossRefID_t monitorId) 
{ 
	WriteLog("Stop monitor service."); 
	if (monitorId!=0) 
	{ 
		BOOL bSave=m_bIsCmdMsg; 
		m_bIsCmdMsg=TRUE; 
		RetCode_t retCode=cstaMonitorStop(m_serverHandle,m_invokeId,monitorId,NULL); 
		if (retCode==ACSPOSITIVE_ACK) 
		{ 
			MSG msg; 
			while (GetMessage(&msg,NULL,0,0)) 
			{ 
				if (msg.message==UM_CMDMSG) 
				{ 
					if (msg.wParam==UM_APIFAILED) 
						break; 
					else if (msg.wParam ==CSTA_MONITOR_STOP_CONF) 
						break; 
				} 
			} 
		} 
	} 
	return ; 
} 
 
STDMETHODIMP CDirectoryNumber::get_HoldConnID(BSTR *pVal) 
{ 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_ActiveConnID(BSTR *pVal) 
{ 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::ID2ConnID(long id, BSTR *connid) 
{ 
	return S_OK; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::UpdateData(BSTR connid, LPKVLIST data) 
{ 
	return TRUE; 
} 
 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::DeleteData(BSTR connid, BSTR key) 
{ 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::DeleteAllData(BSTR connid) 
{ 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::AttachData(BSTR connid, LPKVLIST data) 
{ 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::CancelForward(FORWARDMODES mode) 
{ 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::Forward(BSTR dn, FORWARDMODES mode) 
{ 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::AlternateCall() 
{ 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::RedirectCall(BSTR dn, BSTR connid) 
{ 
	return TRUE; 
} 
STDMETHODIMP_(BOOL) CDirectoryNumber::MergeCalls(MERGETYPES type) 
{ 
	return TRUE; 
} 
STDMETHODIMP_(BOOL) CDirectoryNumber::DeleteFromConference(BSTR dn) 
{ 
	return TRUE; 
} 
STDMETHODIMP CDirectoryNumber::get_ErrReport(BOOL *pVal) 
{ 
	// TODO: Add your implementation code here 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_DND(BOOL *pVal) 
{ 
	// TODO: Add your implementation code here 
	return S_OK; 
} 
 
STDMETHODIMP CDirectoryNumber::get_OnHook(BOOL *pVal) 
{ 
	// TODO: Add your implementation code here 
	return S_OK; 
} 
STDMETHODIMP CDirectoryNumber::get_ACDQ(BSTR *pVal) 
{ 
	// TODO: Add your implementation code here 
	return S_OK; 
} 
STDMETHODIMP CDirectoryNumber::get_Type(ADDRTYPES *pVal) 
{ 
	// TODO: Add your implementation code here 
	return S_OK; 
} 
STDMETHODIMP CDirectoryNumber::get_Number(BSTR *pVal) 
{ 
	// TODO: Add your implementation code here 
	return S_OK; 
} 
 
BOOL CDirectoryNumber::ValidateString(char* pStr,UINT bufLen) 
{ 
	char* pTemp=new char[2*bufLen]; 
	memset(pTemp,0,2*bufLen*sizeof(char)); 
	if (pTemp) 
	{ 
		int nTempPos=0; 
		for (int nPos=0;pStr[nPos];nPos++) 
		{ 
			if (strlen(pTemp)>=bufLen) 
				break; 
			if (pStr[nPos]!='/') 
			{ 
				pTemp[nTempPos]=pStr[nPos]; 
				nTempPos++; 
			}else 
			{ 
				pTemp[nTempPos]='/'; 
				pTemp[nTempPos+1]='/'; 
				nTempPos+=2; 
			} 
		} 
		strcpy(pStr,pTemp); 
		delete pTemp; 
	} 
	return TRUE; 
} 
 
STDMETHODIMP_(BOOL) CDirectoryNumber::SendDTMF(BSTR tone) 
{ 
	// TODO: Add your implementation code here 
	BOOL ret=FALSE; 
	char pTone[40]={0}; 
	if (B2C(tone,pTone,sizeof(pTone))&&m_activeConnId.callID!=0) 
	{ 
		ATTPrivateData_t privateData={0}; 
		if (strlen(pTone)>0) 
		{ 
			RetCode_t retCode=attSendDTMFToneExt( 
								&privateData, 
								&m_activeConnId, 
								NULL,// The reciver, ignored 
								(char*)&pTone,// 
								0,// tone duration, ignored 
								0);//pause duration, ignored 
			if (retCode==ACSPOSITIVE_ACK) 
			{ 
				retCode=cstaEscapeService(m_serverHandle,m_invokeId, 
									(PrivateData_t *)&privateData); 
				if (retCode==ACSPOSITIVE_ACK) 
				{ 
					MSG msg; 
					while (GetMessage(&msg,NULL,0,0)) 
					{ 
						if (msg.message==UM_CMDMSG) 
						{ 
							if (msg.wParam==CSTA_ESCAPE_SVC_CONF) 
							{ 
								ret=TRUE; 
								break; 
							}else if (msg.wParam==UM_APIFAILED) 
							{ 
								break; 
							} 
						} 
					} 
				}else 
				{ 
					m_lErrCode=retCode; 
					m_ErrMsg="cstaEscapeService failed."; 
				} 
			}else 
			{ 
				m_lErrCode=retCode; 
				m_ErrMsg="attSendDTMFToneExt failed."; 
			} 
		}else 
			ret=TRUE; 
	}else 
	{ 
		m_lErrCode=LUCENT_INVALID_PARAM; 
		m_ErrMsg="Invalid parameter."; 
	} 
	if (!ret) 
	{ 
		char tep[300]; 
		wsprintf((char*)&tep,"error:%s,code:%d.",m_ErrMsg.c_str(),m_lErrCode); 
		WriteLog((char*)&tep); 
	} 
	return ret; 
}