qthighway/xqserviceipc/xqserviceipcserver/xqserviceipcserver_symbiansession.cpp
branchRCL_3
changeset 10 cd2778e5acfe
parent 9 5d007b20cfd0
child 11 19a54be74e5e
equal deleted inserted replaced
9:5d007b20cfd0 10:cd2778e5acfe
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * This program is free software: you can redistribute it and/or modify
       
     6 * it under the terms of the GNU Lesser General Public License as published by
       
     7 * the Free Software Foundation, version 2.1 of the License.
       
     8 * 
       
     9 * This program is distributed in the hope that it will be useful,
       
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 * GNU Lesser General Public License for more details.
       
    13 *
       
    14 * You should have received a copy of the GNU Lesser General Public License
       
    15 * along with this program.  If not, 
       
    16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
       
    17 *
       
    18 * Description:  Service IPC Session
       
    19 *
       
    20 */
       
    21 
       
    22 #include <e32capability.h> 
       
    23 
       
    24 #include "xqservicelog.h"
       
    25 
       
    26 #include <xqserviceclientinfo.h>
       
    27 #include "xqserviceipcobserver.h"
       
    28 #include "xqserviceipcrequest.h"
       
    29 #include "xqserviceipcserver_symbiansession.h"
       
    30 #include "xqrequestutil.h"
       
    31 
       
    32 namespace QtService
       
    33 {
       
    34 
       
    35 // Constants for the IPC operation id
       
    36 const TInt KIPCNewOperation = 0;
       
    37 const TInt KIPCGetData = 1;
       
    38 const TInt KIPCCancelAsync = 2;
       
    39 const TInt KIPCOperationWithSharableFile = 3;  // Sharable file support
       
    40 
       
    41 
       
    42 /*!
       
    43     \class CServiceSymbianSession
       
    44     \brief Symbian Session class
       
    45 */
       
    46 
       
    47 /*!
       
    48     Constructor.
       
    49     \param aObserver Observer to the server.
       
    50 */
       
    51 CServiceSymbianSession::CServiceSymbianSession(MServiceIPCObserver* aObserver) :
       
    52     ServiceIPCSession(aObserver)
       
    53 {
       
    54     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::CServiceSymbianSession");
       
    55 }
       
    56 
       
    57 /*!
       
    58     2nd phased constructor.
       
    59 */
       
    60 void CServiceSymbianSession::ConstructL()
       
    61 {
       
    62 }
       
    63 
       
    64 /*!
       
    65     Two-Phased Constructor.
       
    66     \param aObserver Observer to the server.
       
    67 */
       
    68 CServiceSymbianSession* CServiceSymbianSession::NewL(MServiceIPCObserver* aObserver)
       
    69 {
       
    70     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::NewL");
       
    71     CServiceSymbianSession* self =
       
    72                     new (ELeave) CServiceSymbianSession(aObserver);
       
    73     CleanupStack::PushL(self);
       
    74     self->ConstructL();
       
    75     CleanupStack::Pop(self);
       
    76     return self;
       
    77 }
       
    78 
       
    79 /*!
       
    80     Destructor.
       
    81 */
       
    82 CServiceSymbianSession::~CServiceSymbianSession()
       
    83 {
       
    84     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::~CServiceSymbianSession");
       
    85     if (iCurRequest) {
       
    86         iObserver->handleDeleteRequest(iCurRequest); 
       
    87         delete iCurRequest;
       
    88     }
       
    89     iCurRequest = NULL;
       
    90 }
       
    91 
       
    92 /*!
       
    93     Write some data in response to a request.
       
    94     \param aData Some data to write as response.
       
    95     \return bool if write was successful.
       
    96 */
       
    97 bool CServiceSymbianSession::write(const QByteArray& aData)
       
    98 {
       
    99     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::write");
       
   100     XQSERVICE_DEBUG_PRINT("aData: %s", aData.constData());
       
   101     // Implicitly shared
       
   102     iData = aData;
       
   103     return false;
       
   104 }
       
   105 
       
   106 /*!
       
   107     Complete a Request.
       
   108     \return bool if request completed 
       
   109 */
       
   110 bool CServiceSymbianSession::completeRequest()
       
   111 {
       
   112     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::completeRequest");
       
   113     XQSERVICE_DEBUG_PRINT("iData: %s", iData.constData());
       
   114     TPtrC8 data(reinterpret_cast<const TUint8*> (iData.constData()), iData.length());
       
   115     iMessage.Complete(data.Length());
       
   116     return true;
       
   117 }
       
   118 
       
   119 /*!
       
   120     Close a session and gracefully shutdown.
       
   121 */
       
   122 void CServiceSymbianSession::close()
       
   123 {
       
   124     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::close");
       
   125     // Symbian doens't really do anything
       
   126 }
       
   127 
       
   128 /*!
       
   129     From CSession2.
       
   130     Service request.
       
   131     \param aMessage Message object.
       
   132 */
       
   133 void CServiceSymbianSession::ServiceL(const RMessage2& aMessage)
       
   134 {
       
   135     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::ServiceL");
       
   136     // Default ServiceErrorL() will complete the message if this method leaves
       
   137     TInt operation(aMessage.Function());
       
   138     XQSERVICE_DEBUG_PRINT("operation: %d", operation);
       
   139     switch (operation) {
       
   140     case KIPCNewOperation:
       
   141     case KIPCOperationWithSharableFile:
       
   142     {
       
   143         handleRequestL(aMessage);
       
   144         break;
       
   145     }
       
   146     case KIPCGetData: {
       
   147         handleGetBufferL(aMessage);
       
   148         break;
       
   149     }
       
   150     case KIPCCancelAsync: {
       
   151         if (iCurRequest) {
       
   152             // Inform also observer, that current pending  request is about to go
       
   153             iObserver->handleCancelRequest(iCurRequest);
       
   154             iCurRequest->completeRequest();
       
   155         }
       
   156         aMessage.Complete(KErrCancel);
       
   157         break;
       
   158     }
       
   159     default: {
       
   160         aMessage.Complete(KErrNotFound);
       
   161         break;
       
   162     }
       
   163     }
       
   164 }
       
   165 
       
   166 /*!
       
   167     From CSession2.
       
   168     Handle any disconnection from the client.
       
   169     \param aMessage Message object.
       
   170 */
       
   171 void CServiceSymbianSession::Disconnect(const RMessage2 &aMessage)
       
   172 {
       
   173     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::Disconnect");
       
   174     CSession2::Disconnect(aMessage);
       
   175 }
       
   176 
       
   177 /*!
       
   178     Handle an IPC request.
       
   179     \param aMessage Message object.
       
   180 */
       
   181 void CServiceSymbianSession::handleRequestL(const RMessage2& aMessage)
       
   182 {
       
   183     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::handleRequestL");
       
   184     // Store the message
       
   185     iMessage = aMessage;
       
   186 
       
   187     // Convert from Symbian to QT
       
   188     HBufC* request = ReadDesLC(aMessage, 0);
       
   189     HBufC8* data = ReadDes8LC(aMessage, 1);
       
   190            
       
   191     XQSharableFile *file = 0;
       
   192     if (aMessage.Function() == KIPCOperationWithSharableFile)
       
   193     {
       
   194         // Only one file support now !
       
   195         file = new XQSharableFile();
       
   196         AdoptSharableFile(aMessage, file);
       
   197     }
       
   198     
       
   199     // Shallow copy only, we want a deep copy
       
   200     QString d = QString::fromUtf16(request->Ptr(), request->Length());
       
   201     QString operation;
       
   202     operation += d;
       
   203     XQSERVICE_DEBUG_PRINT("operation: %s", qPrintable(operation));
       
   204 
       
   205     //QByteArray convertData;
       
   206     TPtr8 ptr8(data->Des());
       
   207     const char* ptrz = reinterpret_cast<const char*> (ptr8.PtrZ());
       
   208     //convertData.append(ptrz);
       
   209 	QByteArray convertData(ptrz,data->Length());
       
   210 	XQSERVICE_DEBUG_PRINT("convertData: %s", convertData.constData());
       
   211 
       
   212     // New request
       
   213     if (iCurRequest) {
       
   214         iObserver->handleDeleteRequest(iCurRequest); 
       
   215         delete iCurRequest;
       
   216     }
       
   217     iCurRequest = NULL;
       
   218     iCurRequest = new ServiceIPCRequest(this, 0, operation);
       
   219     iData.clear();
       
   220 
       
   221     // Get client info
       
   222     ClientInfo *client = new ClientInfo();
       
   223     client->setProcessId(aMessage.SecureId().iId);
       
   224     client->setVendorId(aMessage.VendorId().iId);
       
   225     RThread clientThread;
       
   226     aMessage.ClientL(clientThread);
       
   227     RProcess clientProc;
       
   228     clientThread.Process(clientProc);
       
   229     client->setName(QString::fromUtf16(clientProc.Name().Ptr(), 
       
   230                                        clientProc.Name().Length()));
       
   231     client->setCapabilities(ClientCapabilities(aMessage));
       
   232     clientThread.Close();
       
   233 
       
   234     // Set the picked sharable file if any
       
   235     if (file != 0)
       
   236     {
       
   237         // Support only one sharable file
       
   238         iCurRequest->addSharableFile(file, 0);
       
   239     }
       
   240     
       
   241     // Add data and callback to the observer
       
   242     // 
       
   243     iCurRequest->addRequestdata(convertData);
       
   244     iCurRequest->setClientInfo(client); // ownership passed
       
   245     iObserver->handleRequest(iCurRequest);
       
   246 
       
   247     CleanupStack::PopAndDestroy(2, request);
       
   248 }
       
   249 
       
   250 /*!
       
   251     Handle getting the result buffer.
       
   252     \param aMessage Message object.
       
   253 */
       
   254 void CServiceSymbianSession::handleGetBufferL(const RMessage2& aMessage)
       
   255 {
       
   256     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::handleGetBufferL");
       
   257     XQSERVICE_DEBUG_PRINT("iData: %s", iData.constData());
       
   258     TPtrC8 data(reinterpret_cast<const TUint8*> (iData.constData()), iData.length());
       
   259     TInt err = aMessage.Write(0, data);
       
   260     aMessage.Complete(err);
       
   261 }
       
   262 
       
   263 /*!
       
   264     Read a 16 bit descriptor from the message.
       
   265     \param aMessage Message to read from.
       
   266     \param aMsgSlot Slot to read from.
       
   267  */
       
   268 HBufC* CServiceSymbianSession::ReadDesLC(const RMessage2& aMessage,
       
   269                                          TInt aMsgSlot)
       
   270 {
       
   271     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::ReadDesLC");
       
   272     TInt length = aMessage.GetDesLengthL(aMsgSlot);
       
   273     HBufC* des = HBufC::NewLC(length);
       
   274     TPtr ptr = des->Des();
       
   275     aMessage.ReadL(aMsgSlot, ptr);
       
   276     return des;
       
   277 }
       
   278 
       
   279 /*!
       
   280     Read a 8 bit descriptor from the message.
       
   281     \param aMessage Message to read from.
       
   282     \param aMsgSlot Slot to read from.
       
   283 */
       
   284 HBufC8* CServiceSymbianSession::ReadDes8LC(const RMessage2& aMessage,
       
   285                                            TInt aMsgSlot)
       
   286 {
       
   287     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::ReadDes8LC");
       
   288     TInt length = aMessage.GetDesLengthL(aMsgSlot);
       
   289     HBufC8* des = HBufC8::NewLC(length + 1); // 1 more for null terminator
       
   290     TPtr8 ptr = des->Des();
       
   291     aMessage.ReadL(aMsgSlot, ptr);
       
   292     return des;
       
   293 }
       
   294 
       
   295 // Sharable file utility
       
   296 const TInt KRFsSlot = 2;
       
   297 const TInt KRFileSlot = 3;
       
   298 
       
   299 bool AdoptSharableFile(const RMessage2& aMsg, XQSharableFile *file)
       
   300 {
       
   301     XQSERVICE_DEBUG_PRINT("AdoptSharableFile");
       
   302     RFile handle;
       
   303     TInt err = handle.AdoptFromClient(aMsg, KRFsSlot, KRFileSlot);
       
   304 
       
   305     bool ret = (err == KErrNone);
       
   306    
       
   307      if (ret)
       
   308     {
       
   309         file->setHandle(handle);
       
   310     }
       
   311     
       
   312     // On error the handle remains invalid !
       
   313     return ret;
       
   314 }
       
   315 
       
   316 /*!
       
   317     Get client capabilities from the IPC request.
       
   318 */
       
   319 quint32 ClientCapabilities(const RMessage2& aMsg)
       
   320 {
       
   321     quint32 caps = 0;
       
   322     for(int i = 0; i < ECapability_Limit; i++)
       
   323     {
       
   324         if (aMsg.HasCapability(static_cast<TCapability>(i)))
       
   325         {
       
   326             caps |= 1 << i;
       
   327         }
       
   328     }
       
   329 
       
   330     return caps;
       
   331 }
       
   332 
       
   333 }
       
   334 
       
   335 
       
   336 // END OF FILE
       
   337