examples/ForumNokia/ThreadAndActiveObjectsEx/src/btdiscoverer.cpp

00001 /*
00002  * Copyright © 2008 Nokia Corporation.
00003  */
00004 
00005 
00006 // INCLUDES
00007 #include "..\inc\btdiscoverer.h"
00008 #include "SharedIntermediator.h"
00009 #include "BluetoothInfo.h"
00010 
00011 #include <btmanclient.h>
00012 #include <btextnotifiers.h>
00013 #include <aknlists.h>
00014 #include <btsdp.h>
00015 
00016 #include <bt_sock.h> 
00017 #include <BTDevice.h>
00018 
00019 _LIT(KBTProtocol, "BTLinkManager");
00020 _LIT( KLine, "-" );
00021 
00022 const TInt KMinBTAddressLength = 5;
00023 const TInt KBufSize = 32;
00024 const TInt KAddressBufSize = 1024;
00025 const TInt KConversionChars = 2;
00026 
00027 CBTDiscoverer* CBTDiscoverer::NewL(CSharedIntermediator* aSMediator)
00028     {
00029     CBTDiscoverer* self = CBTDiscoverer::NewLC(aSMediator);
00030     CleanupStack::Pop(self);
00031     return self;
00032     }
00033 
00034 CBTDiscoverer* CBTDiscoverer::NewLC( CSharedIntermediator* aSMediator )
00035     {
00036     CBTDiscoverer* self = new (ELeave) CBTDiscoverer( aSMediator );
00037     CleanupStack::PushL( self );
00038     self->ConstructL();
00039     return self;
00040     }
00041 
00042 // ----------------------------------------------------------------------------
00043 // CBTDiscoverer::CBTDiscoverer()
00044 //
00045 // Constructor.
00046 // ----------------------------------------------------------------------------
00047 CBTDiscoverer::CBTDiscoverer( CSharedIntermediator* aSMediator )
00048         : CActive( EPriorityStandard ), iSMediator ( aSMediator )
00049         {
00050         }
00051 
00052 // ----------------------------------------------------------------------------
00053 // CBTDiscoverer::CBTDiscoverer()
00054 //
00055 // Destructor.
00056 // ----------------------------------------------------------------------------
00057 CBTDiscoverer::~CBTDiscoverer()
00058         {
00059         Cancel();
00060 
00061         iDeviceNames->ResetAndDestroy();
00062         delete iDeviceNames;
00063 
00064         iDeviceAddress->ResetAndDestroy();
00065         delete iDeviceAddress;
00066         
00067         iInqSockAddrArray.Close();
00068         iHostResolver.Close();
00069         iSocketServer.Close();
00070         }
00071 
00072 // Standard Symbian OS 2nd phase constructor
00073 void CBTDiscoverer::ConstructL()
00074     {
00075         iDeviceNames =  new (ELeave) CArrayPtrFlat<HBufC>(1);
00076         iDeviceAddress = new (ELeave) CArrayPtrFlat<HBufC>(1);
00077     
00078         CActiveScheduler::Add(this);
00079     }
00080 // ----------------------------------------------------------------------------
00081 // CBTDiscoverer::GetNames()
00082 //
00083 // Return a pointer to list of names.
00084 // ----------------------------------------------------------------------------
00085 CArrayPtrFlat< HBufC >* CBTDiscoverer::GetNames()
00086         {
00087         return iDeviceNames;
00088         }
00089 
00090 // ----------------------------------------------------------------------------
00091 // CBTDiscoverer::GetDeviceAddress()
00092 //
00093 // Return a pointer to list of addresses.
00094 // ----------------------------------------------------------------------------
00095 CArrayPtrFlat< HBufC >* CBTDiscoverer::GetDeviceAddress()
00096         {
00097         return iDeviceAddress;
00098         }
00099 
00100 // ----------------------------------------------------------------------------
00101 // CBTDiscoverer::StartDiscoveringDevicesL()
00102 //
00103 // Find devices.
00104 // ----------------------------------------------------------------------------
00105  void CBTDiscoverer::StartDiscoveringDevicesL()
00106         {
00107         User::LeaveIfError(iSocketServer.Connect() ); 
00108         
00109         TProtocolDesc protocolInfo;
00110 
00111         // Gets the description of a protocol by name.
00112         User::LeaveIfError(iSocketServer.FindProtocol(
00113                                     KBTProtocol(), protocolInfo) ); 
00114 
00115         // Initialises a name resolution service provided by a particular protocol. 
00116         // It must be called before other object functions are used.
00117         User::LeaveIfError( iHostResolver.Open( iSocketServer, 
00118                     protocolInfo.iAddrFamily, protocolInfo.iProtocol ) );
00119 
00120         // Interested in all bluetooth devices that have BT turned on.
00121         iSockAddr.SetIAC(KGIAC); 
00122 
00123         // Resolve name of the device and device address. Do not use cache.
00124         iSockAddr.SetAction(KHostResInquiry | KHostResName | KHostResIgnoreCache); 
00125         
00126         // Start discovering devices asynchronously. RunL is called.
00127         iHostResolver.GetByAddress(iSockAddr,iNameEntry,iStatus); 
00128 
00129         // Set this active object active.
00130         SetActive();
00131 
00132         }
00133 
00134 // ----------------------------------------------------------------------------
00135 // CBTDiscoverer::RunL()
00136 //
00137 // ----------------------------------------------------------------------------
00138  void CBTDiscoverer::RunL()
00139         {
00140         
00141         // Found a new device, iStatus would be KErrHostResNoMoreResults
00142         // if no more new devices are found.
00143         if ( iStatus == KErrNone ) 
00144                 {       
00145                 PushListL(iNameEntry); 
00146                 // Find the next bluetooth device
00147                 iHostResolver.Next(iNameEntry,iStatus);
00148 
00149                 SetActive();
00150                 }       
00151         }
00152 
00153 // ----------------------------------------------------------------------------
00154 // CBTDiscoverer::TransformSockAddressL(TInquirySockAddr& aInquirySockAddr)
00155 //
00156 // Transform inquiryaddress to format XX-XX-XX-XX-XX (BT address)
00157 // ----------------------------------------------------------------------------
00158 void CBTDiscoverer::TransformSockAddressL(TInquirySockAddr& aInquirySockAddr) 
00159         {
00160         TBTDevAddr localAddr= aInquirySockAddr.BTAddr();
00161         TBuf<KAddressBufSize> btAddr; 
00162 
00163         for(TInt i=0; i < localAddr.Des().Length() ;i++) 
00164                 { 
00165                 btAddr.AppendNumFixedWidthUC( localAddr[i], EHex, KConversionChars );
00166                 if ( i != localAddr.Des().Length() -1 ) 
00167                         {
00168                         btAddr.Append( KLine );
00169                         }
00170                 }
00171 
00172         HBufC* element = HBufC::New(KBTDeviceAddress);
00173         element = btAddr.Alloc();
00174         iDeviceAddress->AppendL( element );
00175         }
00176 
00177 // ----------------------------------------------------------------------------
00178 // CBTDiscoverer::RunError(TInt aError)
00179 // ----------------------------------------------------------------------------
00180 TInt CBTDiscoverer::RunError(TInt)
00181         {
00182         return KErrNone;
00183         }
00184 
00185 // ----------------------------------------------------------------------------
00186 // CBTDiscoverer::DoCancel()
00187 // ----------------------------------------------------------------------------
00188  void CBTDiscoverer::DoCancel()
00189         {
00190         iHostResolver.Cancel();
00191         }
00192 
00193 // ----------------------------------------------------------------------------
00194 // CBTDiscoverer::PushListL(TNameEntry& aNameEntry) 
00195 //
00196 // Separete both name/address from the aNameEntry and insert them into separe 
00197 // lists.
00198 // ----------------------------------------------------------------------------
00199 void CBTDiscoverer::PushListL(TNameEntry& aNameEntry) 
00200         { 
00201 
00202         TInquirySockAddr &addr = TInquirySockAddr::Cast(aNameEntry().iAddr); 
00203 
00204         // Add only different devices. 
00205         for( TInt i = 0; i < iInqSockAddrArray.Count(); i++ )
00206                 { 
00207                 if( iInqSockAddrArray[i].BTAddr() == addr.BTAddr( ) || 
00208                          addr.BTAddr().Des().Length() < KMinBTAddressLength )
00209                         { 
00210                         return; 
00211                         }        
00212                 }        
00213 
00214         HBufC* element = NULL;
00215         
00216         // Check the length of the bluetooth device name
00217         if ( aNameEntry().iName.Length() >= KBTDeviceLength )
00218                 {
00219                 element = aNameEntry().iName.Left( KBTDeviceLength -1 ).AllocLC();
00220                 }
00221         // Get the name 
00222         else {
00223                 element = aNameEntry().iName.AllocLC();
00224                 }
00225         // Add the name onto the list. Devices must have some kind of name
00226         // otherwise it won't be added.
00227         if ( element->Length() != 0 ) 
00228                 {
00229                 iDeviceNames->AppendL( element );
00230                 CleanupStack::Pop( element );           
00231                 }
00232         
00233         TInquirySockAddr *addr_ptr = new (ELeave)TInquirySockAddr( addr ); 
00234         
00235         CleanupStack::PushL( addr_ptr ); 
00236 
00237         // Append the BT address onto the list
00238         User::LeaveIfError( iInqSockAddrArray.Append(*addr_ptr) ); 
00239         CleanupStack::Pop( addr_ptr ); 
00240 
00241         // Make address printable.
00242         TransformSockAddressL( *addr_ptr );
00243 
00244         // Get name of the device and BT address as hex. Add name&address
00245         // into shared intermediator.
00246         TPtr16 deviceName = (*iDeviceNames)[ iDeviceNames->Count() - 1 ]->Des();
00247         TPtr16 deviceBTAddr = 
00248                     (*iDeviceAddress)[ iDeviceAddress->Count() - 1 ]->Des();
00249         TBluetoothInfo btInfo = TBluetoothInfo (deviceName, deviceBTAddr);
00250 
00251         // Give data to the shared intermediator. Shared intermediator gives
00252         // device names to the listbox after this.
00253         iSMediator->AddBluetoothInfoL(btInfo);
00254         }
00255 
00256 // ----------------------------------------------------------------------------
00257 // CBTDiscoverer::RefreshDevices()
00258 //
00259 // Cancels the wait for completion of an outstanding bluetooth request. 
00260 // Cleans lists and starts the search again by calling GetByAddress.
00261 // ----------------------------------------------------------------------------
00262 void CBTDiscoverer::RefreshDevices()
00263         {
00264         // In case bt discover is already active.
00265         Cancel();
00266 
00267          //Clear all lists 
00268         iDeviceNames->Reset();
00269         iInqSockAddrArray.Reset();      
00270         iDeviceAddress->Reset();
00271         
00272         iSockAddr.SetAction(KHostResInquiry | KHostResName | KHostResIgnoreCache); 
00273 
00274         // Start discovering devices asynchronously. RunL is called afterwards.
00275         iHostResolver.GetByAddress(iSockAddr,iNameEntry,iStatus); 
00276         SetActive();
00277         }

Generated by  doxygen 1.6.2