examples/Qt/qtbluetoothapp/bluetoothdiscovery_symbian.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 // INCLUDE FILES
00030 #include <utf.h>
00031 #include "bluetoothdiscovery_symbian.h"
00032 
00033 
00034 BluetoothDiscoveryPrivate* BluetoothDiscoveryPrivate::NewL(BluetoothDiscovery* aWrapper)
00035     {
00036     BluetoothDiscoveryPrivate* self =
00037             BluetoothDiscoveryPrivate::NewLC(aWrapper);
00038     CleanupStack::Pop(self);
00039     return self;
00040     }
00041 
00042 
00043 BluetoothDiscoveryPrivate* BluetoothDiscoveryPrivate::NewLC(
00044         BluetoothDiscovery* aWrapper)
00045     {
00046     BluetoothDiscoveryPrivate* self =
00047         new (ELeave) BluetoothDiscoveryPrivate(aWrapper);
00048     CleanupStack::PushL(self);
00049     self->ConstructL();
00050     return self;
00051     }
00052 
00053 
00054 // Standard EPOC 2nd phase constructor
00055 void BluetoothDiscoveryPrivate::ConstructL()
00056     {
00057     // get socket server session
00058     User::LeaveIfError(iSocketServ.Connect());
00059 
00060     // init listener
00061     iListener = CListener::NewL(*this, iSocketServ);
00062     // init device discoverer
00063     iDeviceDiscoverer = CDeviceDiscoverer::NewL(iSocketServ, *this);
00064     
00065     // init service advertiser
00066     iServiceAdvertiser = CServiceAdvertiser::NewL();
00067     // init service discoverer
00068     iServiceDiscoverer = CServiceDiscoverer::NewL(*this);
00069 
00070     // clean connections table to begin with
00071     for ( TInt idx=0; idx<KMaxConnectedDevices; idx++ )
00072         {
00073         iConnectedDevices[idx] = NULL;
00074         }
00075     }
00076 
00082 BluetoothDiscoveryPrivate::BluetoothDiscoveryPrivate(
00083         BluetoothDiscovery* aWrapper): iIsSlave(EFalse),
00084                                        iDiscovery(aWrapper)
00085     {
00086     //Nothing to do
00087     }
00088 
00093 BluetoothDiscoveryPrivate::~BluetoothDiscoveryPrivate()
00094     {
00095     if ( IsDiscoveryActive() )
00096         {
00097         iDeviceDiscoverer->StopDiscovery();
00098         } 
00099     // disconnect all devices and clean up connections table
00100     DisconnectDevices();
00101     // stop and kill helpers
00102 
00103     delete iServiceAdvertiser;
00104     iServiceAdvertiser=NULL;
00105 
00106     delete iListener;
00107     iListener=NULL;
00108     
00109     iDeviceDiscoverer->Cancel();
00110     delete iDeviceDiscoverer;
00111     iDeviceDiscoverer = NULL;
00112 
00113     delete iServiceDiscoverer;
00114     iServiceDiscoverer=NULL;
00115 
00116     iSocketServ.Close();
00117     // wipe device data list
00118     iDevDataList.ResetAndDestroy();
00119     
00120     }
00121 
00126 void BluetoothDiscoveryPrivate::DiscoverDevicesL()
00127     {
00128     //timing:
00129     iStartTime.HomeTime();
00130     iResponse = KDiscDevicesTxt;
00131     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00132     TRAPD(err,iDeviceDiscoverer->DiscoverDevicesL(&iDevDataList));
00133     if (err)
00134         {
00135         HandleDeviceDiscoveryComplete(err);
00136         }
00137     ChangeMenuOptions();
00138     }
00139 
00144 void BluetoothDiscoveryPrivate::DiscoverServicesL()
00145     {
00146     iStartTime.HomeTime();
00147     iResponse = KDiscServicesTxt;
00148     iServiceDiscoverer->DiscoverServicesL(&iDevDataList);
00149     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00150     ChangeMenuOptions();
00151     }
00152 
00159 void BluetoothDiscoveryPrivate::StartSlaveL()
00160     {
00161     if ( iIsSlave )
00162         return;
00163     
00164     iResponse = KSlaveInitTxt;
00165     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00166       
00167     TInt channel;
00168     iListener->StartListenerL(channel);
00169     TBuf<KThirty> msg;
00170     msg.AppendFormat(KListeningTxt, channel);
00171        
00172     emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00173 
00174     iServiceAdvertiser->StartAdvertiserL(channel);
00175     
00176     iResponse = KSlaveInitCompTxt;
00177     emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00178     iIsSlave=ETrue;
00179     ChangeMenuOptions();
00180     }
00181 
00186 void BluetoothDiscoveryPrivate::StopSlaveL()
00187     {
00188     if ( !iIsSlave )
00189         return;
00190     
00191     _LIT(KStopSlave,"Stopped the slave");
00192     iResponse = KStopSlave;
00193     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00194 
00195     iListener->StopListener();
00196     iServiceAdvertiser->StopAdvertiserL();
00197     iIsSlave = EFalse;
00198     ChangeMenuOptions();
00199     }
00200 
00205 void BluetoothDiscoveryPrivate::DisconnectDevices()
00206     {
00207     for ( TInt idx=0; idx<KMaxConnectedDevices; idx++ )
00208         {
00209         if ( iConnectedDevices[idx] )
00210             {
00211             delete iConnectedDevices[idx];
00212             iConnectedDevices[idx]=NULL;
00213             }
00214         }
00215     
00216     iResponse = KDisconnDevicesTxt;
00217     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00218     iIsMaster = EFalse;
00219     ChangeMenuOptions();
00220     }
00221 
00226 void BluetoothDiscoveryPrivate::ConnectDevicesL()
00227      {
00228      // close and delete all existing connections
00229      DisconnectDevices();
00230 
00231      iResponse = KConnectingTxt;
00232      emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00233      // now attempt to connect
00234      for ( TInt idx=0; idx<(iDevDataList.Count()); idx++ )
00235          {
00236          if ( iConnectedDeviceCount>=KMaxConnectedDevices )
00237              return;
00238 
00239          TDeviceData *dev = iDevDataList[idx];
00240 
00241          // if matching service on remote device was found, the service port
00242          // is set and will be > 0.  if so, we can attempt to connect.
00243          if ( dev->iDeviceServicePort>0 )
00244              {
00245              CConnector* connector = CConnector::NewLC(*this, iSocketServ);
00246              if ( (connector->ConnectL(dev->iDeviceName,
00247                                        dev->iDeviceAddr,
00248                                        dev->iDeviceServicePort))==KErrNone )
00249                  {
00250                  iConnectedDevices[iConnectedDeviceCount] = connector;
00251                  iConnectedDeviceCount++;
00252                  CleanupStack::Pop(connector);
00253                  }
00254              else
00255                  {
00256                  // connection to device failed!!
00257                  CleanupStack::PopAndDestroy();
00258                  }
00259              }
00260          }
00261 
00262      ShowConnectedDevicesL();
00263      ChangeMenuOptions();
00264      }
00265 
00270 void BluetoothDiscoveryPrivate::ShowConnectedDevicesL()
00271     {
00272     TInt count=0;
00273     iResponse = KConnDevicesTxt;
00274     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00275     for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00276         {
00277         if ( iConnectedDevices[idx] )
00278             {
00279             THostName name;
00280             name = iConnectedDevices[idx]->iName;
00281             name.Append(KNewLine);
00282             emit(iDiscovery->showMessage(false,QString::fromUtf16(name.Ptr(),name.Length())));
00283             count++;
00284             }
00285         }
00286     if ( count==0 )
00287         {
00288         // no connections!
00289         // this may be because of no devices has been discovered,
00290         // or no devices are offering the requested service.
00291         iResponse = KNoConns; 
00292         emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00293         }
00294     }
00295 
00301 void BluetoothDiscoveryPrivate::SendMessageL()
00302     {
00303     _LIT(KSendMessage,"Hi friends");
00304     TBuf<KEighty> msg(KSendMessage);
00305     // explicitly convert from 16bit to 8bit character set
00306     CnvUtfConverter::ConvertFromUnicodeToUtf8(iMsgtext8, msg);
00307 
00308     if(iIsSlave)
00309         {
00310         // slave sending data
00311         iListener->SendData(iMsgtext8);
00312         emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00313         }
00314     else
00315         {
00316         // master sending data
00317         for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00318             {
00319             if ( iConnectedDevices[idx])
00320                 {
00321                 iConnectedDevices[idx]->SendData(iMsgtext8);
00322                 THostName name;
00323                 name=iConnectedDevices[idx]->iName;
00324                 msg.Format(KFormatStr2, &name, &iMsgtext);
00325                 emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00326                 }
00327             }
00328         }
00329     }
00330 
00336 void BluetoothDiscoveryPrivate::HandleListenerDataReceivedL(const TDesC& aData)
00337     {
00338     // display received message
00339     TBuf<KEighty> msg;
00340     msg.Format(KFormatStr1, &aData);
00341     emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00342     }
00343 
00349 void BluetoothDiscoveryPrivate::HandleListenerConnectedL()
00350     {
00351     iResponse = KConnMsg; 
00352     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00353     }
00354 
00359 void BluetoothDiscoveryPrivate::HandleListenerDisconnectedL()
00360     {
00361     if ( !iIsSlave )
00362         return;
00363     // Stop listener and advertiser
00364     // Set app to init mode
00365     StopSlaveL();
00366     iResponse = KDisconMsg;
00367     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00368     }
00369 
00377 void BluetoothDiscoveryPrivate::HandleConnectorDataReceivedL(THostName aName,
00378                                                               const TDesC& aData)
00379     {
00380     // display received message
00381     TBuf<KEighty> msg;
00382     msg.Format(KFormatStr, &aName, &aData);
00383     emit(iDiscovery->showMessage(true,QString::fromUtf16(msg.Ptr(),msg.Length())));
00384 
00385     // echo the message to other slaves
00386     _LIT8(KSeparator, ":");
00387 
00388     TBuf8<KEighty> buf; //should use HBufC so the size will be big enough
00389     TPtr8 msgtext8((TUint8*)buf.Ptr(), aData.Size()+KSeparator().Length() + aName.Size());
00390     CnvUtfConverter::ConvertFromUnicodeToUtf8(msgtext8, aData);
00391 
00392     //convert name to UTF8 so other slaves see
00393     //the sender name
00394     TBuf8<KEighty> bufName;
00395     TPtr8 name8((TUint8*)bufName.Ptr(), aName.Size());
00396     CnvUtfConverter::ConvertFromUnicodeToUtf8(name8, aName);
00397 
00398     //add the separator and name in the beginning;
00399     msgtext8.Insert(0, KSeparator );
00400     msgtext8.Insert(0, name8);
00401 
00402     for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00403         {
00404         if ( iConnectedDevices[idx])
00405             {
00406             THostName name;
00407             name=iConnectedDevices[idx]->iName;
00408 
00409             //echo to other slaves than the sender
00410             if( name.Compare(aName) != 0)
00411                 iConnectedDevices[idx]->SendData(msgtext8);
00412             }
00413         }
00414     }
00415 
00419 void BluetoothDiscoveryPrivate::HandleConnectorErrorL(THostName aName, TInt aError)
00420     {
00421     if (aError)
00422         {
00423         // display received message
00424         TBuf<KEighty> msg;
00425         msg.Format(KDeviceDisconMsg, &aName);
00426         emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00427 
00428         for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00429             {
00430             if ( iConnectedDevices[idx])
00431                 {
00432                 THostName name;
00433                 name=iConnectedDevices[idx]->iName;
00434 
00435                 //echo to other slaves than the sender
00436                 if( name.Compare(aName) == 0)
00437                     {
00438                     delete iConnectedDevices[idx];
00439                     iConnectedDevices[idx] = NULL;
00440                     }
00441                 }
00442             } 
00443     }
00444     }
00445 
00451 void BluetoothDiscoveryPrivate::HandleDeviceDiscoveryComplete(TInt aError)
00452     {
00453     if (aError)
00454         {
00455         iIsMaster = ETrue;
00456         }
00457     else
00458         {
00459         iIsMaster = EFalse;
00460         }
00461     
00462     iEndTime.HomeTime();
00463 
00464     TTimeIntervalSeconds seconds;
00465     iEndTime.SecondsFrom(iStartTime, seconds);
00466 
00467     TInt time = seconds.Int();
00468     TBuf<KTwelve> temp = KTimeTxt();
00469     temp.AppendNum(time);
00470     temp.Append(KSecTxt);
00471     TRAPD(err,emit(iDiscovery->showMessage(false,QString::fromUtf16(temp.Ptr(),temp.Length()))));
00472 
00473     // iterate and display found devices, if any
00474     if ( iDevDataList.Count()> 0 )
00475         {
00476         TBuf<KTwenty> count = KFoundTxt();
00477         count.AppendNum( iDevDataList.Count() );
00478         count.Append( KDevices );
00479         TRAP(err,emit(iDiscovery->showMessage(false,QString::fromUtf16(count.Ptr(),count.Length()))));
00480         }
00481     else
00482         {
00483         // no devices found
00484         iResponse = KNoDevFound;
00485         TRAP(err,emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length()))));
00486         }
00487     emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EDeviceDiscoveryComplete);
00488     }
00489 
00495 void BluetoothDiscoveryPrivate::HandleServiceDiscoveryCompleteL()
00496     {
00497     iEndTime.HomeTime();
00498 
00499     TTimeIntervalSeconds seconds;
00500     iEndTime.SecondsFrom(iStartTime, seconds);
00501 
00502     TInt time = seconds.Int();
00503     TBuf<KTwelve> temp = KTimeTxt();
00504     temp.AppendNum(time);
00505     temp.Append(KSecTxt);
00506     emit(iDiscovery->showMessage(true,QString::fromUtf16(temp.Ptr(),temp.Length())));
00507 
00508     TInt count=0;
00509     // display devices with service we can use
00510     for ( TInt idx=0; idx<(iDevDataList.Count()); idx++ )
00511         {
00512         TDeviceData *dev = iDevDataList[idx];
00513         if ( dev->iDeviceServicePort>0 )
00514             {
00515             THostName name = dev->iDeviceName;
00516             name.Append(KNewLine);
00517             emit(iDiscovery->showMessage(false,QString::fromUtf16(name.Ptr(),name.Length())));
00518             count++;
00519             }
00520         }
00521     if ( count==0 )
00522         {
00523         iResponse = KNoServiceFound;
00524         emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00525         }
00526     else
00527         {
00528         iResponse = KServiceFound;
00529         emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00530         }
00531     }
00532 
00537 TBool BluetoothDiscoveryPrivate::HasConnections()
00538     {
00539     TBool exists = EFalse;
00540     for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00541         {
00542         if ( iConnectedDevices[idx])
00543             {
00544             exists = ETrue;
00545             break;
00546             }
00547         }
00548     return exists;
00549     }
00550 
00551 
00552 // ----------------------------------------------------------------------------
00553 // CBluetoothPMPExampleEngine::DeviceDiscovered
00554 // ----------------------------------------------------------------------------
00555 //a callback to indicate that a device has been found
00556 //main reason for this is that the UI can react so user
00557 //knows that something is going on and the app is not "frozen"
00558 void BluetoothDiscoveryPrivate::DeviceDiscovered(const TDeviceData &aDevice)
00559     {
00560     
00561     TInt len = aDevice.iDeviceName.Length();
00562     if (len >80)
00563         len=80;
00564     TBuf<80> name(aDevice.iDeviceName.MidTPtr(0,len));
00565    
00566     name.Trim();
00567 
00568     if( name.Length() == 0 )
00569         name.Append(KDeviceWithNoName);
00570         name.Append(KNewLine);
00571     emit(iDiscovery->showMessage(false,QString::fromUtf16(name.Ptr(),name.Length())));
00572     iIsMaster = ETrue;
00573     emit(iDiscovery->showMessage(false,QString("\n")));
00574     ChangeMenuOptions();
00575     }
00576 
00577 // ----------------------------------------------------------------------------
00578 // CBluetoothPMPExampleEngine::ReportServiceDiscoveryErrorL
00579 // ----------------------------------------------------------------------------
00580 void BluetoothDiscoveryPrivate::ReportServiceDiscoveryErrorL(TInt aError)
00581     {
00582     TBuf<KThirty> discError = KServiceDiscoveryError();
00583     discError.AppendNum(aError);
00584     emit(iDiscovery->showMessage(false,QString::fromUtf16(discError.Ptr(),discError.Length())));
00585     }
00586 
00587 // ----------------------------------------------------------------------------
00588 // CBluetoothPMPExampleEngine::TurnBtOnL
00589 // ----------------------------------------------------------------------------
00590 //Uses the Notifier API to ask the user to turn on Bluetooth
00591 //if it's not on already.
00592 void BluetoothDiscoveryPrivate::TurnBtOnL()
00593     {
00594     //the constant is from btnotifierapi.h which is not in all SDKs
00595     //so it's hard coded here
00596     const TUid KPowerModeSettingNotifierUid = {0x100059E2};
00597     //const TUid KBTPowerStateNotifierUid = {0x101F808E}; //S80 and 7710
00598     
00599     RNotifier notifier;
00600     User::LeaveIfError( notifier.Connect() );
00601     TPckgBuf<TBool> dummy(ETrue);
00602     TPckgBuf<TBool> reply(EFalse);
00603     TRequestStatus stat;
00604     notifier.StartNotifierAndGetResponse(stat, KPowerModeSettingNotifierUid, dummy, reply);
00605     User::WaitForRequest(stat);
00606     notifier.CancelNotifier(KPowerModeSettingNotifierUid);
00607     notifier.Close();
00608     }
00609 
00610 // ----------------------------------------------------------------------------
00611 // CBluetoothPMPExampleEngine::IsDiscoveryActive
00612 // ----------------------------------------------------------------------------
00613 TBool BluetoothDiscoveryPrivate::IsDiscoveryActive()
00614     {
00615     return iDeviceDiscoverer->IsActive();
00616     }
00617 
00618 // ----------------------------------------------------------------------------
00619 // CBluetoothPMPExampleEngine::StopDiscovery
00620 // ----------------------------------------------------------------------------
00621 void BluetoothDiscoveryPrivate::StopDiscovery()
00622     {
00623     if ( IsDiscoveryActive() )
00624         {
00625         iDeviceDiscoverer->StopDiscovery();
00626         ChangeMenuOptions();
00627         } 
00628     }
00629 
00630 // Change the menu options.
00631 void BluetoothDiscoveryPrivate::ChangeMenuOptions()
00632     {
00633     // Arrange the menu items.
00634     
00635     // Slave Mode =========================================================
00636     
00637     if (iIsSlave)
00638         {
00639         if ( iListener->IsConnected() )
00640             {
00641             // Show the Send Message option
00642             emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::ESendMessage);
00643             }
00644         emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EStopSlave);
00645         }
00646     
00647     TBool myActiveDiscovery(IsDiscoveryActive());
00648     
00649     if(myActiveDiscovery)
00650         {
00651         emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EStopDeviceDiscovery);
00652         }
00653     
00654     // Master Mode ========================================================
00655     if (iIsMaster) 
00656         {
00657         if(!iIsSlave)
00658             {
00659             if ( iDeviceDiscoverer->HasDevices() && !iDeviceDiscoverer->IsActive())
00660                 {
00661                 // we have found devices, show discover services item
00662                 emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EHasDevices);
00663                 }
00664             if ( iServiceDiscoverer->HasServices() && !iServiceDiscoverer->iRunning)
00665                 {
00666                 // we have found services, show connect item
00667                 emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EHasServices);
00668                 }
00669             if ( HasConnections() )
00670                 {
00671                 // we are connected
00672                 emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EHasConnections);
00673                 }
00674             }
00675         }
00676     }

Generated by  doxygen 1.6.2