PageRenderTime 60ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/bluetoothengine/bthid/bthidserver/src/bthidserver.cpp

https://github.com/liskin/btservices-kbdlayout-s60v5
C++ | 1825 lines | 1263 code | 309 blank | 253 comment | 183 complexity | 37be49aa0b95e0d401204f8aeb60066f MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
  3. * All rights reserved.
  4. * This component and the accompanying materials are made available
  5. * under the terms of "Eclipse Public License v1.0"
  6. * which accompanies this distribution, and is available
  7. * at the URL "http://www.eclipse.org/legal/epl-v10.html".
  8. *
  9. * Initial Contributors:
  10. * Nokia Corporation - initial contribution.
  11. *
  12. * Contributors:
  13. *
  14. * Description: This is the implementation of application class
  15. *
  16. */
  17. #include <e32svr.h>
  18. #include <s32file.h>
  19. #include <bt_sock.h>
  20. #include <sysutil.h>
  21. //#include <hal.h> // for checking the MachineUID. also link to hal.lib
  22. #include <e32std.h>
  23. //#include <btmanclient.h>
  24. #include <btnotif.h>
  25. #include "bthidserver.h"
  26. #include "bthidsession.h"
  27. #include "bthidclientsrv.h"
  28. #include "bthidconnection.h"
  29. #include "socketlistener.h"
  30. #include "bthidtypes.h"
  31. #include "bthiddevice.h"
  32. #include "hiddescriptorlist.h"
  33. #include "hiddescriptor.h"
  34. #include "bthidserver.pan"
  35. #include "debug.h"
  36. #include "debugconfig.h"
  37. #include "hidgeneric.h"
  38. #include "hidlayoutids.h"
  39. #include "bthidPsKey.h"
  40. #include "hidsdpclient.h"
  41. #ifndef DBG
  42. #ifdef _DEBUG
  43. #define DBG(a) a
  44. #else
  45. #define DBG(a)
  46. #endif
  47. #endif
  48. //File store location
  49. _LIT(KFileStore,"C:\\private\\2001E301\\bthiddevices.dat");
  50. /** PubSub key read and write policies */
  51. _LIT_SECURITY_POLICY_C2( KBTHIDPSKeyReadPolicy,
  52. ECapabilityLocalServices, ECapabilityReadDeviceData );
  53. _LIT_SECURITY_POLICY_C2( KBTHIDPSKeyWritePolicy,
  54. ECapabilityLocalServices, ECapabilityWriteDeviceData );
  55. // A version number to use when storing device information
  56. // Only for future proofing.
  57. const TInt KDataFileVersionNumber = 1;
  58. CBTHidServer::CBTHidServer() :
  59. CGenericServer(CActive::EPriorityStandard)
  60. {
  61. // Implementation not required
  62. }
  63. CBTHidServer::~CBTHidServer()
  64. {
  65. delete iShutDownTimer;
  66. delete iControlListener;
  67. delete iInterruptListener;
  68. delete iBTConnIndex;
  69. delete iMasterContIndex; // Causes deletion of iBTConnContainer
  70. if (iTempInterrupt)
  71. {
  72. iTempInterrupt->Close();
  73. delete iTempInterrupt;
  74. }
  75. if (iTempControl)
  76. {
  77. iTempControl->Close();
  78. delete iTempControl;
  79. }
  80. iFs.Close();
  81. iSocketServ.Close();
  82. iReqs.ResetAndDestroy();
  83. delete iGenHID;
  84. delete iHidSdpClient;
  85. }
  86. CBTHidServer* CBTHidServer::NewL()
  87. {
  88. CBTHidServer* self = CBTHidServer::NewLC();
  89. CleanupStack::Pop(self);
  90. return self;
  91. }
  92. CBTHidServer* CBTHidServer::NewLC()
  93. {
  94. CBTHidServer* self = new (ELeave) CBTHidServer;
  95. CleanupStack::PushL(self);
  96. self->ConstructL();
  97. return self;
  98. }
  99. const TInt KShutdownDelay = 5000000;
  100. void CBTHidServer::StartShutdownTimerIfNoSession()
  101. {
  102. if (!ConnectionCount()
  103. && (!iShutDownTimer || !iShutDownTimer->IsActive()))
  104. {
  105. if (!iShutDownTimer)TRAP_IGNORE(iShutDownTimer = CPeriodic::NewL(CActive::EPriorityStandard));
  106. if (iShutDownTimer)
  107. iShutDownTimer->Start(KShutdownDelay, 0, TCallBack(
  108. CBTHidServer::TimerFired, this));
  109. TRACE_FUNC
  110. }
  111. }
  112. TInt CBTHidServer::TimerFired(TAny* /*aThis*/)
  113. {
  114. TRACE_STATIC_FUNC
  115. CActiveScheduler::Stop();
  116. return KErrNone;
  117. }
  118. void CBTHidServer::CancelShutdownTimer()
  119. {
  120. TRACE_FUNC
  121. delete iShutDownTimer;
  122. iShutDownTimer = NULL;
  123. }
  124. void CBTHidServer::ConstructL()
  125. {
  126. TRACE_INFO(_L("CBTHidServer::ConstructL()..."));
  127. iMasterContIndex = CObjectConIx::NewL();
  128. iBTConnContainer = iMasterContIndex->CreateL();
  129. iBTConnIndex = CObjectIx::NewL();
  130. // Connect to the file server
  131. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConstructL(): Connecting to file server"));
  132. User::LeaveIfError(iFs.Connect());
  133. // Make the data storage path (if it doesn't exist)
  134. // If we can't create it, we can still make connections. They just won't
  135. // persist.
  136. iFs.MkDirAll(KFileStore);
  137. // Connect to the socket server.
  138. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConstructL(): Connecting to socket server"));
  139. User::LeaveIfError(iSocketServ.Connect());
  140. // Create initial sockets to accept a connection on the control
  141. // and interrupt channels
  142. iTempControl = new (ELeave) RSocket;
  143. iTempInterrupt = new (ELeave) RSocket;
  144. // Set the security required for incoming connections on the
  145. // control and interrupt channels. This is handled in socket level now.
  146. // Create Socket listeners for the control and interrupt channel
  147. // ETrue, authorisation from user for incoming connection is asked
  148. iControlListener = CSocketListener::NewL(iSocketServ, KL2CAPHidControl,
  149. *this, ETrue);
  150. //no authorisation needs to be asked,
  151. //since it is asked during Control channel re-connection.
  152. iInterruptListener = CSocketListener::NewL(iSocketServ,
  153. KL2CAPHidInterrupt, *this, EFalse);
  154. // Request to accept connections into the sockets just created
  155. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConstructL(): AcceptingConnections..."));
  156. User::LeaveIfError(iControlListener->AcceptConnection(*iTempControl));
  157. User::LeaveIfError(iInterruptListener->AcceptConnection(*iTempInterrupt));
  158. // Create the generic HID:
  159. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConstructL(): Creating Generic HID"));
  160. iGenHID = CGenericHid::NewL(this);
  161. // Load details of any virtually-cabled devices.
  162. // Trap the error, but we can live with failure to load stored
  163. // information. The file may be corrupt and we don't want this
  164. // to prevent us using the application
  165. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConstructL(): Loading virtually cabled devices"));
  166. TRAPD( err, LoadVirtuallyCabledDevicesL(KFileStore) );
  167. if (KErrNone != err)
  168. {
  169. err = err;
  170. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConstructL(): Loading virtually cabled devices FAILED"));
  171. }
  172. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConstructL(): Starting the server"));
  173. StartL(KBTHidSrvName);
  174. iActiveState = EFalse;
  175. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConstructL(): Server Started."));
  176. }
  177. CSession2* CBTHidServer::NewSessionL(const TVersion& aVersion,
  178. const RMessage2& /*aMessage*/) const
  179. {
  180. // check we're the right version
  181. if (!User::QueryVersionSupported(TVersion(KBTHIDServMajorVersionNumber,
  182. KBTHIDServMinorVersionNumber, KBTHIDServBuildVersionNumber),
  183. aVersion))
  184. {
  185. User::Leave(KErrNotSupported);
  186. }
  187. const_cast<CBTHidServer*> (this)->CancelShutdownTimer();
  188. // make new session
  189. return CBTHidServerSession::NewL(*const_cast<CBTHidServer*> (this));
  190. }
  191. void CBTHidServer::InformClientsOfStatusChange(
  192. const CBTHidDevice& aDeviceDetails, TBTHidConnState aState)
  193. {
  194. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::InformClientsOfStatusChange, state=%d"),aState) );
  195. if (aState == EBTDeviceConnected ||
  196. aState == EBTDeviceLinkRestored ||
  197. aState == EBTDeviceLinkLost ||
  198. aState == EBTDeviceDisconnected ||
  199. aState == EBTDeviceConnectedFromRemote)
  200. {
  201. iLastUsedAddr = aDeviceDetails.iAddress;
  202. iActiveState = ETrue;
  203. }
  204. else
  205. {
  206. iActiveState = EFalse;
  207. }
  208. InformStatusChange(aDeviceDetails.iAddress, aState);
  209. GlobalNotify(aDeviceDetails.iAddress, aState);
  210. }
  211. void CBTHidServer::InformStatusChange(const TBTDevAddr& aAddress,
  212. TBTHidConnState aState)
  213. {
  214. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::InformStatusChange, state=%d"),aState) );
  215. THIDStateUpdateBuf updateBuf;
  216. THIDStateUpdate& update = updateBuf();
  217. update.iDeviceAddress = aAddress;
  218. update.iState = aState;
  219. // Send to all clients
  220. iSessionIter.SetToFirst();
  221. for (;;)
  222. {
  223. CBTHidServerSession* session;
  224. session = reinterpret_cast<CBTHidServerSession*> (iSessionIter++);
  225. if (!session)
  226. {
  227. break;
  228. }
  229. session->InformStatusChange(updateBuf);
  230. }
  231. }
  232. void CBTHidServer::GlobalNotify(const TBTDevAddr& aDeviceAddr,
  233. TBTHidConnState aState)
  234. {
  235. switch (aState)
  236. {
  237. case EBTDeviceLinkRestored:
  238. case EBTDeviceConnectedFromRemote:
  239. {
  240. HandleAsyncRequest(aDeviceAddr, EBTConnected);
  241. break;
  242. }
  243. case EBTDeviceLinkLost:
  244. case EBTDeviceDisconnected:
  245. case EBTDeviceUnplugged:
  246. {
  247. HandleAsyncRequest(aDeviceAddr, EBTDisconnected);
  248. break;
  249. }
  250. default:
  251. //No need to bother
  252. break;
  253. }
  254. }
  255. TInt CBTHidServer::HandleAsyncRequest(const TBTDevAddr& aDeviceAddr,
  256. TInt aNote)
  257. {
  258. TRAPD(err, HandleAsyncRequestL(aDeviceAddr, aNote));
  259. return err;
  260. }
  261. void CBTHidServer::HandleAsyncRequestL(const TBTDevAddr& aDeviceAddr,
  262. TInt aNote)
  263. {
  264. CBTHidNotifierHelper* notifier = CBTHidNotifierHelper::NewL(*this, aNote, aDeviceAddr);
  265. CleanupStack::PushL(notifier);
  266. iReqs.AppendL(notifier);
  267. CleanupStack::Pop(notifier);
  268. if (iReqs.Count() == 1) // only display our notifier if there's nothing already showing
  269. {
  270. notifier->Start();
  271. }
  272. }
  273. void CBTHidServer::NotifierRequestCompleted()
  274. {
  275. delete iReqs[0];
  276. iReqs.Remove(0);
  277. if (iReqs.Count())
  278. {
  279. iReqs[0]->Start();
  280. }
  281. }
  282. void CBTHidServer::GenericHIDConnectL(CBTHidConnection* aConnection,
  283. TBool aStartDriver)
  284. {
  285. TRACE_INFO(_L("[BTHID]\tCBTHidServer::GenericHIDConnectL"));
  286. CBTHidDevice& devDetails = aConnection->DeviceDetails();
  287. // Search for the first report descriptor and give this
  288. // to Generic HID
  289. TBool foundRepDesc = EFalse;
  290. TInt i = 0;
  291. while ((i < devDetails.iDescList->DescriptorCount()) && (!foundRepDesc))
  292. {
  293. // Get the next descriptor.
  294. const CHidDescriptor& desc =
  295. (*(aConnection->DeviceDetails().iDescList))[i];
  296. if (desc.DescriptorType() == CHidDescriptor::EReportDescriptor)
  297. {
  298. foundRepDesc = ETrue;
  299. User::LeaveIfError(iGenHID->ConnectedL(aConnection->ConnID(),
  300. desc.RawData()));
  301. // Try to start the driver if required.
  302. if (aStartDriver)
  303. {
  304. User::LeaveIfError(iGenHID->DriverActive(
  305. aConnection->ConnID(), CHidTransport::EActive));
  306. }
  307. }
  308. i++;
  309. }
  310. // If we didn't find a report descriptor, the device information is corrupt
  311. if (!foundRepDesc)
  312. {
  313. User::Leave(KErrCorrupt);
  314. }
  315. }
  316. void CBTHidServer::IncrementSessions()
  317. {
  318. iSessionCount++;
  319. CancelShutdownTimer();
  320. }
  321. void CBTHidServer::DecrementSessions()
  322. {
  323. iSessionCount--;
  324. __ASSERT_DEBUG(iSessionCount >= 0, PanicServer(EMainSchedulerError));
  325. if (iSessionCount <= 0)
  326. {
  327. iSessionCount = 0;
  328. StartShutdownTimerIfNoSession();
  329. }
  330. }
  331. TInt CBTHidServer::RunError(TInt aError)
  332. {
  333. if (aError == KErrBadDescriptor)
  334. {
  335. // A bad descriptor error implies a badly programmed client,
  336. // so panic it;
  337. // otherwise report the error to the client
  338. PanicClient(Message(), EBadDescriptor);
  339. }
  340. else
  341. {
  342. Message().Complete(aError);
  343. }
  344. // The leave will result in an early return from CServer::RunL(), skipping
  345. // the call to request another message. So do that now in order to keep the
  346. // server running.
  347. ReStart();
  348. return KErrNone; // handled the error fully
  349. }
  350. void CBTHidServer::PanicClient(const RMessage2& aMessage, TInt aPanic)
  351. {
  352. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::PanicClient(%d)"), aPanic) );
  353. aMessage.Panic(KBTHIDServer, aPanic);
  354. }
  355. void CBTHidServer::PanicServer(TInt aPanic)
  356. {
  357. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::PanicServer( %d )"), aPanic) );
  358. User::Panic(KBTHIDServer, aPanic);
  359. }
  360. void CBTHidServer::ShutdownListeners(TInt aError)
  361. {
  362. // Shutdown listeners and close accepting sockets
  363. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::ShutdownListeners(%d)"), aError) )
  364. (void) aError;
  365. iControlListener->Cancel();
  366. iInterruptListener->Cancel();
  367. if (iTempInterrupt)
  368. {
  369. iTempInterrupt->Close();
  370. }
  371. if (iTempControl)
  372. {
  373. iTempControl->Close();
  374. }
  375. }
  376. TUint CBTHidServer::ConnectionCount()
  377. {
  378. return iBTConnContainer->Count();
  379. }
  380. CBTHidDevice& CBTHidServer::ConnectionDetailsL(TInt aConnID)
  381. {
  382. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  383. return connection->DeviceDetails();
  384. }
  385. TBTEngConnectionStatus CBTHidServer::ConnectStatus(const TBTDevAddr& aAddress)
  386. {
  387. TInt i = 0;
  388. TBool foundItem = EFalse;
  389. TBTEngConnectionStatus retVal = EBTEngNotConnected;
  390. TInt BTConnectionObjCount = iBTConnContainer->Count();
  391. TRACE_INFO(_L("[BTHID]\tCBTHidServer::ConnectStatus()"));
  392. while ((i < BTConnectionObjCount) && (!foundItem))
  393. {
  394. CBTHidConnection *connection =
  395. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  396. if (connection)
  397. {
  398. CBTHidDevice& devDetails = connection->DeviceDetails();
  399. if (devDetails.iAddress == aAddress)
  400. {
  401. foundItem = ETrue;
  402. TBTConnectionState HidConnectionStatus =
  403. connection->ConnectStatus();
  404. if ( (EFirstConnection == HidConnectionStatus) ||
  405. (EConnecting == HidConnectionStatus) ||
  406. (EHIDReconnecting == HidConnectionStatus) ||
  407. (EHostReconnecting == HidConnectionStatus) ||
  408. (EHIDInitConnecting == HidConnectionStatus) )
  409. {
  410. retVal = EBTEngConnecting;
  411. }
  412. if (EConnected == HidConnectionStatus)
  413. {
  414. retVal = EBTEngConnected;
  415. }
  416. }
  417. }
  418. i++;
  419. }
  420. return retVal;
  421. }
  422. TBool CBTHidServer::DeviceExistInContainer(const TBTDevAddr& aAddress)
  423. {
  424. TInt i = 0;
  425. TBool foundItem = EFalse;
  426. TInt BTConnectionObjCount = iBTConnContainer->Count();
  427. TRACE_INFO(_L("[BTHID]\tCBTHidServer::DeviceExistInContainer()"));
  428. while ((i < BTConnectionObjCount) && (!foundItem))
  429. {
  430. CBTHidConnection *connection =
  431. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  432. if (connection)
  433. {
  434. CBTHidDevice& devDetails = connection->DeviceDetails();
  435. if (devDetails.iAddress == aAddress)
  436. {
  437. foundItem = ETrue;
  438. }
  439. }
  440. i++;
  441. }
  442. return foundItem;
  443. }
  444. TBool CBTHidServer::GetConnectionAddress(TDes8& aAddressBuf)
  445. {
  446. TInt i = 0;
  447. TBool retVal = EFalse;
  448. TInt BTConnectionObjCount = iBTConnContainer->Count();
  449. TRACE_INFO(_L("[BTHID]\tCBTHidServer::IsAllowToConnect()"));
  450. while ((i < BTConnectionObjCount))
  451. {
  452. CBTHidConnection *connection =
  453. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  454. if (connection)
  455. {
  456. CBTHidDevice& devDetails = connection->DeviceDetails();
  457. if (connection->IsConnected())
  458. {
  459. retVal = ETrue;
  460. aAddressBuf.Append((devDetails.iAddress).Des());
  461. if (aAddressBuf.Length() == KBTDevAddrSize * 2)
  462. break;
  463. }
  464. }
  465. i++;
  466. }
  467. return retVal;
  468. }
  469. TBool CBTHidServer::IsAllowToConnectFromServerSide(TUint aDeviceSubClass)
  470. {
  471. TInt i = 0;
  472. TBool retVal = ETrue;
  473. TInt BTConnectionObjCount = iBTConnContainer->Count();
  474. TRACE_INFO(_L("[BTHID]\tCBTHidServer::IsAllowToConnectFromServerSide()"));
  475. while ((i < BTConnectionObjCount) && retVal)
  476. {
  477. CBTHidConnection *connection =
  478. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  479. if (connection)
  480. {
  481. CBTHidDevice& devDetails = connection->DeviceDetails();
  482. TBTConnectionState HidConnectionStatus =
  483. connection->ConnectStatus();
  484. if (connection->IsConnected() ||
  485. HidConnectionStatus == EHIDReconnecting ||
  486. HidConnectionStatus == EHIDInitConnecting)
  487. {
  488. if ((IsKeyboard(aDeviceSubClass) && IsKeyboard(
  489. devDetails.iDeviceSubClass)) || (IsPointer(
  490. aDeviceSubClass) && IsPointer(
  491. devDetails.iDeviceSubClass)))
  492. {
  493. retVal = EFalse;
  494. iConflictAddr = devDetails.iAddress;
  495. }
  496. }
  497. }
  498. i++;
  499. }
  500. return retVal;
  501. }
  502. TBool CBTHidServer::IsKeyboard(TUint aDeviceSubClass)
  503. {
  504. TUint deviceSubClass = aDeviceSubClass;
  505. TBool retVal = EFalse;
  506. if ((deviceSubClass >> 2) & EMinorDevicePeripheralKeyboard)
  507. {
  508. retVal = ETrue;
  509. }
  510. return retVal;
  511. }
  512. TBool CBTHidServer::IsPointer(TUint aDeviceSubClass)
  513. {
  514. TUint deviceSubClass = aDeviceSubClass;
  515. TBool retVal = EFalse;
  516. if ((deviceSubClass >> 2) & EMinorDevicePeripheralPointer)
  517. {
  518. retVal = ETrue;
  519. }
  520. return retVal;
  521. }
  522. TBool CBTHidServer::IsAllowToConnectFromClientSide(TBTDevAddr aDevAddr)
  523. {
  524. TInt i = 0;
  525. TBool retVal = ETrue;
  526. TInt BTConnectionObjCount = iBTConnContainer->Count();
  527. TUint deviceSubClass = GetDeviceSubClass(aDevAddr);
  528. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::IsAllowToConnectFromClientSide() BTConnectionObjCount = %d"), BTConnectionObjCount) );
  529. while ((i < BTConnectionObjCount) && retVal)
  530. {
  531. CBTHidConnection *connection =
  532. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  533. if (connection)
  534. {
  535. CBTHidDevice& devDetails = connection->DeviceDetails();
  536. TBTConnectionState HidConnectionStatus =
  537. connection->ConnectStatus();
  538. if (connection->IsConnected() ||
  539. HidConnectionStatus == EConnecting ||
  540. HidConnectionStatus == EHIDInitConnecting)
  541. {
  542. if (devDetails.iAddress != aDevAddr)
  543. {
  544. if ((IsKeyboard(deviceSubClass) && IsKeyboard(
  545. devDetails.iDeviceSubClass)) || (IsPointer(
  546. deviceSubClass) && IsPointer(
  547. devDetails.iDeviceSubClass)))
  548. {
  549. TRACE_INFO(_L("[BTHID]\tCBTHidServer::() NO connection allowed, connection exist already!"));
  550. retVal = EFalse;
  551. iConflictAddr = devDetails.iAddress;
  552. }
  553. }
  554. }
  555. }
  556. i++;
  557. }
  558. return retVal;
  559. }
  560. TUint CBTHidServer::GetDeviceSubClass(TBTDevAddr aDevAddr)
  561. {
  562. TInt i = 0;
  563. TUint deviceSubClass = 0;
  564. TInt BTConnectionObjCount = iBTConnContainer->Count();
  565. TRACE_INFO(_L("[BTHID]\tCBTHidServer::GetMinorDeviceClass()"));
  566. while (i < BTConnectionObjCount)
  567. {
  568. CBTHidConnection *connection =
  569. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  570. if (connection)
  571. {
  572. CBTHidDevice& devDetails = connection->DeviceDetails();
  573. if (devDetails.iAddress == aDevAddr)
  574. {
  575. deviceSubClass = devDetails.iDeviceSubClass;
  576. }
  577. }
  578. i++;
  579. }
  580. return deviceSubClass;
  581. }
  582. TBTDevAddr CBTHidServer::ConflictAddress()
  583. {
  584. return iConflictAddr;
  585. }
  586. void CBTHidServer::CleanOldConnection(TInt aConnID)
  587. {
  588. TInt i = 0;
  589. TBTDevAddr currentAddr;
  590. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::CleanOldConnection() aConnID[%d]"), aConnID) );
  591. CBTHidConnection* connection =
  592. static_cast<CBTHidConnection*>(iBTConnIndex->At(aConnID));
  593. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::CleanOldConnection() aConnID[%d]"), aConnID) );
  594. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  595. if (connection)
  596. {
  597. TRACE_INFO( _L("[BTHID]\tCBTHidServer::CleanOldConnection() if ") );
  598. CBTHidDevice& currentDetails = connection->DeviceDetails();
  599. currentAddr = currentDetails.iAddress;
  600. TRACE_INFO( _L("[BTHID]\tCBTHidServer::CleanOldConnection() if 1") );
  601. while (i < iBTConnContainer->Count())
  602. {
  603. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::CleanOldConnection() i = [%d]"), i) );
  604. connection = static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  605. if (connection)
  606. {
  607. CBTHidDevice& devDetails = connection->DeviceDetails();
  608. if (devDetails.iAddress == currentAddr && !(connection->IsConnected()))
  609. {
  610. TRACE_INFO( _L("[BTHID]\tCBTHidServer::CleanOldConnection() if 2") );
  611. iGenHID->Disconnected(connection->ConnID());
  612. iBTConnIndex->Remove(connection->ConnID());
  613. }
  614. }
  615. i++;
  616. }
  617. }
  618. return;
  619. }
  620. TInt CBTHidServer::NewConnectionL(TBTConnectionState aConnectionStatus)
  621. {
  622. TRACE_INFO(_L("[BTHID]\tCBTHidServer::NewConnectionL"));
  623. __ASSERT_DEBUG( aConnectionStatus == EConnecting || aConnectionStatus == EHIDInitConnecting ,
  624. CBTHidServer::PanicServer(EBadState));
  625. CBTHidConnection *connection = CBTHidConnection::NewLC(iSocketServ,
  626. *this, aConnectionStatus);
  627. // Add to the connection container object.
  628. iBTConnContainer->AddL(connection);
  629. CleanupStack::Pop(); // connection
  630. // Now add the object to the index to get an id.
  631. // We can't let this just leave since we have already inserted the
  632. // connection object into the container.
  633. TInt id = 0;
  634. TRAPD( res,
  635. id = iBTConnIndex->AddL(connection);
  636. connection->SetConnID(id);
  637. )
  638. if (res != KErrNone)
  639. {
  640. // Couldn't make an index entry.
  641. // Close the connection object, causing it to be removed from the
  642. // container
  643. connection->Close();
  644. User::Leave(res);
  645. }
  646. return id;
  647. }
  648. void CBTHidServer::DoFirstConnectionL(TInt aConnID)
  649. {
  650. TRACE_INFO(_L("[BTHID]\tCBTHidServer::DoFirstConnectionL"));
  651. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  652. CBTHidDevice &devDetails = ConnectionDetailsL(aConnID);
  653. DBG(TUint DeviceClass = devDetails.iDeviceSubClass;
  654. DBG(RDebug::Print(_L("[BTHID]\tCBTHidServer::DoFirstConnectionL iDeviceSubClass = %d"), DeviceClass));
  655. )
  656. if (!IsAllowToConnectFromServerSide(devDetails.iDeviceSubClass))
  657. {
  658. User::Leave(KErrAlreadyExists);
  659. }
  660. connection->ConnectL();
  661. }
  662. void CBTHidServer::DeleteNewConnection(TInt aConnID)
  663. {
  664. TRACE_INFO(_L("[BTHID]\tCBTHidServer::DeleteNewConnection"));
  665. iBTConnIndex->Remove(aConnID);
  666. }
  667. /*Asks the server to disconnect (virtual cable unplug) a device totally,
  668. * remove the connection entry from the connection container.
  669. */
  670. void CBTHidServer::CloseBluetoothConnection(const TBTDevAddr& aAddress)
  671. {
  672. TInt i = 0;
  673. TBool foundItem = EFalse;
  674. TRACE_INFO(_L("[BTHID]\tCBTHidServer::CloseBluetoothConnection"));
  675. while ((i < iBTConnContainer->Count()) && (!foundItem))
  676. {
  677. CBTHidConnection *connection =
  678. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  679. CBTHidDevice& devDetails = connection->DeviceDetails();
  680. if (devDetails.iAddress == aAddress)
  681. {
  682. foundItem = ETrue;
  683. // Inform the Generic HID of the disconnection.
  684. iGenHID->Disconnected(connection->ConnID());
  685. // Get it to disconnect if its connected.
  686. connection->Disconnect();
  687. InformClientsOfStatusChange(connection->DeviceDetails(),
  688. EBTDeviceDisconnected);
  689. // Delete the connection object.
  690. iBTConnIndex->Remove(connection->ConnID());
  691. // Update the stored devices, as we could have power off
  692. // and no clean shutdown.
  693. // Use the non-leaving version.
  694. StoreVirtuallyCabledDevices(KFileStore);
  695. }
  696. i++;
  697. }
  698. }
  699. /*Asks the server to disconnect all the devices totally,
  700. * remove the connection entries from the connection container.
  701. */
  702. void CBTHidServer::CloseAllBluetoothConnection()
  703. {
  704. TInt i = 0;
  705. TRACE_INFO(_L("[BTHID]\tCBTHidServer::CloseAllBluetoothConnection"));
  706. while (i < iBTConnContainer->Count())
  707. {
  708. CBTHidConnection *connection =
  709. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  710. if (connection)
  711. {
  712. if (connection->IsConnected())
  713. {
  714. // Inform the Generic HID of the disconnection.
  715. iGenHID->Disconnected(connection->ConnID());
  716. // Get it to disconnect if its connected.
  717. connection->Disconnect();
  718. InformClientsOfStatusChange(connection->DeviceDetails(),
  719. EBTDeviceDisconnected);
  720. // Delete the connection object.
  721. iBTConnIndex->Remove(connection->ConnID());
  722. // Update the stored devices, as we could have power off
  723. // and no clean shutdown.
  724. // Use the non-leaving version.
  725. StoreVirtuallyCabledDevices(KFileStore);
  726. }
  727. }
  728. i++;
  729. }
  730. }
  731. void CBTHidServer::DisconnectDeviceL(const TBTDevAddr& aAddress)
  732. {
  733. TInt i = 0;
  734. TBool foundItem = EFalse;
  735. TRACE_INFO(_L("[BTHID]\tCBTHidServer::DisconnectDeviceL"));
  736. while ((i < iBTConnContainer->Count()) && (!foundItem))
  737. {
  738. CBTHidConnection *connection =
  739. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  740. CBTHidDevice& devDetails = connection->DeviceDetails();
  741. if (devDetails.iAddress == aAddress)
  742. {
  743. foundItem = ETrue;
  744. // Drop the bluetooth connection.
  745. connection->DropConnection();
  746. // Stop the driver.
  747. iGenHID->DriverActive(connection->ConnID(),
  748. CHidTransport::ESuspend);
  749. InformClientsOfStatusChange(connection->DeviceDetails(),
  750. EBTDeviceDisconnected);
  751. //Microsoft Keyboard & other "Unsecure" devices
  752. CheckAndSetControlListenerSecurityL(
  753. connection->DeviceDetails().iUseSecurity);
  754. }
  755. i++;
  756. }
  757. }
  758. void CBTHidServer::DisconnectAllDeviceL()
  759. {
  760. TInt i = 0;
  761. TRACE_INFO(_L("[BTHID]\tCBTHidServer::DisconnectAllDeviceL"));
  762. while (i < iBTConnContainer->Count())
  763. {
  764. CBTHidConnection *connection =
  765. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  766. if (connection)
  767. {
  768. if (connection->IsConnected())
  769. {
  770. CBTHidDevice& devDetails = connection->DeviceDetails();
  771. // Drop the bluetooth connection.
  772. connection->DropConnection();
  773. // Stop the driver.
  774. iGenHID->DriverActive(connection->ConnID(),
  775. CHidTransport::ESuspend);
  776. InformClientsOfStatusChange(devDetails,
  777. EBTDeviceDisconnected);
  778. //Microsoft Keyboard & other "Unsecure" devices
  779. CheckAndSetControlListenerSecurityL(
  780. devDetails.iUseSecurity);
  781. }
  782. i++;
  783. }
  784. }
  785. }
  786. void CBTHidServer::CheckAndSetControlListenerSecurityL(TBool aSec)
  787. {
  788. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::CheckAndSetControlListenerSecurityL(%d)"), aSec) );
  789. //Checking for Microsoft Keyboard & other "Unsecure" devices
  790. if (!aSec) //Security is set on in Constructor of listener. This overrides that setting.
  791. {
  792. delete iControlListener;
  793. iControlListener = NULL;
  794. if (iTempControl)
  795. iTempControl->Close();
  796. iControlListener = CSocketListener::NewL(iSocketServ,
  797. KL2CAPHidControl, *this, EFalse); //iAuthorisationFlag); We need authorisation, unless otherwise stated.
  798. User::LeaveIfError(iControlListener->AcceptConnection(*iTempControl));
  799. }
  800. }
  801. // from MBTConnectionObserver
  802. void CBTHidServer::HandleControlData(TInt aConnID, const TDesC8& aBuffer)
  803. {
  804. iGenHID->DataIn(aConnID, CHidTransport::EHidChannelCtrl, aBuffer);
  805. }
  806. void CBTHidServer::HandleCommandAck(TInt aConnID, TInt aStatus)
  807. {
  808. iGenHID->CommandResult(aConnID, aStatus);
  809. }
  810. void CBTHidServer::HandleInterruptData(TInt aConnID, const TDesC8& aBuffer)
  811. {
  812. iGenHID->DataIn(aConnID, CHidTransport::EHidChannelInt, aBuffer);
  813. }
  814. void CBTHidServer::FirstTimeConnectionComplete(TInt aConnID, TInt aStatus)
  815. {
  816. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::FirstTimeConnectionComplete(%d)"), aStatus));
  817. TInt error = aStatus;
  818. CBTHidConnection* connection =
  819. static_cast<CBTHidConnection*> (iBTConnIndex->At(aConnID));
  820. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  821. if (error == KErrNone)
  822. {
  823. TBool genHidConnected = EFalse;
  824. TRAP( error,
  825. // Inform the Generic HID of the Connection
  826. GenericHIDConnectL(connection, ETrue);
  827. // Record that we got as far as informing the Generic HID.
  828. genHidConnected = ETrue;
  829. // Try to start monitoring the channels.
  830. connection->StartMonitoringChannelsL();
  831. )
  832. if (error != KErrNone)
  833. {
  834. // If we informed the Generic HID of the connection, then
  835. // we must also disconnect.
  836. if (genHidConnected)
  837. {
  838. iGenHID->Disconnected(aConnID);
  839. }
  840. // Delete the connection object.
  841. iBTConnIndex->Remove(aConnID);
  842. }
  843. else
  844. {
  845. // Update the stored devices, as we could have power off
  846. // and no clean shutdown.
  847. // Use the non-leaving version.
  848. TRACE_INFO( _L("[BTHID]\tCBTHidServer::FirstTimeConnectionComplete() before CleanOldConnection") );
  849. CleanOldConnection(aConnID);
  850. TRACE_INFO( _L("[BTHID]\tCBTHidServer::FirstTimeConnectionComplete() after CleanOldConnection") );
  851. StoreVirtuallyCabledDevices(KFileStore);
  852. }
  853. }
  854. else
  855. {
  856. iBTConnIndex->Remove(aConnID);
  857. }
  858. // Report the connection result to the sessions.
  859. iSessionIter.SetToFirst();
  860. for (;;)
  861. {
  862. CBTHidServerSession* session;
  863. session = reinterpret_cast<CBTHidServerSession*> (iSessionIter++);
  864. if (!session)
  865. {
  866. break;
  867. }
  868. session->InformConnectionResult(aConnID, error);
  869. }
  870. }
  871. void CBTHidServer::FirstTimeConnectionCompleteFromRemote(TInt aConnID, TInt aStatus)
  872. {
  873. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::FirstTimeConnectionCompleteFromRemote(%d)"), aStatus));
  874. TInt error = aStatus;
  875. CBTHidConnection* connection =
  876. static_cast<CBTHidConnection*> (iBTConnIndex->At(aConnID));
  877. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  878. if (error == KErrNone)
  879. {
  880. TBool genHidConnected = EFalse;
  881. TRAP( error,
  882. // Inform the Generic HID of the Connection
  883. GenericHIDConnectL(connection, ETrue);
  884. // Record that we got as far as informing the Generic HID.
  885. genHidConnected = ETrue;
  886. // Try to start monitoring the channels.
  887. connection->StartMonitoringChannelsL();
  888. )
  889. if (error != KErrNone)
  890. {
  891. // If we informed the Generic HID of the connection, then
  892. // we must also disconnect.
  893. if (genHidConnected)
  894. {
  895. iGenHID->Disconnected(aConnID);
  896. }
  897. // Delete the connection object.
  898. //Quietly refuse the remote initialized connection in case of error.
  899. //No need to bother user.
  900. iBTConnIndex->Remove(aConnID);
  901. }
  902. else
  903. {
  904. // Update the stored devices, as we could have power off
  905. // and no clean shutdown.
  906. // Use the non-leaving version.
  907. CleanOldConnection(aConnID);
  908. StoreVirtuallyCabledDevices(KFileStore);
  909. InformClientsOfStatusChange(connection->DeviceDetails(),
  910. EBTDeviceConnectedFromRemote);
  911. }
  912. }
  913. else
  914. {
  915. //Quietly refuse the remote initialized connection in case of error.
  916. //No need to bother user.
  917. iBTConnIndex->Remove(aConnID);
  918. }
  919. }
  920. void CBTHidServer::StartSDPSearch(TInt aConnID)
  921. {
  922. iConnID = aConnID;
  923. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::StartSDPSearch aConnID= (%d)"), aConnID));
  924. CBTHidConnection* connection =
  925. static_cast<CBTHidConnection*> (iBTConnIndex->At(iConnID));
  926. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  927. TRAPD( res,
  928. // Retrieve the hid device object for this new connection
  929. CBTHidDevice &devDetails =
  930. ConnectionDetailsL(iConnID);
  931. // Create a new HID Sdp Client
  932. // Its only used here so it doesn't matter if we leave.
  933. delete iHidSdpClient;
  934. iHidSdpClient = 0;
  935. //Create a new hid sdp client using the hid device object.
  936. iHidSdpClient = CHidSdpClient::NewL(devDetails, *this);
  937. // Start the hid sdp client
  938. iHidSdpClient->StartL();
  939. )
  940. if (res != KErrNone)
  941. {
  942. // Get the server to delete the new connection object
  943. DeleteNewConnection(iConnID);
  944. }
  945. }
  946. void CBTHidServer::HidSdpSearchComplete(TInt aResult)
  947. {
  948. TRACE_FUNC(_L("[BTHID]\tCBTHidServer::HidSdpSearchComplete"));
  949. // This is a callback from the Hid SDP client so we can't delete it here
  950. // Get it to destroy itself when its convenient.
  951. iHidSdpClient->Kill();
  952. // Deleted outside destructor.
  953. iHidSdpClient = 0;
  954. // If the SDP search was a success
  955. if (aResult == KErrNone)
  956. {
  957. // Try to connect to the device as a HID
  958. CBTHidConnection* connection =
  959. static_cast<CBTHidConnection*> (iBTConnIndex->At(iConnID));
  960. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  961. if (connection)
  962. {
  963. CBTHidDevice& devDetails = connection->DeviceDetails();
  964. //Only after SDP search complete, do we know the CoD which is needed
  965. //to tell if the incoming connection is allowed or not.
  966. //ETrue , establish the connection.
  967. //EFalse, refuse the remote connecion sliently
  968. if (IsAllowToConnectFromClientSide(devDetails.iAddress))
  969. {
  970. FirstTimeConnectionCompleteFromRemote(iConnID, aResult);
  971. }
  972. else
  973. {
  974. FirstTimeConnectionCompleteFromRemote(iConnID, KErrAlreadyExists);
  975. }
  976. }
  977. }
  978. }
  979. void CBTHidServer::LinkLost(TInt aConnID)
  980. {
  981. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::LinkLost(%d)"), aConnID));
  982. // Stop the driver.
  983. iGenHID->DriverActive(aConnID, CHidTransport::ESuspend);
  984. CBTHidConnection* connection =
  985. static_cast<CBTHidConnection*> (iBTConnIndex->At(aConnID));
  986. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  987. // Inform clients of the change in status of this connection.
  988. InformClientsOfStatusChange(connection->DeviceDetails(),
  989. EBTDeviceLinkLost);
  990. }
  991. void CBTHidServer::LinkRestored(TInt aConnID)
  992. {
  993. CBTHidConnection* connection =
  994. static_cast<CBTHidConnection*> (iBTConnIndex->At(aConnID));
  995. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  996. // Inform the Generic HID of the reconnection
  997. TInt error = iGenHID->DriverActive(aConnID, CHidTransport::EActive);
  998. // If there was no error, try to start monitoring the channels.
  999. if (error == KErrNone)
  1000. {
  1001. // Try to start monitoring channels.
  1002. TRAP( error, connection->StartMonitoringChannelsL(); )
  1003. }
  1004. // Report new connection status.
  1005. if (error == KErrNone)
  1006. {
  1007. InformClientsOfStatusChange(connection->DeviceDetails(),
  1008. EBTDeviceLinkRestored);
  1009. }
  1010. else
  1011. {
  1012. InformClientsOfStatusChange(connection->DeviceDetails(),
  1013. EBTDeviceUnplugged);
  1014. // Inform the Generic HID of the disconnection.
  1015. iGenHID->Disconnected(aConnID);
  1016. // Delete the connection object.
  1017. iBTConnIndex->Remove(aConnID);
  1018. // Update the stored devices, as we could have power off
  1019. // and no clean shutdown.
  1020. // Use the non-leaving version.
  1021. StoreVirtuallyCabledDevices(KFileStore);
  1022. }
  1023. }
  1024. void CBTHidServer::Disconnected(TInt aConnID)
  1025. {
  1026. CBTHidConnection *connection =
  1027. static_cast<CBTHidConnection*> (iBTConnIndex->At(aConnID));
  1028. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  1029. // Stop the driver.
  1030. iGenHID->DriverActive(aConnID, CHidTransport::ESuspend);
  1031. // Report new connection status.
  1032. InformClientsOfStatusChange(connection->DeviceDetails(),
  1033. EBTDeviceDisconnected);
  1034. //Check if no security is needed for listening socket
  1035. //Microsoft Keyboard & other "Unsecure" devices need this.
  1036. // possible leave is sign of severe problems in BT stack. So no reason to handle leave.
  1037. TRAP_IGNORE( CheckAndSetControlListenerSecurityL(connection->DeviceDetails().iUseSecurity) );
  1038. }
  1039. void CBTHidServer::Unplugged(TInt aConnID)
  1040. {
  1041. CBTHidConnection *connection =
  1042. static_cast<CBTHidConnection*> (iBTConnIndex->At(aConnID));
  1043. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  1044. // Report new connection status.
  1045. InformClientsOfStatusChange(connection->DeviceDetails(),
  1046. EBTDeviceUnplugged);
  1047. // Inform the Generic HID of the disconnection.
  1048. iGenHID->Disconnected(aConnID);
  1049. iBTConnIndex->Remove(aConnID);
  1050. // Update the stored devices, as we could have power off
  1051. // and no clean shutdown.
  1052. // Use the non-leaving version.
  1053. StoreVirtuallyCabledDevices(KFileStore);
  1054. }
  1055. //from MListenerObserver
  1056. void CBTHidServer::SocketAccepted(TUint aPort, TInt aErrorCode)
  1057. {
  1058. TBTSockAddr sockAddr;
  1059. TBTDevAddr devAddr;
  1060. TRACE_INFO( (_L("[BTHID]\tCBTHidServer::SocketAccepted, port=%d, error code=%d"), aPort, aErrorCode) );
  1061. // Check error code
  1062. if (aErrorCode != KErrNone)
  1063. {
  1064. // If we do get an error there isn't much we can about it.
  1065. // Just tidy up.
  1066. ShutdownListeners(aErrorCode);
  1067. }
  1068. else
  1069. {
  1070. TInt i = 0;
  1071. TInt err = KErrNone;
  1072. TInt connectingID = 0;
  1073. // Check which port has accepted a connection
  1074. switch (aPort)
  1075. {
  1076. // The HID Control Channel
  1077. case KL2CAPHidControl:
  1078. // Get the BT address of the device that has connected
  1079. iTempControl->RemoteName(sockAddr);
  1080. devAddr = sockAddr.BTAddr();
  1081. // incoming HID connection is allowed
  1082. if (!DeviceExistInContainer(devAddr))
  1083. {
  1084. TRAPD( res,
  1085. // to be created as New if device not yet listed in container
  1086. connectingID = NewConnectionL(EHIDInitConnecting);
  1087. // Retrieve the hid device object for this new connection
  1088. CBTHidDevice &devDetails =
  1089. ConnectionDetailsL(connectingID);
  1090. // Fill in the information we got from the client
  1091. devDetails.iAddress = devAddr;
  1092. devDetails.iUseSecurity = ETrue;
  1093. )
  1094. if (res != KErrNone && connectingID != 0)
  1095. {
  1096. // Get the server to delete the new connection object
  1097. DeleteNewConnection(connectingID);
  1098. }
  1099. }
  1100. if (IsAllowToConnectFromClientSide(devAddr))
  1101. {
  1102. TInt count = iBTConnContainer->Count();
  1103. while ((i < count) && (iTempControl))
  1104. {
  1105. CBTHidConnection
  1106. * connection =
  1107. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  1108. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  1109. connection->OfferControlSocket(devAddr, iTempControl);
  1110. i++;
  1111. }
  1112. }
  1113. else
  1114. {
  1115. InformStatusChange(devAddr, EBTDeviceAnotherExist);
  1116. }
  1117. // The next socket to accept into
  1118. if (iTempControl)
  1119. {
  1120. // Reuse this socket
  1121. iTempControl->Close();
  1122. err = KErrNone;
  1123. }
  1124. else
  1125. {
  1126. // Socket ownership has been transferred so create a new
  1127. // socket
  1128. //TRAP( err, iTempControl = new (ELeave) RSocket; )
  1129. iTempControl = new RSocket;
  1130. }
  1131. // Created a socket to accept into so accept next connection
  1132. if (err == KErrNone)
  1133. {
  1134. err = iControlListener->AcceptConnection(*iTempControl);
  1135. }
  1136. // If we failed to allocate a new RSocket or failed
  1137. // in the AcceptConnectionL call it means we can no longer
  1138. // accept connections from a device.
  1139. if (err != KErrNone)
  1140. {
  1141. TRACE_INFO(_L("[BTHID]\tCBTHidServer::SocketAccepted, control channel failed, shutdown listener"));
  1142. ShutdownListeners(err);
  1143. }
  1144. break;
  1145. // The HID Interrupt Channel
  1146. case KL2CAPHidInterrupt:
  1147. // Get the BT address of the device that has connected
  1148. iTempInterrupt->RemoteName(sockAddr);
  1149. devAddr = sockAddr.BTAddr();
  1150. if (IsAllowToConnectFromClientSide(devAddr))
  1151. {
  1152. TInt count = iBTConnContainer->Count();
  1153. while ((i < count) && (iTempInterrupt))
  1154. {
  1155. CBTHidConnection
  1156. *connection =
  1157. static_cast<CBTHidConnection*> ((*iBTConnContainer)[i]);
  1158. __ASSERT_ALWAYS(connection, PanicServer(EInvalidHandle));
  1159. connection->OfferInterruptSocket(devAddr,
  1160. iTempInterrupt);
  1161. i++;
  1162. }
  1163. }
  1164. else
  1165. {
  1166. //Commented for avoiding display the same notes twice for same device
  1167. //because of two channels(Control+Interrupt) has been rejected
  1168. //InformStatusChange(devAddr, EBTDeviceAnotherExist);
  1169. }
  1170. // The next socket to accept into
  1171. if (iTempInterrupt)
  1172. {
  1173. // Reuse this socket
  1174. iTempInterrupt->Close();
  1175. err = KErrNone;
  1176. }
  1177. else
  1178. {
  1179. // Socket ownership has been transferred so create a new
  1180. // socket
  1181. //TRAP( err, iTempInterrupt = new (ELeave) RSocket; )
  1182. iTempInterrupt = new RSocket;
  1183. }
  1184. // Created a socket to accept into so accept next connection
  1185. if (err == KErrNone)
  1186. {
  1187. err = iInterruptListener->AcceptConnection(
  1188. *iTempInterrupt);
  1189. }
  1190. // If we failed to allocate a new RSocket or failed
  1191. // in the AcceptConnectionL call it means we can no longer
  1192. // accept connections from a device.
  1193. if (err != KErrNone)
  1194. {
  1195. TRACE_INFO(_L("[BTHID]\tCBTHidServer::SocketAccepted, interrupt channel failed, shutdown listener"));
  1196. ShutdownListeners(err);
  1197. }
  1198. break;
  1199. default:
  1200. PanicServer(EInvalidHandle);
  1201. break;
  1202. }
  1203. }
  1204. }
  1205. //from MTransportLayer
  1206. TUint CBTHidServer::CountryCodeL(TInt aConnID)
  1207. {
  1208. // Identify the connection object.
  1209. CBTHidConnection* conn = IdentifyConnectionL(aConnID);
  1210. // Retrieve its device details.
  1211. const CBTHidDevice& device = conn->DeviceDetails();
  1212. //return the country code
  1213. return device.iCountryCode;
  1214. }
  1215. TUint CBTHidServer::VendorIdL(TInt aConnID)
  1216. {
  1217. // Identify the connection object.
  1218. CBTHidConnection* conn = IdentifyConnectionL(aConnID);
  1219. // Retrieve its device details.
  1220. const CBTHidDevice& device = conn->DeviceDetails();
  1221. //return the Vendor Id.
  1222. return device.iVendorID;
  1223. }
  1224. TUint CBTHidServer::ProductIdL(TInt aConnID)
  1225. {
  1226. // Identify the connection object.
  1227. CBTHidConnection* conn = IdentifyConnectionL(aConnID);
  1228. // Retrieve its device details.
  1229. const CBTHidDevice& device = conn->DeviceDetails();
  1230. //return the Product Id.
  1231. return device.iProductID;
  1232. }
  1233. void CBTHidServer::GetProtocolL(TInt aConnID, TUint16 /*aInterface*/)
  1234. {
  1235. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  1236. // Bluetooth HID only has one interface. We don't need the interface param.
  1237. connection->GetProtocolL();
  1238. }
  1239. void CBTHidServer::SetProtocolL(TInt aConnID, TUint16 aValue, TUint16 /*aInterface*/)
  1240. {
  1241. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  1242. // Bluetooth HID only has one interface. We don't need the interface param.
  1243. connection->SetProtocolL(aValue);
  1244. }
  1245. void CBTHidServer::GetReportL(TInt aConnID, TUint8 aReportType,
  1246. TUint8 aReportID, TUint16 /*aInterface*/, TUint16 aLength)
  1247. {
  1248. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  1249. // Bluetooth HID only has one interface. We don't need the interface param.
  1250. connection->GetReportL(aReportType, aReportID, aLength);
  1251. }
  1252. void CBTHidServer::SetReportL(TInt aConnID, TUint8 aReportType,
  1253. TUint8 aReportID, TUint16 /*aInterface*/, const TDesC8& aReport)
  1254. {
  1255. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  1256. // Bluetooth HID only has one interface. We don't need the interface param
  1257. connection->SetReportL(aReportType, aReportID, aReport);
  1258. }
  1259. void CBTHidServer::DataOutL(TInt aConnID, TUint8 aReportID,
  1260. TUint16 /*aInterface*/, const TDesC8& aReport)
  1261. {
  1262. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  1263. // Bluetooth HID only has one interface. We don't need the interface param
  1264. connection->DataOutL(aReportID, aReport); //we disregard DATA Input, DATA Feature and DATA Other
  1265. }
  1266. void CBTHidServer::GetIdleL(TInt aConnID, TUint8 /*aReportID*/, TUint16 /*aInterface*/)
  1267. {
  1268. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  1269. // Bluetooth HID only has one interface. We don't need the interface param.
  1270. // Bluetooth HID doesn't specify Report ID.
  1271. connection->GetIdleL();
  1272. }
  1273. void CBTHidServer::SetIdleL(TInt aConnID, TUint8 aDuration,
  1274. TUint8 /*aReportID*/, TUint16 /*aInterface*/)
  1275. {
  1276. CBTHidConnection *connection = IdentifyConnectionL(aConnID);
  1277. // Bluetooth HID only has one interface. We don't need the interface param.
  1278. // Bluetooth HID doesn't specify Report ID.
  1279. connection->SetIdleL(aDuration);
  1280. }
  1281. CBTHidConnection* CBTHidServer::IdentifyConnectionL(TInt aConnID) const
  1282. {
  1283. CBTHidConnection *connection =
  1284. static_cast<CBTHidConnection*> (iBTConnIndex->At(aConnID));
  1285. if (!connection)
  1286. {
  1287. User::Leave(KErrNotFound);
  1288. }
  1289. return connection;
  1290. }
  1291. void CBTHidServer::LoadVirtuallyCabledDevicesL(const TDesC& aStoreN

Large files files are truncated, but you can click here to view the full file