|         |      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 "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: Telephony Multimedia Service | 
|         |     15  * | 
|         |     16  */ | 
|         |     17  | 
|         |     18 #include <tms.h> | 
|         |     19 #include <tmsbuffer.h> | 
|         |     20 #include "tmsutility.h" | 
|         |     21 #include "tmsshared.h" | 
|         |     22 #include "tmsqueuehandler.h" | 
|         |     23 #include "tmsmembuffer.h" | 
|         |     24 #include "tmsglobalcontext.h" | 
|         |     25 #include "tmscallproxy.h" | 
|         |     26  | 
|         |     27 using namespace TMS; | 
|         |     28  | 
|         |     29 // ---------------------------------------------------------------------------- | 
|         |     30 // CQueueHandler::NewL | 
|         |     31 // Symbian constructor | 
|         |     32 // ---------------------------------------------------------------------------- | 
|         |     33 // | 
|         |     34 CQueueHandler* CQueueHandler::NewL(RMsgQueue<TmsMsgBuf>* aMsgQueue, | 
|         |     35         TMSGlobalContext* glblCtx) | 
|         |     36     { | 
|         |     37     CQueueHandler* self = new (ELeave) CQueueHandler(aMsgQueue, glblCtx); | 
|         |     38     CleanupStack::PushL(self); | 
|         |     39     self->ConstructL(); | 
|         |     40     CleanupStack::Pop(self); | 
|         |     41     return self; | 
|         |     42     } | 
|         |     43  | 
|         |     44 // ---------------------------------------------------------------------------- | 
|         |     45 // CQueueHandler::ConstructL | 
|         |     46 // Second phase constructor. | 
|         |     47 // ---------------------------------------------------------------------------- | 
|         |     48 // | 
|         |     49 void CQueueHandler::ConstructL() | 
|         |     50     { | 
|         |     51     } | 
|         |     52  | 
|         |     53 // ---------------------------------------------------------------------------- | 
|         |     54 // CQueueHandler::~CQueueHandler | 
|         |     55 // Destructor. | 
|         |     56 // ---------------------------------------------------------------------------- | 
|         |     57 // | 
|         |     58 CQueueHandler::~CQueueHandler() | 
|         |     59     { | 
|         |     60     Cancel(); | 
|         |     61     iObserversList.Reset(); | 
|         |     62     iClientList.Reset(); | 
|         |     63     iChunk.Close(); | 
|         |     64     delete iBuffer; | 
|         |     65     } | 
|         |     66  | 
|         |     67 // ---------------------------------------------------------------------------- | 
|         |     68 // CQueueHandler::CQueueHandler | 
|         |     69 // Constructor. | 
|         |     70 // ---------------------------------------------------------------------------- | 
|         |     71 // | 
|         |     72 CQueueHandler::CQueueHandler(RMsgQueue<TmsMsgBuf>* aMsgQueue, | 
|         |     73         TMSGlobalContext* glblCtx) : | 
|         |     74     CActive(CActive::EPriorityStandard), | 
|         |     75     iMsgQueue(aMsgQueue), | 
|         |     76     iChunkDataPtr(0, 0, 0) | 
|         |     77     { | 
|         |     78     CActiveScheduler::Add(this); | 
|         |     79     iTMSGlobalContext = glblCtx; | 
|         |     80     } | 
|         |     81  | 
|         |     82 // ---------------------------------------------------------------------------- | 
|         |     83 // CQueueHandler::Start | 
|         |     84 // Start listening for events on queue 0. | 
|         |     85 // ---------------------------------------------------------------------------- | 
|         |     86 // | 
|         |     87 void CQueueHandler::Start() | 
|         |     88     { | 
|         |     89     if (!IsActive() && iMsgQueue) | 
|         |     90         { | 
|         |     91         iMsgQueue->NotifyDataAvailable(iStatus); | 
|         |     92         SetActive(); | 
|         |     93         } | 
|         |     94     } | 
|         |     95  | 
|         |     96 TInt CQueueHandler::AddObserver(MQueueHandlerObserver& aObserver, | 
|         |     97         TInt aClientId) | 
|         |     98     { | 
|         |     99     // Add to list if observer is not already added | 
|         |    100     TInt status = iObserversList.Find(&aObserver); | 
|         |    101     if (status == KErrNotFound) | 
|         |    102         { | 
|         |    103         status = iObserversList.Append(&aObserver); | 
|         |    104         status = iClientList.Append(aClientId); | 
|         |    105         } | 
|         |    106     else | 
|         |    107         { | 
|         |    108         status = KErrAlreadyExists; | 
|         |    109         } | 
|         |    110     return status; | 
|         |    111     } | 
|         |    112  | 
|         |    113 // Marks observer as inactive in the list | 
|         |    114 TInt CQueueHandler::RemoveObserver(MQueueHandlerObserver& aObserver) | 
|         |    115     { | 
|         |    116     TInt status(KErrNone); | 
|         |    117     TInt index = iObserversList.Find(&aObserver); | 
|         |    118     // If found status has index to observer in the array | 
|         |    119     // else it would contain KErrNotFound | 
|         |    120     if (index >= 0) | 
|         |    121         { | 
|         |    122         iObserversList.Remove(index); | 
|         |    123         iClientList.Remove(index); | 
|         |    124         status = KErrNone; | 
|         |    125         } | 
|         |    126     else | 
|         |    127         { | 
|         |    128         status = KErrNotFound; | 
|         |    129         } | 
|         |    130     return status; | 
|         |    131     } | 
|         |    132  | 
|         |    133 // ---------------------------------------------------------------------------- | 
|         |    134 // CQueueHandler::DoCancel | 
|         |    135 // Cancel outstanding request | 
|         |    136 // ---------------------------------------------------------------------------- | 
|         |    137 // | 
|         |    138 void CQueueHandler::DoCancel() | 
|         |    139     { | 
|         |    140     if (iMsgQueue) | 
|         |    141         { | 
|         |    142         iMsgQueue->CancelDataAvailable(); | 
|         |    143         } | 
|         |    144     } | 
|         |    145  | 
|         |    146 // ---------------------------------------------------------------------------- | 
|         |    147 // CQueueHandler::RunL | 
|         |    148 // Process requests. | 
|         |    149 // ---------------------------------------------------------------------------- | 
|         |    150 // | 
|         |    151 void CQueueHandler::RunL() | 
|         |    152     { | 
|         |    153     TmsMsgBuf msgBuf; | 
|         |    154     TInt err = KErrNone; | 
|         |    155  | 
|         |    156     if (iMsgQueue) | 
|         |    157         { | 
|         |    158         iMsgQueue->Receive(msgBuf); | 
|         |    159         } | 
|         |    160     else | 
|         |    161         { | 
|         |    162         err = KErrGeneral; | 
|         |    163         } | 
|         |    164  | 
|         |    165     // Start monitoring for more events before calling the observer as client | 
|         |    166     // may decide to destroy us before this RunL completes executing. | 
|         |    167     Start(); | 
|         |    168  | 
|         |    169     if (err == KErrNone) | 
|         |    170         { | 
|         |    171         switch (msgBuf.iRequest) | 
|         |    172             { | 
|         |    173             case ECmdDownlinkInitComplete: | 
|         |    174             case ECmdUplinkInitComplete: | 
|         |    175             case ECmdDownlinkDeInitComplete: | 
|         |    176             case ECmdUplinkDeInitComplete: | 
|         |    177             case ECmdDownlinkStarted: | 
|         |    178             case ECmdUplinkStarted: | 
|         |    179             case ECmdDownlinkPaused: | 
|         |    180             case ECmdUplinkPaused: | 
|         |    181                 { | 
|         |    182                 TInt index = FindStreamInList(); | 
|         |    183                 if (index != KErrNotFound) | 
|         |    184                     { | 
|         |    185                     TMSStreamState streamstate = ConvertToStreamState( | 
|         |    186                             msgBuf.iRequest); | 
|         |    187                     iObserversList[index]->QueueEvent(streamstate, | 
|         |    188                             msgBuf.iStatus, NULL); | 
|         |    189                     } | 
|         |    190                 else | 
|         |    191                     { | 
|         |    192                     // This should never happen | 
|         |    193                     err = KErrNotFound; | 
|         |    194                     } | 
|         |    195                 break; | 
|         |    196                 } | 
|         |    197             case ECmdFillBuffer: | 
|         |    198                 { | 
|         |    199                 DoFillBuffer(msgBuf.iInt, msgBuf.iStatus, msgBuf.iBool, | 
|         |    200                         msgBuf.iUint32); | 
|         |    201                 break; | 
|         |    202                 } | 
|         |    203             case ECmdEmptyBuffer: | 
|         |    204                 { | 
|         |    205                 DoEmptyBuffer(msgBuf.iInt, msgBuf.iStatus, msgBuf.iBool, | 
|         |    206                         msgBuf.iUint32); | 
|         |    207                 break; | 
|         |    208                 } | 
|         |    209             case ECmdDownlinkClosed: | 
|         |    210                 { | 
|         |    211                 iChunk.Close(); | 
|         |    212                 break; | 
|         |    213                 } | 
|         |    214             case ECmdUplinkClosed: | 
|         |    215                 { | 
|         |    216                 iChunk.Close(); | 
|         |    217                 break; | 
|         |    218                 } | 
|         |    219             case ECmdDnLinkError: | 
|         |    220                 { | 
|         |    221                 break; | 
|         |    222                 } | 
|         |    223             case ECmdUpLinkError: | 
|         |    224                 { | 
|         |    225                 break; | 
|         |    226                 } | 
|         |    227             case ECmdSetGain: | 
|         |    228                 { | 
|         |    229                 TInt index = FindGainEffectInList(); | 
|         |    230                 if (index != KErrNotFound) | 
|         |    231                     { | 
|         |    232                     iObserversList[index]->QueueEvent(TMS_EVENT_EFFECT_GAIN_CHANGED, | 
|         |    233                             msgBuf.iStatus, NULL); | 
|         |    234                     } | 
|         |    235                 } | 
|         |    236                 break; | 
|         |    237             case ECmdSetVolume: | 
|         |    238                 { | 
|         |    239                 TInt index = FindVolEffectInList(); | 
|         |    240                 if (index != KErrNotFound) | 
|         |    241                     { | 
|         |    242                     iObserversList[index]->QueueEvent(TMS_EVENT_EFFECT_VOL_CHANGED, | 
|         |    243                             msgBuf.iStatus, NULL); | 
|         |    244                     } | 
|         |    245                 } | 
|         |    246                 break; | 
|         |    247             default: | 
|         |    248                 break; | 
|         |    249             } | 
|         |    250         } | 
|         |    251     } | 
|         |    252  | 
|         |    253 // ---------------------------------------------------------------------------- | 
|         |    254 // CQueueHandler::DoFillBuffer | 
|         |    255 // | 
|         |    256 // ---------------------------------------------------------------------------- | 
|         |    257 // | 
|         |    258 void CQueueHandler::DoFillBuffer(TInt aBufLen, TInt aStatus, | 
|         |    259         TBool aOpenChunk, TUint32 key) | 
|         |    260     { | 
|         |    261     TInt err = KErrNone; | 
|         |    262  | 
|         |    263     // See if chunk needs to be opened | 
|         |    264     if (aOpenChunk) | 
|         |    265         { | 
|         |    266         if (iChunk.Handle()) | 
|         |    267             { | 
|         |    268             iChunk.Close(); | 
|         |    269             } | 
|         |    270         delete iBuffer; | 
|         |    271         iBuffer = NULL; | 
|         |    272  | 
|         |    273         // Get handle to chunk from proxy | 
|         |    274         TInt hndl(0); | 
|         |    275         err = KErrNotReady; | 
|         |    276         if (iTMSGlobalContext->CallProxy) | 
|         |    277             { | 
|         |    278             hndl = (iTMSGlobalContext->CallProxy)->GetDataXferChunkHandle( | 
|         |    279                     iTMSGlobalContext->CallType, | 
|         |    280                     iTMSGlobalContext->StreamType, | 
|         |    281                     iTMSGlobalContext->StreamId, | 
|         |    282                     key); | 
|         |    283             err = iChunk.SetReturnedHandle(hndl); | 
|         |    284             } | 
|         |    285         } | 
|         |    286  | 
|         |    287     if (err == KErrNone) | 
|         |    288         { | 
|         |    289         iChunkDataPtr.Set(iChunk.Base(), 0, aBufLen); | 
|         |    290         if (!iBuffer) | 
|         |    291             { | 
|         |    292             TMSMemBuffer::Create((guint) aBufLen, | 
|         |    293                     const_cast<guint8*> (iChunkDataPtr.Ptr()), iBuffer); | 
|         |    294             } | 
|         |    295         iBuffer->SetDataSize(aBufLen); | 
|         |    296  | 
|         |    297         TInt index = iClientList.Find(TMS_SOURCE_CLIENT); | 
|         |    298         if (index != KErrNotFound) | 
|         |    299             { | 
|         |    300             iObserversList[index]->QueueEvent( | 
|         |    301                     TMS_EVENT_SOURCE_FILL_BUFFER, aStatus, iBuffer); | 
|         |    302             } | 
|         |    303         else | 
|         |    304             { | 
|         |    305             err = KErrNotFound; | 
|         |    306             } | 
|         |    307         } | 
|         |    308     else | 
|         |    309         { | 
|         |    310         // TODO handle error here | 
|         |    311         } | 
|         |    312     } | 
|         |    313  | 
|         |    314 // ---------------------------------------------------------------------------- | 
|         |    315 // CQueueHandler::DoEmptyBuffer | 
|         |    316 // | 
|         |    317 // ---------------------------------------------------------------------------- | 
|         |    318 // | 
|         |    319 void CQueueHandler::DoEmptyBuffer(TInt aBufLen, TInt aStatus, | 
|         |    320         TBool aOpenChunk, TUint32 key) | 
|         |    321     { | 
|         |    322     TInt err(KErrNone); | 
|         |    323  | 
|         |    324     // See if chunk needs to be opened | 
|         |    325     if (aOpenChunk) | 
|         |    326         { | 
|         |    327         if (iChunk.Handle()) | 
|         |    328             { | 
|         |    329             iChunk.Close(); | 
|         |    330             } | 
|         |    331  | 
|         |    332         // Get handle to chunk from proxy | 
|         |    333         TInt hndl(0); | 
|         |    334         err = KErrNotReady; | 
|         |    335         if (iTMSGlobalContext->CallProxy) | 
|         |    336             { | 
|         |    337             hndl = (iTMSGlobalContext->CallProxy)->GetDataXferChunkHandle( | 
|         |    338                     iTMSGlobalContext->CallType, | 
|         |    339                     iTMSGlobalContext->StreamType, | 
|         |    340                     iTMSGlobalContext->StreamId, | 
|         |    341                     key); | 
|         |    342             err = iChunk.SetReturnedHandle(hndl); | 
|         |    343             } | 
|         |    344         // TODO handle error here | 
|         |    345         delete iBuffer; | 
|         |    346         iBuffer = NULL; | 
|         |    347         } | 
|         |    348  | 
|         |    349     if (err == KErrNone) | 
|         |    350         { | 
|         |    351         iChunkDataPtr.Set(iChunk.Base(), aBufLen, aBufLen); | 
|         |    352         if (!iBuffer) | 
|         |    353             { | 
|         |    354             TMSMemBuffer::Create((guint) aBufLen, | 
|         |    355                     const_cast<guint8*> (iChunkDataPtr.Ptr()), iBuffer); | 
|         |    356             } | 
|         |    357         iBuffer->SetDataSize(aBufLen); | 
|         |    358         TInt index = iClientList.Find(TMS_SINK_CLIENT); | 
|         |    359         if (index != KErrNotFound) | 
|         |    360             { | 
|         |    361             iObserversList[index]->QueueEvent( | 
|         |    362                     TMS_EVENT_SINK_PROCESS_BUFFER, aStatus, iBuffer); | 
|         |    363             } | 
|         |    364         else | 
|         |    365             { | 
|         |    366             err = KErrNotFound; | 
|         |    367             } | 
|         |    368         } | 
|         |    369     else | 
|         |    370         { | 
|         |    371         //iObserver->Event(MVoIPUplinkObserver::KUplinkError, aStatus); | 
|         |    372         } | 
|         |    373     } | 
|         |    374  | 
|         |    375 // ---------------------------------------------------------------------------- | 
|         |    376 // CQueueHandler::ConvertToStreamState | 
|         |    377 // | 
|         |    378 // ---------------------------------------------------------------------------- | 
|         |    379 // | 
|         |    380 TMSStreamState CQueueHandler::ConvertToStreamState(TInt request) | 
|         |    381     { | 
|         |    382     TMSStreamState state = TMS_STREAM_UNINITIALIZED; | 
|         |    383     switch (request) | 
|         |    384         { | 
|         |    385         case ECmdDownlinkInitComplete: | 
|         |    386         case ECmdUplinkInitComplete: | 
|         |    387             state = TMS_STREAM_INITIALIZED; | 
|         |    388             break; | 
|         |    389         case ECmdDownlinkStarted: | 
|         |    390         case ECmdUplinkStarted: | 
|         |    391             state = TMS_STREAM_STARTED; | 
|         |    392             break; | 
|         |    393         case ECmdDownlinkPaused: | 
|         |    394         case ECmdUplinkPaused: | 
|         |    395             state = TMS_STREAM_PAUSED; | 
|         |    396             break; | 
|         |    397         case ECmdDownlinkDeInitComplete: | 
|         |    398         case ECmdUplinkDeInitComplete: | 
|         |    399             state = TMS_STREAM_UNINITIALIZED; | 
|         |    400             break; | 
|         |    401         default: | 
|         |    402             break; | 
|         |    403         } | 
|         |    404     return state; | 
|         |    405     } | 
|         |    406  | 
|         |    407 // ---------------------------------------------------------------------------- | 
|         |    408 // CQueueHandler::RunError | 
|         |    409 // Process requests. | 
|         |    410 // ---------------------------------------------------------------------------- | 
|         |    411 // | 
|         |    412 TInt CQueueHandler::RunError(TInt /*aError*/) | 
|         |    413     { | 
|         |    414     // Current implementation of RunL does not leave | 
|         |    415     return 0; | 
|         |    416     } | 
|         |    417  | 
|         |    418 // ---------------------------------------------------------------------------- | 
|         |    419 // CQueueHandler::Status | 
|         |    420 // Return request status. | 
|         |    421 // ---------------------------------------------------------------------------- | 
|         |    422 // | 
|         |    423 TRequestStatus* CQueueHandler::Status() | 
|         |    424     { | 
|         |    425     return &iStatus; | 
|         |    426     } | 
|         |    427  | 
|         |    428 // ---------------------------------------------------------------------------- | 
|         |    429 // CQueueHandler::FindStreamInList | 
|         |    430 // Return stream index. | 
|         |    431 // ---------------------------------------------------------------------------- | 
|         |    432 // | 
|         |    433 TInt CQueueHandler::FindStreamInList() | 
|         |    434     { | 
|         |    435     gint index(-1); | 
|         |    436     index = iClientList.Find(TMS_STREAM_UPLINK); | 
|         |    437     if (index == KErrNotFound) | 
|         |    438         { | 
|         |    439         index = iClientList.Find(TMS_STREAM_DOWNLINK); | 
|         |    440         return index; | 
|         |    441         } | 
|         |    442     return index; | 
|         |    443     } | 
|         |    444  | 
|         |    445 // ---------------------------------------------------------------------------- | 
|         |    446 // CQueueHandler::FindGainEffectInList | 
|         |    447 // Return effect index. | 
|         |    448 // ---------------------------------------------------------------------------- | 
|         |    449 // | 
|         |    450 TInt CQueueHandler::FindGainEffectInList() | 
|         |    451     { | 
|         |    452     gint index(-1); | 
|         |    453     index = iClientList.Find(TMS_EFFECT_GAIN); | 
|         |    454     return index; | 
|         |    455     } | 
|         |    456  | 
|         |    457 // ---------------------------------------------------------------------------- | 
|         |    458 // CQueueHandler::FindVolEffectInList | 
|         |    459 // Return effect index. | 
|         |    460 // ---------------------------------------------------------------------------- | 
|         |    461 // | 
|         |    462 TInt CQueueHandler::FindVolEffectInList() | 
|         |    463     { | 
|         |    464     gint index(-1); | 
|         |    465     index = iClientList.Find(TMS_EFFECT_VOLUME); | 
|         |    466     return index; | 
|         |    467     } | 
|         |    468  | 
|         |    469 // End of File |