📄 btconnectionhost.cpp
字号:
/* Copyright (c) 2002, Nokia Mobile Phones. All rights reserved */
#include "BTConnectionHost.h"
#include "MessageProtocolConstants.h"
#include "Log.h"
#include "S60BTLab.pan"
#include "BTHostNotify.h"
#include "s60btlabapp.h"
#include "BTServiceAdvertiser.h"
static const TInt KListeningQueSize = 1;
CBTConnectionHost* CBTConnectionHost::NewL(MBTHostNotify& aNotify, MLog& aLog)
{
CBTConnectionHost* self = new (ELeave) CBTConnectionHost(aNotify, aLog);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
CBTConnectionHost::CBTConnectionHost(MBTHostNotify& aNotify, MLog& aLog) :
CBTConnectionBase(aLog),
iNotify(aNotify),
iState(EDisconnected)
{
}
CBTConnectionHost::~CBTConnectionHost()
{
TRAPD(err,StopL());
if (err != KErrNone)
{
TRAPD(logErr, iLog.LogL(_L8("Error stoping host, error = "), err);)
Panic(ES60BTLabServerStop);
}
delete iAdvertiser;
iAdvertiser = NULL;
}
void CBTConnectionHost::ConstructL()
{
iAdvertiser = new (ELeave) CBTServiceAdvertiser(KUidS60BTLab.iUid);
}
void CBTConnectionHost::DoCancel()
{
if (IsActive())
{
if (EConnected == iState)
{
iDataSocket.CancelRecv();
}
else if (EConnecting == iState)
{
iListeningSocket.CancelAccept();
}
}
}
void CBTConnectionHost::RunL()
{
TInt status = iStatus.Int();
if (KErrNone != status)
{
StopL();
if (KErrDisconnected == status)
{
iLog.LogL(_L8("Disconnected"));
iNotify.ClientDisconnected(status);
}
else if (EConnected == iState)
{
iLog.LogL(_L8("Read error "), status);
iNotify.ClientDisconnected(status);
}
else if (EConnecting == iState)
{
iNotify.ClientConnected(status);
}
else if (KErrAbort == status)
{
iLog.LogL(_L8("Aborted"));
}
}
else
{
switch (iState)
{
case EConnecting:
iLog.LogL(_L8("Connected"));
iState = EConnected;
iLog.LogL(_L8("Invoking callback"));
iNotify.ClientConnected(status);
break;
case EConnected:
// Get the key press of the incoming data
iNotify.ClientDataRead(iBuffer);
break;
default:
Panic(ES60BTLabInvalidHostState);
break;
}
}
}
void CBTConnectionHost::StartL()
{
iLog.LogL(_L8("StartL - function entry"));
if (iState != EDisconnected)
{
User::Leave(KErrInUse);
}
User::LeaveIfError(iSocketServer.Connect());
User::LeaveIfError(iListeningSocket.Open(iSocketServer, KBTAddrFamily, KSockStream, KRFCOMM));
// Get the next available port number to listen on
User::LeaveIfError(
iListeningSocket.GetOpt(KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, iPort)
);
TBTSockAddr listeningAddress;
listeningAddress.SetPort(iPort);
iLog.LogL(_L8("Get port = "), iPort);
User::LeaveIfError(iListeningSocket.Bind(listeningAddress));
User::LeaveIfError(iListeningSocket.Listen(KListeningQueSize));
iDataSocket.Close(); // close old data connection - if any
// Open a blank socket to send and receive data
User::LeaveIfError(iDataSocket.Open(iSocketServer));
// accept any incoming connections
iListeningSocket.Accept(iDataSocket, iStatus);
// set an internal state variable to determine what
// action to take in this class' RunL function
iState = EConnecting;
// Indicate to Active Scheduler that a request is outstanding
SetActive();
iLog.LogL(_L8("Accept next Connection"));
SetSecurityOnChannelL(EFalse, EFalse, ETrue, iPort);
iAdvertiser->StartAdvertisingL(iPort);
}
void CBTConnectionHost::SetSecurityOnChannelL(TBool aAuthentication,
TBool aEncryption,
TBool aAuthorisation,
TInt aChannel)
{
// a connection to the security manager
RBTMan secManager;
// a security session
RBTSecuritySettings secSettingsSession;
// define the security on this port
User::LeaveIfError(secManager.Connect());
CleanupClosePushL(secManager);
User::LeaveIfError(secSettingsSession.Open(secManager));
CleanupClosePushL(secSettingsSession);
// the security settings
TBTServiceSecurity serviceSecurity(KUidS60BTLab, KSolBtRFCOMM, aChannel);
//Define security requirements
serviceSecurity.SetAuthentication(aAuthentication);
serviceSecurity.SetEncryption(aEncryption);
serviceSecurity.SetAuthorisation(aAuthorisation);
TRequestStatus status;
secSettingsSession.RegisterService(serviceSecurity, status);
User::WaitForRequest(status); // wait until the security settings are set
User::LeaveIfError(status.Int());
CleanupStack::PopAndDestroy(); // secManager
CleanupStack::PopAndDestroy(); // secSettingsSession
}
void CBTConnectionHost::RemoveSecurityL(TInt aChannel)
{
// a connection to the security manager
RBTMan secManager;
// a security session
RBTSecuritySettings secSettingsSession;
// define the security on this port
User::LeaveIfError(secManager.Connect());
CleanupClosePushL(secManager);
User::LeaveIfError(secSettingsSession.Open(secManager));
CleanupClosePushL(secSettingsSession);
TBTServiceSecurity serviceSecurity(KUidS60BTLab, KSolBtRFCOMM, aChannel);
TRequestStatus status;
secSettingsSession.UnregisterService(serviceSecurity, status);
User::WaitForRequest(status); // wait until the security settings are set
User::LeaveIfError(status.Int());
CleanupStack::PopAndDestroy(); // secManager
CleanupStack::PopAndDestroy(); // secSettingsSession
}
void CBTConnectionHost::StopL()
{
iLog.LogL(_L8("StopL - function entry"));
if (EDisconnected != iState)
{
RemoveSecurityL(iPort);
if (iAdvertiser && iAdvertiser->IsAdvertising())
{
iAdvertiser->StopAdvertisingL();
}
iLog.LogL(_L8("calling Cancel()"));
Cancel();
iLog.LogL(_L8("closing data sock"));
iDataSocket.Close();
iLog.LogL(_L8("closing listening sock"));
iListeningSocket.Close();
iLog.LogL(_L8("closing sockserv"));
iSocketServer.Close();
iState = EDisconnected;
}
iLog.LogL(_L8("StopL - function exit"));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -