hti/HtiCommPlugins/HtiBtCommPlugin/BtEngine/src/BtSerialClient.cpp
branchRCL_3
changeset 59 8ad140f3dd41
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     1 /*
       
     2 * Copyright (c) 2009 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:  Bluetooth serial client.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32std.h>
       
    21 #include <c32comm.h>
       
    22 #include "BtSerialClient.h"
       
    23 #include "messageservicesearcher.h"
       
    24 #include "BtSerialEngine.pan"
       
    25 #include "HtiBtEngineLogging.h"
       
    26 #include "socketswriter.h"
       
    27 #include "socketsreader.h"
       
    28 
       
    29 // CONSTANTS
       
    30 const TUint KServiceUid = 0x12341101;
       
    31 
       
    32 // ----------------------------------------------------------------------------
       
    33 EXPORT_C CBtSerialClient* CBtSerialClient::NewL( MBtSerialClientObserver& aObserver )
       
    34     {
       
    35     CBtSerialClient* self = new ( ELeave ) CBtSerialClient( aObserver );
       
    36     CleanupStack::PushL( self );
       
    37     self->ConstructL();
       
    38     CleanupStack::Pop( self );
       
    39     return self;
       
    40     }
       
    41 
       
    42 // ----------------------------------------------------------------------------
       
    43 CBtSerialClient::CBtSerialClient( MBtSerialClientObserver& aObserver )
       
    44 : CActive( CActive::EPriorityStandard ), iObserver( aObserver ),
       
    45   iState( EWaitingToGetDevice ), iCurrentServiceIndex( 0 )
       
    46     {
       
    47     CActiveScheduler::Add( this );
       
    48     }
       
    49 
       
    50 // ----------------------------------------------------------------------------
       
    51 EXPORT_C CBtSerialClient::~CBtSerialClient()
       
    52     {
       
    53     delete iSocketReader;
       
    54     delete iSocketWriter;
       
    55 
       
    56     Cancel();
       
    57 
       
    58     iSocket.Close();
       
    59     iSocketServer.Close();
       
    60 
       
    61     delete iServiceSearcher;
       
    62 
       
    63     iPowerControl.Close();
       
    64     }
       
    65 
       
    66 // ----------------------------------------------------------------------------
       
    67 void CBtSerialClient::ConstructL()
       
    68     {
       
    69     LOG_D( "CBtSerialClient::ConstructL()" );
       
    70 
       
    71     TInt err = iPowerControl.Open();
       
    72     if ( err != KErrNone )
       
    73     	{
       
    74     	LOGFMT_E( "Could not open BT power controller %d", err );
       
    75     	User::Leave( err );
       
    76     	}
       
    77 
       
    78     // Check current BT power state and try to turn ON if necessary
       
    79     TBTPowerState powerState = EBTOff;
       
    80     err = iPowerControl.GetPower( ( TBTPowerState& ) powerState, NULL );
       
    81     LOGFMT_D( "GetPower return code %d", err );
       
    82     LOGFMT_D( "Current BT power state %d", powerState );
       
    83     if ( powerState != EBTOn )
       
    84     	{
       
    85     	LOG_I( "Turning BT ON" );
       
    86     	TRequestStatus status = KRequestPending;
       
    87     	iPowerControl.SetPower( EBTOn, NULL, status );
       
    88     	User::WaitForRequest( status );
       
    89     	LOGFMT_D( "SetPower return code %d", status.Int() );
       
    90     	if ( status != KErrNone && status != KErrAlreadyExists )
       
    91     		{
       
    92     		LOGFMT_E( "Could not turn BT on, err: %d", status.Int() );
       
    93     		User::Leave( status.Int() );
       
    94     		}
       
    95         LOG_I( "Waiting a while for BT to turn on" );
       
    96         User::After( 1 * 1000 * 1000 );
       
    97     	}
       
    98 
       
    99 	err = StartC32();
       
   100     LOGFMT_D( "StartC32 return code %d", err );
       
   101 
       
   102     LOG_I( "Continuing BT connect" );
       
   103 
       
   104     iServiceSearcher = CMessageServiceSearcher::NewL();
       
   105     User::LeaveIfError( iSocketServer.Connect() );
       
   106     iSocketReader = CSocketsReader::NewL( *this, iSocket );
       
   107     iSocketWriter = CSocketsWriter::NewL( *this, iSocket );
       
   108     }
       
   109 
       
   110 // ----------------------------------------------------------------------------
       
   111 void CBtSerialClient::DoCancel()
       
   112     {
       
   113     LOG_W("CBtSerialClient::DoCancel(): Doing nothing");
       
   114     }
       
   115 
       
   116 // ----------------------------------------------------------------------------
       
   117 void CBtSerialClient::RunL()
       
   118     {
       
   119     if ( iStatus != KErrNone )
       
   120         {
       
   121         switch ( iState )
       
   122             {
       
   123             case EGettingDevice:
       
   124                 if ( iStatus == KErrCancel )
       
   125                     {
       
   126                     LOG_W( "CBtSerialClient: No device selected" );
       
   127                     }
       
   128                 iState = EWaitingToGetDevice;
       
   129                 iObserver.ConnectedToServer( iStatus.Int() );
       
   130                 break;
       
   131             case EGettingService:
       
   132                 LOGFMT_W( "CBtSerialClient: Failed to fetch remote service: %d", iStatus.Int() );
       
   133                 iObserver.ConnectedToServer( iStatus.Int() );
       
   134                 iState = EWaitingToGetDevice;
       
   135                 break;
       
   136             case EGettingConnection:
       
   137                 LOGFMT_W( "CBtSerialClient: Failed to connect to remote service: %d", iStatus.Int() );
       
   138                 if ( iCurrentServiceIndex < iServiceSearcher->ServiceCount() )
       
   139                     {
       
   140                     // Try another service
       
   141                     iCurrentServiceIndex++;
       
   142                     ConnectToServerL(); // establish RFComm connection
       
   143                     }
       
   144                 else
       
   145                     {
       
   146                     iState = EWaitingToGetDevice;
       
   147                     iObserver.ConnectedToServer( iStatus.Int() );
       
   148                     }
       
   149                 break;
       
   150             case EConnected:
       
   151                 LOGFMT_I( "CBtSerialClient: Lost connection: %d", iStatus.Int() )
       
   152                 DisconnectFromServer();
       
   153                 iState = EDisconnecting;
       
   154                 break;
       
   155             case EDisconnecting:
       
   156                 LOGFMT_I("CBtSerialClient: Disconnected from server: %d", iStatus.Int() );
       
   157                 iSocket.Close();
       
   158                 iState = EWaitingToGetDevice;
       
   159                 iObserver.DisconnectedFromServer();
       
   160                 break;
       
   161             default:
       
   162                 Panic( EBTPointToPointInvalidLogicState );
       
   163                 break;
       
   164             }
       
   165         }
       
   166     else // iStatus = KErrNone
       
   167         {
       
   168         switch ( iState )
       
   169             {
       
   170             case EGettingDevice:
       
   171                 // found a device now search for a suitable service
       
   172                 LOGFMT_I("CBtSerialClient: Found device: %S. Finding correct service.", &(iServiceSearcher->ResponseParams().DeviceName()) );
       
   173                 iState = EGettingService;
       
   174                 iStatus = KRequestPending;  // this means that the RunL can not
       
   175                                             // be called until this program
       
   176                                             // does something to iStatus
       
   177                 iBTServerDevice = iServiceSearcher->BTDevAddr();
       
   178                 iServiceSearcher->FindServiceL( iBTServerDevice, iStatus );
       
   179                 SetActive();
       
   180                 break;
       
   181             case EGettingService:
       
   182                 LOGFMT_I("CBtSerialClient: Found %d remote services", iServiceSearcher->ServiceCount());
       
   183                 iState = EGettingConnection;
       
   184                 ConnectToServerL(); // establish RFComm connection
       
   185                 break;
       
   186             case EGettingConnection:
       
   187                 LOG_I( "CBtSerialClient: Connected to remote service" );
       
   188                 iState = EConnected;
       
   189                 iObserver.ConnectedToServer( KErrNone );
       
   190                 break;
       
   191             case EDisconnecting:
       
   192                 LOG_I( "CBtSerialClient: Disconnecting" );
       
   193                 iSocket.Close();
       
   194                 iState = EWaitingToGetDevice;
       
   195                 iObserver.DisconnectedFromServer();
       
   196                 break;
       
   197             default:
       
   198                 LOGFMT_E( "CBtSerialClient: Invalid logic state in RunL: %d. Will panic", iState );
       
   199                 Panic( EBTPointToPointInvalidLogicState );
       
   200                 break;
       
   201             };
       
   202         }
       
   203     }
       
   204 
       
   205 // ----------------------------------------------------------------------------
       
   206 EXPORT_C void CBtSerialClient::ConnectL()
       
   207     {
       
   208     if ( iState == EWaitingToGetDevice && !IsActive() )
       
   209         {
       
   210         LOG_D( "CBtSerialClient: Connecting by user selection" );
       
   211         iState = EGettingDevice;
       
   212         iServiceSearcher->SelectDeviceByDiscoveryL( iStatus );
       
   213         SetActive();
       
   214         }
       
   215     else
       
   216         {
       
   217         LOG_W( "CBtSerialClient: Already connecting or connected" );
       
   218         User::Leave( KErrInUse );
       
   219         }
       
   220     }
       
   221 
       
   222 // ----------------------------------------------------------------------------
       
   223 EXPORT_C void CBtSerialClient::ConnectL( const TBTDevAddr aBTServerDevice,
       
   224                                          const TInt aPort )
       
   225     {
       
   226     if ( iState == EWaitingToGetDevice && !IsActive() )
       
   227         {
       
   228         if ( aPort >= 0 )
       
   229             {
       
   230             // If there was a valid port given, add it as the first port to try
       
   231             iServiceSearcher->AppendPort( aPort );
       
   232             }
       
   233         LOG_D( "CBtSerialClient: Connecting by address" );
       
   234         iBTServerDevice = aBTServerDevice;
       
   235         iServiceSearcher->FindServiceL( iBTServerDevice, iStatus );
       
   236         iState = EGettingService;
       
   237         iStatus = KRequestPending;  // this means that the RunL can not
       
   238                                     // be called until this program
       
   239                                     // does something to iStatus
       
   240         SetActive();
       
   241         }
       
   242     else
       
   243         {
       
   244         LOG_W("CBtSerialClient: Already connecting or connected");
       
   245         User::Leave( KErrInUse );
       
   246         }
       
   247     }
       
   248 
       
   249 // ----------------------------------------------------------------------------
       
   250 EXPORT_C void CBtSerialClient::ConnectL( const TDesC& aBTServerDeviceName,
       
   251                                          const TInt aPort )
       
   252     {
       
   253     if ( iState == EWaitingToGetDevice && !IsActive() )
       
   254         {
       
   255         if ( aPort >= 0 )
       
   256             {
       
   257             // If there was a valid port given, add it as the first port to try
       
   258             iServiceSearcher->AppendPort( aPort );
       
   259             }
       
   260         LOG_D( "CBtSerialClient: Connecting by name" );
       
   261         iState = EGettingDevice;
       
   262         iServiceSearcher->SelectDeviceByNameL( aBTServerDeviceName, iStatus );
       
   263         SetActive();
       
   264         }
       
   265     else
       
   266         {
       
   267         LOG_W( "CBtSerialClient: Already connecting or connected" );
       
   268         User::Leave( KErrInUse );
       
   269         }
       
   270     }
       
   271 
       
   272 // ----------------------------------------------------------------------------
       
   273 EXPORT_C TBTDevAddr CBtSerialClient::ServerAddressL()
       
   274     {
       
   275     if ( !Connected() )
       
   276         {
       
   277         LOG_E( "CBtSerialClient: ServerAddressL: Not connected" );
       
   278         User::Leave( KErrNotReady );
       
   279         }
       
   280     return iBTServerDevice;
       
   281     }
       
   282 
       
   283 // ----------------------------------------------------------------------------
       
   284 EXPORT_C void CBtSerialClient::Disconnect()
       
   285     {
       
   286     if ( iState == EConnected )
       
   287         {
       
   288         DisconnectFromServer();
       
   289         iState = EDisconnecting;
       
   290         }
       
   291     else
       
   292         {
       
   293         LOG_W( "CBtSerialClient: Disconnect: Not connected" );
       
   294         User::Leave( KErrDisconnected );
       
   295         }
       
   296     }
       
   297 
       
   298 // ----------------------------------------------------------------------------
       
   299 void CBtSerialClient::DisconnectFromServer()
       
   300     {
       
   301     // Terminate all operations
       
   302     iSocket.CancelAll();
       
   303     Cancel();
       
   304     iSocketReader->Cancel();
       
   305     iSocketWriter->CancelSending();
       
   306 
       
   307     LOG_I( "CBtSerialClient: Disconnecting from server" );
       
   308     iSocket.Shutdown( RSocket::ENormal, iStatus );
       
   309     SetActive();
       
   310     }
       
   311 
       
   312 // ----------------------------------------------------------------------------
       
   313 void CBtSerialClient::ConnectToServerL()
       
   314     {
       
   315     LOG_I("CBtSerialClient: ConnectToServerL")
       
   316     User::LeaveIfError( iSocket.Open( iSocketServer, KStrRFCOMM ) );
       
   317 
       
   318     TBTSockAddr address;
       
   319     address.SetBTAddr( iServiceSearcher->BTDevAddr() );
       
   320     address.SetPort( iServiceSearcher->Port( iCurrentServiceIndex ) );
       
   321     TBTServiceSecurity btSec;
       
   322     btSec.SetUid( TUid::Uid( KServiceUid ) );
       
   323     btSec.SetAuthentication( EMitmNotRequired );
       
   324     btSec.SetEncryption( EFalse );
       
   325     btSec.SetAuthorisation( EFalse );
       
   326     btSec.SetDenied( EFalse );
       
   327     address.SetSecurity( btSec );
       
   328 
       
   329     LOGFMT_I("CBtSerialClient: ConnectToServerL: Port = %d", address.Port() );
       
   330     iSocket.Connect( address, iStatus );
       
   331 
       
   332 #ifdef __WINS__
       
   333     User::After( 1 ); // Needed to allow emulator client to connect to server
       
   334 #endif
       
   335 
       
   336     SetActive();
       
   337     }
       
   338 
       
   339 // ----------------------------------------------------------------------------
       
   340 EXPORT_C void CBtSerialClient::SendL(const TDesC8& aData)
       
   341     {
       
   342     if ( !Connected() )
       
   343         {
       
   344         LOG_E( "CBtSerialClient: SendL: Not connected" );
       
   345         User::Leave( KErrNotReady );
       
   346         }
       
   347 
       
   348     LOGFMT_D("CBtSerialClient::SendL: Sending data (max first 32 bytes): \"%S\"", &(aData.Left(32)));
       
   349     iSocketWriter->SendL( aData ); // Add to data queue and start sending
       
   350     LOG_D("CBtSerialClient::SendL: Sent to socket");
       
   351     }
       
   352 
       
   353 EXPORT_C void CBtSerialClient::ReadAsyncL()
       
   354     {
       
   355     if ( !Connected() )
       
   356         {
       
   357         LOG_E( "CBtSerialClient: ReadAsyncL: Not connected" );
       
   358         User::Leave( KErrNotReady );
       
   359         }
       
   360     iSocketReader->ReadAsync();
       
   361     }
       
   362 
       
   363 // ----------------------------------------------------------------------------
       
   364 EXPORT_C TInt CBtSerialClient::FreeSpaceInSendBuffer()
       
   365     {
       
   366     return iSocketWriter->FreeSpaceInSendBuffer();
       
   367     }
       
   368 
       
   369 // ----------------------------------------------------------------------------
       
   370 EXPORT_C TInt CBtSerialClient::SendBufferMaxSize()
       
   371     {
       
   372     return iSocketWriter->SendBufferMaxSize();
       
   373     }
       
   374 
       
   375 // ----------------------------------------------------------------------------
       
   376 EXPORT_C TBool CBtSerialClient::Connected()
       
   377     {
       
   378     return (iState == EConnected);
       
   379     }
       
   380 
       
   381 // ----------------------------------------------------------------------------
       
   382 EXPORT_C TBool CBtSerialClient::Connecting()
       
   383     {
       
   384     return ( ( iState == EGettingDevice ) ||
       
   385              ( iState == EGettingService ) ||
       
   386              ( iState == EGettingConnection ) );
       
   387     }
       
   388 
       
   389 // ----------------------------------------------------------------------------
       
   390 EXPORT_C TInt CBtSerialClient::ServicePort()
       
   391     {
       
   392     if ( !Connected() )
       
   393         {
       
   394         return KErrDisconnected;
       
   395         }
       
   396     return iServiceSearcher->Port( iCurrentServiceIndex );
       
   397     }
       
   398 
       
   399 // ----------------------------------------------------------------------------
       
   400 void CBtSerialClient::ReportError( TErrorType aErrorType, TInt aErrorCode )
       
   401     {
       
   402     LOGFMT_W( "CBtSerialClient::ReportError: %d", aErrorCode );
       
   403     // From socket reader or writer
       
   404     switch ( aErrorType )
       
   405         {
       
   406         case EDisconnected:
       
   407             {
       
   408             LOG_I( "CBtSerialClient: disconnected" );
       
   409             }
       
   410             break;
       
   411         case ETimeOutOnWrite:
       
   412             {
       
   413             LOG_I( "CBtSerialClient: timout writing data. Disconnecting from server" );
       
   414             }
       
   415             break;
       
   416         case EGeneralReadError:
       
   417             {
       
   418             LOG_I( "CBtSerialClient: general read error. Disconnecting from server" );
       
   419             }
       
   420             break;
       
   421         case EGeneralWriteError:
       
   422             {
       
   423             LOG_I( "CBtSerialClient: general write error. Disconnecting from server" );
       
   424             }
       
   425             break;
       
   426         }
       
   427     Disconnect();
       
   428     aErrorCode = aErrorCode;
       
   429     }
       
   430 
       
   431 // ----------------------------------------------------------------------------
       
   432  void CBtSerialClient::NewData( const TDesC8& aData )
       
   433     {
       
   434     iObserver.DataFromServer( aData );
       
   435     }
       
   436 
       
   437 // ----------------------------------------------------------------------------
       
   438 void CBtSerialClient::AllBufferedDataSent()
       
   439     {
       
   440     iObserver.AllBufferedDataSent();
       
   441     }
       
   442 
       
   443 // End of File