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 (r 1) { 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 }