--- a/bluetoothengine/bthid/bthidserver/src/bthidserver.cpp Fri Mar 12 15:43:23 2010 +0200
+++ b/bluetoothengine/bthid/bthidserver/src/bthidserver.cpp Mon Mar 15 12:41:15 2010 +0200
@@ -38,6 +38,7 @@
#include "hidgeneric.h"
#include "hidlayoutids.h"
#include "bthidPsKey.h"
+#include "hidsdpclient.h"
#ifndef DBG
@@ -98,6 +99,8 @@
delete iGenHID;
+ delete iHidSdpClient;
+
RProperty::Delete( KPSUidBthidSrv, KBTMouseCursorState );
}
@@ -241,8 +244,11 @@
const CBTHidDevice& aDeviceDetails, TBTHidConnState aState)
{
TRACE_INFO( (_L("[BTHID]\tCBTHidServer::InformClientsOfStatusChange, state=%d"),aState) );
- if (aState == EBTDeviceConnected || aState == EBTDeviceLinkRestored
- || aState == EBTDeviceLinkLost || aState == EBTDeviceDisconnected)
+ if (aState == EBTDeviceConnected ||
+ aState == EBTDeviceLinkRestored ||
+ aState == EBTDeviceLinkLost ||
+ aState == EBTDeviceDisconnected ||
+ aState == EBTDeviceConnectedFromRemote)
{
iLastUsedAddr = aDeviceDetails.iAddress;
iActiveState = ETrue;
@@ -286,6 +292,7 @@
switch (aState)
{
case EBTDeviceLinkRestored:
+ case EBTDeviceConnectedFromRemote:
{
HandleAsyncRequest(aDeviceAddr, EBTConnected);
break;
@@ -484,10 +491,11 @@
foundItem = ETrue;
TBTConnectionState HidConnectionStatus =
connection->ConnectStatus();
- if (EFirstConnection == HidConnectionStatus || EConnecting
- == HidConnectionStatus || EHIDReconnecting
- == HidConnectionStatus || EHostReconnecting
- == HidConnectionStatus)
+ if ( (EFirstConnection == HidConnectionStatus) ||
+ (EConnecting == HidConnectionStatus) ||
+ (EHIDReconnecting == HidConnectionStatus) ||
+ (EHostReconnecting == HidConnectionStatus) ||
+ (EHIDInitConnecting == HidConnectionStatus) )
{
retVal = EBTEngConnecting;
}
@@ -504,6 +512,33 @@
return retVal;
}
+TBool CBTHidServer::DeviceExistInContainer(const TBTDevAddr& aAddress)
+ {
+ TInt i = 0;
+ TBool foundItem = EFalse;
+ TInt BTConnectionObjCount = iBTConnContainer->Count();
+
+ TRACE_INFO(_L("[BTHID]\tCBTHidServer::DeviceExistInContainer()"));
+ while ((i < BTConnectionObjCount) && (!foundItem))
+ {
+ CBTHidConnection *connection =
+ static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
+
+ if (connection)
+ {
+ CBTHidDevice& devDetails = connection->DeviceDetails();
+
+ if (devDetails.iAddress == aAddress)
+ {
+ foundItem = ETrue;
+ }
+ }
+ i++;
+ }
+
+ return foundItem;
+ }
+
TBool CBTHidServer::GetConnectionAddress(TDes8& aAddressBuf)
{
TInt i = 0;
@@ -549,8 +584,9 @@
CBTHidDevice& devDetails = connection->DeviceDetails();
TBTConnectionState HidConnectionStatus =
connection->ConnectStatus();
- if (connection->IsConnected() || HidConnectionStatus
- == EHIDReconnecting)
+ if (connection->IsConnected() ||
+ HidConnectionStatus == EHIDReconnecting ||
+ HidConnectionStatus == EHIDInitConnecting)
{
if ((IsKeyboard(aDeviceSubClass) && IsKeyboard(
devDetails.iDeviceSubClass)) || (IsPointer(
@@ -597,7 +633,7 @@
TInt BTConnectionObjCount = iBTConnContainer->Count();
TUint deviceSubClass = GetDeviceSubClass(aDevAddr);
- TRACE_INFO(_L("[BTHID]\tCBTHidServer::IsAllowToConnectFromClientSide()"));
+ TRACE_INFO( (_L("[BTHID]\tCBTHidServer::IsAllowToConnectFromClientSide() BTConnectionObjCount = %d"), BTConnectionObjCount) );
while ((i < BTConnectionObjCount) && retVal)
{
CBTHidConnection *connection =
@@ -608,16 +644,18 @@
CBTHidDevice& devDetails = connection->DeviceDetails();
TBTConnectionState HidConnectionStatus =
connection->ConnectStatus();
- if (connection->IsConnected() || HidConnectionStatus
- == EConnecting)
+ if (connection->IsConnected() ||
+ HidConnectionStatus == EConnecting ||
+ HidConnectionStatus == EHIDInitConnecting)
{
if (devDetails.iAddress != aDevAddr)
- {
+ {
if ((IsKeyboard(deviceSubClass) && IsKeyboard(
devDetails.iDeviceSubClass)) || (IsPointer(
deviceSubClass) && IsPointer(
devDetails.iDeviceSubClass)))
{
+ TRACE_INFO(_L("[BTHID]\tCBTHidServer::() NO connection allowed, connection exist already!"));
retVal = EFalse;
iConflictAddr = devDetails.iAddress;
}
@@ -699,11 +737,14 @@
return;
}
-TInt CBTHidServer::NewConnectionL()
+TInt CBTHidServer::NewConnectionL(TBTConnectionState aConnectionStatus)
{
TRACE_INFO(_L("[BTHID]\tCBTHidServer::NewConnectionL"));
+ __ASSERT_DEBUG( aConnectionStatus == EConnecting || aConnectionStatus == EHIDInitConnecting ,
+ CBTHidServer::PanicServer(EBadState));
+
CBTHidConnection *connection = CBTHidConnection::NewLC(iSocketServ,
- *this, EConnecting);
+ *this, aConnectionStatus);
// Add to the connection container object.
iBTConnContainer->AddL(connection);
CleanupStack::Pop(); // connection
@@ -1012,6 +1053,132 @@
}
}
+void CBTHidServer::FirstTimeConnectionCompleteFromRemote(TInt aConnID, TInt aStatus)
+ {
+ TRACE_INFO( (_L("[BTHID]\tCBTHidServer::FirstTimeConnectionCompleteFromRemote(%d)"), aStatus));
+ TInt error = aStatus;
+
+ CBTHidConnection* connection =
+ static_cast<CBTHidConnection*> (iBTConnIndex->At(aConnID));
+ __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
+
+ if (error == KErrNone)
+ {
+ TBool genHidConnected = EFalse;
+
+ TRAP( error,
+ // Inform the Generic HID of the Connection
+ GenericHIDConnectL(connection, ETrue);
+
+ // Record that we got as far as informing the Generic HID.
+ genHidConnected = ETrue;
+
+ // Try to start monitoring the channels.
+ connection->StartMonitoringChannelsL();
+ )
+
+ if (error != KErrNone)
+ {
+ // If we informed the Generic HID of the connection, then
+ // we must also disconnect.
+ if (genHidConnected)
+ {
+ iGenHID->Disconnected(aConnID);
+ }
+
+ // Delete the connection object.
+ //Quietly refuse the remote initialized connection in case of error.
+ //No need to bother user.
+ iBTConnIndex->Remove(aConnID);
+ }
+ else
+ {
+ // Update the stored devices, as we could have power off
+ // and no clean shutdown.
+ // Use the non-leaving version.
+ CleanOldConnection(aConnID);
+ StoreVirtuallyCabledDevices(KFileStore);
+ InformClientsOfStatusChange(connection->DeviceDetails(),
+ EBTDeviceConnectedFromRemote);
+ }
+ }
+ else
+ {
+ //Quietly refuse the remote initialized connection in case of error.
+ //No need to bother user.
+ iBTConnIndex->Remove(aConnID);
+ }
+ }
+
+void CBTHidServer::StartSDPSearch(TInt aConnID)
+ {
+ iConnID = aConnID;
+ TRACE_INFO( (_L("[BTHID]\tCBTHidServer::StartSDPSearch aConnID= (%d)"), aConnID));
+ CBTHidConnection* connection =
+ static_cast<CBTHidConnection*> (iBTConnIndex->At(iConnID));
+ __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
+
+ TRAPD( res,
+ // Retrieve the hid device object for this new connection
+ CBTHidDevice &devDetails =
+ ConnectionDetailsL(iConnID);
+
+ // Create a new HID Sdp Client
+ // Its only used here so it doesn't matter if we leave.
+ delete iHidSdpClient;
+ iHidSdpClient = 0;
+ //Create a new hid sdp client using the hid device object.
+ iHidSdpClient = CHidSdpClient::NewL(devDetails, *this);
+
+ // Start the hid sdp client
+ iHidSdpClient->StartL();
+ )
+
+ if (res != KErrNone)
+ {
+ // Get the server to delete the new connection object
+ DeleteNewConnection(iConnID);
+ }
+ }
+
+void CBTHidServer::HidSdpSearchComplete(TInt aResult)
+ {
+ TRACE_FUNC(_L("[BTHID]\tCBTHidServer::HidSdpSearchComplete"));
+ // This is a callback from the Hid SDP client so we can't delete it here
+ // Get it to destroy itself when its convenient.
+ iHidSdpClient->Kill();
+ // Deleted outside destructor.
+ iHidSdpClient = 0;
+
+ // If the SDP search was a success
+ if (aResult == KErrNone)
+ {
+ // Try to connect to the device as a HID
+ CBTHidConnection* connection =
+ static_cast<CBTHidConnection*> (iBTConnIndex->At(iConnID));
+ __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
+ if (connection)
+ {
+ CBTHidDevice& devDetails = connection->DeviceDetails();
+
+ //Only after SDP search complete, do we know the CoD which is needed
+ //to tell if the incoming connection is allowed or not.
+ //ETrue , establish the connection.
+ //EFalse, refuse the remote connecion sliently
+ if (IsAllowToConnectFromClientSide(devDetails.iAddress))
+ {
+ FirstTimeConnectionCompleteFromRemote(iConnID, aResult);
+ }
+ else
+ {
+ FirstTimeConnectionCompleteFromRemote(iConnID, KErrAlreadyExists);
+ }
+ }
+
+ }
+ }
+
+
void CBTHidServer::LinkLost(TInt aConnID)
{
TRACE_INFO( (_L("[BTHID]\tCBTHidServer::LinkLost(%d)"), aConnID));
@@ -1126,9 +1293,10 @@
else
{
TInt i = 0;
- TInt count = iBTConnContainer->Count();
+
TInt err = KErrNone;
+ TInt connectingID = 0;
// Check which port has accepted a connection
switch (aPort)
{
@@ -1137,8 +1305,32 @@
// Get the BT address of the device that has connected
iTempControl->RemoteName(sockAddr);
devAddr = sockAddr.BTAddr();
+ // incoming HID connection is allowed
+ if (!DeviceExistInContainer(devAddr))
+ {
+ TRAPD( res,
+ // to be created as New if device not yet listed in container
+ connectingID = NewConnectionL(EHIDInitConnecting);
+
+ // Retrieve the hid device object for this new connection
+ CBTHidDevice &devDetails =
+ ConnectionDetailsL(connectingID);
+
+ // Fill in the information we got from the client
+ devDetails.iAddress = devAddr;
+ devDetails.iUseSecurity = ETrue;
+ )
+
+ if (res != KErrNone && connectingID != 0)
+ {
+ // Get the server to delete the new connection object
+ DeleteNewConnection(connectingID);
+ }
+ }
+
if (IsAllowToConnectFromClientSide(devAddr))
{
+ TInt count = iBTConnContainer->Count();
while ((i < count) && (iTempControl))
{
CBTHidConnection
@@ -1184,7 +1376,7 @@
TRACE_INFO(_L("[BTHID]\tCBTHidServer::SocketAccepted, control channel failed, shutdown listener"));
ShutdownListeners(err);
}
-
+
break;
// The HID Interrupt Channel
@@ -1194,6 +1386,7 @@
devAddr = sockAddr.BTAddr();
if (IsAllowToConnectFromClientSide(devAddr))
{
+ TInt count = iBTConnContainer->Count();
while ((i < count) && (iTempInterrupt))
{
CBTHidConnection