📄 listener.cpp
字号:
/*
* ============================================================================
* Name : CListener from Listener.h
* Part of : BluetoothPMPExample
* Created : 14.01.2004 by Forum Nokia
* Implementation notes:
* Initial content was generated by Series 60 AppWizard.
* Version :
* Copyright: Nokia Corporation
* ============================================================================
*/
// INCLUDE FILES
#include "Listener.h"
CListener* CListener::NewL(MListenerObserver* aObserver,
RSocketServ *aSocketServ)
{
CListener* self = CListener::NewLC(aObserver, aSocketServ);
CleanupStack::Pop(self);
return self;
}
CListener* CListener::NewLC(MListenerObserver* aObserver,
RSocketServ *aSocketServ)
{
CListener* self = new (ELeave) CListener(aObserver, aSocketServ);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CListener::ConstructL()
{
}
// ----------------------------------------------------------------------------
// CListener::CListener(MListernetObserver* aObserver,
// RSocketServ *aSocketServ)
//
// constructor
// ----------------------------------------------------------------------------
CListener::CListener(MListenerObserver* aObserver,
RSocketServ *aSocketServ):
CActive(CActive::EPriorityStandard),
iObserver(aObserver),
iSocketServ(aSocketServ),
iIsConnected(EFalse),
iState(ENone)
{
CActiveScheduler::Add(this);
}
// ----------------------------------------------------------------------------
// CListener::~CListener()
//
// destructor
// ----------------------------------------------------------------------------
CListener::~CListener()
{
// cancel active object
Cancel();
// close sockets
StopListenerL();
}
// ----------------------------------------------------------------------------
// CListener::StartListenerL()
//
// start listener. listener will open a listening socket on a channel (port)
// gotten from GetOpt() call.
// ----------------------------------------------------------------------------
TInt CListener::StartListenerL()
{
// get out if we're already running..
if ( iState!=ENone )
return -1;
// set this active object to connecting state
iState=EConnecting;
// load protocol, RFCOMM
TProtocolDesc pdesc;
User::LeaveIfError(iSocketServ->FindProtocol(_L("RFCOMM"), pdesc));
// open a socket
iListenSock.Open(*iSocketServ,pdesc.iAddrFamily,pdesc.iSockType,KRFCOMM);
// get listening channel
TInt channel;
User::LeaveIfError(iListenSock.GetOpt(KRFCOMMGetAvailableServerChannel,
KSolBtRFCOMM, channel));
// bluetooth socket address object
TBTSockAddr btsockaddr;
btsockaddr.SetPort(channel);
// bind socket
User::LeaveIfError(iListenSock.Bind(btsockaddr));
// listen on port
iListenSock.Listen(5);
// set channel security
SetSecurityL(channel);
// close old accepted socket if open
iSock.Close();
// open blank socket and pass it to accept to be assigned a proper
// socket upon completion of Accept()
User::LeaveIfError(iSock.Open(*iSocketServ));
// set to accept incoming connections, active object will handle
iListenSock.Accept(iSock,iStatus);
SetActive();
return channel;
}
// ----------------------------------------------------------------------------
// CListener::SetSecurityL(TInt aChannel)
//
// sets the security of given bluetooth channel. these settings will turn
// off authentication, authorisation and encryption on given channel.
// ----------------------------------------------------------------------------
void CListener::SetSecurityL(TInt aChannel)
{
// setup channel security
TRequestStatus status;
RBTMan secManager;
RBTSecuritySettings secDatabase;
TBTServiceSecurity secSettings;
// connect to security manager
User::LeaveIfError(secManager.Connect());
CleanupClosePushL(secManager);
User::LeaveIfError(secDatabase.Open(secManager));
CleanupClosePushL(secDatabase);
// setup security
TUid settingsUID;
settingsUID.iUid = KBT_serviceID;
secSettings.SetUid(settingsUID);
secSettings.SetChannelID(aChannel);
secSettings.SetProtocolID(KSolBtRFCOMM);
secSettings.SetAuthentication(EFalse);
secSettings.SetAuthorisation(EFalse);
secSettings.SetEncryption(EFalse);
// register settings with security
secDatabase.RegisterService(secSettings, status);
User::WaitForRequest(status);
CleanupStack::PopAndDestroy(); // secManager
CleanupStack::PopAndDestroy(); // secSettings
}
// ----------------------------------------------------------------------------
// CListener::StopListenerL()
//
// stops the listener by closing the listening socket
// ----------------------------------------------------------------------------
void CListener::StopListenerL()
{
// kill sockets
if ( iState!=ENone )
{
iSock.Close();
iListenSock.Close();
iState=ENone;
}
}
// ----------------------------------------------------------------------------
// CListener::ReceiveData()
//
// receive more data from listening socket, asynchronously.
// ----------------------------------------------------------------------------
void CListener::ReceiveData()
{
// set state to waiting - for RunL()
iState = EWaiting;
// make async request
iSock.RecvOneOrMore(iBuffer, 0, iStatus, iLen);
// set as active to get the async req response (iState) in RunL()
SetActive();
}
// ----------------------------------------------------------------------------
// CListener::SendDataL(const TDesC8& aData)
//
// send data to remote device, write data to socket.
// ----------------------------------------------------------------------------
void CListener::SendDataL(const TDesC8& aData)
{
if ( iState!=EWaiting )
return;
// cancel any read requests on socket
Cancel();
// try to send message by writing to socket
// - set the state of this active object to "sending"
iState=ESending;
// - make async socket write request
iSock.Write(aData, iStatus);
// - start waiting async req response (iState) from active scheduler
SetActive();
}
void CListener::RunL()
{
if ( iStatus==KErrDisconnected )
{
StopListenerL();
HandleListenerDisconnectedL();
}
if ( iStatus!=KErrNone )
return;
switch (iState)
{
case EConnecting:
{
// connected listening socket!
HandleListenerConnectedL();
ReceiveData();
break;
}
case EWaiting:
{
// returned from receiving data
if(iState!=KErrNone)
{
// add the error handling / re-reading code here..
// not needed in this example
}
HBufC* text = HBufC::NewLC(iBuffer.Length());
text->Des().Copy(iBuffer);
// observer will handle data
HandleListenerDataReceivedL(*text);
CleanupStack::PopAndDestroy(text);
// start expecting next data to be read
ReceiveData();
break;
}
case ESending:
{
// returned from sending the date, check the state
if(iState!=KErrNone)
{
// add the error handling / re-sending code here..
// not needed in this example
}
// start expecting next data to be read
ReceiveData();
break;
}
default:
break;
}
}
void CListener::DoCancel()
{
// cancel all pending socket operations
iSock.CancelAll();
iListenSock.CancelAll();
}
// ----------------------------------------------------------------------------
// CListener::IsConnected()
//
// returns true if listener has been connected to
// ----------------------------------------------------------------------------
TBool CListener::IsConnected()
{
return iIsConnected;
}
// ----------------------------------------------------------------------------
// CListener::HandleListenerDataReceivedL(TDesC& aData)
//
// a callback to observer indicating that listener has received data
// ----------------------------------------------------------------------------
void CListener::HandleListenerDataReceivedL(TDesC& aData)
{
iObserver->HandleListenerDataReceivedL(aData);
}
// ----------------------------------------------------------------------------
// CListener::HandleListenerConnectedL()
//
// a callback to observer indicating that listener has been connected to
// ----------------------------------------------------------------------------
void CListener::HandleListenerConnectedL()
{
iIsConnected=ETrue;
iObserver->HandleListenerConnectedL();
}
// ----------------------------------------------------------------------------
// CListener::HandleListenerDisconnectedL()
//
// a callback to observer indicating that listener has been disconnected
// ----------------------------------------------------------------------------
void CListener::HandleListenerDisconnectedL()
{
iIsConnected=EFalse;
iObserver->HandleListenerDisconnectedL();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -