examples/QtQuick/bluetoothex/bluetoothex_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 "bluetoothex_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): iIsMaster(EFalse), 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     }
00138 
00143 void BluetoothDiscoveryPrivate::DiscoverServicesL()
00144     {
00145     iStartTime.HomeTime();
00146     iResponse = KDiscServicesTxt;
00147     iServiceDiscoverer->DiscoverServicesL(&iDevDataList);
00148     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00149     }
00150 
00157 void BluetoothDiscoveryPrivate::StartSlaveL()
00158     {
00159     if ( iIsSlave )
00160         return;
00161     
00162     iResponse = KSlaveInitTxt;
00163     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00164       
00165     TInt channel;
00166     iListener->StartListenerL(channel);
00167     TBuf<KThirty> msg;
00168     msg.AppendFormat(KListeningTxt, channel);
00169        
00170     emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00171 
00172     iServiceAdvertiser->StartAdvertiserL(channel);
00173     
00174     iResponse = KSlaveInitCompTxt;
00175     emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00176     iIsSlave=ETrue;
00177     ChangeMenuOptions();
00178     }
00179 
00184 void BluetoothDiscoveryPrivate::StopSlaveL()
00185     {
00186     if ( !iIsSlave )
00187         return;
00188     
00189     _LIT(KStopSlave,"Stopped the slave");
00190     iResponse = KStopSlave;
00191     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00192 
00193     iListener->StopListener();
00194     iServiceAdvertiser->StopAdvertiserL();
00195     iIsSlave = EFalse;
00196 
00197     // initialize the menu.
00198     emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EStartSlave);
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 
00220     //initialize the menu.
00221     emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EStartSlave);
00222     }
00223 
00228 void BluetoothDiscoveryPrivate::ConnectDevicesL()
00229      {
00230      // close and delete all existing connections
00231      DisconnectDevices();
00232 
00233      iResponse = KConnectingTxt;
00234      emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00235      // now attempt to connect
00236      for ( TInt idx=0; idx<(iDevDataList.Count()); idx++ )
00237          {
00238          if ( iConnectedDeviceCount>=KMaxConnectedDevices )
00239              return;
00240 
00241          TDeviceData *dev = iDevDataList[idx];
00242 
00243          // if matching service on remote device was found, the service port
00244          // is set and will be > 0.  if so, we can attempt to connect.
00245          if ( dev->iDeviceServicePort>0 )
00246              {
00247              CConnector* connector = CConnector::NewLC(*this, iSocketServ);
00248              if ( (connector->ConnectL(dev->iDeviceName,
00249                                        dev->iDeviceAddr,
00250                                        dev->iDeviceServicePort))==KErrNone )
00251                  {
00252                  iConnectedDevices[iConnectedDeviceCount] = connector;
00253                  iConnectedDeviceCount++;
00254                  CleanupStack::Pop(connector);
00255                  }
00256              else
00257                  {
00258                  // connection to device failed!!
00259                  CleanupStack::PopAndDestroy();
00260                  }
00261              }
00262          }
00263 
00264      ShowConnectedDevicesL();
00265      emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EHasConnections);
00266      }
00267 
00272 void BluetoothDiscoveryPrivate::ShowConnectedDevicesL()
00273     {
00274     TInt count=0;
00275     iResponse = KConnDevicesTxt;
00276     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00277     for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00278         {
00279         if ( iConnectedDevices[idx] )
00280             {
00281             THostName name;
00282             name = iConnectedDevices[idx]->iName;
00283             name.Append(KNewLine);
00284             emit(iDiscovery->showMessage(false,QString::fromUtf16(name.Ptr(),name.Length())));
00285             count++;
00286             }
00287         }
00288     if ( count==0 )
00289         {
00290         // no connections!
00291         // this may be because of no devices has been discovered,
00292         // or no devices are offering the requested service.
00293         iResponse = KNoConns; 
00294         emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00295         }
00296     }
00297 
00303 void BluetoothDiscoveryPrivate::SendMessageL()
00304     {
00305     _LIT(KSendMessage,"Hi friends");
00306     TBuf<KEighty> msg(KSendMessage);
00307     // explicitly convert from 16bit to 8bit character set
00308     CnvUtfConverter::ConvertFromUnicodeToUtf8(iMsgtext8, msg);
00309 
00310     if(iIsSlave)
00311         {
00312         // slave sending data
00313         iListener->SendData(iMsgtext8);
00314         emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00315         }
00316     else
00317         {
00318         // master sending data
00319         for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00320             {
00321             if ( iConnectedDevices[idx])
00322                 {
00323                 iConnectedDevices[idx]->SendData(iMsgtext8);
00324                 THostName name;
00325                 name=iConnectedDevices[idx]->iName;
00326                 msg.Format(KFormatStr2, &name, &iMsgtext);
00327                 emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00328                 }
00329             }
00330         }
00331     }
00332 
00338 void BluetoothDiscoveryPrivate::HandleListenerDataReceivedL(const TDesC& aData)
00339     {
00340     // display received message
00341     TBuf<KEighty> msg;
00342     msg.Format(KFormatStr1, &aData);
00343     emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00344     }
00345 
00351 void BluetoothDiscoveryPrivate::HandleListenerConnectedL()
00352     {
00353     iResponse = KConnMsg; 
00354     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00355     ChangeMenuOptions();
00356     }
00357 
00362 void BluetoothDiscoveryPrivate::HandleListenerDisconnectedL()
00363     {
00364     if ( !iIsSlave )
00365         return;
00366     // Stop listener and advertiser
00367     // Set app to init mode
00368     StopSlaveL();
00369     iResponse = KDisconMsg;
00370     emit(iDiscovery->showMessage(true,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00371     ChangeMenuOptions();
00372     }
00373 
00381 void BluetoothDiscoveryPrivate::HandleConnectorDataReceivedL(THostName aName,
00382                                                               const TDesC& aData)
00383     {
00384     // display received message
00385     TBuf<KEighty> msg;
00386     msg.Format(KFormatStr, &aName, &aData);
00387     emit(iDiscovery->showMessage(true,QString::fromUtf16(msg.Ptr(),msg.Length())));
00388 
00389     // echo the message to other slaves
00390     _LIT8(KSeparator, ":");
00391 
00392     TBuf8<KEighty> buf; //should use HBufC so the size will be big enough
00393     TPtr8 msgtext8((TUint8*)buf.Ptr(), aData.Size()+KSeparator().Length() + aName.Size());
00394     CnvUtfConverter::ConvertFromUnicodeToUtf8(msgtext8, aData);
00395 
00396     //convert name to UTF8 so other slaves see
00397     //the sender name
00398     TBuf8<KEighty> bufName;
00399     TPtr8 name8((TUint8*)bufName.Ptr(), aName.Size());
00400     CnvUtfConverter::ConvertFromUnicodeToUtf8(name8, aName);
00401 
00402     //add the separator and name in the beginning;
00403     msgtext8.Insert(0, KSeparator );
00404     msgtext8.Insert(0, name8);
00405 
00406     for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00407         {
00408         if ( iConnectedDevices[idx])
00409             {
00410             THostName name;
00411             name=iConnectedDevices[idx]->iName;
00412 
00413             //echo to other slaves than the sender
00414             if( name.Compare(aName) != 0)
00415                 iConnectedDevices[idx]->SendData(msgtext8);
00416             }
00417         }
00418     }
00419 
00423 void BluetoothDiscoveryPrivate::HandleConnectorErrorL(THostName aName, TInt aError)
00424     {
00425     if (aError)
00426         {
00427         // display received message
00428         TBuf<KEighty> msg;
00429         msg.Format(KDeviceDisconMsg, &aName);
00430         emit(iDiscovery->showMessage(false,QString::fromUtf16(msg.Ptr(),msg.Length())));
00431 
00432         for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00433             {
00434             if ( iConnectedDevices[idx])
00435                 {
00436                 THostName name;
00437                 name=iConnectedDevices[idx]->iName;
00438 
00439                 //echo to other slaves than the sender
00440                 if( name.Compare(aName) == 0)
00441                     {
00442                     delete iConnectedDevices[idx];
00443                     iConnectedDevices[idx] = NULL;
00444                     }
00445                 }
00446             } 
00447     }
00448     }
00449 
00455 void BluetoothDiscoveryPrivate::HandleDeviceDiscoveryComplete(TInt aError)
00456     {
00457     if (aError == KErrNone)
00458         {
00459         iIsMaster = ETrue;
00460         }
00461     else
00462         {
00463         iIsMaster = EFalse;
00464         }
00465     
00466     iEndTime.HomeTime();
00467 
00468     TTimeIntervalSeconds seconds;
00469     iEndTime.SecondsFrom(iStartTime, seconds);
00470 
00471     TInt time = seconds.Int();
00472     TBuf<KTwelve> temp = KTimeTxt();
00473     temp.AppendNum(time);
00474     temp.Append(KSecTxt);
00475     TRAPD(err,emit(iDiscovery->showMessage(false,QString::fromUtf16(temp.Ptr(),temp.Length()))));
00476 
00477     // iterate and display found devices, if any
00478     if ( iDevDataList.Count()> 0 )
00479         {
00480         TBuf<KTwenty> count = KFoundTxt();
00481         count.AppendNum( iDevDataList.Count() );
00482         count.Append( KDevices );
00483         TRAP(err,emit(iDiscovery->showMessage(false,QString::fromUtf16(count.Ptr(),count.Length()))));
00484         }
00485     else
00486         {
00487         // no devices found
00488         iResponse = KNoDevFound;
00489         TRAP(err,emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length()))));
00490         }
00491     ChangeMenuOptions();
00492     }
00493 
00499 void BluetoothDiscoveryPrivate::HandleServiceDiscoveryCompleteL()
00500     {
00501     iEndTime.HomeTime();
00502 
00503     TTimeIntervalSeconds seconds;
00504     iEndTime.SecondsFrom(iStartTime, seconds);
00505 
00506     TInt time = seconds.Int();
00507     TBuf<KTwelve> temp = KTimeTxt();
00508     temp.AppendNum(time);
00509     temp.Append(KSecTxt);
00510     emit(iDiscovery->showMessage(true,QString::fromUtf16(temp.Ptr(),temp.Length())));
00511 
00512     TInt count=0;
00513     // display devices with service we can use
00514     for ( TInt idx=0; idx<(iDevDataList.Count()); idx++ )
00515         {
00516         TDeviceData *dev = iDevDataList[idx];
00517         if ( dev->iDeviceServicePort>0 )
00518             {
00519             THostName name = dev->iDeviceName;
00520             name.Append(KNewLine);
00521             emit(iDiscovery->showMessage(false,QString::fromUtf16(name.Ptr(),name.Length())));
00522             count++;
00523             }
00524         }
00525     if ( count==0 )
00526         {
00527         iResponse = KNoServiceFound;
00528         emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00529         }
00530     else
00531         {
00532         iResponse = KServiceFound;
00533         emit(iDiscovery->showMessage(false,QString::fromUtf16(iResponse.Ptr(),iResponse.Length())));
00534         }
00535     ChangeMenuOptions();
00536     }
00537 
00542 TBool BluetoothDiscoveryPrivate::HasConnections()
00543     {
00544     TBool exists = EFalse;
00545     for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
00546         {
00547         if ( iConnectedDevices[idx])
00548             {
00549             exists = ETrue;
00550             break;
00551             }
00552         }
00553     return exists;
00554     }
00555 
00556 
00557 // ----------------------------------------------------------------------------
00558 // CBluetoothPMPExampleEngine::DeviceDiscovered
00559 // ----------------------------------------------------------------------------
00560 //a callback to indicate that a device has been found
00561 //main reason for this is that the UI can react so user
00562 //knows that something is going on and the app is not "frozen"
00563 void BluetoothDiscoveryPrivate::DeviceDiscovered(const TDeviceData &aDevice)
00564     {
00565     
00566     TInt len = aDevice.iDeviceName.Length();
00567     if (len >80)
00568         len=80;
00569     TBuf<80> name(aDevice.iDeviceName.MidTPtr(0,len));
00570    
00571     name.Trim();
00572 
00573     if( name.Length() == 0 )
00574         name.Append(KDeviceWithNoName);
00575         name.Append(KNewLine);
00576     emit(iDiscovery->showMessage(false,QString::fromUtf16(name.Ptr(),name.Length())));
00577     iIsMaster = ETrue;
00578     emit(iDiscovery->showMessage(false,QString("\n")));
00579     ChangeMenuOptions();
00580     }
00581 
00582 // ----------------------------------------------------------------------------
00583 // CBluetoothPMPExampleEngine::ReportServiceDiscoveryErrorL
00584 // ----------------------------------------------------------------------------
00585 void BluetoothDiscoveryPrivate::ReportServiceDiscoveryErrorL(TInt aError)
00586     {
00587     TBuf<KThirty> discError = KServiceDiscoveryError();
00588     discError.AppendNum(aError);
00589     emit(iDiscovery->showMessage(false,QString::fromUtf16(discError.Ptr(),discError.Length())));
00590     }
00591 
00592 // ----------------------------------------------------------------------------
00593 // CBluetoothPMPExampleEngine::TurnBtOnL
00594 // ----------------------------------------------------------------------------
00595 //Uses the Notifier API to ask the user to turn on Bluetooth
00596 //if it's not on already.
00597 void BluetoothDiscoveryPrivate::TurnBtOnL()
00598     {
00599     //the constant is from btnotifierapi.h which is not in all SDKs
00600     //so it's hard coded here
00601     const TUid KPowerModeSettingNotifierUid = {0x100059E2};
00602     //const TUid KBTPowerStateNotifierUid = {0x101F808E}; //S80 and 7710
00603     
00604     RNotifier notifier;
00605     User::LeaveIfError( notifier.Connect() );
00606     TPckgBuf<TBool> dummy(ETrue);
00607     TPckgBuf<TBool> reply(EFalse);
00608     TRequestStatus stat;
00609     notifier.StartNotifierAndGetResponse(stat, KPowerModeSettingNotifierUid, dummy, reply);
00610     User::WaitForRequest(stat);
00611     notifier.CancelNotifier(KPowerModeSettingNotifierUid);
00612     notifier.Close();
00613     }
00614 
00615 // ----------------------------------------------------------------------------
00616 // CBluetoothPMPExampleEngine::IsDiscoveryActive
00617 // ----------------------------------------------------------------------------
00618 TBool BluetoothDiscoveryPrivate::IsDiscoveryActive()
00619     {
00620     return iDeviceDiscoverer->IsActive();
00621     }
00622 
00623 // ----------------------------------------------------------------------------
00624 // CBluetoothPMPExampleEngine::StopDiscovery
00625 // ----------------------------------------------------------------------------
00626 void BluetoothDiscoveryPrivate::StopDiscovery()
00627     {
00628     if ( IsDiscoveryActive() )
00629         {
00630         iDeviceDiscoverer->StopDiscovery();
00631         ChangeMenuOptions();
00632         } 
00633     }
00634 
00635 // Change the menu options.
00636 void BluetoothDiscoveryPrivate::ChangeMenuOptions()
00637     {
00638     // Arrange the menu items.
00639     
00640     // Slave Mode =========================================================
00641     
00642     if (iIsSlave)
00643         {
00644         if ( iListener->IsConnected() )
00645             {
00646             // Show the Send Message option
00647             emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::ESendMessage);
00648             }
00649         emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EStopSlave);
00650         }
00651 
00652     
00653     // Master Mode ========================================================
00654     else if (iIsMaster)
00655         {
00656             if(iDeviceDiscoverer->IsActive())
00657                 {
00658                 emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EStopDeviceDiscovery);
00659                 }
00660             if ( iDeviceDiscoverer->HasDevices() && !iDeviceDiscoverer->IsActive())
00661                 {
00662                 // we have found devices, show discover services item
00663                 emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EHasDevices);
00664                 }
00665             if ( iServiceDiscoverer->HasServices() && !iServiceDiscoverer->iRunning)
00666                 {
00667                 // we have found services, show connect item
00668                 emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EHasServices);
00669                 }
00670             if ( HasConnections() )
00671                 {
00672                 // we are connected
00673                 emit iDiscovery->changeMenu(BluetoothDiscoveryPrivate::EHasConnections);
00674                 }
00675             }
00676     }

Generated by  doxygen 1.6.2