/*************************************************************************** KRemoteConnect.cpp - description ------------------- begin : Tue May 2 2000 copyright : (C) 2000 by Martin Heni email : martin@heni-online.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /*************************************************************************** FILENAME| - description ------------------- begin : Tue Apr 4 2000 copyright : (C) |1995-2000 by Martin Heni email : martin@heni-online.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include "KRemoteConnect.h" #include "KRemoteConnect.moc" const char* LSKAT_SERVICE = "_lskat._tcp"; KRemoteConnect::KRemoteConnect() : KChildConnect() { port=7687; IP="localhost"; socketStatus=KR_INVALID; kSocket=0; service=0; kServerSocket=0; bufferMsg=0; buffer=new char[4097]; inputbuffer=""; input_pending=false; } KRemoteConnect::~KRemoteConnect() { Exit(); delete buffer; delete service; printf("DESTGRUCTING KRemoteConenct\n"); } KR_STATUS KRemoteConnect::QueryStatus() { return socketStatus; } bool KRemoteConnect::Init(int id,KEMessage *msg) { short prt; char *p; int size; bool tryserver; SetID(id); if (msg) { if (msg->GetData(TQCString("Port"),prt)) { port=(unsigned int)prt; msg->Remove(TQCString("Port")); } if (msg->GetData(TQCString("IP"),p,size)) { IP=TQCString(p); msg->Remove(TQCString("IP")); } if (msg->GetData(TQCString("Name"),p,size)) { Name=TQString::fromUtf8(p); msg->Remove(TQCString("Name")); } } /* printf("Connecting to %s %u (remain=%d)\n", (const char *)IP,port,msg->QueryNumberOfKeys()); */ // First try to connect to given host:socket // if no IP given only offer server tryserver=false; if (!IP.isEmpty()) { kSocket=new TDESocket(IP.latin1(),port); if (!kSocket) return false; if (kSocket->socket()!=-1) // success { kSocket->enableRead(TRUE); //kSocket->enableWrite(TRUE); connect(kSocket,TQ_SIGNAL(closeEvent(TDESocket *)), this,TQ_SLOT(socketClosed(TDESocket *))); connect(kSocket,TQ_SIGNAL(readEvent(TDESocket *)), this,TQ_SLOT(socketRead(TDESocket *))); /* connect(kSocket,TQ_SIGNAL(writeEvent(TDESocket *)), this,TQ_SLOT(socketWrite(TDESocket *))); */ /* printf("Socket(%d) %p connection built to a server\n", kSocket->socket(),kSocket); */ socketStatus=KR_CLIENT; // Send msg if any if (msg->QueryNumberOfKeys()>0) { msg->AddData(TQCString("Server"),(short)QueryID()); SendMsg(msg); } } else { tryserver=true; } } else { printf("NO IP given..only server possible\n"); tryserver=true; } if (tryserver) // become a server { delete kSocket; kSocket=0; delete service; service = 0; // Store message if (msg->QueryNumberOfKeys()>0) { bufferMsg=new KEMessage; *bufferMsg=*msg; } else { bufferMsg=0; } socketStatus=KR_WAIT_FOR_CLIENT; OfferServerSocket(); return false; } return true; } bool KRemoteConnect::OfferServerSocket() { if (kServerSocket) { return false; } kServerSocket=new KRServerSocket(port,SO_REUSEADDR); if (!kServerSocket) { socketStatus=KR_INVALID; return false; } if (kServerSocket->socket()==-1) { socketStatus=KR_NO_SOCKET; return false; } printf("Offering socket and publishing stuff\n"); service = new DNSSD::PublicService(Name,LSKAT_SERVICE,port); service->publishAsync(); connect(kServerSocket,TQ_SIGNAL(accepted(TDESocket *)), this,TQ_SLOT(socketRequest(TDESocket *))); return true; } void KRemoteConnect::socketRequest(TDESocket *sock) { if (kSocket) // already connected { delete sock; delete kServerSocket; kServerSocket=0; return ; } kSocket=sock; if (kSocket->socket()!=-1) // success { kSocket->enableRead(TRUE); //kSocket->enableWrite(TRUE); connect(kSocket,TQ_SIGNAL(closeEvent(TDESocket *)), this,TQ_SLOT(socketClosed(TDESocket *))); connect(kSocket,TQ_SIGNAL(readEvent(TDESocket *)), this,TQ_SLOT(socketRead(TDESocket *))); /* connect(kSocket,TQ_SIGNAL(writeEvent(TDESocket *)), this,TQ_SLOT(socketWrite(TDESocket *))); */ socketStatus=KR_SERVER; delete kServerSocket; // no more connections kServerSocket=0; if (bufferMsg) { // Delayed sending of init msg bufferMsg->AddData(TQCString("Client"),(short)QueryID()); SendMsg(bufferMsg); delete bufferMsg; bufferMsg=0; } } } void KRemoteConnect::socketClosed(TDESocket *sock) { delete sock; kSocket=0; socketStatus=KR_INVALID; KEMessage *msg=new KEMessage; msg->AddData(TQCString("ConnectionLost"),(short)QueryID()); emit signalReceiveMsg(msg,QueryID()); delete msg; } void KRemoteConnect::socketRead(TDESocket *sock) { ssize_t buflen; TQString s; char c; int pos; // printf("++++++ Incoming socket read +++++++\n"); if (-1==sock->socket()) return ; // printf("Read input on socket %p\n",sock); buflen=read(sock->socket(),buffer,4096); buffer[buflen]=0; // printf("Read %d byte <%s>\n",buflen,buffer); if (buflen<1) return ; if (buffer[buflen-1]!=0) // shit..we got a not null terminated string { c=buffer[buflen-1]; buffer[buflen-1]=0; s=buffer; s+=c; } else { s=buffer; } // Append old unresolved input s=inputbuffer+s; pos=s.findRev(KEMESSAGE_CR); // printf("String '%s' pos=%d len=%d\n",(const char *)s,pos,s.length()); if (pos<0) { inputbuffer=s; } else if (pos+KEMESSAGE_CR.length()==s.length()) { // CR at the end...calling receive Receive(s); } else { inputbuffer=s.right(s.length()-pos-KEMESSAGE_CR.length()); s=s.left(pos+KEMESSAGE_CR.length()); // printf("s='%s' in='%s'\n",(const char *)s,(const char *)inputbuffer); Receive(s); } } void KRemoteConnect::socketWrite(TDESocket *) { // printf("wrtie input on socket %p\n",sock); } bool KRemoteConnect::Exit() { delete kSocket; delete kServerSocket; delete bufferMsg; kSocket=0; kServerSocket=0; bufferMsg=0; socketStatus=KR_INVALID; return true; } bool KRemoteConnect::Next() { bool result; // printf("+- KRemoteConnect::Next() status=%d\n",socketStatus); if (socketStatus<=0) return false; // create and send message KEMessage *msg=new KEMessage; // User fills message emit signalPrepareMove(msg,KG_INPUTTYPE_REMOTE); result=SendMsg(msg); delete msg; return result; } // Send string to child bool KRemoteConnect::Send(TQString str) { // connected? if (!kSocket || kSocket->socket()==-1) return false; if (socketStatus<=0) return false; if (-1==write(kSocket->socket(),str.latin1(),str.length()+1)) { printf("Warning: Problems writing to socket.\n"); return false; } return true;; }