wlan_bearer/wlanengine/wlan_symbian/wlanengine_symbian_3.1/src/wlanbgscancommand.cpp
changeset 0 c40eb8fe8501
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "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:  This class implements command queue for BgScan.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 4 %
       
    20 */
       
    21 
       
    22 #include <s32mem.h>
       
    23 #include "wlanbgscancommand.h" 
       
    24 #include "wlanbgscancommandlistener.h"
       
    25 #include "am_debug.h"
       
    26 
       
    27 // Number of message slots in BgScan message queue, which is used for
       
    28 // passing commands from AWS to BgScan
       
    29 const TInt KNumberOfSlots( 5 );
       
    30 
       
    31 // ======== MEMBER FUNCTIONS ========
       
    32 
       
    33 // ---------------------------------------------------------------------------
       
    34 // C++ constructor.
       
    35 //
       
    36 // Runs in: WLAN Engine thread context.
       
    37 // ---------------------------------------------------------------------------
       
    38 //
       
    39 CWlanBgScanCommand::CWlanBgScanCommand( MWlanBgScanCommandListener& aListener ) : 
       
    40     CActive( CActive::EPriorityStandard ),
       
    41     iListener( aListener )
       
    42     {
       
    43     DEBUG( "CWlanBgScanCommand::CWlanBgScanCommand()" );
       
    44     }
       
    45 
       
    46 // ---------------------------------------------------------------------------
       
    47 // Symbian 2nd phase constructor.
       
    48 //
       
    49 // Runs in: WLAN Engine thread context.
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 void CWlanBgScanCommand::ConstructL()
       
    53     {
       
    54     DEBUG( "CWlanBgScanCommand::ConstructL()" );
       
    55     CActiveScheduler::Add( this );
       
    56     
       
    57     // create message queue for passing messages from AWS to BgScan
       
    58     TInt err = iMsgQueue.CreateLocal( KNumberOfSlots );
       
    59     
       
    60     if( err != KErrNone )
       
    61         {
       
    62         DEBUG1( "CWlanBgScanCommand::ConstructL() - message queue creation failed, err: %d",
       
    63                 err );
       
    64         User::Leave( err );
       
    65         }
       
    66     
       
    67     // subscribe notification about when new messages land on the queue
       
    68     iMsgQueue.NotifyDataAvailable( iStatus );
       
    69     
       
    70     SetActive();
       
    71     
       
    72     DEBUG( "CWlanBgScanCommand::ConstructL() - returning" );
       
    73     }
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // Static constructor.
       
    77 //
       
    78 // Runs in: WLAN Engine thread context.
       
    79 // ---------------------------------------------------------------------------
       
    80 //
       
    81 CWlanBgScanCommand* CWlanBgScanCommand::NewL(
       
    82     MWlanBgScanCommandListener& aListener )
       
    83     {
       
    84     DEBUG( "CWlanBgScanCommand::NewL()" );
       
    85     CWlanBgScanCommand* self = new ( ELeave ) CWlanBgScanCommand( aListener );
       
    86     CleanupStack::PushL( self );
       
    87     self->ConstructL();
       
    88     CleanupStack::Pop( self );
       
    89     return self;
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------------------------
       
    93 // Destructor.
       
    94 //
       
    95 // Runs in: WLAN Engine thread context.
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 CWlanBgScanCommand::~CWlanBgScanCommand()
       
    99     {
       
   100     DEBUG( "CWlanBgScanCommand::~CWlanBgScanCommand()" );
       
   101     Cancel();
       
   102     }
       
   103 
       
   104 // ---------------------------------------------------------------------------
       
   105 // Do Cancel.
       
   106 // Cancels any pending command and completes client's request on that part.
       
   107 //
       
   108 // Runs in: WLAN Engine thread context.
       
   109 // ---------------------------------------------------------------------------
       
   110 //
       
   111 void CWlanBgScanCommand::DoCancel()
       
   112     {
       
   113     DEBUG( "CWlanBgScanCommand::DoCancel()" );
       
   114     
       
   115     TWlanBgScanMsg msg;
       
   116     
       
   117     // Retrieve messages from message queue as long as there are any
       
   118     // and cancel them
       
   119     while( iMsgQueue.Receive( msg ) == KErrNone )
       
   120          {
       
   121          // Complete client's request with KErrCancel
       
   122          msg.iClientThread.RequestComplete( msg.iReportStatusPtr, KErrCancel );
       
   123                      
       
   124          // Destroy the handle to the client thread
       
   125          msg.iClientThread.Close();
       
   126          }
       
   127     
       
   128     DEBUG( "CWlanBgScanCommand::DoCancel() - cancelling data available notification" );
       
   129     iMsgQueue.CancelDataAvailable();
       
   130     DEBUG( "CWlanBgScanCommand::DoCancel() - done" );
       
   131     }
       
   132 
       
   133 // ---------------------------------------------------------------------------
       
   134 // Command Queue.
       
   135 // This method completes BgScan command AO thereby signalling WLAN Engine 
       
   136 // thread that it is eligible for runnning i.e. the command itself is processed 
       
   137 // in WLAN Engine thread context.
       
   138 //
       
   139 // Runs in: AWS thread context.
       
   140 // ---------------------------------------------------------------------------
       
   141 //
       
   142 void CWlanBgScanCommand::CommandQueue(
       
   143     TWlanBgScanCommand aCommand,     // IN: Command to be processed
       
   144     TUint32 aParameter,              // IN: Command parameter
       
   145     TRequestStatus& aReportStatus )  // IN: Client's request status that needs
       
   146                                      //     to be completed when the command
       
   147                                      //     has been processed.
       
   148     {
       
   149     DEBUG( "CWlanBgScanCommand::CommandQueue()" );
       
   150     
       
   151     TRequestStatus* statusPtr = &aReportStatus;
       
   152     TWlanBgScanMsg msg;
       
   153     
       
   154     // Set client's (BgScan) request status to request pending
       
   155     *statusPtr = KRequestPending;
       
   156     
       
   157     // NOTE! About which class has to be used when completing
       
   158     // the request statuses of both WLAN thread and AWS thread.
       
   159     // RThread class is always used for completing statuses in other
       
   160     // threads and User class for completing statuses in running thread.
       
   161     // Using incorrect class's RequestComplete method changes the status
       
   162     // of the active object BUT it does not increment the thread's
       
   163     // semaphore and hence the thread does not go to "ready to
       
   164     // be run" state. Consequently, the active object would be
       
   165     // run only when some other trigger causes the thread's 
       
   166     // semaphore to be incremented and hence making thread
       
   167     // eligible to be run.
       
   168     
       
   169     // Get handle to client thread (AWS thread) so that
       
   170     // the handle can be later used for completing the client's
       
   171     // request status
       
   172     TThreadId id = RThread().Id();
       
   173     TInt err = msg.iClientThread.Open( id );
       
   174     if( err != KErrNone )
       
   175         {
       
   176         DEBUG( "CWlanBgScanCommand::CommandQueue() - Opening client thread handle failed" );
       
   177         // Complete request with error code
       
   178         // Note! User class is used for completing the status here
       
   179         // as we are completing the active object in the same thread
       
   180         // (WLAN Engine thread) that is running this method.
       
   181         User::RequestComplete( statusPtr, KErrBadHandle );
       
   182         return;
       
   183         }
       
   184     
       
   185     // Store command so that it will be processed when RunL is called.
       
   186     msg.iCommand = aCommand;
       
   187     // Store parameter so that it will be processed when RunL is called.
       
   188     msg.iParameter = aParameter;
       
   189     // Store handle to report status which is completed when command
       
   190     // has been processed (i.e. RunL called)
       
   191     msg.iReportStatusPtr = statusPtr;    
       
   192     
       
   193     // Put message to message queue, so that the command
       
   194     // itself will be processed in WLAN Engine thread context
       
   195     err = iMsgQueue.Send( msg );
       
   196     if( err != KErrNone ) // Sending failed
       
   197         {
       
   198         // Complete request with error code
       
   199         DEBUG( "CWlanBgScanCommand::CommandQueue() - command sending failed due to BgScan message queue full" );
       
   200         msg.iClientThread.Close();
       
   201         User::RequestComplete( statusPtr, KErrServerBusy );
       
   202         }
       
   203 
       
   204     DEBUG( "CWlanBgScanCommand::CommandQueue() - command sent to BgScan message queue" );
       
   205     
       
   206     }
       
   207 
       
   208 // ---------------------------------------------------------------------------
       
   209 // RunL.
       
   210 // Executes the command that was requested with CommandQueue method.
       
   211 //
       
   212 // Runs in: WLAN Engine thread context.
       
   213 // ---------------------------------------------------------------------------
       
   214 //
       
   215 void CWlanBgScanCommand::RunL()
       
   216     {
       
   217     DEBUG( "CWlanBgScanCommand::RunL()" );
       
   218     ProcessCommands();
       
   219     }
       
   220 
       
   221 // ---------------------------------------------------------------------------
       
   222 // Process Commands.
       
   223 // Reads commands (sent by AWS) from BgScan message queue and
       
   224 // processes them.
       
   225 //
       
   226 // Runs in: WLAN Engine thread context.
       
   227 // ---------------------------------------------------------------------------
       
   228 //
       
   229 void CWlanBgScanCommand::ProcessCommands()
       
   230     {
       
   231     DEBUG( "CWlanBgScanCommand::ProcessCommands()" );
       
   232     
       
   233     TWlanBgScanMsg msg;
       
   234         
       
   235     // retrieve a message from queue and process it
       
   236     TInt rx_err = iMsgQueue.Receive( msg );
       
   237     
       
   238     switch( rx_err )
       
   239         {
       
   240         case KErrNone:
       
   241             {
       
   242             TInt err( KErrNone );
       
   243             
       
   244             switch( msg.iCommand )
       
   245                 {
       
   246                 case ESetInterval:
       
   247                     DEBUG( "CWlanBgScanCommand::ProcessCommands() - calling DoSetInterval" );
       
   248                     iListener.DoSetInterval( msg.iParameter );
       
   249                     DEBUG( "CWlanBgScanCommand::ProcessCommands() - DoSetInterval returned" );
       
   250                     break;
       
   251                 default: // Unknown command
       
   252                     DEBUG1( "CWlanBgScanCommand::ProcessCommands() - unknown command (%d)", msg.iCommand );
       
   253                     err = KErrNotSupported;
       
   254                     break;
       
   255                 }
       
   256             
       
   257             // complete client's request
       
   258             msg.iClientThread.RequestComplete( msg.iReportStatusPtr, err );
       
   259                 
       
   260             // destroy the handle to the client thread
       
   261             msg.iClientThread.Close();
       
   262 
       
   263             break;
       
   264             }
       
   265         case KErrUnderflow:
       
   266             {
       
   267             DEBUG( "CWlanBgScanCommand::ProcessCommands() - signalled for pending message but queue was empty");
       
   268             iMsgQueue.CancelDataAvailable();
       
   269             DEBUG( "CWlanBgScanCommand::ProcessCommands() - DataAvailable notification cancelled");
       
   270             break;
       
   271             }
       
   272         default:
       
   273             {
       
   274             DEBUG1( "CWlanBgScanCommand::ProcessCommands() - unrecognised error code %d", rx_err );
       
   275             iMsgQueue.CancelDataAvailable();
       
   276             DEBUG( "CWlanBgScanCommand::ProcessCommands() - DataAvailable notification cancelled");
       
   277             ASSERT( 0 );
       
   278             break;
       
   279             }
       
   280         }
       
   281 
       
   282     // Subscribe notification about when new messages land on the queue
       
   283     iMsgQueue.NotifyDataAvailable( iStatus );
       
   284     
       
   285     SetActive();
       
   286     DEBUG( "CWlanBgScanCommand::ProcessCommands() - done");
       
   287     }
       
   288 
       
   289 // ---------------------------------------------------------------------------
       
   290 // Error in RunL.
       
   291 //
       
   292 // Runs in: WLAN Engine thread context.
       
   293 // ---------------------------------------------------------------------------
       
   294 //
       
   295 TInt CWlanBgScanCommand::RunError( TInt aError )
       
   296     {
       
   297     if( KErrNone != aError )
       
   298         {
       
   299         DEBUG1( "CWlanBgScanCommand::RunError() - RunError %d", aError );
       
   300         }
       
   301     
       
   302     return KErrNone;
       
   303     }