examples/ForumNokia/ThreadAndActiveObjectsEx/src/btdiscoverer.cpp

00001 /*
00002  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003  *    
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *    
00007  *  * Redistributions of source code must retain the above copyright notice, this
00008  *    list of conditions and the following disclaimer.
00009  *  * Redistributions in binary form must reproduce the above copyright notice,
00010  *    this list of conditions and the following disclaimer in the documentation
00011  *    and/or other materials provided with the distribution.
00012  *  * Neither the name of Nokia Corporation nor the names of its contributors
00013  *    may be used to endorse or promote products derived from this software
00014  *    without specific prior written permission.
00015  *    
00016  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021  *    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022  *    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023  *    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024  *    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *    
00027  *    Description:  
00028  */
00029 
00030 
00031 // INCLUDES
00032 #include "../inc/btdiscoverer.h"
00033 #include "SharedIntermediator.h"
00034 #include "BluetoothInfo.h"
00035 
00036 #include <btmanclient.h>
00037 #include <btextnotifiers.h>
00038 #include <aknlists.h>
00039 #include <btsdp.h>
00040 
00041 #include <bt_sock.h> 
00042 #include <BTDevice.h>
00043 
00044 _LIT(KBTProtocol, "BTLinkManager");
00045 _LIT( KLine, "-" );
00046 
00047 const TInt KMinBTAddressLength = 5;
00048 const TInt KAddressBufSize = 1024;
00049 const TInt KConversionChars = 2;
00050 
00051 CBTDiscoverer* CBTDiscoverer::NewL(CSharedIntermediator* aSMediator)
00052     {
00053     CBTDiscoverer* self = CBTDiscoverer::NewLC(aSMediator);
00054     CleanupStack::Pop(self);
00055     return self;
00056     }
00057 
00058 CBTDiscoverer* CBTDiscoverer::NewLC( CSharedIntermediator* aSMediator )
00059     {
00060     CBTDiscoverer* self = new (ELeave) CBTDiscoverer( aSMediator );
00061     CleanupStack::PushL( self );
00062     self->ConstructL();
00063     return self;
00064     }
00065 
00066 // ----------------------------------------------------------------------------
00067 // CBTDiscoverer::CBTDiscoverer()
00068 //
00069 // Constructor.
00070 // ----------------------------------------------------------------------------
00071 CBTDiscoverer::CBTDiscoverer( CSharedIntermediator* aSMediator )
00072         : CActive( EPriorityStandard ), iSMediator ( aSMediator )
00073         {
00074         }
00075 
00076 // ----------------------------------------------------------------------------
00077 // CBTDiscoverer::CBTDiscoverer()
00078 //
00079 // Destructor.
00080 // ----------------------------------------------------------------------------
00081 CBTDiscoverer::~CBTDiscoverer()
00082         {
00083         Cancel();
00084 
00085         iDeviceNames->ResetAndDestroy();
00086         delete iDeviceNames;
00087 
00088         iDeviceAddress->ResetAndDestroy();
00089         delete iDeviceAddress;
00090         
00091         iInqSockAddrArray.Close();
00092         iHostResolver.Close();
00093         iSocketServer.Close();
00094         }
00095 
00096 // Standard Symbian OS 2nd phase constructor
00097 void CBTDiscoverer::ConstructL()
00098     {
00099         iDeviceNames =  new (ELeave) CArrayPtrFlat<HBufC>(1);
00100         iDeviceAddress = new (ELeave) CArrayPtrFlat<HBufC>(1);
00101     
00102         CActiveScheduler::Add(this);
00103     }
00104 // ----------------------------------------------------------------------------
00105 // CBTDiscoverer::GetNames()
00106 //
00107 // Return a pointer to list of names.
00108 // ----------------------------------------------------------------------------
00109 CArrayPtrFlat< HBufC >* CBTDiscoverer::GetNames()
00110         {
00111         return iDeviceNames;
00112         }
00113 
00114 // ----------------------------------------------------------------------------
00115 // CBTDiscoverer::GetDeviceAddress()
00116 //
00117 // Return a pointer to list of addresses.
00118 // ----------------------------------------------------------------------------
00119 CArrayPtrFlat< HBufC >* CBTDiscoverer::GetDeviceAddress()
00120         {
00121         return iDeviceAddress;
00122         }
00123 
00124 // ----------------------------------------------------------------------------
00125 // CBTDiscoverer::StartDiscoveringDevicesL()
00126 //
00127 // Find devices.
00128 // ----------------------------------------------------------------------------
00129  void CBTDiscoverer::StartDiscoveringDevicesL()
00130         {
00131         User::LeaveIfError(iSocketServer.Connect() ); 
00132         
00133         TProtocolDesc protocolInfo;
00134 
00135         // Gets the description of a protocol by name.
00136         User::LeaveIfError(iSocketServer.FindProtocol(
00137                                     KBTProtocol(), protocolInfo) ); 
00138 
00139         // Initialises a name resolution service provided by a particular protocol. 
00140         // It must be called before other object functions are used.
00141         User::LeaveIfError( iHostResolver.Open( iSocketServer, 
00142                     protocolInfo.iAddrFamily, protocolInfo.iProtocol ) );
00143 
00144         // Interested in all bluetooth devices that have BT turned on.
00145         iSockAddr.SetIAC(KGIAC); 
00146 
00147         // Resolve name of the device and device address. Do not use cache.
00148         iSockAddr.SetAction(KHostResInquiry | KHostResName | KHostResIgnoreCache); 
00149         
00150         // Start discovering devices asynchronously. RunL is called.
00151         iHostResolver.GetByAddress(iSockAddr,iNameEntry,iStatus); 
00152 
00153         // Set this active object active.
00154         SetActive();
00155 
00156         }
00157 
00158 // ----------------------------------------------------------------------------
00159 // CBTDiscoverer::RunL()
00160 //
00161 // ----------------------------------------------------------------------------
00162  void CBTDiscoverer::RunL()
00163         {
00164         
00165         // Found a new device, iStatus would be KErrHostResNoMoreResults
00166         // if no more new devices are found.
00167         if ( iStatus == KErrNone ) 
00168                 {       
00169                 PushListL(iNameEntry); 
00170                 // Find the next bluetooth device
00171                 iHostResolver.Next(iNameEntry,iStatus);
00172 
00173                 SetActive();
00174                 }       
00175         }
00176 
00177 // ----------------------------------------------------------------------------
00178 // CBTDiscoverer::TransformSockAddressL(TInquirySockAddr& aInquirySockAddr)
00179 //
00180 // Transform inquiryaddress to format XX-XX-XX-XX-XX (BT address)
00181 // ----------------------------------------------------------------------------
00182 void CBTDiscoverer::TransformSockAddressL(TInquirySockAddr& aInquirySockAddr) 
00183         {
00184         TBTDevAddr localAddr= aInquirySockAddr.BTAddr();
00185         TBuf<KAddressBufSize> btAddr; 
00186 
00187         for(TInt i=0; i < localAddr.Des().Length() ;i++) 
00188                 { 
00189                 btAddr.AppendNumFixedWidthUC( localAddr[i], EHex, KConversionChars );
00190                 if ( i != localAddr.Des().Length() -1 ) 
00191                         {
00192                         btAddr.Append( KLine );
00193                         }
00194                 }
00195 
00196         HBufC* element = HBufC::New(KBTDeviceAddress);
00197         element = btAddr.Alloc();
00198         iDeviceAddress->AppendL( element );
00199         }
00200 
00201 // ----------------------------------------------------------------------------
00202 // CBTDiscoverer::RunError(TInt aError)
00203 // ----------------------------------------------------------------------------
00204 TInt CBTDiscoverer::RunError(TInt)
00205         {
00206         return KErrNone;
00207         }
00208 
00209 // ----------------------------------------------------------------------------
00210 // CBTDiscoverer::DoCancel()
00211 // ----------------------------------------------------------------------------
00212  void CBTDiscoverer::DoCancel()
00213         {
00214         iHostResolver.Cancel();
00215         }
00216 
00217 // ----------------------------------------------------------------------------
00218 // CBTDiscoverer::PushListL(TNameEntry& aNameEntry) 
00219 //
00220 // Separete both name/address from the aNameEntry and insert them into separe 
00221 // lists.
00222 // ----------------------------------------------------------------------------
00223 void CBTDiscoverer::PushListL(TNameEntry& aNameEntry) 
00224         { 
00225 
00226         TInquirySockAddr &addr = TInquirySockAddr::Cast(aNameEntry().iAddr); 
00227 
00228         // Add only different devices. 
00229         for( TInt i = 0; i < iInqSockAddrArray.Count(); i++ )
00230                 { 
00231                 if( iInqSockAddrArray[i].BTAddr() == addr.BTAddr( ) || 
00232                          addr.BTAddr().Des().Length() < KMinBTAddressLength )
00233                         { 
00234                         return; 
00235                         }        
00236                 }        
00237 
00238         HBufC* element = NULL;
00239         
00240         // Check the length of the bluetooth device name
00241         if ( aNameEntry().iName.Length() >= KBTDeviceLength )
00242                 {
00243                 element = aNameEntry().iName.Left( KBTDeviceLength -1 ).AllocLC();
00244                 }
00245         // Get the name 
00246         else {
00247                 element = aNameEntry().iName.AllocLC();
00248                 }
00249         // Add the name onto the list. Devices must have some kind of name
00250         // otherwise it won't be added.
00251         if ( element->Length() != 0 ) 
00252                 {
00253                 iDeviceNames->AppendL( element );
00254                 CleanupStack::Pop( element );           
00255                 }
00256         
00257         TInquirySockAddr *addr_ptr = new (ELeave)TInquirySockAddr( addr ); 
00258         
00259         CleanupStack::PushL( addr_ptr ); 
00260 
00261         // Append the BT address onto the list
00262         User::LeaveIfError( iInqSockAddrArray.Append(*addr_ptr) ); 
00263         CleanupStack::Pop( addr_ptr ); 
00264 
00265         // Make address printable.
00266         TransformSockAddressL( *addr_ptr );
00267 
00268         // Get name of the device and BT address as hex. Add name&address
00269         // into shared intermediator.
00270         TPtr16 deviceName = (*iDeviceNames)[ iDeviceNames->Count() - 1 ]->Des();
00271         TPtr16 deviceBTAddr = 
00272                     (*iDeviceAddress)[ iDeviceAddress->Count() - 1 ]->Des();
00273         TBluetoothInfo btInfo = TBluetoothInfo (deviceName, deviceBTAddr);
00274 
00275         // Give data to the shared intermediator. Shared intermediator gives
00276         // device names to the listbox after this.
00277         iSMediator->AddBluetoothInfoL(btInfo);
00278         }
00279 
00280 // ----------------------------------------------------------------------------
00281 // CBTDiscoverer::RefreshDevices()
00282 //
00283 // Cancels the wait for completion of an outstanding bluetooth request. 
00284 // Cleans lists and starts the search again by calling GetByAddress.
00285 // ----------------------------------------------------------------------------
00286 void CBTDiscoverer::RefreshDevices()
00287         {
00288         // In case bt discover is already active.
00289         Cancel();
00290 
00291          //Clear all lists 
00292         iDeviceNames->Reset();
00293         iInqSockAddrArray.Reset();      
00294         iDeviceAddress->Reset();
00295         
00296         iSockAddr.SetAction(KHostResInquiry | KHostResName | KHostResIgnoreCache); 
00297 
00298         // Start discovering devices asynchronously. RunL is called afterwards.
00299         iHostResolver.GetByAddress(iSockAddr,iNameEntry,iStatus); 
00300         SetActive();
00301         }

Generated by  doxygen 1.6.2