mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-16 03:14:31 -05:00
87344de7d4
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1850 b45a01b8-16f6-495d-af2f-9b41ad6348cc
339 lines
8.2 KiB
C++
339 lines
8.2 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2008 by normal *
|
|
* normal@Desktop2 *
|
|
* *
|
|
* 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. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
#include "ConnectionI2P.h"
|
|
|
|
cConnectionI2P::cConnectionI2P(
|
|
QString SamHost,
|
|
QString SamPort,
|
|
SESSION_Types::SESSION_STYLE SessionStyle,
|
|
QString SessionDestination,
|
|
SESSION_Types::SESSION_DIRECTION SessionDirection,
|
|
QString SessionOptions,
|
|
QObject *parent)
|
|
:SamHost(SamHost),SamPort(SamPort),SessionStyle(SessionStyle),SessionDestination(SessionDestination),
|
|
SessionDirection(SessionDirection),SessionOptions(SessionOptions)//, QObject(parent)
|
|
{
|
|
|
|
IncomingPackets= new QByteArray();
|
|
tcpSocket= new QTcpSocket(parent);
|
|
|
|
tcpSocket->moveToThread(this->thread());
|
|
|
|
Analyser= new I2PSamMessageAnalyser();
|
|
this->HandShakeWasSuccesfullDone=false;
|
|
this->SessionWasSuccesfullCreated=false;
|
|
this->nextFreeID=1;
|
|
|
|
connect(tcpSocket,SIGNAL(connected() ),this,SLOT(connected() ),Qt::DirectConnection );
|
|
connect(tcpSocket,SIGNAL(readyRead() ),this, SLOT(readFromSocket()),Qt::DirectConnection);
|
|
|
|
}
|
|
|
|
cConnectionI2P::~cConnectionI2P()
|
|
{
|
|
doDisconnect();
|
|
delete tcpSocket;
|
|
delete Analyser;
|
|
}
|
|
void cConnectionI2P::doConnect()
|
|
{
|
|
|
|
if(tcpSocket->state()==QAbstractSocket::UnconnectedState)
|
|
{
|
|
tcpSocket->connectToHost(SamHost,SamPort.toInt( ));
|
|
}
|
|
if(!tcpSocket->waitForConnected(1000))
|
|
doDisconnect();
|
|
|
|
}
|
|
|
|
void cConnectionI2P::doDisconnect()
|
|
{
|
|
|
|
if(tcpSocket->state()!=0)
|
|
{
|
|
tcpSocket->disconnectFromHost();
|
|
emit debugMessages("<-- I2P Socket Disconnected -->\n");
|
|
}
|
|
else if(tcpSocket->state()==QAbstractSocket::UnconnectedState)
|
|
emit debugMessages("<-- I2P Socket Disconnected -->\n");
|
|
|
|
this->nextFreeID=1;
|
|
}
|
|
|
|
void cConnectionI2P::connected()
|
|
{
|
|
|
|
emit debugMessages("<-- I2P Socket Connected -->\n");
|
|
//emit debugMessages("<-- SAM Connection Handshake send -->\n");
|
|
emit debugMessages(SAM_HANDSHAKE);
|
|
|
|
if(tcpSocket->state()==QAbstractSocket::ConnectedState)
|
|
{
|
|
tcpSocket->write(SAM_HANDSHAKE);
|
|
tcpSocket->flush();
|
|
}
|
|
}
|
|
|
|
void cConnectionI2P::readFromSocket()
|
|
{
|
|
|
|
|
|
|
|
using namespace SAM_Message_Types;
|
|
|
|
QByteArray newData =tcpSocket->readAll();
|
|
|
|
QByteArray CurrentPacket;
|
|
IncomingPackets->append(newData);
|
|
|
|
|
|
while(IncomingPackets->contains("\n")==true){
|
|
|
|
CurrentPacket=IncomingPackets->left(IncomingPackets->indexOf("\n",0)+1);
|
|
//else return;//Not the complead Packet recived ??? maybe possible ???
|
|
|
|
QString t(CurrentPacket.data());
|
|
|
|
SAM_MESSAGE sam=Analyser->Analyse(t);
|
|
switch(sam.type)
|
|
{ //emit the signals
|
|
case HELLO_REPLAY:{
|
|
emit debugMessages(t);
|
|
emit HelloReplayRecived(sam.result);
|
|
if(sam.result==OK){
|
|
this->HandShakeWasSuccesfullDone=true;
|
|
doSessionCreate();
|
|
}
|
|
break;
|
|
}
|
|
case SESSION_STATUS:{
|
|
emit debugMessages(t);
|
|
if(sam.result==OK)this->SessionWasSuccesfullCreated=true;
|
|
|
|
emit SessionStatusRecived(sam.result,sam.Destination,sam.Message);
|
|
break;
|
|
}
|
|
case STREAM_STATUS:{
|
|
emit debugMessages(t);
|
|
if(sam.result==OK)
|
|
this->doSendStreamSessionLimit(sam.ID,0);
|
|
|
|
emit StreamStatusRecived(sam.result,sam.ID,sam.Message);
|
|
break;
|
|
}
|
|
case STREAM_CONNECTED:{
|
|
emit debugMessages(t);
|
|
|
|
this->doSendStreamSessionLimit(sam.ID,0);
|
|
|
|
emit StreamConnectedRecived(sam.Destination,sam.ID);
|
|
break;
|
|
}
|
|
case STREAM_CLOSED:{
|
|
emit debugMessages(t);
|
|
emit StreamClosedRecived(sam.result,sam.ID,sam.Message);
|
|
break;
|
|
}
|
|
case STREAM_SEND:{
|
|
emit debugMessages(t);
|
|
emit StreamSendRecived(sam.ID,sam.result,sam.state);
|
|
break;
|
|
}
|
|
|
|
case STREAM_READY_TO_SEND:{
|
|
emit debugMessages(t);
|
|
emit StreamReadyToSendRecived(sam.ID);
|
|
break;
|
|
}
|
|
case NAMING_REPLY:{
|
|
emit debugMessages(t);
|
|
emit NamingReplyRecived(sam.result,sam.Name,sam.Value,sam.Message);
|
|
break;
|
|
}
|
|
case STREAM_RECEIVED:{
|
|
|
|
if( sam.Size.toLong() > (IncomingPackets->length() - CurrentPacket.length()) )
|
|
return;//Not the complead Packet recived ??? maybe possible ???
|
|
|
|
QByteArray Data=IncomingPackets->mid(CurrentPacket.length(),sam.Size.toLong());
|
|
emit debugMessages(t+Data);
|
|
emit StreamDataRecived(sam.ID,sam.Size,Data);
|
|
IncomingPackets->remove(CurrentPacket.length(),sam.Size.toLong());
|
|
break;
|
|
}
|
|
|
|
|
|
case ERROR_IN_ANALYSE:{
|
|
emit debugMessages("<ERROR_IN_ANALYSE>\n"+t);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
emit debugMessages("<Unknown Packet>\n"+t);
|
|
break;
|
|
}
|
|
}
|
|
IncomingPackets->remove(0,IncomingPackets->indexOf("\n",0)+1);
|
|
}//while
|
|
}
|
|
|
|
void cConnectionI2P::doSessionCreate(){
|
|
using namespace SESSION_Types;
|
|
ConnectionReadyCheck();
|
|
|
|
QByteArray Message="SESSION CREATE STYLE=";
|
|
|
|
switch(this->SessionStyle)
|
|
{
|
|
case STREAM:
|
|
{
|
|
Message+="STREAM";
|
|
break;
|
|
}
|
|
case DATAGRAMM:
|
|
{
|
|
Message+="DATAGRAMM";
|
|
break;
|
|
}
|
|
case RAW:
|
|
{
|
|
Message+="RAW";
|
|
break;
|
|
}
|
|
}
|
|
|
|
Message+=" DESTINATION="+this->SessionDestination+" DIRECTION=";
|
|
|
|
switch(this->SessionDirection)
|
|
{
|
|
case BOTH:
|
|
{
|
|
Message+="BOTH";
|
|
break;
|
|
}
|
|
case RECEIVE:
|
|
{
|
|
Message+="RECEIVE";
|
|
break;
|
|
}
|
|
case CREATE:
|
|
{
|
|
Message+="CREATE";
|
|
break;
|
|
}
|
|
}
|
|
if(this->SessionOptions.isEmpty()==false)
|
|
Message+=" "+SessionOptions;
|
|
|
|
Message+="\n";
|
|
|
|
//emit debugMessages("<-Send Create Session Message->\n");
|
|
emit debugMessages(Message);
|
|
|
|
tcpSocket->write(Message);
|
|
tcpSocket->flush();
|
|
|
|
}
|
|
|
|
qint32 cConnectionI2P::get_NextFreeId()
|
|
{
|
|
return nextFreeID++;
|
|
}
|
|
|
|
qint32 cConnectionI2P::doStreamConnect(QString Destination)
|
|
{
|
|
|
|
ConnectionReadyCheck();
|
|
qint32 ID=get_NextFreeId();
|
|
|
|
QByteArray Message="STREAM CONNECT ID=";
|
|
Message+=QString::number(ID,10);
|
|
Message+=" DESTINATION="+Destination+"\n";
|
|
|
|
emit debugMessages(Message);
|
|
tcpSocket->write(Message);
|
|
tcpSocket->flush();
|
|
return ID;
|
|
}
|
|
|
|
void cConnectionI2P::doStreamClose(qint32 ID)
|
|
{
|
|
ConnectionReadyCheck();
|
|
QByteArray Message="STREAM CLOSE ID=";
|
|
Message+=QString::number(ID,10)+"\n";
|
|
|
|
emit debugMessages(Message);
|
|
tcpSocket->write(Message);
|
|
tcpSocket->flush();
|
|
}
|
|
|
|
void cConnectionI2P::doSendStreamSessionLimit(qint32 ID,quint64 value)
|
|
{
|
|
ConnectionReadyCheck();
|
|
QByteArray Message="STREAM RECEIVE ID=";
|
|
Message+=QString::number(ID,10)+" LIMIT=";
|
|
if(value==0)
|
|
Message+="NONE\n";
|
|
else
|
|
{
|
|
QString Svalue;
|
|
Svalue.setNum(value,10);
|
|
Message+=Svalue+"\n";
|
|
}
|
|
emit debugMessages(Message);
|
|
tcpSocket->write(Message);
|
|
tcpSocket->flush();
|
|
}
|
|
void cConnectionI2P::doStreamSend(qint32 ID,QString Data)
|
|
{
|
|
QByteArray t="";
|
|
t.insert(0,Data);
|
|
doStreamSend(ID,t);
|
|
}
|
|
void cConnectionI2P::doStreamSend(qint32 ID,QByteArray Data)
|
|
{
|
|
ConnectionReadyCheck();
|
|
|
|
QString Size;
|
|
Size.setNum(Data.length());
|
|
|
|
QByteArray Message="STREAM SEND ID=";
|
|
Message+=QString::number(ID,10)+" SIZE="+Size+"\n";
|
|
Message.append(Data+="\n");
|
|
|
|
emit debugMessages(Message);
|
|
tcpSocket->write(Message);
|
|
tcpSocket->flush();
|
|
|
|
}
|
|
void cConnectionI2P::doNamingLookUP(QString Name)
|
|
{
|
|
|
|
ConnectionReadyCheck();
|
|
|
|
QByteArray Message="NAMING LOOKUP NAME=";
|
|
Message+=Name+"\n";
|
|
emit debugMessages(Message);
|
|
tcpSocket->write(Message);
|
|
tcpSocket->flush();
|
|
|
|
}
|