📄 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"));
// TODO: notify the calling code (CS60BTLabAppView in this case)
// that a client is now connected.
// Hint: use MBTHostNotify::ClientConnected()
// (this class has a MBTHostNotify& member variable)
break;
case EConnected:
// Get the key press of the incoming data
// TODO: notify the calling code (CS60BTLabAppView in this case)
// that data has been read from the client
// Hint: use MBTHostNotify::ClientDataRead()
// The data is contained in iBuffer
break;
default:
Panic(ES60BTLabInvalidHostState);
break;
}
}
}
void CBTConnectionHost::StartL()
{
iLog.LogL(_L8("StartL - function entry"));
if (iState != EDisconnected)
{
User::Leave(KErrInUse);
}
// TODO: If any of the actions that are implemented in the following 6 TODO sections
// return an error, the function should leave.
// Hint: use User::LeaveIfError()
// TODO: Connect to the socket server here using RSocketServ::Connect() with iSocketServer
// TODO: Open a listening socket here using iListeningSocket and RSocket::Open()
// Use: addrFamily - KBTAddrFamily,
// sockType - KSockStream
// protocol - KRFCOMM
// TODO: Get the next available port number here
// Use RSocket::GetOpt on the listening socket with
// KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, iPort as parameters
TBTSockAddr listeningAddress;
listeningAddress.SetPort(iPort);
iLog.LogL(_L8("Get port = "), iPort);
// TODO: Bind the listeningAddress variable to the listening socket
// Use RSocket::Bind()
// TODO: Listen for connections
// Use RSocket::Listen() with KListeningQueSize defined at the top of the file
iDataSocket.Close(); // close old data connection - if any
// Open a blank socket to send and receive data
User::LeaveIfError(iDataSocket.Open(iSocketServer));
// TODO: Accept incoming connections asychronously
// Use RSocket::Accept() on the listening socket, passing the blank socket
// and the iStatus member variable of this class (declared in CActive)
// 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"));
// TODO: Set the incoming Bluetooth Security requirements
// Use CBTConnectionHost::SetSecurityOnChannelL()
// No authentication or encryption is required, but authorisation is.
// This displays a dialog on the host to request user confirmation of
// the incoming connection.
// Also use the port number obtained using RSocket::GetOpt
// TODO: Start advertising the service in the Service Discovery Database
// Use CBTServiceAdvertiser::StartAdvertisingL()
// Hint: there is a CBTServiceAdvertiser* member variable in this class
}
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 + -