www.pudn.com > acdx.rar > GkClient.cpp


 /*============================================================= 
 
  
 Function: 
		 
 
 
 Author: Leon Wang  
==============================================================*/ 
// GkClient.cpp: implementation of the GkClient class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "GkClient.h" 
#include "acdx.h" 
#include "h323utils.h" 
 
#include  
#include  
#include  
 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
//##ModelId=42198D180097 
class ACDX; 
class H323Utils; 
 
//using namespace std; 
//##ModelId=424BB6460130 
long GkClient::WAIT_SEC = 5;// wait 5 seconds before reconnecting to GnuGk 
 
//##ModelId=424BB6460017 
GkClient::GkClient() 
{ 
	//splitFields_cmd.reserve(10);// for gk command 
	//splitFields_alia.reserve(4);// for alias 
	stopped = FALSE; 
	m_buf = NULL; 
} 
 
//##ModelId=424BB6460018 
GkClient::GkClient(ACDX* p, DWORD ip, int port) 
{ 
	m_buf = NULL; 
} 
 
//##ModelId=424BB64600B3 
GkClient::~GkClient() 
{ 
 
} 
 
//##ModelId=424BB6460007 
unsigned __stdcall  GkClient::_RUN(void *p) 
{ 
	GkClient * pThis = (GkClient*)p; 
	pThis->RUN(); 
	delete pThis; 
	return 0;	 
} 
 
//##ModelId=424BB64503E1 
void GkClient::RUN() 
{ 
	//DWORD ip = inet_addr("192.168.1.43"); 
	//open socket 
	while (!stopped) { 
		// connect GK port  
		int rv; 
		GK_socket = socket(AF_INET, SOCK_STREAM,0); 
		if(GK_socket == ~0){ 
			printErrorMessage(); 
			closesocket(GK_socket); 
			return ; 
		} 
 
 
		struct sockaddr_in sin = {0}; 
		sin.sin_family = AF_INET; 
		sin.sin_addr.s_addr = inet_addr(host); 
		sin.sin_port = htons(port); 
 
		rv = connect(GK_socket, (struct sockaddr*)&sin,sizeof(sin)); 
		if(rv != 0){ 
			printErrorMessage(); 
			closesocket(GK_socket); 
			return ; 
		} 
         router->clearAllAliasStates();// clear list 
         refresh();	// get initial gk status 
		 Logger::log("Connection established."); 
 
 
		while (parseMessage());//-----> need debug this function 
		 
 
	} 
 
} 
 
//##ModelId=424BB64600A4 
void GkClient::init(ACDX* _store, CString _host, int _port) 
{ 
        router = _store; 
		host = _host; 
		port = _port; 
} 
 
/** 
* Stop this thread. 
*/ 
//##ModelId=424BB6460096 
void GkClient::stop() 
{ 
	stopped = TRUE; 
	close(); 
} 
 
/** 
* close connection to GnuGk. 
*/ 
//##ModelId=424BB6460095 
void GkClient::close() 
{ 
	//close net io socket 
	if (GK_socket!=NULL) { 
		closesocket(GK_socket); 
	} 
 
} 
 
 /** 
 * Split GnuGk events into files (separated by pipe char). 
 * @param aString   string to split 
 * @return          array of fields 
 */ 
//##ModelId=424BB6460086 
void GkClient::splitFields(CString aString,cstring_vec_t &splitFields) 
{ 
	if (!splitFields.empty()) { 
		splitFields.clear();// clear all element 
	} 
	 
	int flag_number = aString.Find('|'); 
	if (flag_number==-1) { 
		return ; 
	} 
 
	// parse gk info 
     
     //	find '|'  split those string in a vector 
	 //	no '|' work over return vector	 
     // 
	while (flag_number!=-1) { 
		 CString needSection = aString.Left(flag_number); 
		 aString = aString.Mid(flag_number+1); 
		 flag_number = aString.Find('|'); 
		 splitFields.push_back(needSection); 
		 // last element 
		 if (flag_number == -1) { 
			splitFields.push_back(aString); 
			break; 
		 } 
		 needSection.FreeExtra(); 
	} 
 
} 
 
/** 
 * Split GnuGk list of aliases (separated by equals char). 
 * @param aString   string to split 
 * @return          array of aliases 
 */ 
//##ModelId=424BB6460077 
void GkClient::splitAliases(CString aString,cstring_vec_t & splitFields ) 
{ 
	if (!splitFields.empty()) { 
		splitFields.clear();// clear all element 
	} 
	 
	int flag_number = aString.Find('='); 
	if (flag_number==-1) { 
		splitFields.push_back(aString); 
		return ; 
	} 
 
	// parse alias string 
     
     //	find '='  split those string in a vector 
	 //	no '=' work over return vector	 
     // 
	while (flag_number!=-1) { 
		 CString needSection = aString.Left(flag_number); 
		 aString = aString.Mid(flag_number+1); 
		 flag_number = aString.Find('='); 
		 splitFields.push_back(needSection); 
		 // last element 
		 if (flag_number == -1) { 
			splitFields.push_back(aString); 
			break; 
		 } 
		 needSection.FreeExtra(); 
	} 
 
} 
 
//##ModelId=424BB6460076 
void GkClient::refresh() 
{ 
	getCurrentRegistrations(); 
	getCurrentCalls(); 
} 
 
//##ModelId=424BB6460075 
void GkClient::getCurrentRegistrations() 
{ 
    sendGkCommand("PrintAllRegistrations"); 
} 
 
//##ModelId=424BB6460068 
void GkClient::getCurrentCalls() 
{ 
	sendGkCommand("PrintCurrentCalls"); 
} 
 
//##ModelId=424BB6460066 
void GkClient::disconnectEndpoint(CString _epid) 
{ 
	sendGkCommand("DisconnectEndpoint " + _epid); 
} 
 
//##ModelId=424BB6460057 
void GkClient::disconnectAlias(CString _alias) 
{ 
	sendGkCommand("DisconnectAlias " + H323Utils::extractAliasName(_alias)); 
} 
 
//##ModelId=424BB6460055 
void GkClient::unregisterAlias(CString _alias) 
{ 
	sendGkCommand("UnregisterAlias " + H323Utils::extractAliasName(_alias)); 
} 
 
//##ModelId=424BB6460048 
void GkClient::makeCall(CString _epid, CString _destination) 
{ 
	sendGkCommand("MakeCall " + _epid + " " + _destination); 
} 
    /** 
     * Send TransferCall command to GnuGk. 
     * @param _alias        alias to stay in call 
     * @param _destination  new destination to transfer the call to 
	 */ 
//##ModelId=424BB6460039 
void GkClient::transferCall(CString _alias, CString _destination) 
{ 
	sendGkCommand("TransferCall " + H323Utils::extractAliasName(_alias) + " " + H323Utils::extractAliasName(_destination)); 
} 
 
 /** 
     * send RouteToAlias response to GnuGk. 
     * @param _alias        endpoint alias 
     * @param callingEpId   endpoint ID of calling endpoint 
     * @param callRef       call reference 
     */ 
//##ModelId=424BB646002A 
void GkClient::routeToAlias(CString _alias, CString callingEpId, CString callRef) 
{ 
	sendGkCommand("RouteToAlias " + H323Utils::extractAliasName(_alias) + " " + callingEpId + " " + callRef); 
} 
 
//##ModelId=424BB6460027 
void GkClient::routeReject(CString callingEpId, CString callRef) 
{ 
	sendGkCommand("RouteReject " + callingEpId + " " + callRef); 
} 
 
/** 
 helper function to send bytes to GnuGk. 
 @param cmd             
        ACDX--->  GK 
*/ 
//##ModelId=42198D180122 
// open socket connect GK and send info to GK 
//##ModelId=424BB64600E4 
void GkClient::sendGkCommand(CString cmd) 
{ 
	Logger::debug("ACD->GK:" + cmd); 
	// ostream.write((cmd + "\r\n").getBytes());	 
	// use socket send back info 
	cmd = cmd + "\n"; 
	//cmd = "r\n";//test code 
	LPTSTR m_buf_s = cmd.GetBuffer(cmd.GetLength()); 
	send(GK_socket,m_buf_s,cmd.GetLength(),0); // (char*)&m_buf is error 
	cmd.ReleaseBuffer(); 
} 
 
//##ModelId=424BB64600D2 
void GkClient::printErrorMessage() 
{ 
	LPTSTR lpMsgBuf; 
	FormatMessage(  
		FORMAT_MESSAGE_ALLOCATE_BUFFER |  
		FORMAT_MESSAGE_FROM_SYSTEM |  
		FORMAT_MESSAGE_IGNORE_INSERTS, 
		NULL, 
		GetLastError(), 
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 
		(LPTSTR) &lpMsgBuf, 
		0, 
		NULL  
		); 
	// Process any inserts in lpMsgBuf. 
	// ... 
	// Display the string. 
	//printf("%S\n", (LPCTSTR)lpMsgBuf); 
	CString msg(lpMsgBuf); 
	Logger::debug(msg); 
	// Free the buffer. 
	LocalFree( lpMsgBuf ); 
 
} 
/* 
 *	read all gk 7000 port info and response it 
 */ 
//##ModelId=424BB64600C4 
BOOL GkClient::parseMessage() 
{ 
 
	int r = recv(GK_socket, (char*)&m_buf, sizeof(m_buf), 0); 
	if(r == 0){ 
		printErrorMessage(); 
		return FALSE; 
	} 
	if(r == SOCKET_ERROR){ 
		printErrorMessage(); 
		return FALSE; 
	} 
	 
    CString recvString((char*)&m_buf); 
	m_buf = NULL;// leon [3/30/2005]***** hi set this can let m_buf clear char 
 
	//save '\r\n' don't use trim function at here 
 
 
	if (recvString.Find(';') != -1)  
	{ 
		GKecho =  GKecho + recvString + "\r\n"; 
	} 
	else 
	{ 
		GKecho =  GKecho + recvString; 
	} 
	 
 
	recvString = ""; 
	recvString.FreeExtra(); 
 
 
	//if receive over 
	if (r1) { 
				Logger::debug(GKecho); 
				GKecho = ""; 
			} 
			// for readline command 
			std::vector::iterator everyLine; 
			CString cmd = ""; 
			for(everyLine = semicolonlist.begin();everyLine!=semicolonlist.end();everyLine++) 
			{ 
				cmd = *everyLine;//every line command 
				// clear \r\n char 
				cmd.TrimLeft(); 
				cmd.TrimRight(); 
				cstring_vec_t vec_flag; 
				splitFields(cmd,vec_flag); 
				cmd = ""; 
				// flush view 
				//find vector of command line info and get command type do logic 
				if (vec_flag.empty()) { 
					return TRUE; 
				} 
				std::vector::iterator vec_element; 
				//vec_element = std::find (vec_flag.begin(), vec_flag.end(), "RCF");  
				vec_element = vec_flag.begin(); 
				//RCF endpoint register confirm 
				if ((CString)(*vec_element)== ("RCF")) { 
					if (vec_flag.size()>=5) { 
						 CString epid = vec_flag[4]; 
						 // extract _list_ of aliases and add all! 
						 cstring_vec_t vec_alias; 
						 splitAliases(vec_flag[2],vec_alias); 
 
							for (int i=0; i < vec_alias.size(); i++) { 
							   router->addAlias(vec_alias[i], epid); 
							}					 
					} 
				}// Disengage Confirm 
				else if ((CString)(*vec_element)== ("DCF")) { 
					if (vec_flag.size()>=3) { 
							CString epid = vec_flag[2]; 
							CString crv = vec_flag[3];     // identify by epid + CRV 
							router->setAliasAvailable(epid, crv); 
					} 
				 
				} 
				//Unregistration Confirm 
				else if ((CString)(*vec_element)== ("UCF")) { 
					if (vec_flag.size()>=3) { 
						CString epid = vec_flag[2];      // remove _all_ aliases for this epid 
						router->removeAllAliases(epid); 
					} 
				} 
				// answer confirm  
				else if ((CString)(*vec_element)== ("ACF")) { 
					if (vec_flag.size()>=3) { 
							CString crv = vec_flag[3];       // remember CRV for DCF 
							cstring_vec_t vec_alias; 
							splitAliases(vec_flag[4],vec_alias);// destinationInfo 
							//String [] alias = splitAliases(msgField[4]);     
 
							for (int i=0; i < vec_alias.size(); i++)  
							{ 
								router->setAliasTalking(vec_alias[i], crv); 
							} 
							splitAliases(vec_flag[5],vec_alias);// srcInfo 
							//alias = splitAliases(msgField[5]);    // srcInfo 
							for (int j=0; j < vec_alias.size(); j++)  
							{ 
								router->setAliasTalking(vec_alias[j], crv); 
							} 
 
					} 
				} 
				// vqueue  route request 
				else if ((CString)(*vec_element)== ("RouteRequest")) 
				{ 
					if (vec_flag.size()>=6) { 
						  CString callingEpId = vec_flag[2]; 
						  CString callref = vec_flag[3]; 
						  CString queue = vec_flag[4]; 
						  router->routeCall(queue, callingEpId, callref, vec_flag[5], vec_flag[1] ); 
					}			 
				 
				} 
 
			} 
		} 
 
	return TRUE; 
} 
// read line 
//##ModelId=424BB64600D3 
void GkClient::parseSemicolon(cstring_vec_t &semicolonlist,CString gkEcho) 
{ 
	semicolonlist.reserve(10); 
	do { 
		CString t = gkEcho.Left(gkEcho.Find("\r\n"));// find each line 
		// have cmd 
		if (gkEcho.Find('|') ==-1) { 
			break; 
		} 
		//cut head have cmd 
		if (t.Find('|') == -1) { 
			gkEcho = gkEcho.Mid(gkEcho.Find("\r\n")+2);//next line 
			continue; 
		} 
		// cut ';' 
		if (t.Find(';') != -1 ) { 
			t = t.Left(t.Find(';')); 
		} 
		// now parse line by '\r\n' with ras cmd 
		semicolonlist.push_back(t); 
		//printf(t+"\r\n");// next line 
		gkEcho = gkEcho.Mid(gkEcho.Find("\r\n")+2); 
	}while (gkEcho.Find("\r\n")!= -1);//if have line 
 
}