usbengines/usbotgwatcher/src/cusbotgwatcher.cpp
changeset 35 9d8b04ca6939
child 63 ef2686f7597e
child 75 809df41c314e
equal deleted inserted replaced
34:7858bc6ead78 35:9d8b04ca6939
       
     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 #include <usbpersonalityids.h>
       
    18 #include <usbuinotif.h>
       
    19 #include <UsbWatcherInternalPSKeys.h>
       
    20 #include "cusbotgwatcher.h"
       
    21 #include "cusbstate.h"
       
    22 #include "cusbstatehostainitiate.h"
       
    23 #include "cusbstatehostahost.h"
       
    24 #include "cusbstatehostaperipheral.h"
       
    25 #include "cusbstatehosthandle.h"
       
    26 #include "cusbstatehostdelayhandle.h"
       
    27 #include "cusbstatehostdelayattachedhandle.h"
       
    28 #include "cusbstatehostdelaynotattachedhandle.h"
       
    29 #include "cusbstatehosthandledropping.h"
       
    30 #include "cusbstatehostundefined.h"
       
    31 #include "cusbwarningnotifier.h"
       
    32 #ifndef STIF
       
    33 #include "cusbnotifmanager.h"
       
    34 #else
       
    35 #include "mockcusbnotifmanager.h"
       
    36 #endif
       
    37 #include "errors.h"
       
    38 #include "debug.h"
       
    39 #include "panic.h"
       
    40 _LIT_SECURITY_POLICY_PASS( KAlwaysPassPolicy );
       
    41 _LIT_SECURITY_POLICY_C1( KLocalServicesPolicy, ECapabilityLocalServices );
       
    42 
       
    43 // ---------------------------------------------------------------------------
       
    44 // 
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 CUsbOtgWatcher::CUsbOtgWatcher(RUsb& aUsbMan) :
       
    48     iUsb(aUsbMan), iPersonalityId(KUsbPersonalityIdMTP), iUsbServiceRequest(
       
    49             CUsbServiceControl::ERequestUndefined)
       
    50     {
       
    51     LOG_FUNC
       
    52     }
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // 
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 void CUsbOtgWatcher::ConstructL()
       
    59     {
       
    60     LOG_FUNC
       
    61 
       
    62 #ifdef _DEBUG
       
    63     SelfTestL();
       
    64 #endif
       
    65 
       
    66 #ifndef STIF
       
    67     LEAVEIFERROR(RProperty::Define(KPSUidUsbWatcher,
       
    68                     KUsbWatcherIsPeripheralConnected, RProperty::EInt,
       
    69                     KAlwaysPassPolicy, KLocalServicesPolicy));
       
    70 
       
    71     LEAVEIFERROR(RProperty::Set(KPSUidUsbWatcher,
       
    72                     KUsbWatcherIsPeripheralConnected,
       
    73                     KUsbWatcherPeripheralIsNotConnected));
       
    74 #endif
       
    75 
       
    76     iUsbServiceControl = CUsbServiceControl::NewL(*this, iUsb);
       
    77 
       
    78     LEAVEIFERROR(iStates.Append(CUsbStateHostUndefined::NewL(*this)));
       
    79     LEAVEIFERROR(iStates.Append(CUsbStateHostAInitiate::NewL(*this)));
       
    80     LEAVEIFERROR(iStates.Append(CUsbStateHostAHost::NewL(*this)));
       
    81     LEAVEIFERROR(iStates.Append(CUsbStateHostAPeripheral::NewL(*this)));
       
    82 
       
    83     LEAVEIFERROR(iStates.Append(CUsbStateHostDelayAttachedHandle::NewL(
       
    84                             *this)));
       
    85     LEAVEIFERROR(iStates.Append(
       
    86                     CUsbStateHostDelayNotAttachedHandle::NewL(*this)));
       
    87     LEAVEIFERROR(iStates.Append(
       
    88                     CUsbStateHostHandleDropping::NewL(*this)));
       
    89 
       
    90     iIdPinObserver = CUsbIdPinObserver::NewL();
       
    91     iVBusObserver = CUsbVBusObserver::NewL();
       
    92     iOtgStateObserver = CUsbOtgStateObserver::NewL();
       
    93     iBusActivityObserver = CUsbBusActivityObserver::NewL();
       
    94     iHostEventNotificationObserver = CUsbHostEventNotificationObserver::NewL(
       
    95             &iUsb);
       
    96     iMessageNotificationObserver = CUsbMessageNotificationObserver::NewL(
       
    97             &iUsb);
       
    98 
       
    99     iHostState = iStates[EUsbStateHostUndefined];
       
   100 
       
   101     // Notif manager must be created at least after VBus observer and iHostState initialization
       
   102     // to allow USb indicator subscribe to its notifications at construction and check their's current states
       
   103     iNotifManager = CUsbNotifManager::NewL(*this);
       
   104 
       
   105     iVBusObserver->SubscribeL(*this);
       
   106     iOtgStateObserver->SubscribeL(*this);
       
   107     iBusActivityObserver->SubscribeL(*this);
       
   108     iHostEventNotificationObserver->SubscribeL(*this);
       
   109     iMessageNotificationObserver->SubscribeL(*this);
       
   110     iIdPinObserver->SubscribeL(*this);
       
   111 
       
   112     if (CUsbIdPinObserver::EIdPinOn == iIdPinObserver->IdPin())
       
   113         {
       
   114         StartSessionL();
       
   115         }
       
   116 
       
   117     }
       
   118 
       
   119 // ---------------------------------------------------------------------------
       
   120 // 
       
   121 // ---------------------------------------------------------------------------
       
   122 //
       
   123 EXPORT_C TBool CUsbOtgWatcher::IsDeviceA()
       
   124     {
       
   125     ASSERT_PANIC(iIdPinObserver != NULL, EIdPinObserverNULLPointer);
       
   126     return (iIdPinObserver->IdPin() == CUsbIdPinObserver::EIdPinOn
       
   127                                                                    ? ETrue
       
   128                                                                       : EFalse);
       
   129     }
       
   130 
       
   131 // ---------------------------------------------------------------------------
       
   132 // 
       
   133 // ---------------------------------------------------------------------------
       
   134 //
       
   135 EXPORT_C CUsbOtgWatcher* CUsbOtgWatcher::NewL(RUsb& aUsbMan)
       
   136     {
       
   137     LOG_FUNC
       
   138 
       
   139     CUsbOtgWatcher* self = new (ELeave) CUsbOtgWatcher(aUsbMan);
       
   140     CleanupStack::PushL(self);
       
   141     self->ConstructL();
       
   142     CleanupStack::Pop(self);
       
   143     return self;
       
   144     }
       
   145 
       
   146 // ---------------------------------------------------------------------------
       
   147 // 
       
   148 // ---------------------------------------------------------------------------
       
   149 //
       
   150 CUsbOtgWatcher::~CUsbOtgWatcher()
       
   151     {
       
   152     LOG_FUNC
       
   153 
       
   154 #ifndef STIF
       
   155     RProperty::Delete(KPSUidUsbWatcher, KUsbWatcherIsPeripheralConnected);
       
   156 #endif
       
   157 
       
   158     // delete Notif manager before VBus observer, due to USB indicator observes VBus
       
   159     delete iNotifManager;
       
   160 
       
   161     if (iIdPinObserver)
       
   162         {
       
   163         TRAP_IGNORE(iIdPinObserver->UnsubscribeL(*this));
       
   164         }
       
   165 
       
   166     if (iVBusObserver)
       
   167         {
       
   168         TRAP_IGNORE(iVBusObserver->UnsubscribeL(*this));
       
   169         }
       
   170     if (iOtgStateObserver)
       
   171         {
       
   172         TRAP_IGNORE(iOtgStateObserver->UnsubscribeL(*this));
       
   173         }
       
   174     if (iBusActivityObserver)
       
   175         {
       
   176         TRAP_IGNORE(iBusActivityObserver->UnsubscribeL(*this));
       
   177         }
       
   178     if (iHostEventNotificationObserver)
       
   179         {
       
   180         TRAP_IGNORE(iHostEventNotificationObserver->UnsubscribeL(*this));
       
   181         }
       
   182     if (iMessageNotificationObserver)
       
   183         {
       
   184         TRAP_IGNORE(iMessageNotificationObserver->UnsubscribeL(*this));
       
   185         }
       
   186 
       
   187     delete iIdPinObserver;
       
   188     delete iVBusObserver;
       
   189     delete iOtgStateObserver;
       
   190     delete iBusActivityObserver;
       
   191     delete iHostEventNotificationObserver;
       
   192     delete iMessageNotificationObserver;
       
   193 
       
   194     iOtgStateObservers.Close();
       
   195 
       
   196     // Destroy states
       
   197     iStates.ResetAndDestroy();
       
   198     iStates.Close();
       
   199 
       
   200     delete iUsbServiceControl;
       
   201 
       
   202     iUsb.Close();
       
   203 
       
   204     }
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 // 
       
   208 // ---------------------------------------------------------------------------
       
   209 //
       
   210 void CUsbOtgWatcher::SetPersonalityL(TRequestStatus& /*aStatus*/,
       
   211         TInt aPersonality)
       
   212     {
       
   213     LOG_FUNC
       
   214 
       
   215     LOG1( "aPersonality = %d" , aPersonality);
       
   216 
       
   217     // watcher keeps this value, no need to pass it to request object
       
   218     // state can read it from watcher when needed
       
   219     iPersonalityId = aPersonality;
       
   220 
       
   221     // more complex processing has to be here, remember aStatus, etc.
       
   222     // pass the request to device state machine
       
   223     iState->SetPersonalityL();
       
   224 
       
   225     // the request is not passed to host state machine due to host ignores SetPersonality
       
   226 
       
   227     }
       
   228 
       
   229 // ---------------------------------------------------------------------------
       
   230 // 
       
   231 // ---------------------------------------------------------------------------
       
   232 //
       
   233 void CUsbOtgWatcher::CancelSetPersonalityL()
       
   234     {
       
   235     LOG_FUNC
       
   236 
       
   237     iState->CancelSetPersonalityL();
       
   238     }
       
   239 
       
   240 // ---------------------------------------------------------------------------
       
   241 // 
       
   242 // ---------------------------------------------------------------------------
       
   243 //
       
   244 void CUsbOtgWatcher::SetPreviousPersonalityL(TRequestStatus& /*aStatus*/)
       
   245     {
       
   246     LOG_FUNC
       
   247 
       
   248     // maybe more complex processing needed here
       
   249     iState->SetPreviousPersonalityL();
       
   250     }
       
   251 
       
   252 // ---------------------------------------------------------------------------
       
   253 // 
       
   254 // ---------------------------------------------------------------------------
       
   255 //
       
   256 void CUsbOtgWatcher::SetPreviousPersonalityL()
       
   257     {
       
   258     LOG_FUNC
       
   259 
       
   260     iState->SetPreviousPersonalityL();
       
   261     }
       
   262 
       
   263 // ---------------------------------------------------------------------------
       
   264 // 
       
   265 // ---------------------------------------------------------------------------
       
   266 //
       
   267 void CUsbOtgWatcher::CancelSetPreviousPersonalityL()
       
   268     {
       
   269     LOG_FUNC
       
   270 
       
   271     iState->CancelSetPreviousPersonalityL();
       
   272     }
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 // 
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 void CUsbOtgWatcher::SetPreviousPreviousPersonalityOnDisconnectL()
       
   279     {
       
   280     LOG_FUNC
       
   281 
       
   282     }
       
   283 
       
   284 // From IdPin observer
       
   285 // ---------------------------------------------------------------------------
       
   286 // 
       
   287 // ---------------------------------------------------------------------------
       
   288 //
       
   289 void CUsbOtgWatcher::StartSessionL()
       
   290     {
       
   291     LOG_FUNC
       
   292 
       
   293     if (!CanStartSessionL())
       
   294         {
       
   295         HandleHostProblemL(EUsbWatcherCanNotStartSession,
       
   296                 EUsbStateHostHandleDropping);
       
   297         return;
       
   298         }
       
   299 
       
   300     iUsbServiceRequest = CUsbServiceControl::EStartUsbService;
       
   301     TInt err = iUsbServiceControl->StartL(iPersonalityId);
       
   302     if (KErrNone != err)
       
   303         {
       
   304         LOG1( "Can not start usb services. err = %d" , err);
       
   305         HandleHostProblemL(EUsbWatcherCanNotStartUsbServices,
       
   306                 EUsbStateHostHandleDropping);
       
   307         return;
       
   308         }
       
   309 
       
   310     // call back from iUsbServiceControl->Start(iPersonalityId) call is UsbServiceControlReqCompletedL(TInt aError)
       
   311     // so, continue there if everything is OK
       
   312 
       
   313     }
       
   314 
       
   315 // ---------------------------------------------------------------------------
       
   316 // 
       
   317 // ---------------------------------------------------------------------------
       
   318 //
       
   319 void CUsbOtgWatcher::HandleHostProblemL(TInt aWhatKindOf,
       
   320         TUsbStateIds aInState)
       
   321     {
       
   322     LOG_FUNC
       
   323     HostHandle(aInState)->SetWhat(aWhatKindOf);
       
   324     ChangeHostStateL(aInState);
       
   325     }
       
   326 
       
   327 // ---------------------------------------------------------------------------
       
   328 // 
       
   329 // ---------------------------------------------------------------------------
       
   330 //
       
   331 void CUsbOtgWatcher::IdPinOnL()
       
   332     {
       
   333     LOG_FUNC
       
   334     StartSessionL();
       
   335     }
       
   336 
       
   337 // ---------------------------------------------------------------------------
       
   338 // 
       
   339 // ---------------------------------------------------------------------------
       
   340 //
       
   341 void CUsbOtgWatcher::IdPinOffL()
       
   342     {
       
   343     LOG_FUNC
       
   344 
       
   345     ChangeHostStateL(EUsbStateHostUndefined);
       
   346 
       
   347     iNotifManager->CloseAllNotifiers();
       
   348 
       
   349     Usb().DisableFunctionDriverLoading();
       
   350 
       
   351     iUsbServiceRequest = CUsbServiceControl::EStopUsbService;
       
   352     TInt err = iUsbServiceControl->StopL();
       
   353 
       
   354     LOG1( "iUsbServiceControl->Stop() err = %d", err );
       
   355 
       
   356     if (KErrNone != err)
       
   357         {
       
   358         LOG( "ErrorStoppingUsbServices" );
       
   359         PANIC(ECanNotStopUsbServices);
       
   360         }
       
   361     }
       
   362 
       
   363 // ---------------------------------------------------------------------------
       
   364 // 
       
   365 // ---------------------------------------------------------------------------
       
   366 //
       
   367 void CUsbOtgWatcher::IdPinErrorL(TInt aError)
       
   368     {
       
   369     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   370     HandleHostProblemL(EUsbWatcherIdPinError, EUsbStateHostHandleDropping);
       
   371 
       
   372     }
       
   373 
       
   374 // From VBus observer
       
   375 // ---------------------------------------------------------------------------
       
   376 // 
       
   377 // ---------------------------------------------------------------------------
       
   378 //
       
   379 void CUsbOtgWatcher::VBusDownL()
       
   380     {
       
   381     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   382     iHostState->VBusDownL();
       
   383     }
       
   384 
       
   385 // ---------------------------------------------------------------------------
       
   386 // 
       
   387 // ---------------------------------------------------------------------------
       
   388 //
       
   389 void CUsbOtgWatcher::VBusUpL()
       
   390     {
       
   391     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   392     iHostState->VBusUpL();
       
   393     }
       
   394 
       
   395 // ---------------------------------------------------------------------------
       
   396 // 
       
   397 // ---------------------------------------------------------------------------
       
   398 //
       
   399 void CUsbOtgWatcher::VBusObserverErrorL(TInt aError)
       
   400     {
       
   401     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   402     HandleHostProblemL(EUsbWatcherVBusObserverError,
       
   403             EUsbStateHostHandleDropping);
       
   404     }
       
   405 
       
   406 // From OTG state observer
       
   407 // ---------------------------------------------------------------------------
       
   408 // 
       
   409 // ---------------------------------------------------------------------------
       
   410 //
       
   411 void CUsbOtgWatcher::AIdleL()
       
   412     {
       
   413     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   414     iHostState->AIdleL();
       
   415     }
       
   416 
       
   417 // ---------------------------------------------------------------------------
       
   418 // 
       
   419 // ---------------------------------------------------------------------------
       
   420 //
       
   421 void CUsbOtgWatcher::AHostL()
       
   422     {
       
   423     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   424     iHostState->AHostL();
       
   425     }
       
   426 
       
   427 // ---------------------------------------------------------------------------
       
   428 // 
       
   429 // ---------------------------------------------------------------------------
       
   430 //
       
   431 void CUsbOtgWatcher::APeripheralL()
       
   432     {
       
   433     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   434     iHostState->APeripheralL();
       
   435     }
       
   436 
       
   437 // ---------------------------------------------------------------------------
       
   438 // 
       
   439 // ---------------------------------------------------------------------------
       
   440 //
       
   441 void CUsbOtgWatcher::AVBusErrorL()
       
   442     {
       
   443     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   444     iHostState->AVBusErrorL();
       
   445     }
       
   446 
       
   447 // ---------------------------------------------------------------------------
       
   448 // 
       
   449 // ---------------------------------------------------------------------------
       
   450 //
       
   451 void CUsbOtgWatcher::BIdleL()
       
   452     {
       
   453     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   454     iHostState->BIdleL();
       
   455     }
       
   456 
       
   457 // ---------------------------------------------------------------------------
       
   458 // 
       
   459 // ---------------------------------------------------------------------------
       
   460 //
       
   461 void CUsbOtgWatcher::BPeripheralL()
       
   462     {
       
   463     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   464     iHostState->BPeripheralL();
       
   465     }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // 
       
   469 // ---------------------------------------------------------------------------
       
   470 //
       
   471 void CUsbOtgWatcher::BHostL()
       
   472     {
       
   473     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   474     iHostState->BHostL();
       
   475     }
       
   476 
       
   477 // ---------------------------------------------------------------------------
       
   478 // 
       
   479 // ---------------------------------------------------------------------------
       
   480 //
       
   481 void CUsbOtgWatcher::OtgStateErrorL(TInt aError)
       
   482     {
       
   483     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   484     HandleHostProblemL(EUsbWatcherOtgStateError, EUsbStateHostHandleDropping);
       
   485     }
       
   486 
       
   487 // From bus activity observer
       
   488 // ---------------------------------------------------------------------------
       
   489 // 
       
   490 // ---------------------------------------------------------------------------
       
   491 //
       
   492 void CUsbOtgWatcher::BusIdleL()
       
   493     {
       
   494     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   495     iHostState->BusIdleL();
       
   496     }
       
   497 
       
   498 // ---------------------------------------------------------------------------
       
   499 // 
       
   500 // ---------------------------------------------------------------------------
       
   501 //
       
   502 void CUsbOtgWatcher::BusActiveL()
       
   503     {
       
   504     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   505     iHostState->BusActiveL();
       
   506     }
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // 
       
   510 // ---------------------------------------------------------------------------
       
   511 //
       
   512 void CUsbOtgWatcher::BusActivityErrorL(TInt aError)
       
   513     {
       
   514     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   515     // no action, continue
       
   516     }
       
   517 
       
   518 // From Host Event notification observer
       
   519 // ---------------------------------------------------------------------------
       
   520 // 
       
   521 // ---------------------------------------------------------------------------
       
   522 //
       
   523 void CUsbOtgWatcher::DeviceAttachedL(TDeviceEventInformation aTdi)
       
   524     {
       
   525     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   526     iHostState->DeviceAttachedL(aTdi);
       
   527     }
       
   528 
       
   529 // ---------------------------------------------------------------------------
       
   530 // 
       
   531 // ---------------------------------------------------------------------------
       
   532 //
       
   533 void CUsbOtgWatcher::DeviceDetachedL(TDeviceEventInformation aTdi)
       
   534     {
       
   535     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   536     iHostState->DeviceDetachedL(aTdi);
       
   537     }
       
   538 
       
   539 // ---------------------------------------------------------------------------
       
   540 // 
       
   541 // ---------------------------------------------------------------------------
       
   542 //
       
   543 void CUsbOtgWatcher::DriverLoadSuccessL(TDeviceEventInformation aTdi)
       
   544     {
       
   545     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   546     iHostState->DriverLoadSuccessL(aTdi);
       
   547     }
       
   548 
       
   549 // ---------------------------------------------------------------------------
       
   550 // 
       
   551 // ---------------------------------------------------------------------------
       
   552 //
       
   553 void CUsbOtgWatcher::DriverLoadPartialSuccessL(TDeviceEventInformation aTdi)
       
   554     {
       
   555     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   556     iHostState->DriverLoadPartialSuccessL(aTdi);
       
   557     }
       
   558 
       
   559 // ---------------------------------------------------------------------------
       
   560 // 
       
   561 // ---------------------------------------------------------------------------
       
   562 //
       
   563 void CUsbOtgWatcher::DriverLoadFailureL(TDeviceEventInformation aTdi)
       
   564     {
       
   565     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   566     iHostState->DriverLoadFailureL(aTdi);
       
   567     }
       
   568 
       
   569 // ---------------------------------------------------------------------------
       
   570 // 
       
   571 // ---------------------------------------------------------------------------
       
   572 //
       
   573 void CUsbOtgWatcher::HostEventNotificationErrorL(TInt aError)
       
   574     {
       
   575     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   576     HandleHostProblemL(EUsbWatcherHostEventNotificationError,
       
   577             EUsbStateHostHandleDropping);
       
   578     }
       
   579 
       
   580 // From message notification observer
       
   581 // ---------------------------------------------------------------------------
       
   582 // 
       
   583 // ---------------------------------------------------------------------------
       
   584 //
       
   585 void CUsbOtgWatcher::MessageNotificationReceivedL(TInt aMessage)
       
   586     {
       
   587     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   588     iHostState->MessageNotificationReceivedL(aMessage);
       
   589     }
       
   590 
       
   591 // ---------------------------------------------------------------------------
       
   592 // 
       
   593 // ---------------------------------------------------------------------------
       
   594 //
       
   595 void CUsbOtgWatcher::BadHubPositionL()
       
   596     {
       
   597     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   598     iHostState->BadHubPositionL();
       
   599     }
       
   600 
       
   601 // ---------------------------------------------------------------------------
       
   602 // 
       
   603 // ---------------------------------------------------------------------------
       
   604 //
       
   605 void CUsbOtgWatcher::VBusErrorL()
       
   606     {
       
   607     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   608     iHostState->VBusErrorL();
       
   609     }
       
   610 
       
   611 // ---------------------------------------------------------------------------
       
   612 // 
       
   613 // ---------------------------------------------------------------------------
       
   614 //
       
   615 void CUsbOtgWatcher::SrpReceivedL()
       
   616     {
       
   617     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   618     iHostState->SrpReceivedL();
       
   619     }
       
   620 
       
   621 // ---------------------------------------------------------------------------
       
   622 // 
       
   623 // ---------------------------------------------------------------------------
       
   624 //
       
   625 void CUsbOtgWatcher::SessionRequestedL()
       
   626     {
       
   627     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   628     iHostState->SessionRequestedL();
       
   629     }
       
   630 
       
   631 // ---------------------------------------------------------------------------
       
   632 // 
       
   633 // ---------------------------------------------------------------------------
       
   634 //
       
   635 void CUsbOtgWatcher::MessageNotificationErrorL(TInt aError)
       
   636     {
       
   637     ASSERT_PANIC(iHostState != NULL, EBadHostState);
       
   638     HandleHostProblemL(EUsbWatcherMessageNotificationError,
       
   639             EUsbStateHostHandleDropping);
       
   640     }
       
   641 
       
   642 // ---------------------------------------------------------------------------
       
   643 // getters
       
   644 // ---------------------------------------------------------------------------
       
   645 //
       
   646 CUsbIdPinObserver* CUsbOtgWatcher::IdPinObserver() const
       
   647     {
       
   648     return iIdPinObserver;
       
   649     }
       
   650 
       
   651 // ---------------------------------------------------------------------------
       
   652 // 
       
   653 // ---------------------------------------------------------------------------
       
   654 //
       
   655 CUsbVBusObserver* CUsbOtgWatcher::VBusObserver() const
       
   656     {
       
   657     return iVBusObserver;
       
   658     }
       
   659 
       
   660 // ---------------------------------------------------------------------------
       
   661 // 
       
   662 // ---------------------------------------------------------------------------
       
   663 //
       
   664 CUsbOtgStateObserver* CUsbOtgWatcher::OtgStateObserver() const
       
   665     {
       
   666     return iOtgStateObserver;
       
   667     }
       
   668 
       
   669 // ---------------------------------------------------------------------------
       
   670 // 
       
   671 // ---------------------------------------------------------------------------
       
   672 //
       
   673 CUsbBusActivityObserver* CUsbOtgWatcher::BusActivityObserver() const
       
   674     {
       
   675     return iBusActivityObserver;
       
   676     }
       
   677 
       
   678 // ---------------------------------------------------------------------------
       
   679 // 
       
   680 // ---------------------------------------------------------------------------
       
   681 //
       
   682 CUsbHostEventNotificationObserver* CUsbOtgWatcher::HostEventNotificationObserver() const
       
   683     {
       
   684     return iHostEventNotificationObserver;
       
   685     }
       
   686 
       
   687 // ---------------------------------------------------------------------------
       
   688 // 
       
   689 // ---------------------------------------------------------------------------
       
   690 //
       
   691 CUsbMessageNotificationObserver* CUsbOtgWatcher::MessageNotificationObserver() const
       
   692     {
       
   693 
       
   694     return iMessageNotificationObserver;
       
   695 
       
   696     }
       
   697 
       
   698 // ---------------------------------------------------------------------------
       
   699 // 
       
   700 // ---------------------------------------------------------------------------
       
   701 //
       
   702 RUsb& CUsbOtgWatcher::Usb()
       
   703     {
       
   704     return iUsb;
       
   705     }
       
   706 
       
   707 // ---------------------------------------------------------------------------
       
   708 // 
       
   709 // ---------------------------------------------------------------------------
       
   710 //
       
   711 CUsbState* CUsbOtgWatcher::CurrentState() const
       
   712     {
       
   713     return iState;
       
   714     }
       
   715 
       
   716 // ---------------------------------------------------------------------------
       
   717 // 
       
   718 // ---------------------------------------------------------------------------
       
   719 //
       
   720 CUsbState* CUsbOtgWatcher::CurrentHostState() const
       
   721     {
       
   722     return iHostState;
       
   723     }
       
   724 
       
   725 // ---------------------------------------------------------------------------
       
   726 // 
       
   727 // ---------------------------------------------------------------------------
       
   728 //
       
   729 CUsbState* CUsbOtgWatcher::State(TUsbStateIds aStateId) const
       
   730     {
       
   731     return iStates[aStateId];
       
   732     }
       
   733 
       
   734 // ---------------------------------------------------------------------------
       
   735 // 
       
   736 // ---------------------------------------------------------------------------
       
   737 //
       
   738 CUsbStateHostHandle* CUsbOtgWatcher::HostHandle(TUsbStateIds aInState) const
       
   739     {
       
   740     ASSERT_PANIC(iStates[aInState] != NULL, EBadState);
       
   741 
       
   742     return (CUsbStateHostHandle*) iStates[aInState];
       
   743     }
       
   744 
       
   745 // ---------------------------------------------------------------------------
       
   746 // 
       
   747 // ---------------------------------------------------------------------------
       
   748 //
       
   749 void CUsbOtgWatcher::ChangeStateL(TUsbStateIds aNewStateId)
       
   750     {
       
   751     LOG_FUNC
       
   752 
       
   753     LOG1( "aNewState = %d" , aNewStateId);
       
   754 
       
   755     if (NULL != iState)
       
   756         {
       
   757         iState->JustBeforeLeavingThisStateL();
       
   758         }
       
   759 
       
   760     // sets new state	
       
   761 
       
   762     // be careful to add states into States in exactly the same order as they enumerated
       
   763     // this method will work right as long as states, which in the enumeration, is added 
       
   764     // to the list iStates in the same order as they enumerated and no one state is added,
       
   765     // if all previous states are not added. no need to add all states, but if added - 
       
   766     // previous all must be added.
       
   767     // For the general case, when some states added, some not, this method has to implement search by state ID. for this CUsbOtgWatcher::Id() is maintained.
       
   768 
       
   769     iState = iStates[aNewStateId];
       
   770 
       
   771     ASSERT_PANIC(iState != NULL, EBadState);
       
   772 
       
   773     iState->JustAdvancedToThisStateL(); // do any initial activity, once advanced to the state
       
   774 
       
   775     }
       
   776 
       
   777 // ---------------------------------------------------------------------------
       
   778 // 
       
   779 // ---------------------------------------------------------------------------
       
   780 //
       
   781 void CUsbOtgWatcher::ChangeHostStateL(TUsbStateIds aNewStateId)
       
   782     {
       
   783     LOG_FUNC
       
   784 
       
   785     LOG1( "aNewState = %d", aNewStateId);
       
   786 
       
   787     if (NULL != iHostState)
       
   788         {
       
   789         iHostState->JustBeforeLeavingThisStateL();
       
   790         }
       
   791 
       
   792     // set new state	
       
   793 
       
   794     // be careful to add states into States in exactly the same order as they enumerated
       
   795     // this method will work right as long as states, which in the enumeration, is added 
       
   796     // to the list iStates in the same order as they enumerated and no one state is added,
       
   797     // if all previous states are not added. no need to add all states, but if added - 
       
   798     // previous all must be added.
       
   799     // For the general case, when some states added, some not, this method has to implement search by state ID. for this CUsbOtgWatcher::Id() is maintained.
       
   800 
       
   801     iHostState = iStates[aNewStateId];
       
   802 
       
   803     ASSERT_PANIC(iHostState != NULL, EBadState)
       
   804 
       
   805     iHostState->JustAdvancedToThisStateL(); // checks if there are conditions for advancing to another state(s)
       
   806 
       
   807     // notify state change to observers
       
   808     for (TInt i(0); i < iOtgStateObservers.Count(); ++i)
       
   809         {
       
   810         iOtgStateObservers[i]->OtgWatcherStateChangedL(iHostState->Id());
       
   811         }
       
   812     }
       
   813 
       
   814 // ---------------------------------------------------------------------------
       
   815 // 
       
   816 // ---------------------------------------------------------------------------
       
   817 //
       
   818 TBool CUsbOtgWatcher::CanStartSessionL()
       
   819     {
       
   820     // define policy here
       
   821     return ETrue;
       
   822     }
       
   823 
       
   824 // ---------------------------------------------------------------------------
       
   825 // 
       
   826 // ---------------------------------------------------------------------------
       
   827 //
       
   828 void CUsbOtgWatcher::PrintStateToLog()
       
   829     {
       
   830     LOG1( "Current state id  = %d" , iHostState->Id());
       
   831     LOG1( "IdPin             = %d" , iIdPinObserver->IdPin());
       
   832     LOG1( "VBus              = %d" , iVBusObserver->VBus());
       
   833     LOG1( "OtgState          = %d" , iOtgStateObserver->OtgState());
       
   834     LOG1( "BusActivity       = %d" , iBusActivityObserver->BusActivity());
       
   835 
       
   836     TInt isPeripheralConnected(KUsbWatcherPeripheralIsNotConnected);
       
   837 
       
   838     RProperty::Get(KPSUidUsbWatcher, KUsbWatcherIsPeripheralConnected,
       
   839             isPeripheralConnected);
       
   840 
       
   841     LOG1( "IsPeripheralConnected = %d" , isPeripheralConnected);
       
   842 
       
   843     }
       
   844 
       
   845 // ---------------------------------------------------------------------------
       
   846 // 
       
   847 // ---------------------------------------------------------------------------
       
   848 //
       
   849 CUsbNotifManager* CUsbOtgWatcher::NotifManager()
       
   850     {
       
   851     return iNotifManager;
       
   852     }
       
   853 
       
   854 // ---------------------------------------------------------------------------
       
   855 // 
       
   856 // ---------------------------------------------------------------------------
       
   857 //
       
   858 void CUsbOtgWatcher::UsbServiceControlReqCompletedL(TInt aError)
       
   859     {
       
   860     LOG_FUNC
       
   861 
       
   862     LOG1( "aError = %d" , aError);
       
   863 
       
   864     iUsbServiceRequest = CUsbServiceControl::ERequestUndefined;
       
   865 
       
   866     switch (aError)
       
   867         {
       
   868         case KErrInUse:
       
   869             // usb services already started (this might happen if more than one idpin on event come)
       
   870             {
       
   871             return;
       
   872             }
       
   873 
       
   874         case KErrNone:
       
   875             {
       
   876             break; // do normal routine
       
   877             }
       
   878         case KErrNoMemory:
       
   879             {
       
   880             HandleHostProblemL(EUsbWatcherNoMemory,
       
   881                     EUsbStateHostHandleDropping);
       
   882             return;
       
   883             }
       
   884 
       
   885         default:
       
   886             // handle the issue
       
   887             {
       
   888             if (iUsbServiceRequest == CUsbServiceControl::EStartUsbService) // Handle only start issues
       
   889                 {
       
   890                 HandleHostProblemL(EUsbWatcherNoMemory,
       
   891                         EUsbStateHostHandleDropping);
       
   892                 }
       
   893 
       
   894             iUsbServiceRequest = CUsbServiceControl::ERequestUndefined;
       
   895             return;
       
   896             }
       
   897         }
       
   898 
       
   899     iUsbServiceRequest = CUsbServiceControl::ERequestUndefined;
       
   900 
       
   901     TUsbServiceState serviceState;
       
   902     TInt err = iUsb.GetServiceState(serviceState);
       
   903 
       
   904     if (KErrNone != err)
       
   905         {
       
   906         LOG1( "Error when requesting GetServiceState = %d" , err);
       
   907         HandleHostProblemL(EUsbWatcherCanNotStartUsbServices,
       
   908                 EUsbStateHostHandleDropping);
       
   909         return;
       
   910         }
       
   911 
       
   912     switch (serviceState)
       
   913         {
       
   914         case EUsbServiceIdle: // just stopped usb service
       
   915 
       
   916             {
       
   917             LOG("UsbServiceState == EUsbServiceIdle" );
       
   918             // do nothing
       
   919             break;
       
   920             }
       
   921 
       
   922         case EUsbServiceStarted: // just started usb service
       
   923 
       
   924             {
       
   925             LOG( "UsbServiceState == EUsbServiceStarted" );
       
   926 
       
   927             ChangeHostStateL(EUsbStateHostAInitiate);
       
   928 
       
   929             break;
       
   930             }
       
   931         case EUsbServiceStarting:
       
   932             {
       
   933             LOG("UsbServiceState == EUsbServiceStarting" );
       
   934             // should not receive that, due to call back is called when service stopped or started
       
   935             // therefore scream
       
   936             PANIC(EUnexpectedUsbServiceState);
       
   937             break;
       
   938             }
       
   939         case EUsbServiceStopping:
       
   940             {
       
   941             LOG("UsbServiceState == EUsbServiceStopping" );
       
   942             // should not receive that, due to call back is called when service stopped or started
       
   943             // therefore scream
       
   944             PANIC(EUnexpectedUsbServiceState);
       
   945             break;
       
   946             }
       
   947         case EUsbServiceFatalError:
       
   948             {
       
   949             LOG( "UsbServiceState == EUsbServiceFatalError" );
       
   950             PANIC(EUnexpectedUsbServiceState);
       
   951             break;
       
   952             }
       
   953 
       
   954         default:
       
   955             {
       
   956             PANIC(EUnknownUsbServiceState);
       
   957             }
       
   958         }
       
   959     }
       
   960 
       
   961 // ---------------------------------------------------------------------------
       
   962 // 
       
   963 // ---------------------------------------------------------------------------
       
   964 //
       
   965 TInt CUsbOtgWatcher::SelfTestL()
       
   966     {
       
   967 #ifdef _DEBUG
       
   968     LOG_FUNC
       
   969 
       
   970     // create all the observers
       
   971     iIdPinObserver = CUsbIdPinObserver::NewL();
       
   972     iVBusObserver = CUsbVBusObserver::NewL();
       
   973     iOtgStateObserver = CUsbOtgStateObserver::NewL();
       
   974     iBusActivityObserver = CUsbBusActivityObserver::NewL();
       
   975     iHostEventNotificationObserver = CUsbHostEventNotificationObserver::NewL(
       
   976             &iUsb);
       
   977     iMessageNotificationObserver = CUsbMessageNotificationObserver::NewL(
       
   978             &iUsb);
       
   979 
       
   980     LOG( "Observers getters" );
       
   981 
       
   982     if (iIdPinObserver != IdPinObserver())
       
   983         {
       
   984         LEAVE(KErrGeneral);
       
   985         }
       
   986 
       
   987     if (iOtgStateObserver != OtgStateObserver())
       
   988         {
       
   989         LEAVE(KErrGeneral);
       
   990         }
       
   991 
       
   992     if (iBusActivityObserver != BusActivityObserver())
       
   993         {
       
   994         LEAVE(KErrGeneral);
       
   995         }
       
   996 
       
   997     if (iHostEventNotificationObserver != HostEventNotificationObserver())
       
   998         {
       
   999         LEAVE(KErrGeneral);
       
  1000         }
       
  1001 
       
  1002     if (iMessageNotificationObserver != MessageNotificationObserver())
       
  1003         {
       
  1004         LEAVE(KErrGeneral);
       
  1005         }
       
  1006 
       
  1007     LOG( "Observers destructors" );
       
  1008 
       
  1009     // idpinobserver is deleted later        
       
  1010     // Vbus observer is deleted later
       
  1011 
       
  1012     delete iOtgStateObserver;
       
  1013     iOtgStateObserver = 0;
       
  1014     delete iBusActivityObserver;
       
  1015     iBusActivityObserver = 0;
       
  1016     delete iHostEventNotificationObserver;
       
  1017     iHostEventNotificationObserver = 0;
       
  1018     delete iMessageNotificationObserver;
       
  1019     iMessageNotificationObserver = 0;
       
  1020 
       
  1021     LOG("Creating states");
       
  1022 
       
  1023     LEAVEIFERROR(iStates.Append(CUsbStateHostUndefined::NewL(*this)));
       
  1024     LEAVEIFERROR(iStates.Append(CUsbStateHostAInitiate::NewL(*this)));
       
  1025     LEAVEIFERROR(iStates.Append(CUsbStateHostAHost::NewL(*this)));
       
  1026     LEAVEIFERROR(iStates.Append(CUsbStateHostAPeripheral::NewL(*this)));
       
  1027     LEAVEIFERROR(iStates.Append(CUsbStateHostDelayAttachedHandle::NewL(
       
  1028             *this)));
       
  1029     LEAVEIFERROR(iStates.Append(
       
  1030             CUsbStateHostDelayNotAttachedHandle::NewL(*this)));
       
  1031     LEAVEIFERROR(iStates.Append(
       
  1032             CUsbStateHostHandleDropping::NewL(*this)));
       
  1033 
       
  1034     LOG("Check State()" );
       
  1035 
       
  1036     if (iStates[EUsbStateHostAInitiate] != State(EUsbStateHostAInitiate))
       
  1037         {
       
  1038         LEAVE(KErrGeneral);
       
  1039         }
       
  1040 
       
  1041     LOG("Check CurrentHostState()" );
       
  1042 
       
  1043     iHostState = iStates[EUsbStateHostAInitiate];
       
  1044 
       
  1045     if (iStates[EUsbStateHostAInitiate] != CurrentHostState())
       
  1046         {
       
  1047         LEAVE(KErrGeneral);
       
  1048         }
       
  1049 
       
  1050     LOG("NotifManager and WarningNotifier." );
       
  1051 
       
  1052     CUsbNotifManager* usbnotifmanager = CUsbNotifManager::NewL(*this);
       
  1053     RNotifier rnotifier;
       
  1054     LEAVEIFERROR(rnotifier.Connect());
       
  1055     CUsbWarningNotifier* usbnotifier = CUsbWarningNotifier::NewL(rnotifier,
       
  1056             *usbnotifmanager, EUsbOtgPartiallySupportedDevice);
       
  1057     usbnotifier->IsFeedbackNeeded();
       
  1058 
       
  1059     LOG( "NotifManager and WarningNotifier destruction." );
       
  1060 
       
  1061     delete usbnotifier;
       
  1062     rnotifier.Close();
       
  1063     delete usbnotifmanager;
       
  1064 
       
  1065     // VBus observer is deleted here, due to it is used by usbnotifmanager.usbindicatornotifier
       
  1066     delete iVBusObserver;
       
  1067     iVBusObserver = 0;
       
  1068 
       
  1069     // id pin observer is deleted here due to it is used by usbnotifmanager.usbindicatornotifier
       
  1070     delete iIdPinObserver;
       
  1071     iIdPinObserver = 0;
       
  1072 
       
  1073     LOG("Destructing states");
       
  1074 
       
  1075     iStates.ResetAndDestroy();
       
  1076 
       
  1077     LOG( "Check UsbServiceControl" );
       
  1078 
       
  1079     CUsbServiceControl* usbServiceControl = CUsbServiceControl::NewL(*this,
       
  1080             iUsb);
       
  1081     usbServiceControl->RunError(KErrNone);
       
  1082     delete usbServiceControl;
       
  1083 
       
  1084     LOG("All completed OK" );
       
  1085 #endif
       
  1086     return KErrNone;
       
  1087 
       
  1088     }
       
  1089 
       
  1090 // ---------------------------------------------------------------------------
       
  1091 // 
       
  1092 // ---------------------------------------------------------------------------
       
  1093 //   
       
  1094 void CUsbOtgWatcher::SubscribeL(MUsbOtgWatcherStateObserver& aObserver)
       
  1095     {
       
  1096     LOG_FUNC
       
  1097 
       
  1098     // check if the same observer already exist in a list
       
  1099     if (KErrNotFound != iOtgStateObservers.Find(&aObserver))
       
  1100         {
       
  1101         LOG( "Observer already exists" );
       
  1102         PANIC(EObserverAlreadyExists);
       
  1103         return;
       
  1104         }
       
  1105     iOtgStateObservers.AppendL(&aObserver);
       
  1106 
       
  1107     }
       
  1108 
       
  1109 // ---------------------------------------------------------------------------
       
  1110 // 
       
  1111 // ---------------------------------------------------------------------------
       
  1112 //
       
  1113 void CUsbOtgWatcher::UnsubscribeL(MUsbOtgWatcherStateObserver& aObserver)
       
  1114     {
       
  1115     LOG_FUNC
       
  1116 
       
  1117     TInt i(iOtgStateObservers.Find(&aObserver));
       
  1118     if (KErrNotFound == i)
       
  1119         {
       
  1120         LOG( "Observer not found" );
       
  1121         PANIC(ECanNotFindUsbOtgWatcherStateObserver);
       
  1122         return;
       
  1123         }
       
  1124 
       
  1125     iOtgStateObservers.Remove(i);
       
  1126     }