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