📄 bluetoothserver.cpp
字号:
/**
*
* @brief Definition of CBluetoothServer
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/
// System include
#include <bt_sock.h>
#include <s32mem.h>
// User include
#include "BluetoothServer.h"
#include "BluetoothAdvertiser.h"
#include "BluetoothChatApplication.h"
/**
* Constructor.
*
* Set observer and flag to indicate not connected
* Add this active object to the scheduler
*
* @param aObserver reference to MBluetoothObserver
**/
CBluetoothServer::CBluetoothServer(MBluetoothObserver& aObserver)
: CActive(CActive::EPriorityStandard),
iObserver(aObserver),
iState(EDisconnected)
{
CActiveScheduler::Add(this);
}
/**
* Factory Constructor.
* Only available way to construct class.
* This function can leave L
* @param none
* @return new instance of the CBluetoothServer
*/
CBluetoothServer* CBluetoothServer::NewL(MBluetoothObserver& aObserver)
{
CBluetoothServer* self = NewLC(aObserver);
CleanupStack::Pop(self);
return self;
}
/**
* Factory Constructor.
* Only available way to construct class.
* This function can leave L, returning value is on Cleanup Stack C
* @param none
* @return new instance of the CBluetoothServer on Cleanup stack
*/
CBluetoothServer* CBluetoothServer::NewLC(MBluetoothObserver& aObserver)
{
CBluetoothServer* self = new (ELeave) CBluetoothServer(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
/**
* Destructor.
*
* Cancel this active object, and disconnect the Server
* Delete the advertiser
*
* @param none
* @retval none
**/
CBluetoothServer::~CBluetoothServer()
{
TRAPD(err,StopL());
// Panic in debug if this didn't work
__ASSERT_DEBUG(err == KErrNone, Panic(EErrorStoppingServer));
Cancel();
// Close handles
if (iSecSettingsSession.SubSessionHandle() != 0)
{
iSecSettingsSession.Close();
}
if (iSecManager.Handle() != 0)
{
iSecManager.Close();
}
if (iAcceptedSocket.SubSessionHandle() != 0)
{
iAcceptedSocket.Close();
}
if (iListeningSocket.SubSessionHandle() != 0)
{
iListeningSocket.Close();
}
if (iSocketServer.Handle() != 0)
{
iSocketServer.Close();
}
delete iAdvertiser;
}
/**
* ConstructL
*
* Create the advertiser
*
* @see NewL
* @see NewLC
* @param none
* @return none
**/
void CBluetoothServer::ConstructL()
{
iAdvertiser = CBluetoothAdvertiser::NewL();
}
void CBluetoothServer::DoCancel()
{
switch(iState)
{
case EDisconnected :
{
break;
}
case ESettingSecurity :
{
iSecSettingsSession.CancelRequest(iStatus); // not asynch call
break;
}
case EConnecting :
{
iListeningSocket.CancelAccept();
break;
}
case EConnected :
{
break;
}
case EWaitingForMessage :
{
iAcceptedSocket.CancelRecv();
break;
}
case ESendData :
{
iAcceptedSocket.CancelSend();
break;
}
default:
{
break;
}
}
}
/**
* StartServerL.
*
* Connect to Socket Server
* Open a listening socket on the Server on the RFCOMM protocol (KServerTransportName)
* Get a channel to listen on
* Bind the socket to this port, and listen
* Open another socket on the Server
* Issue an asynchronous Accept on the listening socket, passing through the AcceptedSocket
* When the Accept completes the Accepted Socket may be utilised for communication and the listening socket will continue
* listening for connections.
* Set Security options on the Port/Channel
*
* @param none
* @return none
**/
void CBluetoothServer::StartServerL()
{
if (iState != EDisconnected)
{
User::Leave(KErrInUse);
}
User::LeaveIfError(iSocketServer.Connect());
User::LeaveIfError(iListeningSocket.Open(iSocketServer, KServerTransportName));
// Get a channel to listen on - same as the socket's port number
User::LeaveIfError(iListeningSocket.GetOpt(KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, iChannel));
TBTSockAddr listeningAddress;
listeningAddress.SetPort(iChannel);
User::LeaveIfError(iListeningSocket.Bind(listeningAddress));
User::LeaveIfError(iListeningSocket.Listen(KListeningQueSize));
SetSecurityOnChannelL(EFalse, EFalse, ETrue);
}
/**
* SetSecurityOnChannelL.
*
* Connect to security manager
* Open a subsession on the security manager used to register settings
* Build the security settings within a TBTServiceSecurity object
* Register these settings
*
* @param aAuthentication true if you wish to enforce authentication
* @param aEncryption true if you wish to enforce encryption on the incomming data
* @param eAuthorisation true if you wish to enforce authorisation.
* @return none
**/
void CBluetoothServer::SetSecurityOnChannelL(TBool aAuthentication, TBool aEncryption, TBool aAuthorisation)
{
// connect to the security manager and open a settings session.
User::LeaveIfError(iSecManager.Connect());
User::LeaveIfError(iSecSettingsSession.Open(iSecManager));
// the security settings
TBTServiceSecurity serviceSecurity(KUidBluetoothChat, KSolBtRFCOMM, 0);
//Define security requirements
serviceSecurity.SetAuthentication(aAuthentication);
serviceSecurity.SetEncryption(aEncryption);
serviceSecurity.SetAuthorisation(aAuthorisation);
serviceSecurity.SetChannelID(iChannel);
// make asynch request
iSecSettingsSession.RegisterService(serviceSecurity, iStatus);
iState = ESettingSecurity;
SetActive();
}
/**
* AcceptConnectionsL.
*
* Sets the socket which should be used to accept incoming connections at the
* listening socket.
*
* @param none
* @return none
**/
void CBluetoothServer::AcceptConnectionsL()
{
iAcceptedSocket.Close(); // close old connection - if any
User::LeaveIfError(iAcceptedSocket.Open(iSocketServer)); // Open abstract socket
iState = EConnecting;
// set the listening socket to accept new connections on
// the accepted socket.
iListeningSocket.Accept(iAcceptedSocket, iStatus);
SetActive();
// notify the observer that the server has started
iObserver.ServerStartedL();
}
/**
* StartAdvertisingL.
*
* Start Advertising
*
* @param none
* @return none
**/
void CBluetoothServer::StartAdvertisingL()
{
iAdvertiser->StartAdvertisingL(iChannel);
iAdvertiser->UpdateAvailabilityL(ETrue);
}
/**
* StopL.
*
* Stop Advertising
* Close the communication socket
* Close the listening socket
* Close the connection to the socket server
*
* @param none
* @return none
**/
void CBluetoothServer::StopL()
{
if (iState != EDisconnected)
{
if (iAdvertiser->IsAdvertising())
{
iAdvertiser->StopAdvertisingL();
}
iAcceptedSocket.Close();
iListeningSocket.Close();
iSocketServer.Close();
}
iState = EDisconnected;
}
/**
* SendL.
*
* Issue an asynchronous Write on the socket, passing through the message to send
*
* @param aMessage the message to send the client
* @return none
**/
void CBluetoothServer::Send(const TDesC& aMessage)
{
TRAPD(err, SendL(aMessage));
}
void CBluetoothServer::SendL(const TDesC& aMessage)
{
iMessage.Zero();
TDesBuf buffer;
buffer.Set (iMessage);
RWriteStream stream(&buffer);
CleanupClosePushL(stream);
stream << aMessage;
CleanupStack::PopAndDestroy();
iState = ESendData;
iAcceptedSocket.Write(iMessage, iStatus);
SetActive();
}
/**
* RequestData.
*
* Issue an asynchronous receive function on the socket, passing through a buffer to be populated
* @param none
* @return none
**/
void CBluetoothServer::RequestData()
{
iMessage.Zero();
iState = EWaitingForMessage;
iAcceptedSocket.RecvOneOrMore(iMessage, 0, iStatus, iLen);
SetActive();
}
/**
* RunL
*
* Called when an asynchronous request completes.
* iStatus variable indicates error conditions
* iState indicates present state of the Server
*
* @param none
* @return none
**/
void CBluetoothServer::RunL()
{
if (iStatus.Int() == KErrNone)
{
switch (iState)
{
case ESettingSecurity :
{
// cleanup after security settings
iSecSettingsSession.Close();
iSecManager.Close();
// accept connections
AcceptConnectionsL();
break;
}
case EConnecting:
{
iObserver.ConnectedL();
// do not accept any more connections
iAdvertiser->StopAdvertisingL();
RequestData();
break;
}
case EWaitingForMessage:
{
iState = EConnected;
TDesBuf buffer;
buffer.Set (iMessage);
RReadStream stream (&buffer);
CleanupClosePushL(stream);
TBuf<KMaxMessageLength> rxBuf;
stream >> rxBuf;
CleanupStack::PopAndDestroy();
iObserver.DataReceivedL(rxBuf);
break;
}
case ESendData:
{
RequestData();
break;
}
default:
Panic(EInvalidServerState);
break;
}
}
else
{
StopL();
iObserver.HandleErrorL(iStatus.Int());
}
}
/**
* Returns information on state of the Bluetooth Server.
*
* @param none
* @returns boolean, true if the server is connected to a client, false otherwise
*/
TBool CBluetoothServer::IsConnected()
{
return !(iState == EDisconnected);
}
/**
* Returns information on state of the Bluetooth Server.
*
* @param none
* @returns boolean, true if the server is able to send data to the client, false otherwise
*/
TBool CBluetoothServer::AvailableToSend()
{
return (iState == EConnected);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -