mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-06 20:45:54 +01:00
fold reading into send socket
This commit is contained in:
parent
81583e30b5
commit
36b4b593e7
2 changed files with 161 additions and 36 deletions
|
@ -33,14 +33,17 @@ const TInt KMaxMsgLen = 512;
|
||||||
class CSendSocket : public CActive {
|
class CSendSocket : public CActive {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CSendSocket* NewL();
|
|
||||||
|
typedef void (*ReadNotifyCallback)( const TDesC8* aBuf,
|
||||||
|
void *aClosure );
|
||||||
|
static CSendSocket* NewL( ReadNotifyCallback aCallback, void* aClosure );
|
||||||
|
|
||||||
~CSendSocket();
|
~CSendSocket();
|
||||||
|
|
||||||
TBool SendL( const XP_U8* aBuf, XP_U16 aLen, const CommsAddrRec* aAddr );
|
TBool SendL( const XP_U8* aBuf, XP_U16 aLen, const CommsAddrRec* aAddr );
|
||||||
|
TBool Listen();
|
||||||
|
|
||||||
void ConnectL();
|
void ConnectL( const CommsAddrRec* aAddr );
|
||||||
void ConnectL( TUint32 aIpAddr );
|
|
||||||
|
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -48,15 +51,21 @@ class CSendSocket : public CActive {
|
||||||
void DoCancel(); /* from CActive */
|
void DoCancel(); /* from CActive */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSendSocket();
|
CSendSocket( ReadNotifyCallback aCallback, void* aClosure );
|
||||||
void ConstructL();
|
void ConstructL();
|
||||||
void DoActualSend();
|
void DoActualSend();
|
||||||
|
|
||||||
|
void ConnectL();
|
||||||
|
void ConnectL( TUint32 aIpAddr );
|
||||||
|
|
||||||
|
TBool CancelListen();
|
||||||
|
|
||||||
enum TSSockState { ENotConnected
|
enum TSSockState { ENotConnected
|
||||||
,ELookingUp
|
,ELookingUp
|
||||||
,EConnecting
|
,EConnecting
|
||||||
,EConnected
|
,EConnected
|
||||||
,ESending
|
,ESending
|
||||||
|
,EListening
|
||||||
};
|
};
|
||||||
|
|
||||||
TSSockState iSSockState;
|
TSSockState iSSockState;
|
||||||
|
@ -65,10 +74,17 @@ class CSendSocket : public CActive {
|
||||||
RHostResolver iResolver;
|
RHostResolver iResolver;
|
||||||
TInetAddr iAddress;
|
TInetAddr iAddress;
|
||||||
TBuf8<KMaxMsgLen> iSendBuf;
|
TBuf8<KMaxMsgLen> iSendBuf;
|
||||||
|
TInt iDataLen; /* How big should next packet be */
|
||||||
|
TUint8 iInBuf[KMaxMsgLen];
|
||||||
|
TPtr8* iInBufDesc; /* points to above buffer */
|
||||||
CommsAddrRec iCurAddr;
|
CommsAddrRec iCurAddr;
|
||||||
TNameEntry iNameEntry;
|
TNameEntry iNameEntry;
|
||||||
TNameRecord iNameRecord;
|
TNameRecord iNameRecord;
|
||||||
TBool iAddrSet;
|
TBool iAddrSet;
|
||||||
|
TBool iListenPending;
|
||||||
|
|
||||||
|
ReadNotifyCallback iCallback;
|
||||||
|
void* iClosure;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,11 +29,12 @@ CSendSocket::RunL()
|
||||||
XP_LOGF( "CSendSocket::RunL called; iStatus=%d", iStatus.Int() );
|
XP_LOGF( "CSendSocket::RunL called; iStatus=%d", iStatus.Int() );
|
||||||
/* iSendTimer.Cancel(); */
|
/* iSendTimer.Cancel(); */
|
||||||
|
|
||||||
|
TBool statusGood = iStatus.Int() == KErrNone;
|
||||||
switch ( iSSockState ) {
|
switch ( iSSockState ) {
|
||||||
case ELookingUp:
|
case ELookingUp:
|
||||||
iResolver.Close(); /* we probably won't need this again */
|
iResolver.Close(); /* we probably won't need this again */
|
||||||
XP_ASSERT( iStatus.Int() == KErrNone );
|
XP_ASSERT( iStatus.Int() == KErrNone );
|
||||||
if ( iStatus == KErrNone ) {
|
if ( statusGood ) {
|
||||||
iNameRecord = iNameEntry();
|
iNameRecord = iNameEntry();
|
||||||
XP_LOGF( "name resolved: now:" );
|
XP_LOGF( "name resolved: now:" );
|
||||||
ConnectL( TInetAddr::Cast(iNameRecord.iAddr).Address() );
|
ConnectL( TInetAddr::Cast(iNameRecord.iAddr).Address() );
|
||||||
|
@ -41,28 +42,95 @@ CSendSocket::RunL()
|
||||||
break;
|
break;
|
||||||
case EConnecting:
|
case EConnecting:
|
||||||
XP_ASSERT( iStatus.Int() == KErrNone );
|
XP_ASSERT( iStatus.Int() == KErrNone );
|
||||||
if ( iStatus == KErrNone ) {
|
if ( statusGood ) {
|
||||||
iSSockState = EConnected;
|
iSSockState = EConnected;
|
||||||
XP_LOGF( "connect successful" );
|
XP_LOGF( "connect successful" );
|
||||||
if ( iSendBuf.Length() > 0 ) {
|
if ( iSendBuf.Length() > 0 ) {
|
||||||
DoActualSend();
|
DoActualSend();
|
||||||
|
} else if ( iListenPending ) {
|
||||||
|
Listen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ESending:
|
case ESending:
|
||||||
XP_ASSERT( iStatus.Int() == KErrNone );
|
XP_ASSERT( iStatus.Int() == KErrNone );
|
||||||
if ( iStatus == KErrNone ) {
|
if ( statusGood ) {
|
||||||
iSSockState = EConnected;
|
iSSockState = EConnected;
|
||||||
iSendBuf.SetLength(0);
|
iSendBuf.SetLength(0);
|
||||||
XP_LOGF( "send successful" );
|
XP_LOGF( "send successful" );
|
||||||
|
|
||||||
|
if ( iListenPending ) {
|
||||||
|
Listen();
|
||||||
|
}
|
||||||
|
|
||||||
/* Send was successful. Need to tell anybody? Might want to
|
/* Send was successful. Need to tell anybody? Might want to
|
||||||
update display somehow. */
|
update display somehow. */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EListening:
|
||||||
|
if ( statusGood ) {
|
||||||
|
if ( iDataLen == 0 ) {
|
||||||
|
/* Do nothing; we need to read again via Listen call */
|
||||||
|
iDataLen = XP_NTOHS( *(XP_U16*)iInBufDesc->Ptr() );
|
||||||
|
XP_LOGF( "Recv succeeded with length; now looking for %d byte packet",
|
||||||
|
iDataLen );
|
||||||
|
} else {
|
||||||
|
iDataLen = 0;
|
||||||
|
XP_LOGF( "Got packet! Calling callback" );
|
||||||
|
(*iCallback)( iInBufDesc, iClosure );
|
||||||
|
}
|
||||||
|
iSSockState = EConnected;
|
||||||
|
Listen(); /* go back to listening */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} /* RunL */
|
} /* RunL */
|
||||||
|
|
||||||
|
TBool
|
||||||
|
CSendSocket::Listen()
|
||||||
|
{
|
||||||
|
XP_LOGF( "CSendSocket::Listen" );
|
||||||
|
TBool result;
|
||||||
|
iListenPending = ETrue;
|
||||||
|
|
||||||
|
if ( IsActive() ) {
|
||||||
|
if ( iSSockState == ESending ) {
|
||||||
|
result = ETrue;
|
||||||
|
}
|
||||||
|
result = EFalse;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if ( iSSockState == ENotConnected ) {
|
||||||
|
ConnectL();
|
||||||
|
} else {
|
||||||
|
delete iInBufDesc;
|
||||||
|
|
||||||
|
TInt seekLen = iDataLen == 0? 2: iDataLen;
|
||||||
|
iInBufDesc = new TPtr8( iInBuf, seekLen );
|
||||||
|
XP_LOGF( "calling iSendSocket.Recv; looking for %d bytes",
|
||||||
|
iInBufDesc->MaxSize() );
|
||||||
|
iSendSocket.Recv( *iInBufDesc, 0, iStatus );
|
||||||
|
|
||||||
|
SetActive();
|
||||||
|
iSSockState = EListening;
|
||||||
|
result = ETrue;
|
||||||
|
iListenPending = EFalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} /* Listen */
|
||||||
|
|
||||||
|
TBool
|
||||||
|
CSendSocket::CancelListen()
|
||||||
|
{
|
||||||
|
TBool result = iSSockState == EListening;
|
||||||
|
if ( result ) {
|
||||||
|
XP_ASSERT( IsActive() );
|
||||||
|
Cancel();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} /* CancelListen */
|
||||||
|
|
||||||
void
|
void
|
||||||
CSendSocket::DoCancel()
|
CSendSocket::DoCancel()
|
||||||
{
|
{
|
||||||
|
@ -75,13 +143,21 @@ CSendSocket::DoCancel()
|
||||||
} else if ( iSSockState == ELookingUp ) {
|
} else if ( iSSockState == ELookingUp ) {
|
||||||
iResolver.Cancel();
|
iResolver.Cancel();
|
||||||
iResolver.Close();
|
iResolver.Close();
|
||||||
|
} else if ( iSSockState == EListening ) {
|
||||||
|
iSendSocket.CancelRecv();
|
||||||
}
|
}
|
||||||
} /* DoCancel */
|
} /* DoCancel */
|
||||||
|
|
||||||
CSendSocket::CSendSocket()
|
CSendSocket::CSendSocket( ReadNotifyCallback aCallback,
|
||||||
|
void* aClosure )
|
||||||
: CActive(EPriorityStandard)
|
: CActive(EPriorityStandard)
|
||||||
,iSSockState(ENotConnected)
|
,iSSockState(ENotConnected)
|
||||||
,iAddrSet( EFalse )
|
,iAddrSet( EFalse )
|
||||||
|
,iCallback(aCallback)
|
||||||
|
,iClosure(aClosure)
|
||||||
|
,iListenPending(EFalse)
|
||||||
|
,iInBufDesc( NULL )
|
||||||
|
,iDataLen( 0 )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,9 +178,9 @@ CSendSocket::ConstructL()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ CSendSocket*
|
/*static*/ CSendSocket*
|
||||||
CSendSocket::NewL()
|
CSendSocket::NewL( ReadNotifyCallback aCallback, void* aClosure )
|
||||||
{
|
{
|
||||||
CSendSocket* me = new CSendSocket();
|
CSendSocket* me = new CSendSocket( aCallback, aClosure );
|
||||||
CleanupStack::PushL( me );
|
CleanupStack::PushL( me );
|
||||||
me->ConstructL();
|
me->ConstructL();
|
||||||
CleanupStack::Pop( me );
|
CleanupStack::Pop( me );
|
||||||
|
@ -117,7 +193,7 @@ CSendSocket::ConnectL( TUint32 aIpAddr )
|
||||||
XP_LOGF( "ConnectL( 0x%x )", aIpAddr );
|
XP_LOGF( "ConnectL( 0x%x )", aIpAddr );
|
||||||
|
|
||||||
TInt err = iSendSocket.Open( iSocketServer, KAfInet,
|
TInt err = iSendSocket.Open( iSocketServer, KAfInet,
|
||||||
KSockDatagram, KProtocolInetUdp );
|
KSockStream, KProtocolInetTcp );
|
||||||
XP_LOGF( "iSocket.Open => %d", err );
|
XP_LOGF( "iSocket.Open => %d", err );
|
||||||
User::LeaveIfError( err );
|
User::LeaveIfError( err );
|
||||||
|
|
||||||
|
@ -126,6 +202,7 @@ CSendSocket::ConnectL( TUint32 aIpAddr )
|
||||||
iAddress.SetAddress( aIpAddr );
|
iAddress.SetAddress( aIpAddr );
|
||||||
|
|
||||||
// Initiate socket connection
|
// Initiate socket connection
|
||||||
|
XP_LOGF( "calling iSendSocket.Connect" );
|
||||||
iSendSocket.Connect( iAddress, iStatus );
|
iSendSocket.Connect( iAddress, iStatus );
|
||||||
|
|
||||||
SetActive();
|
SetActive();
|
||||||
|
@ -143,29 +220,56 @@ CSendSocket::ConnectL()
|
||||||
if ( iSSockState == ENotConnected ) {
|
if ( iSSockState == ENotConnected ) {
|
||||||
TInetAddr ipAddr;
|
TInetAddr ipAddr;
|
||||||
|
|
||||||
XP_LOGF( "connecting to %s", iCurAddr.u.ip.hostName );
|
if ( iCurAddr.u.ip.hostName && iCurAddr.u.ip.hostName[0] ) {
|
||||||
|
|
||||||
TBuf16<MAX_HOSTNAME_LEN> tbuf;
|
XP_LOGF( "connecting to %s", iCurAddr.u.ip.hostName );
|
||||||
tbuf.Copy( TBuf8<MAX_HOSTNAME_LEN>(iCurAddr.u.ip.hostName) );
|
|
||||||
TInt err = ipAddr.Input( tbuf );
|
|
||||||
XP_LOGF( "ipAddr.Input => %d", err );
|
|
||||||
|
|
||||||
if ( err != KErrNone ) {
|
TBuf16<MAX_HOSTNAME_LEN> tbuf;
|
||||||
/* need to look it up */
|
tbuf.Copy( TBuf8<MAX_HOSTNAME_LEN>(iCurAddr.u.ip.hostName) );
|
||||||
err = iResolver.Open( iSocketServer, KAfInet, KProtocolInetUdp );
|
TInt err = ipAddr.Input( tbuf );
|
||||||
XP_LOGF( "iResolver.Open => %d", err );
|
XP_LOGF( "ipAddr.Input => %d", err );
|
||||||
User::LeaveIfError( err );
|
|
||||||
|
|
||||||
iResolver.GetByName( tbuf, iNameEntry, iStatus );
|
if ( err != KErrNone ) {
|
||||||
iSSockState = ELookingUp;
|
/* need to look it up */
|
||||||
|
err = iResolver.Open( iSocketServer, KAfInet, KProtocolInetUdp );
|
||||||
|
XP_LOGF( "iResolver.Open => %d", err );
|
||||||
|
User::LeaveIfError( err );
|
||||||
|
|
||||||
SetActive();
|
iResolver.GetByName( tbuf, iNameEntry, iStatus );
|
||||||
|
iSSockState = ELookingUp;
|
||||||
|
|
||||||
|
SetActive();
|
||||||
|
} else {
|
||||||
|
ConnectL( ipAddr.Address() );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ConnectL( ipAddr.Address() );
|
/* PENDING FIX THIS!!!! */
|
||||||
|
XP_LOGF( "Can't connect: no relay name" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* ConnectL */
|
} /* ConnectL */
|
||||||
|
|
||||||
|
void
|
||||||
|
CSendSocket::ConnectL( const CommsAddrRec* aAddr )
|
||||||
|
{
|
||||||
|
/* If we're connected and the address is the same, do nothing. Otherwise
|
||||||
|
disconnect, change the address, and reconnect. */
|
||||||
|
|
||||||
|
TBool sameAddr = iAddrSet &&
|
||||||
|
(0 == XP_MEMCMP( (void*)&iCurAddr, (void*)aAddr, sizeof(aAddr) ) );
|
||||||
|
|
||||||
|
if ( sameAddr && iSSockState >= EConnected ) {
|
||||||
|
/* do nothing */
|
||||||
|
} else {
|
||||||
|
Disconnect();
|
||||||
|
|
||||||
|
iCurAddr = *aAddr;
|
||||||
|
iAddrSet = ETrue;
|
||||||
|
|
||||||
|
ConnectL();
|
||||||
|
}
|
||||||
|
} /* ConnectL */
|
||||||
|
|
||||||
void
|
void
|
||||||
CSendSocket::Disconnect()
|
CSendSocket::Disconnect()
|
||||||
{
|
{
|
||||||
|
@ -183,27 +287,27 @@ CSendSocket::SendL( const XP_U8* aBuf, XP_U16 aLen, const CommsAddrRec* aAddr )
|
||||||
XP_LOGF( "CSendSocket::SendL called" );
|
XP_LOGF( "CSendSocket::SendL called" );
|
||||||
TBool success;
|
TBool success;
|
||||||
|
|
||||||
XP_ASSERT( !IsActive() );
|
XP_ASSERT( iSSockState == EListening || !IsActive() );
|
||||||
if ( iSSockState == ESending ) {
|
if ( iSSockState == ESending ) {
|
||||||
success = EFalse;
|
success = EFalse;
|
||||||
} else if ( aLen > KMaxMsgLen ) {
|
} else if ( aLen > KMaxMsgLen ) {
|
||||||
success = EFalse;
|
success = EFalse;
|
||||||
} else {
|
} else {
|
||||||
XP_ASSERT( iSendBuf.Length() == 0 );
|
XP_ASSERT( iSendBuf.Length() == 0 );
|
||||||
iSendBuf.Copy( aBuf, aLen );
|
|
||||||
|
|
||||||
if ( iAddrSet && (0 != XP_MEMCMP( (void*)&iCurAddr, (void*)aAddr,
|
/* TCP-based protocol requires 16-bits of length, in network
|
||||||
sizeof(aAddr) )) ) {
|
byte-order, followed by data. */
|
||||||
Disconnect();
|
iSendBuf.SetLength(0);
|
||||||
}
|
XP_U16 netLen = XP_HTONS( aLen );
|
||||||
XP_ASSERT( !iAddrSet );
|
iSendBuf.Append( (TUint8*)&netLen, sizeof(netLen) );
|
||||||
iCurAddr = *aAddr;
|
iSendBuf.Append( aBuf, aLen );
|
||||||
iAddrSet = ETrue;
|
|
||||||
|
|
||||||
if ( iSSockState == ENotConnected ) {
|
if ( iSSockState == ENotConnected ) {
|
||||||
ConnectL();
|
ConnectL();
|
||||||
} else if ( iSSockState == EConnected ) {
|
} else if ( iSSockState == EConnected || iSSockState == EListening ) {
|
||||||
DoActualSend();
|
DoActualSend();
|
||||||
|
} else {
|
||||||
|
XP_ASSERT( 0 ); /* not sure why we'd be here */
|
||||||
}
|
}
|
||||||
success = ETrue;
|
success = ETrue;
|
||||||
}
|
}
|
||||||
|
@ -215,6 +319,11 @@ void
|
||||||
CSendSocket::DoActualSend()
|
CSendSocket::DoActualSend()
|
||||||
{
|
{
|
||||||
XP_LOGF( "CSendSocket::DoActualSend called" );
|
XP_LOGF( "CSendSocket::DoActualSend called" );
|
||||||
|
|
||||||
|
if ( CancelListen() ) {
|
||||||
|
iListenPending = ETrue;
|
||||||
|
}
|
||||||
|
|
||||||
iSendSocket.Write( iSendBuf, iStatus ); // Initiate actual write
|
iSendSocket.Write( iSendBuf, iStatus ); // Initiate actual write
|
||||||
SetActive();
|
SetActive();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue