📄 gdpbt.cpp
字号:
CGdpStateMachine::TState* CGdpBTSender::TWriteState::CompleteL()
{
// Hey! We're done! Stop going through the state machine
iSender.iHandler->SendComplete(KErrNone);
return NULL;
}
void CGdpBTSender::TWriteState::Cancel()
{
// Cancel any writes on the socket
iSender.iWriteSocket.CancelWrite();
}
/**************** GdpBTReceiver ****************/
#pragma warning(disable:4355) // Disable "C4355: 'this' used in member initialization".
CGdpBTReceiver::CGdpBTReceiver(CGdpBTResourceManager& aResMan)
: CGdpBTStateMachine(aResMan),
// Initialise the two member states so they know who they're owned by
iAcceptState(*this),
iReadState(*this)
{
}
#pragma warning(default:4355) // Turn C4355 back on.
/// Just close what we opened previously
CGdpBTReceiver::~CGdpBTReceiver()
{
DEBUG_PRINT(_L("Entering CGdpBTReceiver::~CGDBTReceiever"));
Close();
DEBUG_PRINT(_L("Leaving CGdpBTReceiver::~CGDBTReceiever"));
}
void CGdpBTReceiver::DoSecurityParams()
{
RBTSecuritySettings secset;
RBTMan btman;
TBTServiceSecurity service;
TUid uid;
uid.iUid = 0x1234;
service.SetUid(uid);
service.SetChannelID(11);
service.SetProtocolID(KSolBtL2CAP);
service.SetAuthentication(EFalse);
service.SetAuthorisation(EFalse);
service.SetEncryption(EFalse);
User::LeaveIfError(btman.Connect());
User::LeaveIfError(secset.Open(btman));
TRequestStatus requestStatus;
secset.RegisterService(service, requestStatus);
User::WaitForRequest(requestStatus);
User::LeaveIfError(requestStatus.Int());
}
void CGdpBTReceiver::OpenL(MGdpPacketHandler& aHandler)
{
DEBUG_PRINT(_L("Entering CGdpBTReceiver::OpenL"));
// Make sure the current iHandler is NULL - if it isn't then
// we've already got a handler so Panic
__ASSERT_DEBUG(iHandler == NULL, GdpUtil::Panic(GdpUtil::EReceiverInUse));
iHandler = &aHandler;
// Get the descriptor for protocol we are using. Better be Bluetooth...
TProtocolDesc& desc = iResMan.ProtocolDesc();
// Open the Listen Socket
User::LeaveIfError(iListenSocket.Open(iResMan.SocketServer(),
desc.iAddrFamily,
desc.iSockType,
desc.iProtocol));
// Set up the port to listen on
TInt port = 0x0b; // Port 11 for GDP
iAddr.SetPort(port);
// Now set the socket to listen on the right port
TInt ret = iListenSocket.Bind(iAddr);
// If the Bind() didn't succeed we're outta here!
if (ret != KErrNone)
User::Leave(KErrInUse); // Port is in use
// Listen with a queue size of 4 (random) to allow more than
// one connection
User::LeaveIfError(iListenSocket.Listen(4));
DoSecurityParams();
// Now start the state machine off to wait for an incoming connection
ChangeState(&iAcceptState);
}
void CGdpBTReceiver::Close()
{
DEBUG_PRINT(_L("Entering CGdpBTReceiver::Close"));
// If theres's no handler, it's closed already so
// we don't need to do anything
if (iHandler == NULL)
return;
// Make sure there's no outstanding requests by cancelling them
Cancel();
// Close the Read and Listen sockets
iReadSocket.Close();
iListenSocket.Close();
// Set the handler to NULL so we know not to close
// anything if we come in here again
iHandler = NULL;
DEBUG_PRINT(_L("Leaving CGdpBTReceiver::Close"));
}
CGdpStateMachine::TState* CGdpBTReceiver::ErrorOnStateEntry(TInt /*aError*/)
//
// This should really try to wait a little first!!!
//
{
// But in the mean time, just go back to the start again!
return &iAcceptState;
}
CGdpStateMachine::TState* CGdpBTReceiver::ErrorOnStateExit(TInt /*aError*/)
//
// Some Async request failed. Start again.
// Individual states will probably do this themselves anyway...
//
{
return &iAcceptState;
}
/**************** GdpBTReceiver State transitions ****************/
CGdpBTReceiver::TReceiverState::TReceiverState(CGdpBTReceiver& aReceiver)
: iReceiver(aReceiver)
{
}
//--------------- Receiver Accept State ---------------//
CGdpBTReceiver::TAcceptState::TAcceptState(CGdpBTReceiver& aReceiver)
: TReceiverState(aReceiver)
{
}
void CGdpBTReceiver::TAcceptState::EnterL()
{
RSocket& readSock = iReceiver.iReadSocket;
readSock.Close(); // Why close it? Leave it open???
User::LeaveIfError(
readSock.Open(iReceiver.iResMan.SocketServer()));
// Tell socket we'll accept an incoming connection...
iReceiver.iListenSocket.Accept(readSock, iReceiver.iStatus);
// ...and wait
iReceiver.SetActive();
}
CGdpStateMachine::TState* CGdpBTReceiver::TAcceptState::CompleteL()
{
// Got an incoming connection!
// Where'd it come from?
TL2CAPSockAddr sockAddr;
iReceiver.iReadSocket.RemoteName(sockAddr);
// Convert and store as hex in the remote address descriptor
TBTDevAddr remAddr = sockAddr.BTAddr();
iReceiver.iRemAddr.Zero(); // Set length to zero
for (TInt i=0; i<KBTMaxDevAddrSize; ++i)
{
// 00 d0 b7 03 0e c5
TUint16 num = remAddr[i];
// Hack to pre-pend with a 0 if single digit hex
if(num < 0x10)
iReceiver.iRemAddr.AppendNum(0, EHex);
iReceiver.iRemAddr.AppendNum(remAddr[i], EHex);
}
// Now read some data
return &(iReceiver.iReadState);
}
CGdpStateMachine::TState* CGdpBTReceiver::TAcceptState::ErrorL(TInt /*aCode*/)
{
return this; // Retry this state
}
void CGdpBTReceiver::TAcceptState::Cancel()
{
iReceiver.iListenSocket.CancelAccept();
}
//--------------- Receiver Read State ---------------//
CGdpBTReceiver::TReadState::TReadState(CGdpBTReceiver& aReceiver)
: TReceiverState(aReceiver)
{
}
void CGdpBTReceiver::TReadState::EnterL()
{
iReceiver.iReadSocket.Read(iReceiver.iPacket, iReceiver.iStatus);
iReceiver.SetActive();
}
CGdpStateMachine::TState* CGdpBTReceiver::TReadState::CompleteL()
{
// _LIT(KNullAddress,"");
// Complete read by telling handler where the packet came from
// and what was in it
iReceiver.iHandler->GdpHandleL(iReceiver.iRemAddr, iReceiver.iPacket);
return this; // Queue another read, while the channel is open
}
CGdpStateMachine::TState* CGdpBTReceiver::TReadState::ErrorL(TInt /*aCode*/)
//
// Go back to accept to pick up the next connection
//
{
return &(iReceiver.iAcceptState);
}
void CGdpBTReceiver::TReadState::Cancel()
{
iReceiver.iReadSocket.CancelRead();
}
/**************** GdpBTResourceManager ****************/
CGdpBTResourceManager::CGdpBTResourceManager()
{
}
CGdpBTResourceManager::~CGdpBTResourceManager()
{
Close();
}
void CGdpBTResourceManager::OpenL()
//
// Allocate shared resources
//
{
// Connect to the Socket Server
User::LeaveIfError(iSocketServer.Connect());
// Find something in there that will give us a protocol called
// 'L2CAP' (hopefully, Bluetooth :) )
// This fills in the Protocol Descriptor, iProtocolDesc
User::LeaveIfError(iSocketServer.FindProtocol(_L("L2CAP"), iProtocolDesc));
}
void CGdpBTResourceManager::Close()
//
// Release shared resources
//
{
iSocketServer.Close();
}
// Define the interface UIDs
const TImplementationProxy ImplementationTable[] =
{
{{0x101f8b5f}, CGdpBTComms::NewL},
};
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
{
aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
return ImplementationTable;
}
TInt E32Dll(TDllReason)
{
return KErrNone;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -