www.pudn.com > Example_BluetoothChat.rar > BluetoothServer.cpp
/** * * @brief Definition of CBluetoothServer * * Copyright (c) EMCC Software Ltd 2003 * @version 1.0 */ // System include #include#include // 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 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); }