bluetoothengine/btmac/src/BTMonoCmdHandler/btmcprotocol.cpp
changeset 0 f63038272f30
child 1 6a1fe72036e3
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2005 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:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "atcodec.h"
       
    20 #include <mmtsy_names.h> // for etel
       
    21 #include <btengconstants.h>
       
    22 #include <btengdiscovery.h>
       
    23 #include <badesca.h>
       
    24 #include "btmcprotocol.h"
       
    25 #include "btmccallinghandler.h"
       
    26 #include "btmcphonestatus.h"
       
    27 #include "btmccallstatus.h"
       
    28 #include "btmcprotocolstatus.h"
       
    29 #include "btmcobserver.h"
       
    30 #include "btmcmobileline.h"
       
    31 #include "btmcnumber.h"
       
    32 #include "btmcoperator.h"
       
    33 
       
    34 #include "debug.h"
       
    35 
       
    36 // Service Level Monitoring
       
    37 const TInt KCmerFromHF = 0x01;
       
    38 const TInt KCmerFromAG = 0x02;
       
    39 const TInt KSLC_No3WayCalling = KCmerFromHF | KCmerFromAG;
       
    40 
       
    41 const TInt KChldFromHF = 0x04;
       
    42 const TInt KChldFromAG = 0x08;
       
    43 
       
    44 const TInt KSLC_3WayCalling = KChldFromHF | KChldFromAG;
       
    45 
       
    46 const TInt KBerUnknown = 99;
       
    47 
       
    48 const TInt KServiceSlcTimer = 1;
       
    49 const TInt KServiceSdpQuery = 2;
       
    50 const TInt KServiceGetSubscriber = 3;
       
    51 const TInt KServiceGetOperator = 4;
       
    52 const TInt KServiceCmdHandling = 5;
       
    53 
       
    54 const TInt KQueryIMEI = 6;
       
    55 const TInt KQueryIMSI = 7;
       
    56 
       
    57 const TInt KServiceFirstHspCkpdTrap = 8;
       
    58 
       
    59 CBtmcProtocol* CBtmcProtocol::NewL(
       
    60     MBtmcObserver& aObserver, TBtmcProfileId aProfile, const TDesC8& aBTDevAddr, TBool aAccessoryInitiated)
       
    61     {
       
    62     CBtmcProtocol* self=new (ELeave) CBtmcProtocol(aObserver);
       
    63     CleanupStack::PushL(self);
       
    64     self->ConstructL(aProfile, aBTDevAddr, aAccessoryInitiated);
       
    65     CleanupStack::Pop(self);
       
    66     return self;
       
    67     }
       
    68 
       
    69 CBtmcProtocol::~CBtmcProtocol()
       
    70     {
       
    71     TRACE_FUNC_ENTRY
       
    72     delete iCallingHandler;
       
    73     
       
    74     delete iCmdHanldingActive;
       
    75     delete iAtExt;
       
    76     
       
    77     delete iTimerActive;
       
    78     iTimer.Close();
       
    79     
       
    80     delete iProtocolStatus;
       
    81     delete iCallStatus;
       
    82     delete iPhoneStatus;
       
    83     
       
    84     delete iNumber;
       
    85     delete iOperator;
       
    86     
       
    87     delete iEtelQuery;
       
    88     delete iBteng;
       
    89   
       
    90     iPhone.Close();
       
    91     iServer.UnloadPhoneModule(KMmTsyModuleName);
       
    92     iServer.Close();
       
    93     delete iOutgoPacketQueue;
       
    94     TRACE_FUNC_EXIT
       
    95     }
       
    96 
       
    97 void CBtmcProtocol::NewProtocolDataL(const TDesC8& aData)
       
    98     {
       
    99     TRACE_FUNC
       
   100     TInt err = iInDataBuf.Append(aData);
       
   101     if (err)
       
   102         {
       
   103         CATResult* nok = CATResult::NewLC(EATERROR);
       
   104         SendResponseL(*nok);
       
   105         CleanupStack::PopAndDestroy(nok);
       
   106         }
       
   107     else if (!iCmdHanldingActive->IsActive())
       
   108         {
       
   109         TRequestStatus* sta = &iCmdHanldingActive->iStatus;
       
   110         *sta = KRequestPending;
       
   111         User::RequestComplete(sta, KErrNone);
       
   112         iCmdHanldingActive->GoActive();
       
   113         }
       
   114     }
       
   115 
       
   116 void CBtmcProtocol::SendResponseL(const CATResult& aResult)
       
   117     {
       
   118     TRACE_FUNC
       
   119     iOutgoPacketQueue->InsertL(0, aResult.Des());
       
   120     iCredit = iOutgoPacketQueue->MdcaCount();
       
   121     DoSendProtocolDataL();
       
   122     }
       
   123     
       
   124 void CBtmcProtocol::SendResponseL(const RPointerArray<CATResult>& aResults)
       
   125     {
       
   126     TRACE_FUNC
       
   127     TInt count = aResults.Count();
       
   128     for (TInt i = 0; i < count; i++)
       
   129         {
       
   130         iOutgoPacketQueue->InsertL(i, aResults[i]->Des());
       
   131         }
       
   132     iCredit = iOutgoPacketQueue->MdcaCount();
       
   133     DoSendProtocolDataL();
       
   134     }
       
   135     
       
   136 void CBtmcProtocol::SendUnsoltResultL(const CATResult& aResult)
       
   137     {
       
   138     TRACE_FUNC_ENTRY
       
   139     if (aResult.Id() == EATVGS)
       
   140         {
       
   141         iOutgoPacketQueue->InsertL(0, aResult.Des());
       
   142         iCredit++;
       
   143         }
       
   144     else
       
   145         {
       
   146         iOutgoPacketQueue->AppendL(aResult.Des());
       
   147         if (!iCallingHandler->ActiveCmdHandling() && !iHandleCmdPending)
       
   148             {
       
   149             iCredit++;
       
   150             }
       
   151         }
       
   152     DoSendProtocolDataL();
       
   153     TRACE_FUNC_EXIT
       
   154     }
       
   155     
       
   156 void CBtmcProtocol::CmdHandlingCompletedL()
       
   157     {
       
   158     TRACE_FUNC
       
   159     iHandleCmdPending = EFalse;
       
   160     TRequestStatus* sta = &iCmdHanldingActive->iStatus;
       
   161     *sta = KRequestPending;
       
   162     User::RequestComplete(sta, KErrNone);
       
   163     iCmdHanldingActive->GoActive();
       
   164     }
       
   165 
       
   166 TBtmcProtocolStatus& CBtmcProtocol::ProtocolStatus()
       
   167     {
       
   168     return *iProtocolStatus;
       
   169     }
       
   170 
       
   171 void CBtmcProtocol::VoiceRecognitionError()
       
   172     {
       
   173     iPhoneStatus->SetRecognitionInitiator(EBTMonoVoiceRecognitionDefaultInitiator);
       
   174     }
       
   175 
       
   176 void CBtmcProtocol::HandleNrecCompletedL(TInt aErr)
       
   177     {
       
   178     TATId id = aErr ? EATERROR : EATOK;
       
   179     CATResult* nok = CATResult::NewLC(id);
       
   180     SendResponseL(*nok);
       
   181     CleanupStack::PopAndDestroy(nok);
       
   182     CmdHandlingCompletedL();
       
   183     }
       
   184 
       
   185 
       
   186 void CBtmcProtocol::ActivateRemoteVolumeControl()
       
   187     {
       
   188     TRACE_FUNC
       
   189     if (iPhoneStatus)
       
   190         iPhoneStatus->ActivateRemoteVolumeControl();
       
   191     else
       
   192         {
       
   193         TRACE_INFO(_L("WARNING, null vol handler!"))
       
   194         }
       
   195     }
       
   196 
       
   197 void CBtmcProtocol::DeActivateRemoteVolumeControl()
       
   198     {
       
   199     TRACE_FUNC
       
   200     if (iPhoneStatus)
       
   201         iPhoneStatus->DeActivateRemoteVolumeControl();
       
   202     else
       
   203         {
       
   204         TRACE_INFO(_L("WARNING, null vol handler!"))
       
   205         }
       
   206     }
       
   207 
       
   208 TInt CBtmcProtocol::GetRemoteSupportedFeature()
       
   209     {
       
   210     return iProtocolStatus->iAccSupportedFeature;
       
   211     }
       
   212 
       
   213 TBool CBtmcProtocol::ActiveChldHandling() const
       
   214     {
       
   215     return iCallingHandler->ActiveChldHandling();
       
   216     }
       
   217 
       
   218 void CBtmcProtocol::RequestCompletedL(CBtmcActive& aActive, TInt aErr)
       
   219     {
       
   220     TRACE_FUNC_ENTRY
       
   221     switch (aActive.ServiceId())
       
   222         {
       
   223         case KServiceSlcTimer:
       
   224             {
       
   225             if (aErr == KErrNone)
       
   226                 {
       
   227                 StopTimer(KServiceSlcTimer);
       
   228                 iObserver.SlcIndicateL(EFalse);
       
   229                 }
       
   230             break;
       
   231             }
       
   232         case KServiceSdpQuery:
       
   233             {
       
   234             }
       
   235         case KServiceGetSubscriber:
       
   236             {
       
   237             delete iNumber;
       
   238             iNumber = NULL;
       
   239             CmdHandlingCompletedL();
       
   240             break;
       
   241             }
       
   242         case KServiceGetOperator:
       
   243             {
       
   244             delete iOperator;
       
   245             iOperator = NULL;
       
   246             CmdHandlingCompletedL();
       
   247             break;
       
   248             }
       
   249         case KServiceCmdHandling:
       
   250             {
       
   251             TRAPD(err, DoHandleCommandL());
       
   252             if (err)
       
   253                 {
       
   254                 CATResult* nok = CATResult::NewLC(EATERROR);
       
   255                 SendResponseL(*nok);
       
   256                 CleanupStack::PopAndDestroy(nok);
       
   257                 CmdHandlingCompletedL();
       
   258                 }
       
   259             break;
       
   260             }
       
   261        	case KQueryIMSI:
       
   262        		{
       
   263        		TBuf8<RMobilePhone::KIMSISize> buf;
       
   264        		buf.Copy(iId);
       
   265             CATResult* cimi = CATResult::NewLC(EATCIMI, EATReadResult, TATParam(buf));
       
   266             SendResponseL(*cimi);
       
   267 	        CleanupStack::PopAndDestroy(cimi);
       
   268 	        CATResult* ok = CATResult::NewLC(EATOK);
       
   269 	        SendResponseL(*ok);
       
   270 	        CleanupStack::PopAndDestroy(ok);
       
   271 	        CmdHandlingCompletedL();      		
       
   272 					break;
       
   273        		}
       
   274        	case KServiceFirstHspCkpdTrap:
       
   275        	    {
       
   276        	    // No handling here. From now on, any incoming CKPD command 
       
   277        	    // will be processed normally.
       
   278        	    TRACE_INFO((_L("CKPD trapper terminated")));
       
   279        	    break;
       
   280        	    }
       
   281         default:
       
   282             break;
       
   283         }
       
   284     TRACE_FUNC_EXIT
       
   285     }
       
   286 
       
   287 void CBtmcProtocol::CancelRequest(TInt aServiceId)
       
   288     {
       
   289     TRACE_FUNC_ENTRY
       
   290     if (aServiceId == KServiceSlcTimer || aServiceId == KServiceFirstHspCkpdTrap )
       
   291         {
       
   292         iTimer.Cancel();
       
   293         }
       
   294     else if (aServiceId == KServiceSdpQuery)
       
   295         {
       
   296         iBteng->CancelRemoteSdpQuery();
       
   297         }
       
   298     TRACE_FUNC_EXIT
       
   299     }
       
   300 
       
   301 CBtmcProtocol::CBtmcProtocol(MBtmcObserver& aObserver)
       
   302     : iObserver(aObserver),
       
   303       iSlcMask(0x00)
       
   304     {
       
   305     }
       
   306 
       
   307 void CBtmcProtocol::ConstructL(TBtmcProfileId aProfile, const TDesC8& aBTDevAddr, TBool aAccessoryInitiated)
       
   308     {
       
   309     TRACE_FUNC_ENTRY
       
   310     iProtocolStatus = new (ELeave) TBtmcProtocolStatus();
       
   311     iProtocolStatus->iProfile = aProfile;
       
   312     iAccessoryInitiated = aAccessoryInitiated;
       
   313     iProtocolStatus->iAGSupportedFeature = KBTAGSupportedFeatureV15;
       
   314     
       
   315     LEAVE_IF_ERROR(iServer.Connect())
       
   316     TInt err = iServer.LoadPhoneModule(KMmTsyModuleName);
       
   317     if (err != KErrNone && err != KErrAlreadyExists)
       
   318         LEAVE(err);
       
   319     LEAVE_IF_ERROR(iPhone.Open(iServer, KMmTsyPhoneName))
       
   320 
       
   321     iCallStatus = CBtmcCallStatus::NewL(*this, iPhone, aProfile);
       
   322     iProtocolStatus->iCallBits = iCallStatus->CallStatusL();
       
   323     
       
   324     iEtelQuery = CBtmcActive::NewL(*this, CActive::EPriorityStandard, KQueryIMEI);
       
   325 
       
   326 		iPhone.GetPhoneId(iEtelQuery->iStatus, iIdentity);
       
   327 		iEtelQuery->GoActive();
       
   328     
       
   329     switch (aProfile)
       
   330         {
       
   331         case EBtmcHFP0105:
       
   332             {
       
   333             TRACE_INFO((_L("constructing option HFP 1.5")))
       
   334             iPhoneStatus = CBtmcPhoneStatus::NewL(*this, iPhone, aProfile);
       
   335             StartTimerL(KServiceSlcTimer, KSlcTimeout);
       
   336             break;
       
   337             }
       
   338         case EBtmcHSP:
       
   339             {
       
   340             TRACE_INFO((_L("constructing option HSP")))
       
   341             if (aBTDevAddr.Length() != KBTDevAddrSize)
       
   342                 {
       
   343                 LEAVE(KErrBadDescriptor);
       
   344                 }
       
   345             iProtocolStatus->iSlc = ETrue;
       
   346             iBteng = CBTEngDiscovery::NewL(this);
       
   347             iBteng->RemoteSdpQuery(TBTDevAddr(aBTDevAddr), TUUID(EBTProfileHSP), KBTHSRemoteAudioVolumeControl);
       
   348             if ( iAccessoryInitiated && ( iProtocolStatus->iCallBits & KCallConnectedBit ) )
       
   349                 {
       
   350                 TRACE_INFO((_L("Incoming HSP connected, start CKPD trapper")));
       
   351                 // In case of incoming HSP connection during a voice call, 
       
   352                 // start timer to trap the CKPD command as part of the audio transfer of HSP.
       
   353                 // If the first CKPD command is received during this period, it will be ignored.
       
   354                 StartTimerL(KServiceFirstHspCkpdTrap, KFirstHspCkpdTimeout);
       
   355                 }
       
   356             break;
       
   357             }
       
   358         default:
       
   359             LEAVE(KErrArgument);
       
   360         }
       
   361     TRAP_IGNORE(iAtExt = CHFPAtCmdHandler::NewL(*this));
       
   362     iOutgoPacketQueue = new (ELeave) CDesC8ArrayFlat(1);
       
   363     iCallingHandler = CBtmcCallingHandler::NewL(*this);
       
   364     iCmdHanldingActive = CBtmcActive::NewL(*this, CActive::EPriorityStandard, KServiceCmdHandling);
       
   365     if (iProtocolStatus->iSlc)
       
   366         {
       
   367         iCallStatus->ReportCallStatusL();
       
   368         }
       
   369     iVolumeSyncFromAccessory = EFalse;
       
   370     TRACE_FUNC_EXIT
       
   371     }
       
   372 
       
   373 void CBtmcProtocol::DoHandleCommandL()
       
   374     {
       
   375     TRACE_FUNC
       
   376     if (iHandleCmdPending)
       
   377         {
       
   378         return;
       
   379         }
       
   380     TBuf8<KMaxATSize> cmddes;
       
   381     if (iInDataBuf.NextCommand(cmddes))
       
   382         {
       
   383         return;
       
   384         }
       
   385     if (cmddes.Length() == 0)
       
   386         {
       
   387         return;
       
   388         }
       
   389     TRACE_INFO_SEG(
       
   390         {
       
   391         TBuf8<KMaxATSize> buf;
       
   392         buf = cmddes;
       
   393         buf.Trim();
       
   394         Trace(_L8("[HFP] [I] %S"), &buf);
       
   395         })
       
   396 
       
   397     CATCommand* cmd = NULL;
       
   398     TRAPD(err, cmd = CATCommand::NewL(cmddes));
       
   399     if (err)
       
   400         {
       
   401       	if(iAtExt)
       
   402         	{
       
   403       		iAtExt->HandleCommand(cmddes, _L8("\n\rERROR\n\r"));
       
   404         	return;
       
   405         	}
       
   406         CATResult* nok = CATResult::NewLC(EATERROR);
       
   407         SendResponseL(*nok);
       
   408         CleanupStack::PopAndDestroy(nok);
       
   409         return;
       
   410         }
       
   411     CleanupStack::PushL(cmd);
       
   412     iHandleCmdPending = ETrue;
       
   413 	TATId id = cmd->Id();
       
   414     if (id == EATA || 
       
   415         id == EATD2 || 
       
   416         id == EATD1 ||
       
   417         (id == EATCHLD && cmd->Type() != EATTestCmd)||
       
   418         id == EATCHUP || 
       
   419         id == EATVTS || 
       
   420         (id == EATBVRA && cmd->Type() == EATWriteCmd) ||
       
   421         id == EATBLDN )
       
   422     	{
       
   423     	if (id == EATBVRA)
       
   424     	    {
       
   425     	    TRACE_ASSERT(cmd->ParamNum() == 1, KErrArgument);
       
   426             TATParam param = TATParam();
       
   427             LEAVE_IF_ERROR(cmd->Parameter(0, param))
       
   428             TInt value;
       
   429             LEAVE_IF_ERROR(param.Int(value))
       
   430             TBTMonoVoiceRecognitionInitiator initor;
       
   431             initor = (value) ? EBTMonoVoiceRecognitionActivatedByRemote
       
   432                 : EBTMonoVoiceRecognitionDeactivatedByRemote;
       
   433             iPhoneStatus->SetRecognitionInitiator(initor);
       
   434     	    }
       
   435     	iCallingHandler->HandleCallingCmdL(*cmd);
       
   436     	}
       
   437     else if ( id == EATCKPD )
       
   438         {
       
   439         if ( iTimerActive && iTimerActive->IsActive() )
       
   440             {
       
   441             // incoming HSP was just connected and the first CKPD is received, 
       
   442             // ignore this command as audio establishment will be done via Acc FW 
       
   443             StopTimer( KServiceFirstHspCkpdTrap );
       
   444             TRACE_INFO((_L("First CKPD, do nothing")));
       
   445             CATResult* nok = CATResult::NewLC( EATOK );
       
   446             SendResponseL(*nok);
       
   447             CleanupStack::PopAndDestroy(nok);
       
   448             CmdHandlingCompletedL();
       
   449             }
       
   450         else
       
   451             {
       
   452             iCallingHandler->HandleCallingCmdL(*cmd);
       
   453             }
       
   454         }
       
   455     else if (id == EATNREC && cmd->Type() == EATWriteCmd)
       
   456         {
       
   457 	    TRACE_ASSERT(cmd->ParamNum() == 1, KErrArgument);
       
   458         TATParam param = TATParam();
       
   459         LEAVE_IF_ERROR(cmd->Parameter(0, param))
       
   460         TInt value;
       
   461         LEAVE_IF_ERROR(param.Int(value))
       
   462         if (!value &&
       
   463         	ServiceLevelConnected() )
       
   464             {
       
   465             //Always respond OK to +NREC=0
       
   466             HandleNrecCompletedL(0);
       
   467             }
       
   468         else
       
   469             {
       
   470             LEAVE(KErrArgument);
       
   471             }
       
   472         }
       
   473     else
       
   474         {
       
   475         // for HSP profile we support only VGS & VGM commands
       
   476         // CKPD is handled elsewhere
       
   477         if(iProtocolStatus->iProfile == EBtmcHSP &&
       
   478            ((cmd->Id() != EATVGS &&
       
   479              cmd->Id() != EATVGM)) )
       
   480             {
       
   481             LEAVE(KErrNotSupported);
       
   482             }
       
   483 
       
   484         switch (cmd->Type())
       
   485             {
       
   486             case EATTestCmd:
       
   487                 {
       
   488                 HandleTestCommandL(*cmd);
       
   489                 break;
       
   490                 }
       
   491             case EATReadCmd:
       
   492                 {
       
   493                 HandleReadCommandL(*cmd);
       
   494                 break;
       
   495                 }
       
   496             case EATWriteCmd:
       
   497                 {
       
   498                 HandleWriteCommandL(*cmd);
       
   499                 break;
       
   500                 }
       
   501             case EATActionCmd:
       
   502                 {
       
   503                 HandleActionCommandL(*cmd);
       
   504                 break;
       
   505                 }
       
   506             default:
       
   507                 LEAVE(KErrNotSupported);
       
   508             }
       
   509         }
       
   510     CleanupStack::PopAndDestroy(cmd);
       
   511 
       
   512     if (!iProtocolStatus->iSlc && ServiceLevelConnected())
       
   513         {
       
   514         StopTimer(KServiceSlcTimer);
       
   515         if(iPhoneStatus)
       
   516             {
       
   517             iPhoneStatus->SetVolumeControlFeatureL(iProtocolStatus->iAccSupportedFeature & KHfFeatureBitVolumeControl);
       
   518             iPhoneStatus->SetVoiceRecognitionControlL(iProtocolStatus->iAccSupportedFeature & KHfFeatureBitVoiceRecognition);
       
   519             }
       
   520         iProtocolStatus->iSlc = ETrue;
       
   521         iCallStatus->ReportCallStatusL();
       
   522         iObserver.SlcIndicateL(ETrue);
       
   523         }
       
   524     }
       
   525 
       
   526 // -----------------------------------------------------------------------------
       
   527 // CBtmcProtocol::HandleTestCommand
       
   528 // 
       
   529 // Test Command handled by this method:
       
   530 //    CHLD, BVRA, CIND, CCWA, CLIP
       
   531 // -----------------------------------------------------------------------------
       
   532 //
       
   533 void CBtmcProtocol::HandleTestCommandL(const CATCommand& aCmd)
       
   534     {
       
   535     TRACE_FUNC
       
   536     RATResultPtrArray resarr;
       
   537     ATObjArrayCleanupResetAndDestroyPushL(resarr);
       
   538     
       
   539     TATParam param;
       
   540     switch (aCmd.Id())
       
   541         {
       
   542         case EAT:
       
   543             {
       
   544             break;
       
   545             }
       
   546         case EATCHLD:
       
   547             {
       
   548             param = TATParam(KDesTestCodeCHLDv15);
       
   549             iSlcMask = KSLC_3WayCalling;
       
   550             break;
       
   551             }
       
   552         case EATBVRA:
       
   553             {
       
   554             param = TATParam(KDesTestCodeBVRA);
       
   555             break;
       
   556             }
       
   557         case EATCIND:
       
   558             {
       
   559             param = TATParam(KDesTestCodeCINDv15);
       
   560             break;
       
   561             }
       
   562         case EATCCWA:
       
   563             {
       
   564             param = TATParam(KDesTestCodeCCWA);
       
   565             break;
       
   566             }
       
   567         case EATCLIP:
       
   568             {
       
   569             param = TATParam(KDesTestCodeCLIP);
       
   570             break;
       
   571             }
       
   572         case EATCREG:
       
   573 	        {
       
   574         	param = TATParam(KDesTestCodeCCWA); // it is the same (0,1)
       
   575         	break;
       
   576     	    }
       
   577     	  case EATCOLP:
       
   578     	  	{
       
   579         	param = TATParam(KDesTestCodeCCWA); // it is the same (0,1)
       
   580         	break;    	  		
       
   581     	  	}
       
   582         default:
       
   583             LEAVE(KErrNotFound);
       
   584         }
       
   585     if (param.Type() != EATNullParam)
       
   586         {
       
   587         CATResult* code = CATResult::NewL(aCmd.Id(), EATTestResult, param);
       
   588         CleanupStack::PushL(code);
       
   589         resarr.AppendL(code);
       
   590         CleanupStack::Pop(code);
       
   591         }
       
   592     CATResult* ok = CATResult::NewL(EATOK);
       
   593     CleanupStack::PushL(ok);
       
   594     resarr.AppendL(ok);
       
   595     CleanupStack::Pop(ok);
       
   596     SendResponseL(resarr);
       
   597     CleanupStack::PopAndDestroy(&resarr);
       
   598     CmdHandlingCompletedL();
       
   599     }
       
   600 
       
   601 // -----------------------------------------------------------------------------
       
   602 // CBtmcProtocol::HandleReadCommand
       
   603 // 
       
   604 // Read Command handled by this method:
       
   605 //     CIND, CLIP, COPS
       
   606 // -----------------------------------------------------------------------------
       
   607 //
       
   608 void CBtmcProtocol::HandleReadCommandL(const CATCommand& aCmd)
       
   609     {
       
   610     TRACE_FUNC
       
   611     CATResult* code = NULL;
       
   612     RArray<TATParam> params;
       
   613     CleanupClosePushL(params);
       
   614     TBool response = EFalse;
       
   615     switch (aCmd.Id())
       
   616         {
       
   617         case EATCIND:
       
   618             {
       
   619             // Network status
       
   620             if(!iPhoneStatus)
       
   621                 {
       
   622                 LEAVE(KErrNotSupported);
       
   623                 }
       
   624             
       
   625             RMobilePhone::TMobilePhoneRegistrationStatus net = 
       
   626                 iPhoneStatus->NetworkStatus();
       
   627             
       
   628             if (net == RMobilePhone::ERegisteredOnHomeNetwork || 
       
   629                 net == RMobilePhone::ERegisteredRoaming)
       
   630                 {
       
   631                 LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoATNetworkAvailable)))
       
   632                 }
       
   633             else
       
   634                 {
       
   635                 LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoATNetworkUnavailable)))
       
   636                 }
       
   637             
       
   638             // call status
       
   639             if ((iProtocolStatus->iCallBits & KCallConnectedBit) ||
       
   640                 (iProtocolStatus->iCallBits & KCallHoldBit))
       
   641                 {
       
   642                 LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoATCallActive)))
       
   643                 }
       
   644             else
       
   645                 {
       
   646                 LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoATNoCall)))
       
   647                 }
       
   648             
       
   649             // Call setup status
       
   650             TInt callSetupInd = EBTMonoATNoCallSetup;
       
   651 
       
   652             if (iProtocolStatus->iCallBits & KCallRingingBit)
       
   653                 {
       
   654                 callSetupInd = EBTMonoATCallRinging;
       
   655                 }
       
   656             else if (iProtocolStatus->iCallBits & KCallDiallingBit)
       
   657                 {
       
   658                 callSetupInd = EBTMonoATCallDialling;
       
   659                 }
       
   660             else if (iProtocolStatus->iCallBits & KCallConnectingBit)
       
   661                 {
       
   662                 callSetupInd = EBTMonoATCallConnecting;
       
   663                 }
       
   664             LEAVE_IF_ERROR(params.Append(TATParam(callSetupInd)))
       
   665             // call_setup == callsetup
       
   666             LEAVE_IF_ERROR(params.Append(TATParam(callSetupInd)))
       
   667                 
       
   668             // Call held status
       
   669             TInt callHeldInd = EBTMonoATNoCallHeld;
       
   670             if( (iProtocolStatus->iCallBits & KCallHoldBit) && (iProtocolStatus->iCallBits & KCallConnectedBit) )
       
   671                 {
       
   672                 callHeldInd = EBTMonoATCallHeldAndActive;
       
   673                 }
       
   674             else if(iProtocolStatus->iCallBits & KCallHoldBit)
       
   675                 {
       
   676                 callHeldInd = EBTMonoATCallHeldOnly;
       
   677                 }
       
   678             LEAVE_IF_ERROR(params.Append(TATParam(callHeldInd)))
       
   679             // signal status
       
   680             LEAVE_IF_ERROR(params.Append(TATParam(iPhoneStatus->GetSignalStrength())))
       
   681             // roaming status
       
   682               if(net == RMobilePhone::ERegisteredRoaming)
       
   683                   {
       
   684                   LEAVE_IF_ERROR(params.Append(TATParam(1)))
       
   685                   }
       
   686               else 
       
   687                   {
       
   688                   LEAVE_IF_ERROR(params.Append(TATParam(0)))
       
   689                   }
       
   690             // battery charge
       
   691             LEAVE_IF_ERROR(params.Append(TATParam(iPhoneStatus->GetBatteryCharge())))
       
   692 
       
   693             code = CATResult::NewL(EATCIND, EATReadResult, &params);
       
   694             response = ETrue;
       
   695             break;
       
   696             }
       
   697         case EATCLIP:
       
   698             {
       
   699             LEAVE_IF_ERROR(params.Append(TATParam(iProtocolStatus->iCallerIdNotif)))
       
   700             LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoATCallerIdNetworkServiceUnknown)))
       
   701             code = CATResult::NewL(EATCLIP, EATReadResult, &params);
       
   702             response = ETrue; 
       
   703             break;
       
   704             }
       
   705         case EATCOPS:
       
   706             {
       
   707             iOperator = CBtmcOperator::NewL(*this, *this, CActive::EPriorityStandard, KServiceGetOperator);
       
   708             iOperator->GoActive();
       
   709 			break;
       
   710             }
       
   711         case EATCREG:
       
   712         	{
       
   713             if(!iPhoneStatus)
       
   714                 {
       
   715                 LEAVE(KErrNotSupported);
       
   716                 }
       
   717             
       
   718             RMobilePhone::TMobilePhoneRegistrationStatus net = 
       
   719                 iPhoneStatus->NetworkStatus();
       
   720 			response = ETrue;
       
   721 			switch(net)
       
   722 				{
       
   723 				case RMobilePhone::ERegistrationUnknown:
       
   724 					{
       
   725 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregEnableUnsolicited)))
       
   726 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregNetworkServiceUnknown)))
       
   727 					code = CATResult::NewL(EATCREG, EATReadResult, &params);
       
   728 					break;
       
   729 					}
       
   730 				case RMobilePhone::ENotRegisteredEmergencyOnly:
       
   731 				case RMobilePhone::ENotRegisteredNoService:
       
   732 					{
       
   733 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregEnableUnsolicited)))
       
   734 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregNetworkServiceNotRegistered)))
       
   735 					code = CATResult::NewL(EATCREG, EATReadResult, &params);
       
   736 					break;
       
   737 					}
       
   738 				case RMobilePhone::ENotRegisteredSearching:
       
   739 				case RMobilePhone::ERegisteredBusy:
       
   740 					{
       
   741 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregEnableUnsolicited)))
       
   742 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregNetworkServiceNotRegisteredSearching)))
       
   743 					code = CATResult::NewL(EATCREG, EATReadResult, &params);
       
   744 					break;
       
   745 					}
       
   746 				case RMobilePhone::ERegisteredOnHomeNetwork:
       
   747 					{
       
   748 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregEnableUnsolicited)))
       
   749 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregNetworkServiceHomeNetwork)))
       
   750 					code = CATResult::NewL(EATCREG, EATReadResult, &params);
       
   751 					break;
       
   752 					}
       
   753 				case RMobilePhone::ERegistrationDenied:
       
   754 					{
       
   755 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregEnableUnsolicited)))
       
   756 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregNetworkServiceRegistrationDenied)))
       
   757 					code = CATResult::NewL(EATCREG, EATReadResult, &params);
       
   758 					break;
       
   759 					}
       
   760 				case RMobilePhone::ERegisteredRoaming:
       
   761 					{
       
   762 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregEnableUnsolicited)))
       
   763 					LEAVE_IF_ERROR(params.Append(TATParam(EBTMonoCregNetworkServiceRegisteredRoaming)))
       
   764 					code = CATResult::NewL(EATCREG, EATReadResult, &params);
       
   765 					break;
       
   766 					}
       
   767 				default:
       
   768 					TRACE_INFO(_L("Error: default in CREG"));
       
   769 					break;	
       
   770 				};
       
   771 			break;	
       
   772       }
       
   773     case EATCSQ:
       
   774     	{
       
   775     	TRACE_INFO(_L("Requesting Signal strength"));
       
   776 			response = ETrue;
       
   777     	LEAVE_IF_ERROR(params.Append(TATParam(iPhoneStatus->GetRssiStrength())))
       
   778     	LEAVE_IF_ERROR(params.Append(TATParam(KBerUnknown)))
       
   779    		code = CATResult::NewL(EATCSQ, EATReadResult, &params);
       
   780     	TRACE_INFO(_L("done"));
       
   781     	break;
       
   782     	}
       
   783         	
       
   784 		case EATCGSN:
       
   785 			{
       
   786 			response = ETrue;
       
   787    		TBuf8<RMobilePhone::KPhoneSerialNumberSize> buf;
       
   788    		buf.Copy(iIdentity.iSerialNumber);
       
   789    		LEAVE_IF_ERROR(params.Append(TATParam(buf)))
       
   790    		code = CATResult::NewL(EATCGSN, EATReadResult, &params);
       
   791 			break;
       
   792 			}
       
   793     case EATCGMI:
       
   794     	{
       
   795     	response = ETrue;
       
   796     	TBuf8<RMobilePhone::KPhoneManufacturerIdSize> buf;
       
   797     	buf.Copy(iIdentity.iManufacturer);
       
   798    		LEAVE_IF_ERROR(params.Append(TATParam(buf)))
       
   799    		code = CATResult::NewL(EATCGMI, EATReadResult, &params);
       
   800    		break;
       
   801     	}
       
   802     case EATCGMM:
       
   803     	{
       
   804     	response = ETrue;
       
   805     	TBuf8<RMobilePhone::KPhoneModelIdSize> buf;
       
   806     	buf.Copy(iIdentity.iModel);
       
   807    		LEAVE_IF_ERROR(params.Append(TATParam(buf)))
       
   808    		code = CATResult::NewL(EATCGMM, EATReadResult, &params);
       
   809    		break;    	
       
   810     	}
       
   811     case EATCGMR:
       
   812     	{
       
   813     	response = ETrue;
       
   814     	TBuf8<RMobilePhone::KPhoneRevisionIdSize> buf;
       
   815     	buf.Copy(iIdentity.iRevision);
       
   816    		LEAVE_IF_ERROR(params.Append(TATParam(buf)))
       
   817    		code = CATResult::NewL(EATCGMR, EATReadResult, &params);
       
   818    		break;    	
       
   819     	}
       
   820 		case EATCIMI:
       
   821 			{
       
   822 			iEtelQuery->SetServiceId(KQueryIMSI);
       
   823 			iPhone.GetSubscriberId(iEtelQuery->iStatus, iId);
       
   824 			iEtelQuery->GoActive();
       
   825 			break;
       
   826 			}
       
   827 		case EATCOLP:
       
   828 			{
       
   829 			response = ETrue;
       
   830     	LEAVE_IF_ERROR(params.Append(TATParam(TInt(iProtocolStatus->iOutgoingCallNotif))))
       
   831 			code = CATResult::NewL(EATCOLP, EATReadResult, &params);
       
   832 			break;
       
   833 			}
       
   834     default:
       
   835       LEAVE(KErrNotSupported);
       
   836       }
       
   837     CleanupStack::PopAndDestroy(&params);
       
   838     if (response)
       
   839         {
       
   840         RATResultPtrArray resarr;
       
   841         ATObjArrayCleanupResetAndDestroyPushL(resarr);        
       
   842         CleanupStack::PushL(code);
       
   843         resarr.AppendL(code);
       
   844         CleanupStack::Pop(code);
       
   845         CATResult* ok = CATResult::NewL(EATOK);
       
   846         CleanupStack::PushL(ok);
       
   847         resarr.AppendL(ok);
       
   848         CleanupStack::Pop(ok);
       
   849         SendResponseL(resarr);
       
   850         CleanupStack::PopAndDestroy(&resarr);
       
   851         CmdHandlingCompletedL();
       
   852         }
       
   853     }
       
   854 
       
   855 // -----------------------------------------------------------------------------
       
   856 // CBtmcProtocol::HandleWriteCommand
       
   857 // 
       
   858 // Write Command handled by this method:
       
   859 //    CHLD BVRA, CCWA, CLIP, VGS, VGM, CMEE, COPS
       
   860 // -----------------------------------------------------------------------------
       
   861 //
       
   862 void CBtmcProtocol::HandleWriteCommandL(const CATCommand& aCmd)
       
   863     {
       
   864     TRACE_FUNC
       
   865     RATResultPtrArray resarr;
       
   866     ATObjArrayCleanupResetAndDestroyPushL(resarr);    
       
   867     CATResult* code = NULL;
       
   868     switch (aCmd.Id())
       
   869         {
       
   870         case EATCMER:
       
   871             {
       
   872             TRACE_ASSERT(aCmd.ParamNum() >= 4, KErrArgument);
       
   873             TATParam param = TATParam();
       
   874             LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   875             TInt value;
       
   876             LEAVE_IF_ERROR(param.Int(value))
       
   877             if (value == 3)
       
   878                 {
       
   879                 param = TATParam();
       
   880                 LEAVE_IF_ERROR(aCmd.Parameter(3, param))
       
   881                 LEAVE_IF_ERROR(param.Int(value))
       
   882                 iProtocolStatus->iIndicatorNotif = (value == 1) ? 
       
   883                     KIndAllActivated : KIndAllDeActivated;
       
   884                 TRACE_INFO((_L("Indicators enabled: %d"), value))
       
   885                 }
       
   886             iSlcMask = KSLC_No3WayCalling;
       
   887             break;
       
   888             }
       
   889         case EATBRSF:
       
   890             {
       
   891             TRACE_ASSERT(aCmd.ParamNum() == 1, KErrArgument);
       
   892             TATParam param = TATParam();
       
   893             LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   894             TInt value;
       
   895             LEAVE_IF_ERROR(param.Int(value))
       
   896             iProtocolStatus->iAccSupportedFeature = value;
       
   897             code = CATResult::NewL(EATBRSF, EATWriteResult, 
       
   898                 TATParam(iProtocolStatus->iAGSupportedFeature));
       
   899             break;
       
   900             }
       
   901         case EATCCWA:
       
   902             {
       
   903             TRACE_ASSERT(aCmd.ParamNum() == 1, KErrArgument);
       
   904             TATParam param = TATParam();
       
   905             LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   906             TInt value;
       
   907             LEAVE_IF_ERROR(param.Int(value))
       
   908             iProtocolStatus->iCallWaitingNotif = (TBTMonoATCallWaitingNotif)value;
       
   909             break;
       
   910             }
       
   911         case EATCLIP:
       
   912             {
       
   913             TRACE_ASSERT(aCmd.ParamNum() == 1, KErrArgument);
       
   914             TATParam param = TATParam();
       
   915             LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   916             TInt value;
       
   917             LEAVE_IF_ERROR(param.Int(value))
       
   918             iProtocolStatus->iCallerIdNotif = (TBTMonoATCallerIdNotif) value ;
       
   919             break;
       
   920             }
       
   921         case EATVGS:
       
   922             {
       
   923             TRACE_ASSERT(aCmd.ParamNum() == 1, KErrArgument);
       
   924             TATParam param = TATParam();
       
   925             LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   926             TInt value;
       
   927             LEAVE_IF_ERROR(param.Int(value))
       
   928             if (!iPhoneStatus)
       
   929                 {
       
   930                 iPhoneStatus = CBtmcPhoneStatus::NewL(*this, iPhone, iProtocolStatus->iProfile);
       
   931                 iPhoneStatus->SetVolumeControlFeatureL(ETrue);
       
   932                 }
       
   933             if(iVolumeSyncFromAccessory)
       
   934                 {
       
   935                 iPhoneStatus->SetSpeakerVolumeL(value);
       
   936                 }
       
   937             break;
       
   938             }
       
   939         case EATVGM:
       
   940             {
       
   941             TRACE_ASSERT(aCmd.ParamNum() == 1, KErrArgument);
       
   942             TATParam param = TATParam();
       
   943             LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   944             TInt value;
       
   945             LEAVE_IF_ERROR(param.Int(value))
       
   946             break;
       
   947             }
       
   948         case EATCMEE:
       
   949             {
       
   950             TRACE_ASSERT(aCmd.ParamNum() == 1, KErrArgument);
       
   951             TATParam param = TATParam();
       
   952             LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   953             TInt value;
       
   954             LEAVE_IF_ERROR(param.Int(value))
       
   955             iProtocolStatus->iAdvancedErrorCode = value;
       
   956             break;
       
   957             }
       
   958         case EATCOPS:
       
   959             {
       
   960             break;
       
   961             }
       
   962         case EATBIA:
       
   963         	{
       
   964         	for(TInt i=0; i<aCmd.ParamNum(); i++)
       
   965 	        	{
       
   966 	        	TATParam param = TATParam();
       
   967 	        	aCmd.Parameter(i, param);
       
   968 	        	if(param.Type() == EATNullParam)
       
   969 	        		continue;
       
   970 	        	else
       
   971 		        	{
       
   972 					TInt value;
       
   973 					param.Int(value);		        	
       
   974 	        		SetIndicatorL(i+1, value);
       
   975 		        	}
       
   976 	        	}
       
   977 	        break;
       
   978         	}
       
   979         case EATCREG:
       
   980         	{
       
   981             TRACE_ASSERT(aCmd.ParamNum() == 1, KErrArgument);
       
   982             TATParam param = TATParam();
       
   983             LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   984             TInt value;
       
   985             LEAVE_IF_ERROR(param.Int(value))
       
   986             iProtocolStatus->iNetworkRegStatusNotif = TBool(value);        	
       
   987             break;
       
   988         	}
       
   989         case EATCOLP:
       
   990         	{
       
   991           TRACE_ASSERT(aCmd.ParamNum() == 1, KErrArgument);
       
   992           TATParam param = TATParam();
       
   993           LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
   994           TInt value;
       
   995           LEAVE_IF_ERROR(param.Int(value))
       
   996           iProtocolStatus->iOutgoingCallNotif = TBool(value);
       
   997           break;
       
   998         	}
       
   999         default:
       
  1000             LEAVE(KErrNotSupported);
       
  1001         }
       
  1002 
       
  1003     if (code)
       
  1004         {
       
  1005         CleanupStack::PushL(code);
       
  1006         resarr.AppendL(code);
       
  1007         CleanupStack::Pop(code);
       
  1008         }
       
  1009     CATResult* ok = CATResult::NewL(EATOK);
       
  1010     CleanupStack::PushL(ok);
       
  1011     resarr.AppendL(ok);
       
  1012     CleanupStack::Pop(ok);
       
  1013     SendResponseL(resarr);
       
  1014     CleanupStack::PopAndDestroy(&resarr);
       
  1015     
       
  1016     // solution to volume sync - phone will always send its volume status back to accessory
       
  1017     
       
  1018     if( (aCmd.Id() == EATVGS) && (iVolumeSyncFromAccessory == EFalse) )
       
  1019     	{
       
  1020     	iVolumeSyncFromAccessory = ETrue;
       
  1021     	TInt vol(KErrNotFound);
       
  1022 
       
  1023         if(iPhoneStatus)
       
  1024             {
       
  1025             vol = iPhoneStatus->GetVolumeStatus();
       
  1026             }
       
  1027 
       
  1028     	if(vol > KErrNotFound) // volume exists
       
  1029     		{
       
  1030         TATParam param = TATParam();
       
  1031         LEAVE_IF_ERROR(aCmd.Parameter(0, param))
       
  1032         TInt value;
       
  1033         LEAVE_IF_ERROR(param.Int(value))
       
  1034         if(value != vol)
       
  1035     			{
       
  1036     			CATResult* event = CATResult::NewLC(EATVGS, EATUnsolicitedResult, vol);
       
  1037     			SendUnsoltResultL(*event);
       
  1038     			CleanupStack::PopAndDestroy(event);
       
  1039     			}
       
  1040     		}
       
  1041     	}
       
  1042     CmdHandlingCompletedL();    
       
  1043     }
       
  1044 
       
  1045 
       
  1046 // -----------------------------------------------------------------------------
       
  1047 // CBtmcProtocol::HandleActionCommandL
       
  1048 // 
       
  1049 // Action Command handled by this method:
       
  1050 //    CLCC CNUM
       
  1051 // -----------------------------------------------------------------------------
       
  1052 //
       
  1053 void CBtmcProtocol::HandleActionCommandL(const CATCommand& aCmd)
       
  1054     {
       
  1055     TRACE_FUNC
       
  1056     
       
  1057     switch (aCmd.Id())
       
  1058         {
       
  1059         case EATCNUM:
       
  1060             {
       
  1061             iNumber = CBtmcNumber::NewL(*this, *this, CActive::EPriorityStandard, KServiceGetSubscriber);
       
  1062             iNumber->GoActive();
       
  1063             break;
       
  1064             }
       
  1065         case EATCLCC:
       
  1066             {
       
  1067             iCallStatus->HandleClccL();
       
  1068             break;
       
  1069             }
       
  1070         case EATCGSN:
       
  1071             {
       
  1072             CATResult* code = NULL;
       
  1073             RArray<TATParam> params;
       
  1074             CleanupClosePushL(params);
       
  1075             TBuf8<RMobilePhone::KPhoneSerialNumberSize> buf;
       
  1076             buf.Copy(iIdentity.iSerialNumber);
       
  1077             LEAVE_IF_ERROR(params.Append(TATParam(buf)))
       
  1078             code = CATResult::NewL(EATCGSN, EATActionResult, &params);
       
  1079             CleanupStack::PopAndDestroy(&params);
       
  1080             RATResultPtrArray resarr;
       
  1081             ATObjArrayCleanupResetAndDestroyPushL(resarr);        
       
  1082             CleanupStack::PushL(code);
       
  1083             resarr.AppendL(code);
       
  1084             CleanupStack::Pop(code);
       
  1085             CATResult* ok = CATResult::NewL(EATOK);
       
  1086             CleanupStack::PushL(ok);
       
  1087             resarr.AppendL(ok);
       
  1088             CleanupStack::Pop(ok);
       
  1089             SendResponseL(resarr);
       
  1090             CleanupStack::PopAndDestroy(&resarr);
       
  1091             CmdHandlingCompletedL();
       
  1092             break;
       
  1093             }
       
  1094         default:
       
  1095             LEAVE(KErrNotSupported);
       
  1096         }
       
  1097     }
       
  1098 
       
  1099 void CBtmcProtocol::DoSendProtocolDataL()
       
  1100     {
       
  1101     TRACE_INFO((_L("credit %d"), iCredit))
       
  1102     TInt count = iOutgoPacketQueue->MdcaCount();
       
  1103     for (TInt i = 0; iCredit >0 && i < count; i++)
       
  1104         {
       
  1105         iCredit--;
       
  1106         TBuf8<KMaxATSize> buf;
       
  1107         buf.Copy(iOutgoPacketQueue->MdcaPoint(0));
       
  1108         iObserver.SendProtocolDataL(buf);
       
  1109         iOutgoPacketQueue->Delete(0);
       
  1110         }
       
  1111     }
       
  1112 
       
  1113 void CBtmcProtocol::StartTimerL(TInt aService, TInt aTimeout)
       
  1114     {
       
  1115     if (!iTimerActive)
       
  1116         {
       
  1117         TRACE_FUNC_ENTRY
       
  1118         iTimerActive = CBtmcActive::NewL(*this, CActive::EPriorityStandard, aService);
       
  1119         iTimer.CreateLocal();
       
  1120         iTimer.After(iTimerActive->iStatus, aTimeout);
       
  1121         iTimerActive->GoActive();
       
  1122         TRACE_FUNC_EXIT
       
  1123         }
       
  1124     else
       
  1125         {
       
  1126         TRACE_WARNING(_L("WARNING, timer is active already"))
       
  1127         }
       
  1128     }
       
  1129 
       
  1130 void CBtmcProtocol::StopTimer(TInt aService)
       
  1131     {
       
  1132     if (iTimerActive && iTimerActive->ServiceId() == aService)
       
  1133         {
       
  1134         TRACE_FUNC_ENTRY
       
  1135         delete iTimerActive;
       
  1136         iTimerActive = NULL;
       
  1137         iTimer.Close();
       
  1138         TRACE_FUNC_EXIT
       
  1139         }
       
  1140     }
       
  1141     
       
  1142 // -----------------------------------------------------------------------------
       
  1143 // CBtmcProtocol::IsServiceLevelEstablished
       
  1144 // -----------------------------------------------------------------------------
       
  1145 //
       
  1146 TBool CBtmcProtocol::ServiceLevelConnected() const
       
  1147     {
       
  1148     TRACE_FUNC
       
  1149     TRACE_INFO((_L("SLC 0x%02x"), iSlcMask))
       
  1150     if ((iProtocolStatus->iAccSupportedFeature & 0x02) && 
       
  1151         (iProtocolStatus->iAGSupportedFeature & 0x01) &&
       
  1152         (iSlcMask == KSLC_3WayCalling))
       
  1153         {
       
  1154         return ETrue;
       
  1155         }
       
  1156     if ((!(iProtocolStatus->iAccSupportedFeature & 0x02) ||
       
  1157          !(iProtocolStatus->iAGSupportedFeature & 0x01)) &&
       
  1158         (iSlcMask == KSLC_No3WayCalling))
       
  1159         {
       
  1160         return ETrue;
       
  1161         }
       
  1162     return EFalse;
       
  1163     }
       
  1164 
       
  1165 // -----------------------------------------------------------------------------
       
  1166 // CBtmcProtocol::ServiceAttributeSearchComplete
       
  1167 // -----------------------------------------------------------------------------
       
  1168 //    
       
  1169 void CBtmcProtocol::ServiceAttributeSearchComplete( TSdpServRecordHandle /*aHandle*/, 
       
  1170                                                     const RSdpResultArray& aAttr, 
       
  1171                                                     TInt aErr )
       
  1172 	{
       
  1173     TRACE_FUNC
       
  1174     if((aErr == KErrNone || aErr == KErrEof) && aAttr.Count() && aAttr[0].iAttrValue.iValNumeric)
       
  1175         {
       
  1176         TRACE_INFO((_L("Remote volume control supported")))
       
  1177         TInt err = KErrNone;
       
  1178         if (!iPhoneStatus)
       
  1179             {
       
  1180             TRAP(err, iPhoneStatus = CBtmcPhoneStatus::NewL(*this, iPhone, iProtocolStatus->iProfile));
       
  1181             }   
       
  1182 			
       
  1183         if (err == KErrNone)
       
  1184             {
       
  1185             TRAP_IGNORE(iPhoneStatus->SetVolumeControlFeatureL(ETrue));
       
  1186             iPhoneStatus->ActivateRemoteVolumeControl();
       
  1187             }        
       
  1188         }
       
  1189         
       
  1190     if(aErr)
       
  1191         {
       
  1192         delete iBteng;
       
  1193         iBteng = NULL;
       
  1194         }
       
  1195     }
       
  1196 
       
  1197 void CBtmcProtocol::SetIndicatorL(TInt aIndicator, TInt aValue)
       
  1198 	{
       
  1199 	TInt indBit( 0 );
       
  1200 	switch(aIndicator)
       
  1201 		{
       
  1202 		case EBTMonoATNetworkIndicator:
       
  1203 		    indBit = KIndServiceBit;
       
  1204 			break;
       
  1205 		case EBTMonoATCallIndicator:
       
  1206 		case EBTMonoATCallSetupIndicator:
       
  1207 		case EBTMonoATCall_SetupIndicator:
       
  1208 		case EBTMonoATCallHeldIndicator:
       
  1209 		    // call, call setup, call held indicators are mandatory.
       
  1210 		    break;
       
  1211 		case EBTMonoATSignalStrengthIndicator:
       
  1212 		    indBit = KIndSignalBit;
       
  1213 			break;
       
  1214 		case EBTMonoATRoamingIndicator:
       
  1215 		    indBit = KIndRoamBit;
       
  1216 			break;
       
  1217 		case EBTMonoATBatteryChargeIndicator:
       
  1218 		    indBit = KIndChargeBit;
       
  1219 			break;
       
  1220 		default:
       
  1221 			LEAVE(KErrArgument)
       
  1222 		}
       
  1223 	if ( indBit )
       
  1224 	    {
       
  1225 	    if ( aValue )
       
  1226 	        {
       
  1227             iProtocolStatus->iIndicatorNotif |= indBit;
       
  1228             }
       
  1229         else
       
  1230             {
       
  1231             iProtocolStatus->iIndicatorNotif &= ~indBit;
       
  1232             }
       
  1233 	    }
       
  1234 	}
       
  1235 void CBtmcProtocol::UnsolicitedResultFromATExtL(TInt aErr, const TDesC8& aAT)
       
  1236     {
       
  1237 		TRACE_FUNC
       
  1238 		if(aErr)
       
  1239 			{
       
  1240 			delete iAtExt;
       
  1241 			iAtExt = NULL;
       
  1242 			}
       
  1243 		else
       
  1244 			{
       
  1245 	    iOutgoPacketQueue->AppendL(aAT);
       
  1246 	    if (!iCallingHandler->ActiveCmdHandling() && !iHandleCmdPending)
       
  1247 		    {
       
  1248 		    iCredit++;
       
  1249 		    }
       
  1250     	DoSendProtocolDataL();
       
  1251   		}
       
  1252     }
       
  1253 
       
  1254 void CBtmcProtocol::ATExtHandleCommandCompletedL(TInt aErr, const TDesC8& aReply)
       
  1255 		{
       
  1256 		TRACE_FUNC
       
  1257 		if(aErr)
       
  1258 			{
       
  1259 	    CATResult* nok = CATResult::NewLC(EATERROR);
       
  1260 	    SendResponseL(*nok);
       
  1261 	    CleanupStack::PopAndDestroy(nok);
       
  1262 			}
       
  1263 		else
       
  1264 			{
       
  1265 	    iOutgoPacketQueue->AppendL(aReply);
       
  1266 	    if (!iCallingHandler->ActiveCmdHandling() && !iHandleCmdPending)
       
  1267 		    {
       
  1268 		    iCredit++;
       
  1269 		    }
       
  1270 	    DoSendProtocolDataL();
       
  1271 			}
       
  1272 		}
       
  1273 
       
  1274 
       
  1275 // End of file