qthighway/xqserviceipc/xqserviceipcserver/xqserviceipcserver_symbiansession.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     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  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.Identity().iUid);
       
   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  */
       
   253 void CServiceSymbianSession::handleGetBufferL(const RMessage2& aMessage)
       
   254 {
       
   255     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::handleGetBufferL");
       
   256     XQSERVICE_DEBUG_PRINT("iData: %s", iData.constData());
       
   257     TPtrC8 data(reinterpret_cast<const TUint8*> (iData.constData()), iData.length());
       
   258     TInt err = aMessage.Write(0, data);
       
   259     aMessage.Complete(err);
       
   260 }
       
   261 
       
   262 /*!
       
   263  Read a 16 bit descriptor from the message
       
   264  @param aMessage message to read from, 
       
   265  @param aMsgSlot slot to read from
       
   266  */
       
   267 HBufC* CServiceSymbianSession::ReadDesLC(const RMessage2& aMessage,
       
   268                                          TInt aMsgSlot)
       
   269 {
       
   270     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::ReadDesLC");
       
   271     TInt length = aMessage.GetDesLengthL(aMsgSlot);
       
   272     HBufC* des = HBufC::NewLC(length);
       
   273     TPtr ptr = des->Des();
       
   274     aMessage.ReadL(aMsgSlot, ptr);
       
   275     return des;
       
   276 }
       
   277 
       
   278 /*!
       
   279  Read a 8 bit descriptor from the message
       
   280  @param aMessage message to read from, 
       
   281  @param aMsgSlot slot to read from
       
   282  */
       
   283 HBufC8* CServiceSymbianSession::ReadDes8LC(const RMessage2& aMessage,
       
   284                                            TInt aMsgSlot)
       
   285 {
       
   286     XQSERVICE_DEBUG_PRINT("CServiceSymbianSession::ReadDes8LC");
       
   287     TInt length = aMessage.GetDesLengthL(aMsgSlot);
       
   288     HBufC8* des = HBufC8::NewLC(length + 1); // 1 more for null terminator
       
   289     TPtr8 ptr = des->Des();
       
   290     aMessage.ReadL(aMsgSlot, ptr);
       
   291     return des;
       
   292 }
       
   293 
       
   294 // Sharable file utility
       
   295 const TInt KRFsSlot = 2;
       
   296 const TInt KRFileSlot = 3;
       
   297 
       
   298 bool AdoptSharableFile(const RMessage2& aMsg, XQSharableFile *file)
       
   299 {
       
   300     XQSERVICE_DEBUG_PRINT("AdoptSharableFile");
       
   301     RFile handle;
       
   302     TInt err = handle.AdoptFromClient(aMsg, KRFsSlot, KRFileSlot);
       
   303 
       
   304     bool ret = (err == KErrNone);
       
   305    
       
   306      if (ret)
       
   307     {
       
   308         file->setHandle(handle);
       
   309     }
       
   310     
       
   311     // On error the handle remains invalid !
       
   312     return ret;
       
   313 }
       
   314 
       
   315 //
       
   316 // Get client capabilities from the IPC request
       
   317 //
       
   318 quint32 ClientCapabilities(const RMessage2& aMsg)
       
   319 {
       
   320     quint32 caps = 0;
       
   321     for(int i = 0; i < ECapability_Limit; i++)
       
   322     {
       
   323         if (aMsg.HasCapability(static_cast<TCapability>(i)))
       
   324         {
       
   325             caps |= 1 << i;
       
   326         }
       
   327     }
       
   328 
       
   329     return caps;
       
   330 }
       
   331 
       
   332 }
       
   333 
       
   334 
       
   335 // END OF FILE
       
   336