📄 securesockets.cpp
字号:
//
// SecureSockets.cpp - SecureSockets example
//
// Copyright (C) UIQ Technology AB, 2007
//
// This material is provided "as is" without any warranty to its performance or functionality.
// In no event shall UIQ Technology be liable for any damages whatsoever arising out of the
// use or inabilty to use this material.
//
#include "SecureSockets.h"
#include "SecureSockets.hrh"
#include <SecureSockets.rsg>
#include <QikViewBase.h>
#include <QikCommand.h>
#include <QikListBoxModel.h>
#include <QikListBox.h>
#include <MQikListBoxData.h>
#include <QikListBoxData.h>
#include <eikstart.h>
#include <es_sock.h>
#include <in_sock.h>
#include <securesocket.h>
#include <x509cert.h>
//////////////////////////////////////////////////////////////////////////////
// The application Uid here MUST match UID3 defined in the MMP file
// This is a development UID and must NOT be used in production type software
const TUid KAppSpecificUid={0xEDEAD013};
// internal secondary view id, must be unique amongst this applications views
const TUid KUidListView={0x00000001};
// views within applications are fully identified by the app Uid and secondary view id
#define KViewIdListView TVwsViewId(KAppSpecificUid,KUidListView)
//////////////////////////////////////////////////////////////////////////////////
class CLogText : public CBase
{
public:
// new methods
~CLogText();
void ConstructL();
TInt Count();
const TDesC& At(const TInt aIndex);
void LogText(const TDesC& aBuf);
void ResetText();
protected:
CArrayFixFlat<HBufC*>* iText;
};
CLogText::~CLogText()
{
ResetText();
delete(iText);
}
void CLogText::ConstructL()
{
iText=new(ELeave)CArrayFixFlat<HBufC*>(32);
}
TInt CLogText::Count()
// Report number of logged messages
{
return(iText->Count());
}
const TDesC& CLogText::At(const TInt aIndex)
// report 'n'th text message
{
return(*iText->At(aIndex));
}
void CLogText::ResetText()
{
TInt count=Count();
for (TInt i=0;i<count;i++)
delete(iText->At(i));
iText->Reset();
}
void CLogText::LogText(const TDesC& aBuf)
{ // add new text item to front of the list
TRAPD(err,
TBuf<128>bb;
if (aBuf.Length()>120)
bb=aBuf.Left(120);
else
bb=aBuf;
HBufC* q=bb.AllocLC();
iText->InsertL(0,q); // at front of list
CleanupStack::Pop(q);
if (iText->Count()>100)
{ // restrict to last 100 log msgs
delete(iText->At(100));
iText->Delete(100);
}
);
}
//////////////////////////////////////////////////////////////////////////////////
class MSocketEngineObserver
{
public:
virtual void LogInfo(const TDesC& aBuf,const TDesC& aBuf2)=0;
virtual void DataReceived(const TDesC8& aData)=0;
virtual void DataSent(const TInt aError)=0;
};
//////////////////////////////////////////////////////////////////////////////////
// we read/write upto 2k at a time from the secure socket
const TInt KMaxSocketBuffer=2048;
class CSecureSocketWriter : public CActive
{
protected:
// from CActive
void DoCancel();
void RunL();
public:
// ew methods
~CSecureSocketWriter();
CSecureSocketWriter(MSocketEngineObserver* aObserver);
TBool SendData(CSecureSocket* aSocket,const TDesC8& aData);
protected:
MSocketEngineObserver* iObserver;
CSecureSocket* iSecureSocket;
TBuf8<KMaxSocketBuffer> iData;
};
CSecureSocketWriter::CSecureSocketWriter(MSocketEngineObserver* aObserver) :
CActive(CActive::EPriorityLow),iObserver(aObserver)
{
CActiveScheduler::Add(this);
}
CSecureSocketWriter::~CSecureSocketWriter()
{
Cancel(); // calls DoCancel() iff we are currently active.
}
TBool CSecureSocketWriter::SendData(CSecureSocket* aSocket,const TDesC8& aData)
// Were requested to send this data. If were currently active report that we cannot send the
// data at this time, dont take ownership of the data. Otherwise take copy of the data and
// start sending it.
{
// the last SendData() request has not yet finished.
if (IsActive())
return(EFalse);
// take local copy so caller can re-use their buffer
iData=aData;
// take a temporary copy of the secure socket handle so we can cancel any writes if required
iSecureSocket=aSocket;
// start transmission of data. It will have finished when our RunL() gets called
iSecureSocket->Send(iData,iStatus);
// dont forget to mark the AO as representing an outstanding event
SetActive();
// tell caller we started data transmission.
return(ETrue);
}
void CSecureSocketWriter::RunL()
// Weve finished writing, sucessfully or otherwise.
{
iObserver->DataSent(iStatus.Int());
iSecureSocket=NULL; // simply tidying up - we dont own this
}
void CSecureSocketWriter::DoCancel()
// Cancel any outstanding activity, maybe called from destructor
// To get here we must have an outstanding Send() request.
{
iSecureSocket->CancelSend();
iSecureSocket=NULL; // simply tidying up - we dont own this
}
//////////////////////////////////////////////////////////////////////////////////
const TInt KMaxServerNameLen=256;
enum TSocketEngineStatus
{
ESeNotConnected=0, // must be 0
ESeConnecting, // were attempting to connect to a server
ESeLookingUp, // translating name to IP
ESeClientHandshake, // establishing the secure connection
ESeReading, // we have a read request outstanding
};
class CSecureSocketEngine : public CActive
{
protected:
// from CActive
void DoCancel();
void RunL();
// new methods
void Connect(const TUint32 aAddr);
public:
~CSecureSocketEngine();
CSecureSocketEngine(RSocketServ& aServer,MSocketEngineObserver* aObserver);
void ConstructL();
void SetServerName(const TDesC& aName);
const TDesC& GetServerName() const;
void SetPort(const TInt aPort);
TInt GetPort() const;
void Connect();
protected:
RSocketServ& iSocketServer; // connection to the Symbian OS socket server process
MSocketEngineObserver* iObserver;
RHostResolver iHostResolver; // host name resolver
TSocketEngineStatus iState; // our state machine status
TInetAddr iAddress; // address were attempting to connect to
TInt iPort; // which port to connect to
TBuf<KMaxServerNameLen> iServerName; // which server we are to talk to
TNameEntry iNameEntry; // resolved name
RSocket iSocket; // socket though which were communicating
CSecureSocket* iSecureSocket; // the secure socket
CSecureSocketWriter* iWriter; // our AO to handle async writing of content
TSockXfrLength iXfrLen;
TBuf8<KMaxSocketBuffer> iRecvBuffer; // where we read data
};
CSecureSocketEngine::CSecureSocketEngine(RSocketServ& aServer,MSocketEngineObserver* aObserver) :
CActive(CActive::EPriorityStandard),iSocketServer(aServer),iObserver(aObserver)
{
CActiveScheduler::Add(this);
}
CSecureSocketEngine::~CSecureSocketEngine()
{
// any outstanding connect/read requests
Cancel();
// cancel any secure socket writes before we shutdown secure socket
delete(iWriter);
// now all possible outstanding events cancelled we can shut down the sockets
if (iSecureSocket)
{
iSecureSocket->Close();
delete(iSecureSocket);
iSecureSocket=NULL;
}
// after secure socket as it references it internally
iSocket.Close();
}
void CSecureSocketEngine::ConstructL()
{
// this app has an AO to represent outstanding write requests
iWriter=new(ELeave)CSecureSocketWriter(iObserver);
}
void CSecureSocketEngine::DoCancel()
//
// Cancel whatever is currently running
//
{
// Cancel appropriate request to socket
switch (iState)
{
case ESeConnecting: // cancel the tcp connect request
iSocket.CancelConnect();
break;
case ESeClientHandshake:
iSecureSocket->CancelHandshake();
break;
case ESeReading:
iSecureSocket->CancelRecv();
break;
case ESeLookingUp: // cancel the name look up
iHostResolver.Cancel();
iHostResolver.Close();
default:
break;
}
iState=ESeNotConnected;
}
_LIT(KEngRunL,"Eng::RunL");
_LIT(KSecureSocket,"SecureSocket");
_LIT(KSecureSocketFailed,"SecureSocketFailed");
_LIT(KConnectFailed,"ConnectFailed");
_LIT(KConnectedOK,"Connected OK");
_LIT(KSecConnFailed,"SecConnFailed %d");
_LIT(KReadFailed,"ReadFailed");
_LIT(KResolverErr,"ResolverErr:%d");
void CSecureSocketEngine::RunL()
//
// One of our requests has completed
//
{
switch (iState)
{
case ESeConnecting: // IP connect request has completed
if (iStatus==KErrNone)
{ // sucessfully established a socket level connec
iObserver->LogInfo(KEngRunL,KSecureSocket);
TRAPD(err,
_LIT(KTLS1,"TLS1.0");
// _LIT(KTLS1,"SSL3.0");
iSecureSocket=CSecureSocket::NewL(iSocket,KTLS1);
);
if (err!=KErrNone)
{
iSocket.Close();
iState=ESeNotConnected;
iObserver->LogInfo(KEngRunL,KSecureSocketFailed);
}
else
{ // perform a client handshake with the server = establish security
// attempt to establish a secure connection
iSecureSocket->StartClientHandshake(iStatus);
iState=ESeClientHandshake;
SetActive();
}
}
else
{ // connect attempt failed, allow retry or different addr
iSocket.Close();
iState=ESeNotConnected;
iObserver->LogInfo(KEngRunL,KConnectFailed);
}
break;
case ESeClientHandshake: // establishing secure connection
if (iStatus==KErrNone)
{ // established a connection, queue a read for any content we get sent..
iObserver->LogInfo(KEngRunL,KConnectedOK);
iSecureSocket->RecvOneOrMore(iRecvBuffer,iStatus,iXfrLen);
iState=ESeReading;
SetActive();
}
else
{ // failed to get secure connection
iSecureSocket->Close();
delete(iSecureSocket);
iSecureSocket=NULL;
iSocket.Close();
iState=ESeNotConnected;
TBuf<64> bb;
bb.Format(KSecConnFailed,iStatus.Int());
iObserver->LogInfo(KEngRunL,bb);
}
break;
case ESeReading:
if (iStatus==KErrNone)
{ // some data has arrived for us to process
// do something with the data received, before we reuse the buffer
iObserver->DataReceived(iRecvBuffer);
// read more data
iSecureSocket->RecvOneOrMore(iRecvBuffer,iStatus,iXfrLen);
iState=ESeReading;
SetActive();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -