bluetoothengine/headsetsimulator/core/src/RemoteControl/hsremotecontrolserver.cpp
branchheadsetsimulator
changeset 60 90dbfc0435e3
equal deleted inserted replaced
59:02103bf20ee5 60:90dbfc0435e3
       
     1 /*
       
     2  * Component Name: Headset Simulator
       
     3  * Author: Comarch S.A.
       
     4  * Version: 1.0
       
     5  * Copyright (c) 2010 Comarch S.A.
       
     6  *  
       
     7  * This Software is submitted by Comarch S.A. to Symbian Foundation Limited on 
       
     8  * the basis of the Member Contribution Agreement entered between Comarch S.A. 
       
     9  * and Symbian Foundation Limited on 5th June 2009 (“Agreement”) and may be 
       
    10  * used only in accordance with the terms and conditions of the Agreement. 
       
    11  * Any other usage, duplication or redistribution of this Software is not 
       
    12  * allowed without written permission of Comarch S.A.
       
    13  * 
       
    14  */
       
    15 #include "hsremotecontrolserver.h"
       
    16 #include "hscore.h" 
       
    17 #include "hsremotecontroldatahandler.h"
       
    18 #include "hsremotecontroltools.h"
       
    19 #include "debug.h"
       
    20 
       
    21 _LIT8(KHsATVGS,"AT+VGS=");
       
    22 _LIT8(KHsATCommandEnding,"\r\n");
       
    23 _LIT8(KHsATVGM,"AT+VGM=");
       
    24 
       
    25 CHsControlServer* CHsControlServer::NewL( RSocketServ& aSocketServ,
       
    26         CHsCore* aHsCore )
       
    27     {
       
    28     CHsControlServer* self = CHsControlServer::NewLC( aSocketServ, aHsCore );
       
    29     CleanupStack::Pop( self );
       
    30     return self;
       
    31     }
       
    32 
       
    33 CHsControlServer* CHsControlServer::NewLC( RSocketServ& aSocketServ,
       
    34         CHsCore* aHsCore )
       
    35     {
       
    36     CHsControlServer* self = new ( ELeave ) CHsControlServer( aSocketServ,
       
    37             aHsCore );
       
    38     CleanupStack::PushL( self );
       
    39     self->ConstructL();
       
    40     return self;
       
    41     }
       
    42 
       
    43 CHsControlServer::CHsControlServer( RSocketServ& aSocketServ, CHsCore* aHsCore ) :
       
    44     iState( ENone ), iSocketServ( aSocketServ ), iHsCore( aHsCore )
       
    45     {
       
    46     }
       
    47 
       
    48 void CHsControlServer::ConstructL()
       
    49     {
       
    50     iDataHandler = CHsRemoteControlDataHandler::NewL();
       
    51     }
       
    52 
       
    53 CHsControlServer::~CHsControlServer()
       
    54     {
       
    55     TRACE_FUNC_ENTRY
       
    56     CancelListen();
       
    57     if ( iSocket )
       
    58         {
       
    59         delete iSocket;
       
    60         }
       
    61     if ( iListenSocket )
       
    62         {
       
    63         delete iListenSocket;
       
    64         }
       
    65     if ( iDataHandler )
       
    66         {
       
    67         delete iDataHandler;
       
    68         }
       
    69 
       
    70     TRACE_FUNC_EXIT
       
    71     }
       
    72 
       
    73 void CHsControlServer::StartRemoteControlServerL()
       
    74     {
       
    75     TRACE_FUNC_ENTRY
       
    76 
       
    77     if ( iState != ENone )
       
    78         {
       
    79         TRACE_INFO (_L("ControlServer is already listening"))
       
    80         TRACE_FUNC_EXIT
       
    81         User::Leave( KErrInUse );
       
    82         }
       
    83 
       
    84     iState = EConnecting;
       
    85     TProtocolDesc ProtocolDesc;
       
    86     User::LeaveIfError( iSocketServ.FindProtocol( KHsRFComm(), ProtocolDesc ) );
       
    87 
       
    88     if ( iListenSocket )
       
    89         {
       
    90         // Return value may be ignored
       
    91         iListenSocket->Shutdown( RSocket::EImmediate );
       
    92         delete iListenSocket;
       
    93         iListenSocket = NULL;
       
    94         }
       
    95     iListenSocket = CBluetoothSocket::NewL( *this, iSocketServ,
       
    96             ProtocolDesc.iSockType, ProtocolDesc.iProtocol );
       
    97 
       
    98     User::LeaveIfError( iListenSocket->GetOpt(
       
    99             KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, iServerPort ) );
       
   100 
       
   101     TBTSockAddr btSockAddr;
       
   102     btSockAddr.SetPort( iServerPort );
       
   103 
       
   104     RegisterSdpL( iServerPort );
       
   105     User::LeaveIfError( iListenSocket->Bind( btSockAddr ) );
       
   106 
       
   107     TRACE_INFO( ( _L("Control Server port =  %d"), iServerPort) )
       
   108     User::LeaveIfError( iListenSocket->Listen( KHsSizeOfListenQueue ) );
       
   109 
       
   110     TBTServiceSecurity secSettings;
       
   111     TUid settingsUID = TUid::Uid( (TInt) KHsRemoteControlServiceID );
       
   112     secSettings.SetUid( settingsUID );
       
   113     secSettings.SetAuthentication( EFalse );
       
   114     secSettings.SetAuthorisation( EFalse );
       
   115     secSettings.SetEncryption( EFalse );
       
   116 
       
   117     btSockAddr.SetSecurity( secSettings );
       
   118 
       
   119     if ( iSocket )
       
   120         {
       
   121         // Return value may be ignored
       
   122         iSocket->Shutdown( RSocket::EImmediate );
       
   123         delete iSocket;
       
   124         iSocket = NULL;
       
   125         }
       
   126     iSocket = CBluetoothSocket::NewL( *this, iSocketServ );
       
   127     User::LeaveIfError( iListenSocket->Accept( *iSocket ) );
       
   128     iInitialized = ETrue;
       
   129     TRACE_INFO( _L("CHSControlServer::Listen() status = OK" ) )
       
   130 
       
   131     TRACE_FUNC_EXIT
       
   132     }
       
   133 
       
   134 void CHsControlServer::CancelListen()
       
   135     {
       
   136     TRACE_FUNC_ENTRY
       
   137    
       
   138     if ( iState == EWaiting )//Client is connected to socket
       
   139         {
       
   140         iSocket->CancelAll();
       
   141         // Return value may be ignored
       
   142         iSocket->Shutdown( RSocket::EImmediate );
       
   143         delete iSocket;
       
   144         iSocket = NULL;
       
   145         iListenSocket->CancelAll();
       
   146 
       
   147         // Return value may be ignored
       
   148         iListenSocket->Shutdown( RSocket::EImmediate );
       
   149         delete iListenSocket;
       
   150         iListenSocket = NULL;
       
   151         }
       
   152     else
       
   153         { //Sockets are ready, but client is not connected
       
   154         delete iSocket;
       
   155         iSocket = NULL;
       
   156         delete iListenSocket;
       
   157         iListenSocket = NULL;
       
   158         }
       
   159 
       
   160     DeleteRecordSdp();
       
   161 
       
   162     iInitialized = EFalse;
       
   163     iState = ENone;
       
   164 
       
   165     TRACE_FUNC_EXIT
       
   166     }
       
   167 
       
   168 void CHsControlServer::SetConnectionObserver(
       
   169         MRemoteControllerConnectionObserver &aRemoteControllerObserver )
       
   170     {
       
   171     iConnectionObserver = &aRemoteControllerObserver;
       
   172     }
       
   173 
       
   174 void CHsControlServer::HandleConnectCompleteL( TInt aErr )
       
   175     {
       
   176     TRACE_FUNC_ENTRY
       
   177     TRACE_INFO( ( _L("aErr = %d"), aErr) );
       
   178     TRACE_FUNC_EXIT
       
   179     }
       
   180 
       
   181 void CHsControlServer::HandleAcceptCompleteL( TInt aErr )
       
   182     {
       
   183     TRACE_FUNC_ENTRY
       
   184     TRACE_INFO( ( _L("aErr = %d"), aErr) );
       
   185     iState = EWaiting;
       
   186     Receive();
       
   187     if ( iConnectionObserver )
       
   188         {
       
   189         iConnectionObserver->HandleRemoteControllerConnected( aErr );
       
   190         }
       
   191     TRACE_FUNC_EXIT
       
   192     }
       
   193 
       
   194 void CHsControlServer::HandleShutdownCompleteL( TInt aErr )
       
   195     {
       
   196     TRACE_FUNC_ENTRY
       
   197     TRACE_INFO( ( _L("aErr = %d"), aErr) );
       
   198     TRACE_FUNC_EXIT
       
   199     }
       
   200 
       
   201 void CHsControlServer::HandleSendCompleteL( TInt aErr )
       
   202     {
       
   203     TRACE_FUNC_ENTRY
       
   204 
       
   205     TRACE_INFO( ( _L8("ControlServer sent %d bytes of data: [%S] with err [%d]")
       
   206             ,iSendDataBuffer.Length(), &iSendDataBuffer, aErr) )
       
   207     
       
   208     TInt error = KErrNone;
       
   209 
       
   210     if ( aErr == KErrNone )
       
   211         {
       
   212         iSendDataBuffer.Zero();
       
   213         if ( iTempDataBuffer.Length() > 0 )
       
   214             {
       
   215             iSendDataBuffer.Append( iTempDataBuffer );
       
   216             iTempDataBuffer.Zero();
       
   217             error = iSocket->Write( iSendDataBuffer );
       
   218             }
       
   219         }
       
   220     Receive();
       
   221 
       
   222     User::LeaveIfError( error );
       
   223 
       
   224     TRACE_FUNC_EXIT
       
   225     }
       
   226 
       
   227 void CHsControlServer::HandleReceiveCompleteL( TInt aErr )
       
   228     {
       
   229     TRACE_FUNC_ENTRY
       
   230     TRACE_INFO( ( _L8("[ControlServer] received %d bytes of data: [%S]"
       
   231             "with err [%d]"), iReceiveDataBuffer.Length(), &iReceiveDataBuffer,
       
   232             aErr) )
       
   233 
       
   234     if ( aErr == KErrNone )
       
   235         {
       
   236         TInt error = KErrNone;
       
   237 
       
   238         if ( iSendDataBuffer.Length() > 0 )
       
   239             {
       
   240             error = iSocket->Write( iSendDataBuffer );
       
   241             }
       
   242         else if ( iTempDataBuffer.Length() > 0 )
       
   243             {
       
   244             iSendDataBuffer.Append( iTempDataBuffer );
       
   245             iTempDataBuffer.Zero();
       
   246             error = iSocket->Write( iSendDataBuffer );
       
   247             }
       
   248 
       
   249         TRAP_IGNORE( HandleRequestL( iReceiveDataBuffer ) );
       
   250 
       
   251         Receive();
       
   252 
       
   253         User::LeaveIfError( error );
       
   254         }
       
   255     else
       
   256         {
       
   257         TRACE_INFO( _L("ControlClient is disconnected") )
       
   258 
       
   259         if ( iConnectionObserver )
       
   260             {
       
   261             iConnectionObserver->HandleRemoteControllerDisconnected( aErr );
       
   262             }
       
   263         CancelListen();
       
   264         StartRemoteControlServerL();
       
   265         }
       
   266     TRACE_FUNC_EXIT
       
   267     }
       
   268 
       
   269 void CHsControlServer::HandleIoctlCompleteL( TInt /*aErr*/)
       
   270     {
       
   271     TRACE_FUNC_ENTRY
       
   272     TRACE_FUNC_EXIT
       
   273     }
       
   274 
       
   275 void CHsControlServer::HandleActivateBasebandEventNotifierCompleteL(
       
   276         TInt /*aErr*/, TBTBasebandEventNotification& /*aEventNotification*/)
       
   277     {
       
   278     TRACE_FUNC_ENTRY
       
   279     TRACE_FUNC_EXIT
       
   280     }
       
   281 
       
   282 TInt CHsControlServer::Send( const TDesC8& aData )
       
   283     {
       
   284     TRACE_FUNC_ENTRY
       
   285     TInt error = KErrNone;
       
   286     if ( iState != EWaiting )
       
   287         {
       
   288         error = KErrNotReady;
       
   289         TRACE_INFO( _L("ControlServer not ready") )
       
   290 
       
   291         return error;
       
   292         }
       
   293 
       
   294     if ( iSendDataBuffer.Length() == 0 )
       
   295         {
       
   296         iSendDataBuffer.Append( iTempDataBuffer );
       
   297         iTempDataBuffer.Zero();
       
   298         iSendDataBuffer.Append( aData );
       
   299         }
       
   300     else
       
   301         {
       
   302         iTempDataBuffer.Append( aData );
       
   303         }
       
   304 
       
   305     if ( iSendDataBuffer.Length() > 0 )
       
   306         {
       
   307         iSocket->CancelRecv();
       
   308         error = iSocket->Write( iSendDataBuffer );
       
   309         Receive();
       
   310         }
       
   311     else
       
   312         {
       
   313         Receive();
       
   314         }
       
   315     TRACE_FUNC_EXIT
       
   316     return error;
       
   317     }
       
   318 
       
   319 void CHsControlServer::Receive()
       
   320     {
       
   321     TRACE_FUNC_ENTRY
       
   322     // Return value may be ignored, 
       
   323     // error will be notified to HandleReceiveCompleteL
       
   324     iSocket->RecvOneOrMore( iReceiveDataBuffer, 0, iDataLength );
       
   325     TRACE_FUNC_EXIT
       
   326     }
       
   327 
       
   328 void CHsControlServer::RegisterSdpL( TInt aChannel )
       
   329     {
       
   330     TRACE_FUNC_ENTRY
       
   331 
       
   332     User::LeaveIfError( iSdpServer.Connect() );
       
   333     User::LeaveIfError( iSdpDB.Open( iSdpServer ) );
       
   334 
       
   335     TUUID serviceUUID( KHsRemoteControlServiceID );
       
   336     iSdpDB.CreateServiceRecordL( serviceUUID, iSdpRecordHandle );
       
   337 
       
   338     CSdpAttrValueDES* valDES = CSdpAttrValueDES::NewDESL( NULL );
       
   339     CleanupStack::PushL( valDES );
       
   340     valDES->StartListL()->BuildDESL()->StartListL()->BuildUUIDL( TUUID(
       
   341             KL2CAPUUID ) )->EndListL()->BuildDESL()->StartListL()->BuildUUIDL(
       
   342             TUUID( KRFCommUUID ) )->BuildUintL(
       
   343             TSdpIntBuf <TUint8> ( aChannel ) )->EndListL()->EndListL();
       
   344     
       
   345     iSdpDB.UpdateAttributeL( iSdpRecordHandle,
       
   346             KSdpAttrIdProtocolDescriptorList, *valDES );
       
   347     
       
   348     CleanupStack::PopAndDestroy( valDES );
       
   349 
       
   350     iSdpDB.UpdateAttributeL( iSdpRecordHandle, KSdpAttrIdBasePrimaryLanguage
       
   351             + KSdpAttrIdOffsetServiceName, KServiceName );
       
   352     
       
   353     iSdpDB.UpdateAttributeL( iSdpRecordHandle, KSdpAttrIdBasePrimaryLanguage
       
   354             + KSdpAttrIdOffsetServiceDescription, KServiceDesc );
       
   355     
       
   356     UpdateAvailabilityL( ETrue );
       
   357     
       
   358     TRACE_INFO ( _L("CHsControlServer::RegisterSdpL, status = OK") )
       
   359     TRACE_FUNC_EXIT
       
   360     }
       
   361 
       
   362 void CHsControlServer::UpdateAvailabilityL( TBool aAvailable )
       
   363     {
       
   364     TInt state = ( aAvailable ? KServicAvailable : KServiceUnavailable );
       
   365     // Set availability
       
   366     iSdpDB.UpdateAttributeL( iSdpRecordHandle, KSdpAttrIdServiceAvailability,
       
   367             state );
       
   368     // Mark record changed
       
   369     iSdpDB.UpdateAttributeL( iSdpRecordHandle, KSdpAttrIdServiceRecordState,
       
   370             ++iRecordState );
       
   371     }
       
   372 
       
   373 void CHsControlServer::DeleteRecordSdp()
       
   374     {
       
   375     TRACE_FUNC_ENTRY
       
   376 
       
   377     iSdpDB.DeleteRecord( iSdpRecordHandle );
       
   378     iSdpRecordHandle = 0;
       
   379     iSdpDB.Close();
       
   380     iSdpServer.Close();
       
   381 
       
   382     TRACE_FUNC_EXIT
       
   383     }
       
   384 
       
   385 void CHsControlServer::HandleRequestL( TDes8 &aRequest )
       
   386     {
       
   387     TRACE_FUNC_ENTRY
       
   388 
       
   389     TBuf8 <KHsRemoteControlPackageLength> buf;
       
   390 
       
   391     THsControlCommandData dummyBuf( KNullDesC8 );
       
   392     THsRemoteControlCommand command( dummyBuf, EHsLast );
       
   393     if ( iDataHandler )
       
   394         {
       
   395         TInt err = iDataHandler->RecognizeCommand( aRequest, command );
       
   396         if ( KErrNone != err )
       
   397             {
       
   398             User::Leave( KErrArgument );
       
   399             }
       
   400         }
       
   401 
       
   402     THsRemoteControlCommandType type = EHsLast;
       
   403     command.GetType( type );
       
   404 
       
   405     switch ( type )
       
   406         {
       
   407         case EHsTurnOn:
       
   408             {
       
   409             command.GetData( buf );
       
   410 
       
   411             RBuf8 cod;
       
   412             RBuf8 sdp;
       
   413             RBuf8 plugin;
       
   414 
       
   415             cod.CleanupClosePushL();
       
   416             sdp.CleanupClosePushL();
       
   417             plugin.CleanupClosePushL();
       
   418 
       
   419             RetrieveStartupParamsL( buf, cod, sdp, plugin );
       
   420 
       
   421             iHsCore->StartSimulationL( cod, sdp, plugin );
       
   422 
       
   423             CleanupStack::PopAndDestroy( 3 );
       
   424             }
       
   425             break;
       
   426 
       
   427         case EHsTurnOff:
       
   428             {
       
   429             iHsCore->StopSimulation();
       
   430             }
       
   431             break;
       
   432         case EHsConnectLastconnected:
       
   433             {
       
   434             iHsCore->ConnectWithLastConnectedL();
       
   435             }
       
   436             break;
       
   437         case EHsConnectDevAddress:
       
   438             {
       
   439             command.GetData( buf );
       
   440             iHsCore->ConnectWithDevAddress( buf.Expand() );
       
   441             }
       
   442             break;
       
   443         case EHsConnectName:
       
   444             {
       
   445             command.GetData( buf );
       
   446             iHsCore->ConnectWithName( buf.Expand() );
       
   447             }
       
   448             break;
       
   449         case EHsDisconnectAGs:
       
   450             {
       
   451             iHsCore->DisconnectClients();
       
   452             }
       
   453             break;
       
   454         case EHsAcceptCall:
       
   455             {
       
   456             User::LeaveIfError( iHsCore->AcceptIncomingCall() );
       
   457             }
       
   458             break;
       
   459         case EHsReleaseCall:
       
   460             {
       
   461             User::LeaveIfError( iHsCore->ReleaseOngoingCall() );
       
   462             }
       
   463             break;
       
   464 
       
   465         case EHsSetSpeakerVolume:
       
   466             {
       
   467             command.GetData( buf );
       
   468             RBuf8 tempBuf;
       
   469             tempBuf.CreateL( buf.Length() + KHsATCommandEnding().Length()
       
   470                     + KHsATVGS().Length() );
       
   471             tempBuf.Copy( KHsATVGS );
       
   472             tempBuf.Append( buf );
       
   473             tempBuf.Append( KHsATCommandEnding );
       
   474 
       
   475             iHsCore->Send( tempBuf );
       
   476             tempBuf.Close();
       
   477 
       
   478             }
       
   479             break;
       
   480         case EHsSetMicVolume:
       
   481             {
       
   482             command.GetData( buf );
       
   483             RBuf8 tempBuf;
       
   484             tempBuf.CreateL( buf.Length() + KHsATCommandEnding().Length()
       
   485                     + KHsATVGM().Length() );
       
   486             tempBuf.Copy( KHsATVGM );
       
   487             tempBuf.Append( buf );
       
   488             tempBuf.Append( KHsATCommandEnding );
       
   489 
       
   490             iHsCore->Send( tempBuf );
       
   491             tempBuf.Close();
       
   492             }
       
   493             break;
       
   494         case EHsSendAnyAt:
       
   495             {
       
   496             command.GetData( buf );
       
   497             User::LeaveIfError( iHsCore->Send( buf ) );
       
   498             }
       
   499             break;
       
   500         default:
       
   501             User::Leave( KErrArgument );
       
   502 
       
   503         }
       
   504     TRACE_FUNC_EXIT
       
   505     }
       
   506 
       
   507 void CHsControlServer::RetrieveStartupParamsL( const TDesC8& aParams,
       
   508         RBuf8& aPluginCod, RBuf8& aPluginSdp, RBuf8& aPluginProfile )
       
   509 
       
   510     {
       
   511     TRACE_FUNC_ENTRY
       
   512 
       
   513     TInt sepPos = aParams.Find( KHsRemoteRequestParamSeparator );
       
   514 
       
   515     User::LeaveIfError( sepPos );
       
   516 
       
   517     aPluginCod.CreateL( aParams.Left( sepPos ) );
       
   518 
       
   519     sepPos += 2;
       
   520 
       
   521     TInt sepPos2 = aParams.Mid( sepPos, aParams.Length() - sepPos ).Find(
       
   522             KHsRemoteRequestParamSeparator );
       
   523 
       
   524     User::LeaveIfError( sepPos2 );
       
   525 
       
   526     aPluginSdp.CreateL( aParams.Mid( sepPos, sepPos2 ) );
       
   527 
       
   528     sepPos += 2;
       
   529     sepPos += sepPos2;
       
   530 
       
   531     aPluginProfile.CreateL( aParams.Mid( sepPos, aParams.Length() - sepPos ) );
       
   532 
       
   533     TRACE_FUNC_EXIT
       
   534     }