usbengines/usbotgwatcher/src/cusbservicecontrol.cpp
changeset 34 7858bc6ead78
parent 31 dfdd8240f7c8
child 35 9d8b04ca6939
equal deleted inserted replaced
31:dfdd8240f7c8 34:7858bc6ead78
     1 /*
       
     2  * Copyright (c) 2008 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:  Implementation
       
    15  *
       
    16  */
       
    17 
       
    18 #include <usbman.h>
       
    19 
       
    20 #include "cusbservicecontrol.h"
       
    21 #include "debug.h"
       
    22 #include "panic.h"
       
    23 
       
    24 // ---------------------------------------------------------------------------
       
    25 // 
       
    26 // ---------------------------------------------------------------------------
       
    27 //
       
    28 CUsbServiceControl::CUsbServiceControl(MUsbServiceControlObserver& aObserver,
       
    29         RUsb& aUsb) :
       
    30     CActive(CActive::EPriorityStandard), iObserver(aObserver), iUsb(aUsb),
       
    31             iPersonalityId(0)
       
    32     {
       
    33     CActiveScheduler::Add(this);
       
    34     }
       
    35 
       
    36 // ---------------------------------------------------------------------------
       
    37 // 
       
    38 // ---------------------------------------------------------------------------
       
    39 //
       
    40 CUsbServiceControl::~CUsbServiceControl()
       
    41     {
       
    42     LOG_FUNC
       
    43 
       
    44     Cancel();
       
    45     }
       
    46 
       
    47 // ---------------------------------------------------------------------------
       
    48 // 
       
    49 // ---------------------------------------------------------------------------
       
    50 //
       
    51 void CUsbServiceControl::ConstructL()
       
    52     {
       
    53     LOG_FUNC
       
    54     }
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 // 
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 CUsbServiceControl* CUsbServiceControl::NewL(
       
    61         MUsbServiceControlObserver& aObserver, RUsb& aUsb)
       
    62     {
       
    63     LOG_FUNC
       
    64 
       
    65     CUsbServiceControl* self = new (ELeave) CUsbServiceControl(aObserver,
       
    66             aUsb);
       
    67     CleanupStack::PushL(self);
       
    68     self->ConstructL();
       
    69     CleanupStack::Pop(self); // pop self
       
    70     return self;
       
    71     }
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 // 
       
    75 // ---------------------------------------------------------------------------
       
    76 //
       
    77 TInt CUsbServiceControl::StartL(TInt aPersonalityId)
       
    78     {
       
    79     LOG_FUNC
       
    80 
       
    81     LOG1( "aPersonalityId = %d" , aPersonalityId);
       
    82 
       
    83     TUsbServiceState serviceState;
       
    84     TInt err = iUsb.GetServiceState(serviceState);
       
    85 
       
    86     if (KErrNone != err)
       
    87         {
       
    88         return err;
       
    89         }
       
    90 
       
    91     switch (serviceState)
       
    92         {
       
    93         case EUsbServiceIdle:
       
    94             {
       
    95             LOG( "UsbServiceState == EUsbServiceIdle" );
       
    96 
       
    97             iPersonalityId = aPersonalityId; // when request completed, this will indicate that we started what we wanted
       
    98             if (IsActive())
       
    99                 {
       
   100                 LOG("Request is outstanding, cancelling first" );
       
   101                 Cancel();
       
   102                 }
       
   103             iUsb.TryStart(aPersonalityId, iStatus);
       
   104             SetActive();
       
   105             break;
       
   106             }
       
   107 
       
   108         case EUsbServiceStarted:
       
   109             {
       
   110             LOG("UsbServiceState == EUsbServiceStarted");
       
   111 
       
   112             TInt currentPersonality(0);
       
   113             err = iUsb.GetCurrentPersonalityId(currentPersonality);
       
   114             if (KErrNone != err)
       
   115                 {
       
   116                 LOG1( "Error getting current personality err = %d" , err);
       
   117                 return err;
       
   118                 }
       
   119 
       
   120             if (aPersonalityId == currentPersonality) // already started
       
   121                 {
       
   122                 LOG("Personality already started" );
       
   123                 iObserver.UsbServiceControlReqCompletedL(KErrInUse);
       
   124                 return KErrNone;
       
   125                 }
       
   126 
       
   127             // we need to stop current personality and start service with new personailty id
       
   128             iPersonalityId = aPersonalityId; // this will indicate that we want to start this personality after
       
   129 
       
   130             StopL();
       
   131 
       
   132             // start new personality in RunL() when state is Idle
       
   133 
       
   134             break;
       
   135             }
       
   136         case EUsbServiceStarting:
       
   137             {
       
   138             LOG("UsbServiceState == EUsbServiceStarting" );
       
   139             // do exactly the same as in case of EUsbServiceStopping;
       
   140             // break statement is not required here
       
   141             }
       
   142         case EUsbServiceStopping:
       
   143             {
       
   144             LOG( "UsbServiceState == EUsbServiceStopping" );
       
   145 
       
   146             // subscribe for usb service state change, and start new usb service once current one started/stopped
       
   147             iPersonalityId = aPersonalityId; // this will indicate that we want to start this personality
       
   148 
       
   149             // this check is needed due to usb service might be stopping by other client  
       
   150             if (IsActive())
       
   151                 {
       
   152                 LOG( "Request outstanding. Waiting for completion" );
       
   153                 return KErrNone; // when the outstanding request get completed, we start usb services with iPersonalityId
       
   154                 }
       
   155 
       
   156             // otherwise, monitor usb service state
       
   157             iUsb.ServiceStateNotification(iServiceState, iStatus);
       
   158             SetActive();
       
   159 
       
   160             break;
       
   161             }
       
   162         case EUsbServiceFatalError:
       
   163             {
       
   164             LOG( "UsbServiceState == EUsbServiceFatalError" );
       
   165             return KErrGeneral;
       
   166             }
       
   167         default:
       
   168             {
       
   169             PANIC( EUnknownUsbServiceState);
       
   170             }
       
   171         }
       
   172 
       
   173     return KErrNone;
       
   174 
       
   175     }
       
   176 
       
   177 // ---------------------------------------------------------------------------
       
   178 // 
       
   179 // ---------------------------------------------------------------------------
       
   180 //
       
   181 TInt CUsbServiceControl::StopL()
       
   182     {
       
   183     LOG_FUNC
       
   184 
       
   185     TUsbServiceState serviceState;
       
   186     TInt err = iUsb.GetServiceState(serviceState);
       
   187 
       
   188     LOG2("err = %d; serviceState = %d" , err, serviceState);
       
   189 
       
   190     if (KErrNone != err)
       
   191         {
       
   192         return err;
       
   193         }
       
   194 
       
   195     switch (serviceState)
       
   196         {
       
   197         case EUsbServiceIdle:
       
   198             {
       
   199             LOG("UsbServiceState == EUsbServiceIdle" );
       
   200 
       
   201             return KErrNone;
       
   202             }
       
   203 
       
   204         case EUsbServiceStarted:
       
   205             {
       
   206             LOG("UsbServiceState == EUsbServiceStarted" );
       
   207 
       
   208             if (IsActive())
       
   209                 {
       
   210                 LOG("Request is outstanding, cancelling it" );
       
   211                 Cancel();
       
   212                 }
       
   213             iUsb.TryStop(iStatus);
       
   214             SetActive();
       
   215 
       
   216             break;
       
   217             }
       
   218         case EUsbServiceStopping:
       
   219             {
       
   220             LOG( "UsbServiceState == EUsbServiceStopping" );
       
   221             // do exactly the same as in case of EUsbServiceStarting;
       
   222             // break statement is not required here
       
   223             }
       
   224         case EUsbServiceStarting:
       
   225             {
       
   226             LOG("UsbServiceState == EUsbServiceStarting" );
       
   227 
       
   228             // subscribe for usb service state change, and stop usb service once current one started
       
   229             iPersonalityId = 0; // this will indicate that we do not want to start this personality
       
   230 
       
   231             // this check is needed due to usb service might be starting by other client  
       
   232             if (IsActive())
       
   233                 {
       
   234                 LOG("Request is outstanding, waiting for completion" );
       
   235                 return KErrNone; // when this request get completed, we request to stop usb services
       
   236                 }
       
   237 
       
   238             // otherwise, monitor usb service state
       
   239             iUsb.ServiceStateNotification(iServiceState, iStatus);
       
   240             SetActive();
       
   241 
       
   242             break;
       
   243             }
       
   244         case EUsbServiceFatalError:
       
   245             {
       
   246             LOG("UsbServiceState == EUsbServiceFatalError" );
       
   247             return KErrGeneral;
       
   248             }
       
   249         default:
       
   250             {
       
   251             PANIC( EUnknownUsbServiceState);
       
   252             }
       
   253         }
       
   254     return KErrNone;
       
   255     }
       
   256 
       
   257 // ---------------------------------------------------------------------------
       
   258 // 
       
   259 // ---------------------------------------------------------------------------
       
   260 //
       
   261 void CUsbServiceControl::RunL()
       
   262     {
       
   263     LOG_FUNC
       
   264 
       
   265     LOG1("iStatus = %d" , iStatus.Int());
       
   266 
       
   267     if (KErrNone != iStatus.Int())
       
   268         {
       
   269         iObserver.UsbServiceControlReqCompletedL(iStatus.Int());
       
   270         return;
       
   271         }
       
   272 
       
   273     TUsbServiceState serviceState;
       
   274     TInt err = iUsb.GetServiceState(serviceState);
       
   275 
       
   276     if (KErrNone != err)
       
   277         {
       
   278         LOG1("Error while getting service state %d" , err);
       
   279         iObserver.UsbServiceControlReqCompletedL(err);
       
   280         return;
       
   281         }
       
   282 
       
   283     switch (serviceState)
       
   284         {
       
   285         case EUsbServiceIdle: // usb service stopped
       
   286             {
       
   287             LOG("UsbServiceState == EUsbServiceIdle" );
       
   288 
       
   289             if (iPersonalityId != 0) // during service stopping, requested to start it
       
   290                 {
       
   291                 LOG1("Requested to start personality %d. Starting it." , iPersonalityId);
       
   292                 TInt personalityId = iPersonalityId;
       
   293                 iPersonalityId = 0; // reset
       
   294                 err = StartL(personalityId);
       
   295                 if (KErrNone != err)
       
   296                     {
       
   297                     iObserver.UsbServiceControlReqCompletedL(err);
       
   298                     }
       
   299                 return;
       
   300                 }
       
   301 
       
   302             // otherwise, we've done, notify
       
   303             iObserver.UsbServiceControlReqCompletedL(KErrNone);
       
   304             break;
       
   305             }
       
   306 
       
   307         case EUsbServiceStarted:
       
   308             {
       
   309             LOG("UsbServiceState == EUsbServiceStarted" );
       
   310 
       
   311             TInt currentPersonality(0);
       
   312             err = iUsb.GetCurrentPersonalityId(currentPersonality);
       
   313             if (KErrNone != err)
       
   314                 {
       
   315                 LOG1("Error while getting PersonalityId err = %d" , err);
       
   316                 iObserver.UsbServiceControlReqCompletedL(err);
       
   317                 return;
       
   318                 }
       
   319 
       
   320             if (iPersonalityId == currentPersonality) // already done
       
   321                 {
       
   322                 LOG("Personality already started" );
       
   323                 iPersonalityId = 0;
       
   324                 iObserver.UsbServiceControlReqCompletedL(KErrNone);
       
   325                 return;
       
   326                 }
       
   327 
       
   328             if (iPersonalityId == 0) // during service start requested to stop it
       
   329                 {
       
   330                 LOG("Requested to stop personality. Stopping." );
       
   331                 err = StopL();
       
   332                 if (KErrNone != err)
       
   333                     {
       
   334                     LOG1("Error while stopping personality err = %d" , err);
       
   335                     iObserver.UsbServiceControlReqCompletedL(err);
       
   336                     }
       
   337                 return;
       
   338                 }
       
   339 
       
   340             // otherwise, during service start, requested to start it with another personality
       
   341             LOG1( "Requested to start personality %d. Starting it.", iPersonalityId);
       
   342             TInt personalityId = iPersonalityId;
       
   343             iPersonalityId = 0; // reset
       
   344             err = StartL(personalityId);
       
   345             if (KErrNone != err)
       
   346                 {
       
   347                 LOG1("Error while starting personality err = %d" , err);
       
   348                 iObserver.UsbServiceControlReqCompletedL(err);
       
   349                 }
       
   350             break;
       
   351             }
       
   352 
       
   353         case EUsbServiceStarting:
       
   354             {
       
   355             // do exactly same as in EUsbServiceStopping
       
   356             // break statement is not required here
       
   357             LOG("State == EUsbServiceStarting. Continue." );
       
   358             }
       
   359         case EUsbServiceStopping:
       
   360             {
       
   361             // we are not interested in these states, just continue monitoring
       
   362             LOG("State == EUsbServiceStopping. Continue." );
       
   363             iUsb.ServiceStateNotification(iServiceState, iStatus);
       
   364             SetActive();
       
   365             break;
       
   366             }
       
   367         case EUsbServiceFatalError:
       
   368             {
       
   369             LOG("UsbServiceState == EUsbServiceFatalError" );
       
   370             iObserver.UsbServiceControlReqCompletedL(KErrGeneral);
       
   371             break;
       
   372             }
       
   373         default:
       
   374             {
       
   375             PANIC( EUnknownUsbServiceState);
       
   376             }
       
   377         }
       
   378 
       
   379     }
       
   380 
       
   381 // ---------------------------------------------------------------------------
       
   382 // 
       
   383 // ---------------------------------------------------------------------------
       
   384 //
       
   385 TInt CUsbServiceControl::RunError(TInt aError)
       
   386     {
       
   387     LOG_FUNC
       
   388     LOG1("aError = %d", aError );
       
   389     TRAP_IGNORE(iObserver.UsbServiceControlReqCompletedL(aError));
       
   390 
       
   391     return KErrNone;
       
   392     }
       
   393 
       
   394 // ---------------------------------------------------------------------------
       
   395 // 
       
   396 // ---------------------------------------------------------------------------
       
   397 //
       
   398 void CUsbServiceControl::DoCancel()
       
   399     {
       
   400     LOG( "Cancelling interest to Usb TryStart.")
       
   401     iUsb.CancelInterest(RUsb::ETryStart);
       
   402     LOG( "Cancelling interest to Usb TrySop.")
       
   403     iUsb.CancelInterest(RUsb::ETryStop);
       
   404     LOG("Cancelling interest to usb states notifications.")
       
   405     iUsb.ServiceStateNotificationCancel();
       
   406     }