diff -r 000000000000 -r 29b1cd4cb562 bluetooth/gavdp/test/tavsrc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetooth/gavdp/test/tavsrc.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,2678 @@ +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "tavsrc.h" +#include "tavsrcUtils.h" +#include "tavsrcSock.h" +#include "tavsrcController.h" +#include "tavsrcStreamer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef DBAWARE +#include "tavsrcmtupdaterdatabaseaware.h" +#else +#include "tavsrcmtupdaterdatabaseunaware.h" +#endif +#include "tavsrcAbsoluteVolume.h" + +#ifdef __WINS__ +static const TSize KMainConsole(75,30); +static const TSize KLogConsole(75,30); +#else +static const TSize KMainConsole(KConsFullScreen,KConsFullScreen); +static const TSize KLogConsole(KConsFullScreen,KConsFullScreen); +#endif + +using namespace SymbianBluetoothAV; +using namespace SymbianSBC; + +void CAVTestApp::PreventLowPowerModes() + { + // Prevent any other application from setting to low power mode + TInt err = iPhy.PreventLowPowerModes(EAnyLowPowerMode); + __LOG(_L("Low power mode prevented, result %d\n"), err); + } + +void CAVTestApp::AllowLowPowerModes() + { + // Allow any other application to set to low power mode + TInt err = iPhy.AllowLowPowerModes(EAnyLowPowerMode); + __LOG(_L("Low power mode allowed, result %d\n"), err); + } + +void CAVTestApp::EchoStorm() + { + //UPF test + //connect phy + CBluetoothPhysicalLinks* phys = NULL; + TRAP_IGNORE(phys = CBluetoothPhysicalLinks::NewL(*this, iSockServ)); + if (phys) + { + phys->CreateConnection(iDevAddr); + } + } + + void CAVTestApp::HandleCreateConnectionCompleteL(TInt /*aErr*/) + { + TBuf8<32> echo; + RSocket sock; + + sock.Open(iSockServ, _L("L2CAP")); + TL2CAPSockAddr addr; + addr.SetBTAddr(iDevAddr); + addr.SetPort(1); + + TRequestStatus status; + + __LOG(_L("Connecting l2cap")); + sock.Connect(addr, status); + User::WaitForRequest(status); + + echo.SetMax(); + echo.Fill('!'); + __LOG(_L("Echooing")); + FOREVER + { + sock.Ioctl(KL2CAPEchoRequestIoctl, status, &echo, KSolBtL2CAP); + User::WaitForRequest(status); + } + } + +void CAVTestApp::HandleDisconnectCompleteL(TInt /*aErr*/) + { + } + +void CAVTestApp::HandleDisconnectAllCompleteL(TInt /*aErr*/) + { + } + +void CAVTestApp::CreateStreamerL(RSocketArray aSockets) + { + __LOG(_L("Creating new streamer\n")); + iStreamer = CActiveStreamer::NewL(aSockets,iLogConsole->Console(), *this, iDisplayMode, iPreloadFile); + __LOG(_L("OK\n")); + } + +void CAVTestApp::Abort() + { + __PRINT(_L("\n (!ABORT!) Enter remote SEID to ABORT")); + TInt seid = TTavsrcUtils::GetIntFromUser(iActiveConsole->Console()); + __PRINT(_L("\n")); + __LOG(_L("Aborting SEID &d...\n"),seid); + iGavdp.AbortStream(TSEID(seid, EFalse)); + } + +void CAVTestApp::SendSecurityControl() + { + __PRINT(_L("\n Enter remote SEID to Send Security Control")); + TInt seid = TTavsrcUtils::GetIntFromUser(iActiveConsole->Console()); + __PRINT(_L("\n")); + __LOG(_L("Sending security control to SEID %d...\n"),seid); + + TBuf8<20> secBuf(_L8("Danger!\n")); + + iGavdp.SendSecurityControl(TSEID(seid, EFalse), secBuf); + } + +void CAVTestApp::GetCapabilities() + { + if (!iLocalReconfigure) // Don't change the remote SEID if we're reconfiguring + { + if (iAutoStream) + { + // start at first in shortlisted sep array + iCurrentSEID = iShortlistedSEIDs[0]; + iShortlistedSEIDs.Remove(0); // so next time around, take head again + } + else + { + __PRINT(_L("\n Enter remote SEID to get caps for")); + iCurrentSEID = TSEID(TTavsrcUtils::GetIntFromUser(iActiveConsole->Console()), EFalse); + } + } + + __PRINT(_L("\n")); + __LOG(_L("Getting Capabilities for SEID %d...\n"),iCurrentSEID.Value()); + + iSEPCapabilities.ResetAndDestroy(); //clear what's already there + + // we're interested in all caps as we are *TEST CODE* + // some GCs should only register interest in the capabilities they might select + TAvdtpServiceCategories caps; + caps.SetCapability(EAllServiceCategories); + + iGavdp.GetRemoteSEPCapabilities(iCurrentSEID, caps); + } + + +void CAVTestApp::GAVDP_SEPCapability(TAvdtpServiceCapability* aCapability) + { + TInt err; + PrettyPrint(*aCapability); + + // we own cap, stash it in our RPointerArray for owning and later use + err = iSEPCapabilities.Append(aCapability); + + if(err == KErrNone) + { + // check if remote does SBC + if (aCapability->Category() == EServiceCategoryMediaCodec) + { + if (static_cast(aCapability)->MediaCodecType() == EAudioCodecSBC) + { + iChosenSEP = ETrue; + __LOG(_L("Found remote suitable SEP with SEID %d\n"), iCurrentSEID.SEID()); + } + } + } + else + { + delete aCapability; + } + } + + +void CAVTestApp::GAVDP_SEPDiscoveryComplete() + { + // complete the operation + iOperations->EndOperation(KTavsrcOpDiscoverSEPs, KErrNone); + + __LOG(_L("GAVDP:SEP Discovery complete.\n")); + + if (iAutoStream) + { + // go through all the shortlisted SEPs to find the SBC one + GetCapabilities(); + } + TestMenu(); + } + +void CAVTestApp::GAVDP_SEPCapabilityComplete() + { + // complete the operation + iOperations->EndOperation(KTavsrcOpGetCapabilities, KErrNone); + + __LOG(_L("GAVDP:SEP has no more capabilities.\n")); + + if ((iAutoStream && iChosenSEP) || iLocalReconfigure) + { + // configure iCurrentSEID + TRAPD(err, ConfigureSEPL()); + if (err != KErrNone) + { + __LOG(_L("Error configuring remote SEP: %d\n"), err); + } + } + else if (iAutoStream && !iShortlistedSEIDs.Count()) + { + __LOG(_L("Error: Remote does not have SBC codec available\n")); + } + else if (iAutoStream) + { + //try next sep + GetCapabilities(); + } + TestMenu(); + } + +void CAVTestApp::GAVDP_ConnectConfirm(const TBTDevAddr& aAddr) + { + // complete the operation + iOperations->EndOperation(KTavsrcOpConnect, KErrNone); + + // update our tiny state... + iGavdpState = ESigConnected; + + // hack :o) + iDevAddr = aAddr; + __LOG(_L("Signalling channel connected = GAVDP ready\n")); + + // Open RBTPhysicalLinkAdapter for prevention of low power modes during streaming + TInt err = iPhy.Open(iSockServ, iDevAddr); + __LOG(_L("Opened iPhy, result %d\n"), err); + + TestMenu(); + } + +void CAVTestApp::GAVDP_SEPDiscovered(const TAvdtpSEPInfo& aSEPInfo) + { + // this test code at present doesnt "remember" the SEPs + switch (aSEPInfo.MediaType()) + { + case EAvdtpMediaTypeAudio: + __LOG(_L("Audio")); + break; + case EAvdtpMediaTypeVideo: + __LOG(_L("Video")); + break; + case EAvdtpMediaTypeMultimedia: + __LOG(_L("Multimedia")); + break; + } + + if (aSEPInfo.IsSink()) + { + __LOG(_L(" Sink")); + } + else + { + __LOG(_L(" Source")); + } + + __LOG(_L(" SEP (SEID %d)"), aSEPInfo.SEID().Value()); + + if (aSEPInfo.InUse()) + { + __LOG(_L("[In use]")); + } + + // as we intend streaming audio, we need a free audio sink sep + if (aSEPInfo.MediaType()==EAvdtpMediaTypeAudio && aSEPInfo.IsSink() && !aSEPInfo.InUse()) + { + __LOG(_L("<-- Shortlisted SEP")); + (void)iShortlistedSEIDs.Append(aSEPInfo.SEID()); + } + + __LOG(_L("\n")); + TestMenu(); + } + + +void CAVTestApp::GAVDP_AbortStreamConfirm() + { + // complete the operation + iOperations->EndOperation(KTavsrcOpAbort, KErrNone); + + __LOG(_L("GAVDP:Aborted\n")); + delete iStreamer; + iStreamer = NULL; + + AllowLowPowerModes(); + + TestMenu(); + } + +void CAVTestApp::GAVDP_SecurityControlConfirm(const TDesC8& aResponseData) + { + // complete the operation + iOperations->EndOperation(KTavsrcOpContentProtection, KErrNone); + + __LOG(_L("GAVDP:Security control complete\n")); + __LOG(_L("GAVDP:Security control rsp=%S\n"), &aResponseData); + + TestMenu(); + } + +void CAVTestApp::GAVDP_StartStreamsConfirm() + { + // complete the operation + iOperations->EndOperation(KTavsrcOpStartStreams, KErrNone); + + __LOG(_L("GAVDP: StartStreamConfirm: now ready for use\n")); + + RThread().SetPriority(EPriorityRealTime); + + if (iLocalReconfigure) + { + iStreamer->ReStream(); + iStreamState = EStreaming; + + iOperations->EndOperation(KTavsrcOpStream, KErrNone); + iLocalReconfigure = EFalse; + } + else if (iAutoStream) + { + //this maynot be true as SNK can be INT (but tavsrc only looks for remote SNKs) + iStreamer->Stream(CurrentSEIDIsSink()); + iStreamState = EStreaming; + + iOperations->EndOperation(KTavsrcOpStream, KErrNone); + } + + iAutoStream = EFalse; // done + iLocalReconfigure = EFalse; + + PreventLowPowerModes(); + + TestMenu(); + } + +void CAVTestApp::GAVDP_SuspendStreamsConfirm() + { + // complete the operation + iOperations->EndOperation(KTavsrcOpSuspendStreams, KErrNone); + + iGavdpState = ESuspended; + + __LOG(_L("Suspending stream!\n")); + iStreamer->Suspend(); + iStreamState = EPaused; + + // we might be doing a reconfigure due to a request from the streamer + if (iLocalReconfigure) + { + GetCapabilities(); + } + + AllowLowPowerModes(); + + TestMenu(); + } + +void CAVTestApp::GAVDP_ConfigurationConfirm() + { + // complete the operation + if (iRegisteringLocalSEP) + { + __LOG(_L("SEP [SEID %d]: Local Configuration complete\n"), iCurrentSEID.SEID()); + iOperations->EndOperation(KTavsrcOpRegisterSEP, KErrNone); + + iRegisteringLocalSEP = EFalse; + + // time to listen now SEP registered, ignore error, logged in Listen() + Listen(); + } + else + { + __LOG(_L("SEP [SEID %d]: Remote Configuration complete\n"), iCurrentSEID.SEID()); + iOperations->EndOperation(KTavsrcOpConfigureSEP, KErrNone); + + // we might be doing a reconfigure due to a request from the streamer + if (iLocalReconfigure) + { + StartStreams(); + } + // if we;re doing autoCSR stuff we choose to go straight to open + else if (iAutoStream) + { + CreateBearers(); + } + } + + TestMenu(); + } + +void CAVTestApp::GAVDP_Error(TInt aError, const TDesC8& /*aErrorData*/) + { + __LOG(_L("GAVDP: **Error**: %d:\n"), aError); + + // complete the outstanding operation with an error + iOperations->EndOperation(0, aError); + + switch (aError) + { + case KErrAvdtpBaseError-KErrAvdtpRequestTimeout: + { + __LOG(_L("AVDTP Request timed out\n")); + break; + } + case -6305: + case KErrDisconnected: + { + iPhy.Close(); + __LOG(_L("Closed iPhy\n")); + + __LOG(_L("Signalling disconnected\nTest code is going to Re-listen...\n")); + aError = Listen(); + + iAutoStream = EFalse; + if (iStreamer) + { + iStreamer->Stop(); + } + iStreamState = EStopped; + + // reset the state + iOperations->EndOperation(KTavsrcOpDisconnectSrc, aError); + break; + } + + // Errors we can't match to a specific command + case EAvdtpBadHeaderFormat: + case EAvdtpBadLength: + case EAvdtpBadACPSEID: + case EAvdtpBadPayloadFormat: + case EAvdtpNotSupportedCommand: + case EAvdtpBadState: + { + __LOG(_L("Couldn't determine operation that caused error\n")); + break; + } + + // Errors on SetConfig/Reconfig + case EAvdtpSEPInUse: + case EAvdtpSepNotInUse: + case EAvdtpBadServCategory: + case EAvdtpInvalidCapabilities: + case EAvdtpBadRecoveryType: + case EAvdtpBadMediaTransportFormat: + case EAvdtpBadReportingFormat: + case EAvdtpBadRecoveryFormat: + case EAvdtpBadRohcFormat: + case EAvdtpBadCpFormat: + case EAvdtpBadMultiplexingFormat: + case EAvdtpUnsupportedConfiguration: + case EGavdpBadService: + case EGavdpInsufficientResource: + case EA2dpInvalidCodec: + case EA2dpNotSupportedCodec: + case EA2dpInvalidSamplingFrequency: + case EA2dpNotSupportedSamplingFrequency: + case EA2dpInvalidChannelMode: + case EA2dpNotSupportedChannelMode: + case EA2dpInvalidSubbands: + case EA2dpNotSupportedSubbands: + case EA2dpInvalidAllocationMethod: + case EA2dpNotSupportedAllocationMethod: + case EA2dpInvalidMinimumBitPoolValue: + case EA2dpNotSupportedMinimumBitPoolValue: + case EA2dpInvalidMaximumBitPoolValue: + case EA2dpNotSupportedMaximumBitPoolValue: + case EA2dpInvalidLayer: + case EA2dpNotSupportedLayer: + case EA2dpNotSupportedCRC: + case EA2dpNotSupportedMPF: + case EA2dpNotSupportedVBR: + case EA2dpInvalidBitRate: + case EA2dpNotSupportedBitRate: + case EA2dpInvalidObjectType: + case EA2dpNotSupportedObjectType: + case EA2dpInvalidChannels: + case EA2dpNotSupportedChannels: + case EA2dpInvalidVersion: + case EA2dpNotSupportedVersion: + case EA2dpNotSupportedSUL: + case EA2dpInvalidBlockLength: + case EA2dpInvalidCPType: + case EA2dpInvalidCPFormat: + { + __LOG(_L("Error setting configuration\n")); + break; + }; + } + + TestMenu(); + } + +// passive gubbins +void CAVTestApp::GAVDP_ConfigurationStartIndication(TSEID aLocalSEID, TSEID aRemoteSEID) + { + // ah - remote is attempting to confuigure us + // we need to set our state + __LOG(_L("Remote SEP [SEID %d] is configuring Local SEP [SEID %d]\n"), aRemoteSEID.Value(), aLocalSEID.Value()); + + + // the seid has already been checked, but we could see which of our endpoints this refers to + iGavdpState = ERemoteReconfiguring; + iCurrentSEID = aRemoteSEID; + iCurrentLocalSEID = aLocalSEID; + } + +TInt CAVTestApp::GAVDP_ConfigurationIndication(TAvdtpServiceCapability* aCapability) + { + // the new capability proposed by remote + __LOG(_L("Configuration proposed: category %d\n"), aCapability->Category()); + + // for this test code we currently accept everything + //** A REAL GC SHOULD THINK ABOUT WHAT THE REMOTE IS PROPOSING + PrettyPrint(*aCapability); + + TInt ret = KErrNone; + if (aCapability->Category() == EServiceCategoryRecovery) + { + TAvdtpRecoveryCapabilities* recCap = static_cast(aCapability); + if (static_cast(recCap->RecoveryType()) == 0xff) + { + ret = ConvertToSymbianError::AvdtpError(EAvdtpBadRecoveryType); + } + + } + + + if (ret == KErrNone) + { + delete aCapability; + } + + return ret; + } + + +TInt CAVTestApp::GAVDP_ConfigurationEndIndication() + { + // just accept all we saw + __LOG(_L("GAVDP: Remote configuration proposals now finished")); + __LOG(_L(" - we are replying that all is OK\n")); + + // real GC should think about what remote has said!! + + return KErrNone; + } + +TInt CAVTestApp::GAVDP_StartIndication(TSEID aLocalSEID) + { + __LOG(_L("Start indication for Local SEID %d\n"), aLocalSEID.SEID()); + TInt err = KErrNone; + + if(iStreamer) + { + __LOG(_L("Starting streamer (passively!)\n")); + + TBool sink = EFalse; + + for (TInt i=0; iStream(sink); + iStreamState = EStreaming; + + iOperations->EndOperation(KTavsrcOpStream, KErrNone); + + PreventLowPowerModes(); + } + else + { + __LOG(_L("No streamer! Rejecting start\n")); + err = KErrNotReady; + } + TestMenu(); + return err; + } + +void CAVTestApp::GAVDP_AbortIndication(TSEID aSEID) + { + __LOG(_L("GAVDP:Stream %d ABORTED by peer\n"), aSEID.SEID()); + + iOperations->EndOperation(KTavsrcOpAbort, KErrNone); + + delete iStreamer; + iStreamer = NULL; + + iPhy.Close(); + __LOG(_L("Closed iPhy\n")); + + TestMenu(); + } + +void CAVTestApp::GAVDP_ReleaseIndication(TSEID aSEID) + { + __LOG(_L("GAVDP:Stream %d RELEASED by peer\n"), aSEID.SEID()); + + AllowLowPowerModes(); + } + + +TInt CAVTestApp::GAVDP_SuspendIndication(TSEID aSEID) + { + __LOG(_L("GAVDP:Stream %d SUSPENDED by peer\n"), aSEID.SEID()); + + iStreamer->Suspend(); + // should ask the streamer object what SEID it is streaming really + + // as test code we always consume this for now + iOperations->EndOperation(KTavsrcOpSuspendStreams, KErrNone); + + AllowLowPowerModes(); + + TestMenu(); + return KErrNone; + } + +TInt CAVTestApp::GAVDP_SecurityControlIndication(TSEID aSEID, TDes8& aSecurityData) + { + __LOG(_L("GAVDP:Got security control data length %d for SEID %d\n"), aSecurityData.Length(), aSEID.Value()); + + TBool identical = TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(), _L("Security control data: respond identically?")); + if (!identical) + { + aSecurityData[0]^='!'; + } + + return KErrNone; + } + +void CAVTestApp::GAVDP_BearerReady(RSocket aNewSocket, const TAvdtpSockAddr& aAddr) + { + // wrap socket with active wrapper... + __LOG(_L("Got a bearer, for session %d\n"), aAddr.Session()); + + // we'll make a streamer now (easy way to keep this socket) + // set the PHY to be AV friendly! + switch(aAddr.Session()) + { + case EMedia: + { + iPendingSockets[0] = aNewSocket; + + // complete the operation + iOperations->EndOperation(KTavsrcOpCreateBearers, KErrNone); + + iGavdpState = EOpen; + + // all bearers ready! + __LOG(_L("Got all bearers, can now start\n")); + + RBTPhysicalLinkAdapter phy; + + // AV sockets don't foward opts yet so use addr version + TInt err = phy.Open(iSockServ, iDevAddr); + TUint16 packets = EPacketsDH1|EPacketsDH3|EPacketsDH5; + err = phy.RequestChangeSupportedPacketTypes(packets); + __LOG(_L("Modified PHY, result %d\n"), err); + TRAP(err, CreateStreamerL(iPendingSockets)); //FIXME arrange array better for different #bearers + if(err) + { + __LOG(_L("Creating streamer failed with err %d, closing socket\n"), err); + aNewSocket.Close(); + } + + if (iAutoStream) + { + StartStreams(); + } + // but not start streaming until manually started + + TestMenu(); + break; + } + case EReporting: + { + iPendingSockets[1] = aNewSocket; +#ifdef CHANNEL_BINDING_DEBUG_CHECK + TInt err(KErrNone); + // Create the active socket reader + TRAP(err,iRepReader = CActiveSockReader::NewL(iPendingSockets[1], EReporting)); + if (err != KErrNone) + { + __LOG(_L("Creating active socket reader failed with error %d"),err); + } + else + { + iRepReader->Start(); + } + // Create the active socket writer + TRAP(err,iRepWriter = CActiveSockWriter::NewL(iPendingSockets[1], EReporting)); + if (err != KErrNone) + { + __LOG(_L("Creating active socket writer failed with error %d"),err); + } + else + { + iRepWriter->Send(); + } +#endif + } + break; + + case ERecovery: + { + iPendingSockets[2] = aNewSocket; +#ifdef CHANNEL_BINDING_DEBUG_CHECK + TInt err(KErrNone); + // Create the active socket reader + TRAP(err,iRecvReader = CActiveSockReader::NewL(iPendingSockets[2], ERecovery)); + if (err != KErrNone) + { + __LOG(_L("Creating active socket reader failed with error %d"),err); + } + else + { + iRecvReader->Start(); + } + // Create the active socket writer + TRAP(err,iRecvWriter = CActiveSockWriter::NewL(iPendingSockets[2], ERecovery)); + if (err != KErrNone) + { + __LOG(_L("Creating active socket writer failed with error %d"),err); + } + else + { + iRecvWriter->Send(); + } +#endif + } + break; + default: + __DEBUGGER(); + break; + } + } + +void CAVTestApp::PrettyPrint(TAvdtpServiceCapability& aCapability) + { + __LOG(_L("Capability = ")); + + switch (aCapability.Category()) + { + case EServiceCategoryMediaTransport: + __LOG(_L("Media Transport\n")); + break; + + case EServiceCategoryReporting: + __LOG(_L("Reporting\n")); + break; + + case EServiceCategoryRecovery: + __LOG(_L("Recovery\n")); + break; + + case EServiceCategoryContentProtection: + __LOG(_L("Content Protection: Type %d\n"), static_cast(aCapability).ContentProtectionType()); + break; + + case EServiceCategoryHeaderCompression: + __LOG(_L("Header Compression\n")); + break; + + case EServiceCategoryMultiplexing: + __LOG(_L("Multiplexing\n")); + break; + + case EServiceCategoryMediaCodec: + __LOG(_L("Media Codec\n-----------\n")); + // print name of codec + TAvdtpMediaCodecCapabilities& codecCaps = static_cast(aCapability); + switch (codecCaps.MediaType()) + { + case EAvdtpMediaTypeAudio: + __LOG(_L("Audio:")); + break; + case EAvdtpMediaTypeVideo: + __LOG(_L("Video:")); + break; + case EAvdtpMediaTypeMultimedia: + __LOG(_L("Multimedia:")); + break; + } + + if (codecCaps.MediaCodecType() == EAudioCodecSBC) + { + __LOG(_L("SBC\n")); + + TSBCCodecCapabilities& sbcCaps = static_cast(aCapability); + __LOG(_L("Sampling frequencies: ")); + if (sbcCaps.SamplingFrequencies() & E48kHz) __LOG(_L("48kHz ")); + if (sbcCaps.SamplingFrequencies() & E44100Hz) __LOG(_L("44.1kHz ")); + if (sbcCaps.SamplingFrequencies() & E32kHz) __LOG(_L("32kHz ")); + if (sbcCaps.SamplingFrequencies() & E16kHz) __LOG(_L("16kHz")); + __LOG(_L("\nChannel modes: ")); + if (sbcCaps.ChannelModes() & EMono) __LOG(_L("Mono ")); + if (sbcCaps.ChannelModes() & EStereo) __LOG(_L("Stereo ")); + if (sbcCaps.ChannelModes() & EJointStereo) __LOG(_L("JointStereo ")); + if (sbcCaps.ChannelModes() & EDualChannel) __LOG(_L("DualChannel")); + __LOG(_L("\nBlockLengths: ")); + if (sbcCaps.BlockLengths() & EBlockLenFour) __LOG(_L("4 ")); + if (sbcCaps.BlockLengths() & EBlockLenEight) __LOG(_L("8 ")); + if (sbcCaps.BlockLengths() & EBlockLenTwelve) __LOG(_L("12 ")); + if (sbcCaps.BlockLengths() & EBlockLenSixteen) __LOG(_L("16")); + __LOG(_L("\nSubbands: ")); + if (sbcCaps.Subbands() & EFourSubbands) __LOG(_L("4 ")); + if (sbcCaps.Subbands() & EEightSubbands) __LOG(_L("8")); + __LOG(_L("\nAllocation: ")); + if (sbcCaps.AllocationMethods() & ELoudness) __LOG(_L("Loudness ")); + if (sbcCaps.AllocationMethods() & ESNR) __LOG(_L("SNR")); + __LOG(_L("\nMinBitpool: %d"), sbcCaps.MinBitpoolValue()); + __LOG(_L("\nMaxBitpool: %d\n"), sbcCaps.MaxBitpoolValue()); + } + else + { + TNonSBCCodecCapabilities& nonSbcCaps = static_cast(aCapability); + TPtrC8 codecData = nonSbcCaps.CodecData(); + + switch (codecCaps.MediaCodecType()) + { + case EAudioCodecMPEG12Audio: + __LOG(_L("MPEG1,2 Audio\n")); + __LOG(_L("Manually parsing caps of length %d\n"), codecData.Length()); + __LOG(_L("Layers: ")); + if (codecData[0] & 0x80) __LOG(_L("mp1")); + if (codecData[0] & 0x40) __LOG(_L("mp2")); + if (codecData[0] & 0x20) __LOG(_L("mp3")); + __LOG(_L("\nCRC protection: ")); + codecData[0] & 0x10 ? __LOG(_L("yes")) : __LOG(_L("no")); + __LOG(_L("\nChannel modes: ")); + if (codecData[0] & 0x08) __LOG(_L("Mono ")); + if (codecData[0] & 0x04) __LOG(_L("DualChannel ")); + if (codecData[0] & 0x02) __LOG(_L("Stereo ")); + if (codecData[0] & 0x01) __LOG(_L("JointStereo")); + __LOG(_L("\nMPF: %d"), codecData[1] & 0x40 ? 1 : 0); + __LOG(_L("\nSampling frequencies: ")); + if (codecData[1] & 0x20) __LOG(_L("16kHz ")); + if (codecData[1] & 0x10) __LOG(_L("22.05kHz ")); + if (codecData[1] & 0x08) __LOG(_L("24kHz ")); + if (codecData[1] & 0x04) __LOG(_L("32kHz ")); + if (codecData[1] & 0x02) __LOG(_L("44.1kHz ")); + if (codecData[1] & 0x01) __LOG(_L("48kHz")); + __LOG(_L("\nVBR: ")); + codecData[2] & 0x80 ? __LOG(_L("yes")) : __LOG(_L("no")); + __LOG(_L("\nBit rate index: %b\n"), codecData[3]+((codecData[2] & 0x7f)<<8)); + break; + case EAudioCodecMPEG24AAC: + __LOG(_L("MPEG 2,4 AAC\n")); + __LOG(_L("Not parsing caps of length %d\n"), nonSbcCaps.CodecData().Length()); + break; + case EAudioCodecATRAC: + __LOG(_L("ATRAC\n")); + __LOG(_L("Not parsing caps of length %d\n"), nonSbcCaps.CodecData().Length()); + break; + + default: + __LOG(_L("Unknown codec, Type %d\n"), codecCaps.MediaCodecType()); + } + } + } + } + +TInt CAVTestApp::Listen() + { + TInt err = iGavdp.Listen(); + __LOG(_L("Listening (result %d)\n"), err); + return err; + } + +void CAVTestApp::StartStreams() + { + iGavdpState = EOpen; + TSEID seid; + + if (iAutoStream) + { + seid = iCurrentSEID; + } + else + { + __PRINT(_L("\n Enter remote SEID to start streaming")); + seid = TSEID(TTavsrcUtils::GetIntFromUser(iActiveConsole->Console()),EFalse); + } + + __PRINT(_L("\n")); + __LOG(_L("Starting remoteSEP %d streaming...\n"),seid.SEID()); + + iGavdp.StartStream(seid); + } + +void CAVTestApp::SuspendStreams() + { + TSEID seid; + + if (iAutoStream) + { + seid = iCurrentSEID; + } + else + { + __PRINT(_L("\n Enter remote SEID to suspend streaming")); + seid = TSEID(TTavsrcUtils::GetIntFromUser(iActiveConsole->Console()),EFalse); + } + + __PRINT(_L("\n")); + __LOG(_L("Suspending remoteSEP %d streaming...\n"),seid.SEID()); + + iGavdp.SuspendStream(seid); + iGavdpState = EOpen; + } + +TSBCCodecCapabilities CAVTestApp::InteractiveSBCMediaCodecConfig(TSBCCodecCapabilities& caps) + { + TSBCCodecCapabilities res; + + TSBCSamplingFrequencyBitmask freqs = caps.SamplingFrequencies(); + TBool resp = EFalse; + + if (freqs) + { + __PRINT(_L("\nFreqs: Remote Supports: ")); + if (freqs & E48kHz && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("48kHz Use")); + if (resp) + { + res.SetSamplingFrequencies(E48kHz); + } + } + if (freqs & E44100Hz && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n44.1kHz Use")); + if (resp) + { + res.SetSamplingFrequencies(E44100Hz); + } + } + if (freqs & E32kHz && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n32kHz Use")); + if (resp) + { + res.SetSamplingFrequencies(E32kHz); + } + } + if (freqs & E16kHz && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n16kHz Use")); + if (resp) + { + res.SetSamplingFrequencies(E16kHz); + } + } + } + + resp = EFalse; + TSBCChannelModeBitmask chmodes = caps.ChannelModes(); + if (chmodes) + { + __PRINT(_L("\nChModes: remote supports:")); + if (chmodes & EJointStereo && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nJointStereo Use")); + if (resp) + { + res.SetChannelModes(EJointStereo); + } + } + if (chmodes & EStereo && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nStereo Use")); + if (resp) + { + res.SetChannelModes(EStereo); + } + } + if (chmodes & EDualChannel && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nDual Ch Use")); + if (resp) + { + res.SetChannelModes(EDualChannel); + } + } + if (chmodes & EMono && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nMono Use")); + if (resp) + { + res.SetChannelModes(EMono); + } + } + } + + TSBCBlockLengthBitmask blockLens = caps.BlockLengths(); + resp = EFalse; + + if (blockLens) + { + __PRINT(_L("\nBlockLens: remote supports:")); + if (blockLens & EBlockLenFour && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n4 Use")); + if (resp) + { + res.SetBlockLengths(EBlockLenFour); + } + } + if (blockLens & EBlockLenEight && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n8 Use")); + if (resp) + { + res.SetBlockLengths(EBlockLenEight); + } + } + if (blockLens & EBlockLenTwelve && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n12 Use")); + if (resp) + { + res.SetBlockLengths(EBlockLenTwelve); + } + } + if (blockLens & EBlockLenSixteen && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n16 Use")); + if (resp) + { + res.SetBlockLengths(EBlockLenSixteen); + } + } + } + + resp = EFalse; + TSBCSubbandsBitmask subbands = caps.Subbands(); + if (subbands) + { + __PRINT(_L("\nSubbands: remote supports:")); + if (subbands & EFourSubbands && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n4 Use")); + if (resp) + { + res.SetSubbands(EFourSubbands); + } + } + if (subbands & EEightSubbands && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\n8 Use")); + if (resp) + { + res.SetSubbands(EEightSubbands); + } + } + } + + + resp = EFalse; + TSBCAllocationMethodBitmask allocs = caps.AllocationMethods(); + if (allocs) + { + __PRINT(_L("\nAllocation methods: remote supports:")); + if (allocs & ESNR && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nSNR Use")); + if (resp) + { + res.SetAllocationMethods(ESNR); + } + } + if (allocs & ELoudness && !resp) + { + resp=TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nLoudness Use")); + if (resp) + { + res.SetAllocationMethods(ELoudness); + } + } + } + + // cat2 test + //res.SetSamplingFrequencies(freqs); + //res.SetBlockLengths(4); + //res.SetSubbands(1); + //res.SetAllocMethods(1); + + // set bitpool to whatever they said - ok to set range - see 4.3.2.6 A2DP + res.SetMaxBitpoolValue(caps.MaxBitpoolValue()); + res.SetMinBitpoolValue(caps.MinBitpoolValue()); + + //dodgy iWish needs to select one + //res.SetMinBitpoolValue(42); + //res.SetMaxBitpoolValue(42); + + return res; + } + +TBool CAVTestApp::CurrentSEIDIsSink() + { + TBool sink = EFalse; + TUint localSEPIndex = iCurrentLocalSEID.Value(); + + //Get the current local SEP index in iLocallyRegisteredSEPs, by screening out flags + localSEPIndex &= 0x3f; + + sink = iLocallyRegisteredSEPs[localSEPIndex-1].IsSink(); + + return sink; + } + +void CAVTestApp::ConfigureSEPL() + { + TInt res; + + // user for test code gets to choose "right" local sep to connect to remote sep + TSEID localSEPtoUse(1, ETrue); // settings for iAutoStream + if (!iAutoStream) + { + __PRINT(_L("Choose local SEP to use for Stream")); + localSEPtoUse.Set(TTavsrcUtils::GetIntFromUser(iActiveConsole->Console())); // it *is* local + } + //Record the SEID of chosen local SEP + iCurrentLocalSEID = localSEPtoUse; + + TSEID remoteSEPtoUse = iCurrentSEID; // settings for iAutoStream + if (!iAutoStream) + { + __PRINT(_L("\nChoose remote SEP to use for Stream")); + remoteSEPtoUse.Set(TTavsrcUtils::GetIntFromUser(iActiveConsole->Console())); + + if (remoteSEPtoUse != iCurrentSEID) + { + __PRINT(_L("\nWARNING: Do not have the capabilities of the selected remote SEP, ")); + __PRINT(_L("\nthis may lead to sending incorrect configuration information. To")); + __PRINT(_L("\nfix this Get Capabilities for selected remote SEP first and then")); + if (!TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(), + _L("\nconfigure. \nDo you still wish to continue this configuration?"))) + { + User::Leave(KErrAbort); + } + } + } + + // we have to choose which of our seps to bind with the remote + // this test code assumes the local SEP to use has SEID 1. + // real code would have better code to fathom a good binding based on caps etc + res = iGavdp.BeginConfiguringRemoteSEP(remoteSEPtoUse, localSEPtoUse); + + __LOG(_L("Begin configuring remote SEP returned %d\n"), res); + User::LeaveIfError(res); + + for (TInt index=0; indexCategory(); + + TBool use = EFalse; + + if (cat==EServiceCategoryMediaTransport) + { + if (iAutoStream) + { + use = ETrue; + } + else + { + use = (TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nSEP Does Media Transport - use?"))); + } + if (use) + { + res = iGavdp.AddSEPCapability(*cap); + __LOG(_L("completed: %d"),res); + } + } + if (cat==EServiceCategoryReporting) + { + if (iAutoStream) + { + use = /*ETrue*/EFalse; + } + else + { + use = TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nSEP Does Reporting - use?")); + } + if (use) + { + res = iGavdp.AddSEPCapability(*cap); + __LOG(_L("completed: %d"),res); + } + } + if (cat==EServiceCategoryRecovery) + { + if (iAutoStream) + { + use = /*ETrue*/EFalse; + } + else + { + use = (TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nSEP Does Recovery - use?"))); + } + if (use) + { + res = iGavdp.AddSEPCapability(*cap); + __LOG(_L("completed: %d"),res); + } + } + + if (cat==EServiceCategoryContentProtection) + { + if (iAutoStream) + { + use = EFalse; + } + else + { + use = (TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nSEP Does Content Protection - use?"))); + } + + if (use) + { + res = iGavdp.AddSEPCapability(*cap); + __LOG(_L("completed: %d"),res); + } + } + + if (cat==EServiceCategoryMediaCodec) + { + if (iAutoStream) + { + use = ETrue; + } + else + { + use = (TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nConfigure Media Codec?"))); + } + + if (use) + { + if (static_cast(static_cast(cap)->MediaCodecType())==EAudioCodecSBC) + { + const TSBCCodecCapabilities& available = *static_cast(cap); + TSBCCodecCapabilities cfg; + + if (iAutoStream || TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(),_L("\nAutomatically Configure Media Codec?"))) + { + // we might be doing a reconfigure due to a request from the streamer + if (iLocalReconfigure) + { + cfg = iReconfigInfo; + } + else + { + // CSR board ignores the configuration + // which makes playlisting quite easy + // will need to fix this to playlist to boards that do care + TInt err, numChannels, chMode, numSubbands, blkLen, bitPool, freq, allocMethod; + err = TTavsrcUtils::GetCodecSettingsFromSBCFile(iFilename, chMode, numChannels, numSubbands, blkLen, bitPool, freq, allocMethod); + + if (err != KErrNone) + { + __LOG(_L("Problem accessing SBC file: %d\n"), err); + __LOG(_L("Warning - Codec settings not obtained\n")); + } + else + { + TSBCSubbandsBitmask subbands = numSubbands == 8 ? EEightSubbands : EFourSubbands; + TSBCAllocationMethodBitmask alloc = allocMethod == 0 ? ELoudness : ESNR; + + TSBCSamplingFrequencyBitmask freqs(0); + if (freq == 48000) freqs = E48kHz; + else if (freq == 44100) freqs = E44100Hz; // note else if now as only select one + else if (freq == 32000) freqs = E32kHz; + else if (freq == 16000) freqs = E16kHz; + + TSBCChannelModeBitmask chs(0); // set it to anything to prevent warning + if (chMode == 0) chs=EMono; + else if (chMode == 1) chs=EDualChannel; + else if (chMode == 2) chs=EStereo; + else if (chMode == 3) chs=EJointStereo; + + TSBCBlockLengthBitmask blkLens(0); // set it to anything to prevent warning + if (blkLen == 4) blkLens = EBlockLenFour; + else if (blkLen == 8) blkLens = EBlockLenEight; + else if (blkLen == 12) blkLens = EBlockLenTwelve; + else if (blkLen == 16) blkLens = EBlockLenSixteen; + + cfg.SetSamplingFrequencies(freqs); + cfg.SetChannelModes(chs); + cfg.SetBlockLengths(blkLens); + cfg.SetSubbands(subbands); + cfg.SetAllocationMethods(alloc); + + } + } + + // use the available bitpool + cfg.SetMaxBitpoolValue(available.MaxBitpoolValue()); + cfg.SetMinBitpoolValue(available.MinBitpoolValue()); + } + else if (use && !iAutoStream) + { + cfg = InteractiveSBCMediaCodecConfig(*static_cast(cap)); + } + + + res = iGavdp.AddSEPCapability(cfg); + __LOG(_L("Add SEP Capability completed: %d"),res); + } + else + { + __LOG(_L("MP3 codec, choosing fixed configuration...\n")); + // assume mp3 for now + // testing with blueant, just choose stereo, 44.1khz + TBuf8<4> mp3Cfg; + mp3Cfg.SetLength(4); + mp3Cfg[0]=0x32; + mp3Cfg[1]=0x02; + mp3Cfg[2]=0x00; + mp3Cfg[3]=0x02; + + TNonSBCCodecCapabilities mp3codecCaps(EAvdtpMediaTypeAudio,EAudioCodecMPEG12Audio); + mp3codecCaps.SetCodecData(mp3Cfg); + res = iGavdp.AddSEPCapability(mp3codecCaps); + } + } + } + }// for + + __LOG(_L("\nCommiting configuration...\n")); + iGavdp.CommitSEPConfiguration(); + } + + +TInt CAVTestApp::StartSrc() + { + TBool failed = EFalse; + + // register source/sink records in sdp + __LOG(_L("Registering A2DP Sink SDP Record")); + TRAPD(err, TTavsrcUtils::RegisterSinkSDPRecordL(iSdpDB, iSnkHandle, ETrue, ETrue, ETrue, ETrue)); + if (err != KErrNone) + { + __LOG(_L("Failed to Register A2DP Sink SDP Record: %d"), err); + __DEBUGGER(); + failed = ETrue; + } + + __LOG(_L("Registering A2DP Source SDP Record")); + TRAP(err, TTavsrcUtils::RegisterSourceSDPRecordL(iSdpDB, iSrcHandle, ETrue, ETrue, ETrue, ETrue)); + if (err != KErrNone) + { + __LOG(_L("Failed to Register A2DP Source SDP Record: %d"), err); + __DEBUGGER(); + failed = ETrue; + } + + __LOG(_L("Opening GAVDP Session")); + err = iGavdp.Open(*this, iSockServ); + if (err == KErrNone) + { + RHostResolver hostResolver; + err = hostResolver.Open( iSockServ, KBTAddrFamily, KBTLinkManager); + if (err == KErrNone) + { + err = hostResolver.SetHostName(_L("Boom Box!")); + hostResolver.Close(); + } + iActiveConsole->Console().Printf(_L("Set Host Name (ret:%d)\r\n"),err); + + iGavdpState = EIdle; + } + else + { + __LOG(_L("Failed to Open GAVDP Session: %d"), err); + __DEBUGGER(); + failed = ETrue; + } + err = RegisterSEP(); + if (err != KErrNone) + { + __LOG(_L("Failed to Register SEP: %d"), err); + __DEBUGGER(); + failed = ETrue; + } + + TRAP(err, CreateRemConInterfacesL()); + if (err != KErrNone) + { + __LOG(_L("Failed to Register RemCon interfaces: %d"), err); + __DEBUGGER(); + failed = ETrue; + } + + if(failed) + { + return KErrGeneral; + } + return KErrNone; + } + +void CAVTestApp::StopSrc() + { + // Close RBTPhysicalLinkAdapter + iPhy.Close(); + __LOG(_L("Closed iPhy\n")); + + iSdpDB.DeleteRecord(iSrcHandle); + iSdpDB.DeleteRecord(iSnkHandle); + delete iStreamer; + iStreamer = NULL; + iGavdp.Close(); + iAutoStream = EFalse; + + iGavdpState = ENoClientOpen; + + } + +void CAVTestApp::DisconnectSrc() + { + // Close RBTPhysicalLinkAdapter + iPhy.Close(); + __LOG(_L("Closed iPhy\n")); + + delete iStreamer; + iStreamer = NULL; + iGavdp.Shutdown(); + iAutoStream = EFalse; + + iGavdpState = EIdle; + Listen(); + } + +void CAVTestApp::Connect() + { + __LOG(_L("Connecting...\n")); + iGavdp.Connect(iDevAddr); + } + +void CAVTestApp::CreateBearers() + { + TInt ret = KErrNone; + TSEID seid; + + if (iAutoStream) + { + seid = iCurrentSEID; + } + else + { + __PRINT(_L("\n-> Create bearers for remote SEID")); + seid = TSEID(TTavsrcUtils::GetIntFromUser(iActiveConsole->Console()), EFalse); + } + + ret = iGavdp.CreateBearerSockets(seid); + __LOG(_L("Asking for Bearers..(sync_result) %d.\n"), ret); + } + +void CAVTestApp::CloseBearers() + { + __LOG(_L("Closing Bearer 0 (via Streamer dtor)...\n\r")); + + delete iStreamer; + iStreamer = NULL; + + __LOG(_L("Bearer closed (via Streamer dtor)...\n\r")); + + AllowLowPowerModes(); + } + +void CAVTestApp::DiscoverSEPs() + { + __LOG(_L("Sending SEP Discovery...\n\r")); + + iGavdp.DiscoverRemoteSEPs(); + } + +CAVTestApp::CAVTestApp() + { + } + +CAVTestApp::~CAVTestApp() + { + StopSrc(); + delete iActiveConsole; + delete iLogConsole; + delete iMtUpdater; + delete iTavsrcAbsoluteVolume; + delete iStreamer; + delete iRemConInterfaceSelector; + delete iController; + delete iPacketDropIoctl; + delete iOperations; + +#ifdef CHANNEL_BINDING_DEBUG_CHECK + delete iRepReader; + delete iRepWriter; + delete iRecvReader; + delete iRecvWriter; +#endif + + iFilename.Close(); + iLocallyRegisteredSEPs.Close(); + iSockServ.Close(); + iSdpDB.Close(); + iSdp.Close(); + iSEPCapabilities.ResetAndDestroy(); + iShortlistedSEIDs.Close(); + } + +CAVTestApp* CAVTestApp::NewL() + { + CAVTestApp* thisapp = new (ELeave) CAVTestApp; + CleanupStack::PushL(thisapp); + thisapp->ConstructL(); + CleanupStack::Pop(); + return thisapp; + } + +void CAVTestApp::ConstructL() + { + iLogConsole = CActiveConsole::NewL(*this,_L("Event Log"),KLogConsole); + iActiveConsole = CActiveConsole::NewL(*this,_L(" Boom Box "),KMainConsole); + + User::LeaveIfError(iSockServ.Connect()); + } + +void CAVTestApp::CreateRemConInterfacesL() + { + iRemConInterfaceSelector = CRemConInterfaceSelector::NewL(); + + RArray coreFeatures; + for(TInt i = 0; i<0x76; i++) + { + coreFeatures.Append(static_cast(i)); + } + + if(iRemConInterfaces & ECoreApiTarget) + { + iRemConTarget = CRemConCoreApiTarget::NewL(*iRemConInterfaceSelector, *this, coreFeatures); + } + coreFeatures.Close(); + + if(iRemConInterfaces & EGroupNavigation) + { + iGroupNavigation = CRemConGroupNavigationApiTarget::NewL(*iRemConInterfaceSelector, *this, ETrue, ETrue); + } + + if(iRemConInterfaces & EMediaInformation) + { + iMediaInformation = CRemConMediaInformationTarget::NewL(*iRemConInterfaceSelector, *this); + } + + if(iRemConInterfaces & EBatteryStatus) + { + iBatteryStatus = CRemConBatteryApiTarget::NewL(*iRemConInterfaceSelector, *this); + } + + if(iRemConInterfaces & (EAbsoluteVolumeTarget | EAbsoluteVolumeController)) + { + iTavsrcAbsoluteVolume = CTavsrcAbsoluteVolume::NewL(*iRemConInterfaceSelector); + } + + if(iRemConInterfaces & EVendorTrackInfoTarget) + { + iTrackInfo = CRemConTrackInfoTarget::NewL(*iRemConInterfaceSelector, *this); + } + + if(iRemConInterfaces & (EPlayerInformation | ENowPlaying | EMediaBrowse )) + { + iMtUpdater = CTavsrcMtUpdater::NewL(*iRemConInterfaceSelector, iRemConInterfaces); + } + + if(iRemConInterfaces & EVendorAbsoluteVolumeTarget) + { + iAbsoluteVolume = CRemConAbsVolTarget::NewL(*iRemConInterfaceSelector, *this); + } + + iController = CTavsrcController::NewL(*iRemConInterfaceSelector, *iLogConsole); + + _LIT8(KTavsrcName, "Tavsrc"); + iRemConInterfaceSelector->OpenTargetL(ERemConAudioPlayer, ERemConNoSubType, KTavsrcName); + + iRemConInterfaceSelector->OpenControllerL(); + iOperations = CTavsrcOperations::NewL(); + } + +void CAVTestApp::DisplayHelp() + { + __LOG(_L("\nUsage: tavsrc [-A ] [-D ] [-P] [-H]\n")); + __LOG(_L("\n-A : Optional argument to specify remote\n")); + __LOG(_L("Bluetooth address. If not specified then you will be prompted\n")); + __LOG(_L("using notifiers.\n")); + __LOG(_L("\n-D : Optional argument to specify the display mode\n")); + __LOG(_L("to use. The possible values are a logical AND of the following:\n")); + __LOG(_L(" 0x00: Status and Command windows only\n")); + __LOG(_L(" 0x01: Streamer Info window\n")); + __LOG(_L(" 0x02: Progress Bar window\n")); + __LOG(_L(" 0x04: Playlist window\n")); + __LOG(_L(" 0x08: Chunky Icon window\n")); + __LOG(_L("For example, for all the windows except the Progress Bar: -D d\n")); + __LOG(_L("Default value is 1 - Status, Command and Streamer Info windows\n")); + __LOG(_L("\n-P: Preload SBC file before streaming.\n")); + __LOG(_L("\n-H: Display this help information.\n")); + __LOG(_L("\n-R : Optional argument to specify what interfaces to use:\n")); + __LOG(_L(" ECoreApiTarget = 1 << 0\n")); + __LOG(_L(" ECoreApiController = 1 << 1\n")); + __LOG(_L(" EGroupNavigation = 1 << 2\n")); + __LOG(_L(" EMediaInformation = 1 << 3\n")); + __LOG(_L(" EBatteryStatus = 1 << 4\n")); + __LOG(_L(" EAbsoluteVolumeTarget = 1 << 5\n")); + __LOG(_L(" EAbsoluteVolumeController = 1 << 6\n")); + __LOG(_L(" EPlayerInformation = 1 << 7\n")); + __LOG(_L(" ENowPlaying = 1 << 8\n")); + __LOG(_L(" EMediaBrowse = 1 << 9\n")); + __LOG(_L(" EDatabaseAware = 1 << 10\n")); + __LOG(_L(" ESeparateThreadForBrowse = 1 << 11\n")); + __LOG(_L(" EVendorTrackInfoTarget = 1 << 12\n")); + __LOG(_L(" EVendorAbsoluteVolumeTarget = 1 << 13\n")); + } + +void CAVTestApp::ParseCommandLineL() + { + CCommandLineArguments *cmdLine = CCommandLineArguments::NewL(); + CleanupStack::PushL(cmdLine); + + // set defaults + iDisplayMode = 0x01; + iPreloadFile = EFalse; + + TBool btAddrFound = EFalse; + TBool remConInterfacesFound = EFalse; + TBuf<20> arg; + for (TInt argIndex = 1; argIndex < cmdLine->Count(); argIndex++) + { + arg = cmdLine->Arg(argIndex); + arg.UpperCase(); + + // look for help + if (arg.FindF(_L("-H")) != KErrNotFound) + { + DisplayHelp(); + User::Leave(KErrArgument); + } + + // look for preload file + if (arg.FindF(_L("-P")) != KErrNotFound) + { + iPreloadFile = ETrue; + continue; + } + + // look for remote device address + if (arg.FindF(_L("-A")) != KErrNotFound) + { + if (argIndex != cmdLine->Count() - 1) + { + btAddrFound = ETrue; + iDevAddr.SetReadable(cmdLine->Arg(++argIndex)); + continue; + } + else + { + __LOG(_L("No address found for -A option\n")); + DisplayHelp(); + User::Leave(KErrArgument); + } + } + + // look for display mode + if (arg.FindF(_L("-D")) != KErrNotFound) + { + if(argIndex != cmdLine->Count() - 1) + { + TLex lex(cmdLine->Arg(++argIndex)); + lex.Val(iDisplayMode, EHex); + continue; + } + else + { + __LOG(_L("No display mode found for -D option\n")); + DisplayHelp(); + User::Leave(KErrArgument); + } + } + + // look for remcon interfaces + if (arg.FindF(_L("-R")) != KErrNotFound) + { + if(argIndex != cmdLine->Count() - 1) + { + TLex lex(cmdLine->Arg(++argIndex)); + TInt err = lex.Val(iRemConInterfaces, EHex); + if(!err) + { + remConInterfacesFound = ETrue; + } + else + { + __LOG(_L("Badly formatted interface bitmask\n")); + } + continue; + } + else + { + __LOG(_L("No remconinterfaces found for -R option\n")); + DisplayHelp(); + User::Leave(KErrArgument); + } + } + + // if we got here it means that we have an unhandled argument + __LOG(_L("Unrecognised argument\n")); + DisplayHelp(); + User::Leave(KErrArgument); + } + CleanupStack::PopAndDestroy(); // cmdLine + + if (!btAddrFound) + { + __LOG(_L("No address found on command line - please enter an address\n")); + TTavsrcUtils::GetDeviceAddressL(iDevAddr); + } + + if(!remConInterfacesFound) + { + __LOG(_L("No interfaces found on command line, defaulting to all interfaces\n")); + iRemConInterfaces = 0xFFFFFFFF; + } + } + +void CAVTestApp::StartL() + { + // connect to sdp + __LOG(_L("Connecting to ESOCK\n")); + User::LeaveIfError(iSockServ.Connect()); + __LOG(_L("Connecting to SDP Server\n")); + + __LOG(_L("Connecting to SDP Server\n")); + User::LeaveIfError(iSdp.Connect()); + __LOG(_L("Opening subsession on SDP Server\n")); + + __LOG(_L("Opening subsession on SDP Server\n")); + User::LeaveIfError(iSdpDB.Open(iSdp)); + TBuf<512> cmdline; + + // ensure that we have something to stream + RFs fs; + CDir* files; + User::LeaveIfError(fs.Connect()); + + TInt err = fs.GetDir(KSBCFiles, KEntryAttNormal, ESortByName, files); + + fs.Close(); + + if (err != KErrNone) + { + __LOG(_L("Error getting files %S: %d \n"), &KSBCFiles, err); + User::Leave(err); + } + + if (files->Count() > 0) + { + // store the filename for registering the SEP later + iFilename.Create(KMaxFileName); + iFilename.Append(KSBCFileRoot); + iFilename.Append(files->operator[](0).iName); + delete files; + } + else + { + __LOG(_L("\nNo files matching %S found, at least one is required,\n"), &KSBCFiles); + __LOG(_L("please add files and restart the application\n")); + delete files; + User::Leave(KErrNotFound); + } + + TRAP(err, ParseCommandLineL()); + if (err != KErrNone) + { + iActiveConsole->Console().ClearScreen(); + iActiveConsole->Console().Printf(_L("\nProblem with Command Line arguments, see status window for")); + iActiveConsole->Console().Printf(_L("\nmore information or press ESC to exit.\n")); + iActiveConsole->RequestKey(); + } + else + { + err = StartSrc(); + if(err == KErrNone) + { + TestMenu(); + } + else + { + iActiveConsole->Console().ClearScreen(); + iActiveConsole->Console().Printf(_L("\nProblem starting source, see status window for")); + iActiveConsole->Console().Printf(_L("\nmore information or press ESC to exit.\n")); + iActiveConsole->RequestKey(); + } + } + CActiveScheduler::Start(); + } + +void CAVTestApp::Stop() + { + CActiveScheduler::Stop(); + } + +//remcon + void CAVTestApp::MrccatoCommand(TRemConCoreApiOperationId aOperationId, + TRemConCoreApiButtonAction aButtonAct) + { + __LOG(_L("RemCon::Command received 0x%02x\t Button Act %d\n"), aOperationId, aButtonAct); + if((aOperationId == ERemConCoreApiStop) && + (aButtonAct == ERemConCoreApiButtonClick || aButtonAct == ERemConCoreApiButtonPress) ) + { + __LOG(_L("RemCon::Stop received\n")); + iAutoStream = EFalse; + if (iStreamer) + { + iStreamer->Stop(); + } + iStreamState = EStopped; + iOperations->EndOperation(KTavsrcOpStopStream, KErrNone); + } + else if (((aOperationId == ERemConCoreApiBackward) || (aOperationId == ERemConCoreApiRewind)) && iStreamer) + { + if (aButtonAct == ERemConCoreApiButtonClick) + { + iStreamer->PrevTrack(); + } + else if ((aButtonAct == ERemConCoreApiButtonPress) && (iStreamState == EStreaming)) + { + iStreamer->Backward(); + iStreamer->Faster(); + } + else if ((aButtonAct == ERemConCoreApiButtonRelease) && (iStreamState == EStreaming)) + { + iStreamer->Forward(); + iStreamer->Slower(); + } + } + else if (((aOperationId == ERemConCoreApiForward) || (aOperationId == ERemConCoreApiFastForward)) && iStreamer) + { + if (aButtonAct == ERemConCoreApiButtonClick) + { + iStreamer->NextTrack(); + } + else if ((aButtonAct == ERemConCoreApiButtonPress) && (iStreamState == EStreaming)) + { + iStreamer->Faster(); + } + else if ((aButtonAct == ERemConCoreApiButtonRelease) && (iStreamState == EStreaming)) + { + iStreamer->Slower(); + } + } + else if ((aOperationId == ERemConCoreApiPause) && (aButtonAct != ERemConCoreApiButtonRelease)) + { + TInt operation = KTavsrcOpStream; + + if (iStreamState == EStreaming) + { + // this demo app doesn't suspend GAVDP, just the streamer + if (iStreamer) + { + iStreamer->Suspend(); + } + iStreamState = EPaused; + operation = KTavsrcOpStopStream; + } + iOperations->EndOperation(operation, KErrNone); + } + + if (iStreamState == EStreaming) + { + PreventLowPowerModes(); + } + + TestMenu(); + } + + void CAVTestApp::MrccatoPlay(TRemConCoreApiPlaybackSpeed /*aSpeed*/, + TRemConCoreApiButtonAction aButtonAct) + { + __LOG(_L("RemCon::Play received\t Button Act %d\n"), aButtonAct); + if((aButtonAct == ERemConCoreApiButtonClick || aButtonAct == ERemConCoreApiButtonPress)) + { + TInt operation = KTavsrcOpStream; + + // kick everything off + if (iGavdpState == ESigConnected) + { + // auto + iAutoStream = ETrue; + // kick off + DiscoverSEPs(); + } + else if (iGavdpState == ESuspended) + { + if (iStreamer) + iStreamer->ReStream(); + iStreamState = EStreaming; + } + else if (iGavdpState == EOpen) + { + if (iStreamState == EPaused) + { + // this demo app doesn't unsuspend GAVDP, just the streamer + if (iStreamer) + iStreamer->ReStream(); + iStreamState = EStreaming; + } + else if (iStreamState == EStopped) + { + // this demo app doesn't unsuspend GAVDP, just the streamer + if (iStreamer) + iStreamer->Stream(CurrentSEIDIsSink()); //could be source or sink + iStreamState = EStreaming; + } + else if (iStreamState == EClosed) + { + if (iStreamer) + iStreamer->Stream(CurrentSEIDIsSink()); + iStreamState = EStreaming; + } + } + iOperations->EndOperation(operation, KErrNone); + + if (iStreamState == EStreaming) + { + PreventLowPowerModes(); + } + + TestMenu(); + } + } + +void CAVTestApp::MediaCodecConfigurationRequired(TSBCCodecCapabilities& aConfig) + { + if (!iLocalReconfigure) + { + // set the reconfigure information + iReconfigInfo = aConfig; + iLocalReconfigure = ETrue; + + // start streaming automatically after the reconfigure + iAutoStream = ETrue; + + SuspendStreams(); + } + } + +void CAVTestApp::PrintCommandOption(TChar aOperation, TPtrC aDesc) + { + if (iOperations->IsOperationAllowed(aOperation)) + { + iActiveConsole->Console().Printf(_L("%c%s"), aOperation.IsUpper() ? aOperation.GetUpperCase() : aOperation.GetLowerCase(), aDesc.Ptr()); + } + else + { + iActiveConsole->Console().Printf(_L(" %s"), aDesc.Ptr()); + } + } + +// from MRemConMediaInformationTargetObserver +void CAVTestApp::MrcmitoGetCurrentlyPlayingMetadata( TMediaAttributeIter& aAttributeIter ) + { + iActiveConsole->Console().Printf(_L("Got MrcpitoGetElementAttributes \n") ); + + // Make sure total of these defines is greater than KAVCMaxFrame (512 bytes) + // to ensure that fragmentation is performed on this response + _LIT8(KMediaTitle, "Frederic Chopin (1810-1849): Ballade for Piano #1 in A flat major, Opus 23, CT 2 - Largo allegretto, Moderato con brio vivace, Presto con fuoco"); + _LIT8(KArtistName, "Maurizio Pollini and the London Philharmonic Orchestra, conducted by Sir Colin Davis, recorded live at the Royal Albert Hall at the 1987 Proms season"); + _LIT8(KAlbumName, "Frederic Chopin (1810-1849): Four Ballades, Two Preludes, the Valse in D-flat major - Op. 64 No. 1 and the Andante Spianato & Grand Polonaise Brillante Op. 22"); + _LIT8(KTrackNumber, "10345"); + _LIT8(KNumberOfTracks, "6876436456"); + _LIT8(KGenre, "Alternative super cool Classical Music with a lemon twist and a hint of progressive rock"); + _LIT8(KPlayingTime, "150000"); + + TBuf8<255> buffer; + + // for each element requested + TMediaAttributeId id; + while (aAttributeIter.Next(id)) + { + switch(id) + { + case ETitleOfMedia: + buffer.Copy(KMediaTitle); + break; + case ENameOfArtist: + buffer.Copy(KArtistName); + break; + case ENameOfAlbum: + buffer.Copy(KAlbumName); + break; + case ETrackNumber: + buffer.Copy(KTrackNumber); + break; + case ENumberOfTracks: + buffer.Copy(KNumberOfTracks); + break; + case EGenre: + buffer.Copy(KGenre); + break; + case EPlayingTime: + buffer.Copy(KPlayingTime); + break; + default: + __DEBUGGER(); + break; + } + + // return the element value + iMediaInformation->AttributeValue( id, buffer ); + + // convert the element value to unicode for display + TBuf16<255> buf16; + buf16.Copy(buffer); + buf16.ZeroTerminate(); + iActiveConsole->Console().Printf(_L("Element:%d value:%s \n"), id, buf16.Ptr() ); + } + + // send response complete + iMediaInformation->Completed(); + + } + + +TInt CAVTestApp::MrcmtcGetElementAttributes(TUint64 /* aElement */, TUint32 aAttribute, HBufC8*& aOutValueOwnershipTransferred) + { +// +// __DEBUGGER(); //try this out + iActiveConsole->Console().Printf(_L("Got GEA, attrib %d!\n"), aAttribute); + + aOutValueOwnershipTransferred = HBufC8::New(20); + if (aOutValueOwnershipTransferred) + { + aOutValueOwnershipTransferred->Des() = _L8("Hello"); + } + + return KErrNone; + } + +void CAVTestApp::MrcncRegisterPlaybackStatusChangedNotification() + { + iActiveConsole->Console().Printf(_L("Queued notify: PlayStatusChanged!\n")); + } + +void CAVTestApp::MrcncRegisterTrackChangedNotification() + { + iActiveConsole->Console().Printf(_L("Queued notify: TrackChanged!\n")); + } + +void CAVTestApp::MrcncRegisterTrackReachedEndNotification() + { + iActiveConsole->Console().Printf(_L("Queued notify: TrackReachedEnd!\n")); + } + +void CAVTestApp::MrcncRegisterTrackReachedStartNotification() + { + iActiveConsole->Console().Printf(_L("Queued notify: TrackReachedStart!\n")); + } + +void CAVTestApp::MrcncRegisterPositionChangedNotification(TUint32 aInterval) + { + iActiveConsole->Console().Printf(_L("Queued notify: PositionChanged (0x%08x)!\n"), aInterval); + } + +void CAVTestApp::MrcncRegisterBatteryStatusChangedNotification() + { + iActiveConsole->Console().Printf(_L("Queued notify: BatteryStatusChanged!\n")); + } + +void CAVTestApp::MrcncRegisterSystemStatusChangedNotification() + { + iActiveConsole->Console().Printf(_L("Queued notify: SystemStatusChanged!\n")); + } + +void CAVTestApp::MrcncRegisterPlayerApplicationStatusChangedNotification() + { + iActiveConsole->Console().Printf(_L("Queued notify: PlayerAppStatusChanged!\n")); + } + +void CAVTestApp::MrcbstoBatteryStatus(TControllerBatteryStatus& aBatteryStatus ) + { + switch(aBatteryStatus) + { + case ENormal: + iActiveConsole->Console().Printf(_L("Battery status: Normal \n")); + break; + case EWarning: + iActiveConsole->Console().Printf(_L("Battery status: Warning \n")); + break; + case ECritical: + iActiveConsole->Console().Printf(_L("Battery status: Critical \n")); + break; + case EExternal: + iActiveConsole->Console().Printf(_L("Battery status: External \n")); + break; + case EFullCharge: + iActiveConsole->Console().Printf(_L("Battery status: FullCharge \n")); + break; + default: + iActiveConsole->Console().Printf(_L("Battery status: %d \n"), aBatteryStatus); + break; + } + } + +void CAVTestApp::MrcgntoNextGroup(TRemConCoreApiButtonAction aButtonAct ) + { + switch(aButtonAct) + { + case ERemConCoreApiButtonPress: + iActiveConsole->Console().Printf(_L("Got NextGroup! Button Press \n")); + break; + case ERemConCoreApiButtonRelease: + iActiveConsole->Console().Printf(_L("Got NextGroup! Button Release \n")); + break; + case ERemConCoreApiButtonClick: + iActiveConsole->Console().Printf(_L("Got NextGroup! Button Click \n")); + break; + default: + iActiveConsole->Console().Printf(_L("Got NextGroup! Button ??? \n")); + break; + } + + // for testing return an error + TRequestStatus status; + TRequestStatus* ptrStatus = &status; + iGroupNavigation->NextGroupResponse( ptrStatus, KErrNone); + User::WaitForRequest(status); + + } + +void CAVTestApp::MrcgntoPreviousGroup(TRemConCoreApiButtonAction aButtonAct ) + { + switch(aButtonAct) + { + case ERemConCoreApiButtonPress: + iActiveConsole->Console().Printf(_L("Got PreviousGroup! Button Press \n")); + break; + case ERemConCoreApiButtonRelease: + iActiveConsole->Console().Printf(_L("Got PreviousGroup! Button Release \n")); + break; + case ERemConCoreApiButtonClick: + iActiveConsole->Console().Printf(_L("Got PreviousGroup! Button Click \n")); + break; + default: + iActiveConsole->Console().Printf(_L("Got PreviousGroup! Button ??? \n")); + break; + } + + // return success + TRequestStatus status; + TRequestStatus* ptrStatus = &status; + iGroupNavigation->PreviousGroupResponse( ptrStatus, KErrNone ); + User::WaitForRequest(status); + } + +void CAVTestApp::MrcavtoGetAbsoluteVolume() + { + TRequestStatus status; + iAbsoluteVolume->GetAbsoluteVolumeResponse(status, 1, 2, KErrNone); + User::WaitForRequest(status); + } + +void CAVTestApp::MrcavtoSetAbsoluteVolume(TUint /*aAbsVol*/, TUint /*aMaxVol*/) + { + TRequestStatus status; + iAbsoluteVolume->SetAbsoluteVolumeResponse(status, KErrNone); + User::WaitForRequest(status); + } + +void CAVTestApp::MrctitoGetTrackName() + { + TRequestStatus status; + _LIT(KTrackName, "trackname"); + iTrackInfo->GetTrackNameResponse(status, KTrackName, KErrNone); + User::WaitForRequest(status); + } + +void CAVTestApp::MrctitoGetArtist() + { + TRequestStatus status; + _LIT(KArtist, "artist"); + iTrackInfo->GetArtistResponse(status, KArtist, KErrNone); + User::WaitForRequest(status); + } + +void CAVTestApp::MrctitoGetTrackDuration() + { + TRequestStatus status; + _LIT(KTrackDuration, "0.2.56"); + TTime trackDuration(KTrackDuration); + iTrackInfo->GetTrackDurationResponse(status, trackDuration, KErrNone); + User::WaitForRequest(status); + } + +_LIT(KOn, "On"); +_LIT(KOff, "Off"); + +void CAVTestApp::TestMenu() + { + iActiveConsole->Console().ClearScreen(); + + iActiveConsole->Console().Printf(_L("Safe Mode: %S\n"), iOperations->SafeMode() ? &KOn() : &KOff()); + + if (iGavdpState!=EIdle) + { + iActiveConsole->Console().Printf(_L("Connected \n\r")); + } + else + { + iActiveConsole->Console().Printf(_L(" \n\r")); + } + + RProperty property; + TBuf8<6> addr; + + TInt err = property.Get(KPropertyUidBluetoothCategory, + KPropertyKeyBluetoothGetLocalDeviceAddress, addr); + + if ((err) || (addr.Length()!=6)) + { + iActiveConsole->Console().Printf(_L("P&S: ERROR retrieving local address\n")); + } + else + { + TBTDevAddr localAddress(addr); + TBuf<20> dispBuf; + localAddress.GetReadable(dispBuf); + TBuf<20> rBuf; + iDevAddr.GetReadable(rBuf); + iActiveConsole->Console().Printf(_L("Local address = 0x%S; Using Remote Addr = 0x%S\n"),&dispBuf,&rBuf); + } + + iActiveConsole->Console().Printf(_L("\n")); + + switch (iGavdpState) + { + case ENoClientOpen: + PrintCommandOption(KTavsrcOpStartSrc, _L(". Open GAVDP for Src\n")); + break; + case EIdle: + PrintCommandOption(KTavsrcOpConnect, _L(". Connect\n")); + PrintCommandOption(KTavsrcOpCancel, _L(". Cancel\n")); + PrintCommandOption(KTavsrcOpRegisterSEP, _L(". Register SEP\n")); + break; + case ESigConnected: + case EOpen: + case ESuspended: + case ERemoteReconfiguring: + PrintCommandOption(KTavsrcOpAutoStream, _L(". Auto Stream\n")); + PrintCommandOption(KTavsrcOpDiscoverSEPs, _L(". Discover remote SEPs ")); + PrintCommandOption(KTavsrcOpCreateBearers, _L(". Create Bearers\n")); + + PrintCommandOption(KTavsrcOpGetCapabilities, _L(". Get Remote SEP Capabilites ")); + PrintCommandOption(KTavsrcOpCloseBearers, _L(". Close Bearers\n")); + + PrintCommandOption(KTavsrcOpStartStreams, _L(". Start Stream ")); + PrintCommandOption(KTavsrcOpSuspendStreams, _L(". Suspend Stream\n")); + + PrintCommandOption(KTavsrcOpContentProtection, _L(". Content Protection ")); + PrintCommandOption(KTavsrcOpAbort, _L(". Abort Stream\n")); + + PrintCommandOption(KTavsrcOpConfigureSEP, _L(". Select Remote SEP (configure the doofer)\n")); + + PrintCommandOption(KTavsrcOpStream, _L(". Start Streamer ")); + PrintCommandOption(KTavsrcOpStopStream, _L(". Stop Streamer\n\n")); + + PrintCommandOption(KTavsrcOpPacketDropIoctl, _L(". Send \"Notify Media Packet Dropped\" IOCTL\n\n")); + + PrintCommandOption(KTavsrcOpDisconnectSrc, _L(". Disconnect GAVDP - don't close\n")); + PrintCommandOption(KTavsrcOpStopSrc, _L(". Close GAVDP\n")); + break; + } + + iActiveConsole->Console().Printf(_L("\n")); + + PrintCommandOption(KTavsrcOpPlay, _L(". AVRCP Play ")); + PrintCommandOption(KTavsrcOpStop, _L(". AVRCP Stop\n")); + + iActiveConsole->Console().Printf(_L("Up. AVRCP Volume Up ")); + iActiveConsole->Console().Printf(_L("Down. AVRCP Volume Down\n")); + + iActiveConsole->Console().Printf(_L("Left. AVRCP Backwards ")); + iActiveConsole->Console().Printf(_L("Right. AVRCP Forwards\n")); + + iActiveConsole->Console().Printf(_L("\n")); + + PrintCommandOption(KTavsrcOpToggleSafeMode, _L(".\tToggle Safe Mode\n")); + iActiveConsole->Console().Printf(_L("Esc.\tStop\n")); + + if (!iActiveConsole->IsActive()) + { + iActiveConsole->RequestKey(); + } + } + +void CAVTestApp::KeyPressed(TChar aKey) + { + TInt beginOperation = iOperations->BeginOperation(aKey); + + if (beginOperation == KErrNone) + { + switch (aKey) + { + case KTavsrcOpConnect: + { + Connect(); + break; + } + case KTavsrcOpCancel: + { + iOperations->EndOperation(KTavsrcOpCancel, KErrCancel); + + iGavdp.Cancel(); + __LOG(_L("Current Request Cancelled \n")); + break; + } + case KTavsrcOpDiscoverSEPs: + { + DiscoverSEPs(); + break; + } + case KTavsrcOpCreateBearers: + { + CreateBearers(); + break; + } + case KTavsrcOpCloseBearers: + { + iOperations->EndOperation(KTavsrcOpCloseBearers, KErrNone); + + CloseBearers(); + break; + } + case KTavsrcOpContentProtection: + { + SendSecurityControl(); + break; + } + case KTavsrcOpGetCapabilities: + { + GetCapabilities(); + break; + } + case KTavsrcOpStartStreams: + { + StartStreams(); + break; + } + case KTavsrcOpSuspendStreams: + { + SuspendStreams(); + break; + } + case KTavsrcOpEchoStorm: + { + iOperations->EndOperation(KTavsrcOpEchoStorm, KErrNone); + + EchoStorm(); + break; + } + case KTavsrcOpAbort: + { + Abort(); + break; + } + case KTavsrcOpStream: + { + iOperations->EndOperation(KTavsrcOpStream, KErrNone); + + iStreamer->Stream(CurrentSEIDIsSink()); + iStreamState = EStreaming; + } + break; + case KTavsrcOpStreamFaster: + { + iOperations->EndOperation(KTavsrcOpStreamFaster, KErrNone); + + iStreamer->Faster(); + break; + } + + case KTavsrcOpStreamSlower: + { + iOperations->EndOperation(KTavsrcOpStreamSlower, KErrNone); + + iStreamer->Slower(); + break; + } + + case KTavsrcOpAutoStream: + { + // auto + iAutoStream = ETrue; + // kick off + DiscoverSEPs(); + } + break; + + case KTavsrcOpStopStream: + { + iOperations->EndOperation(KTavsrcOpStopStream, KErrNone); + + __LOG(_L("Stopping streaming... \n")); + iStreamState = EPaused; + iStreamer->Suspend(); + } + break; + case KTavsrcOpRegisterSEP: + { + iOperations->EndOperation(KTavsrcOpRegisterSEP, KErrNone); + + RegisterSEP(); + break; + } + case KTavsrcOpRegisterMultipleSEPs: + { + iOperations->EndOperation(KTavsrcOpRegisterMultipleSEPs, KErrNone); + + for (TInt i=0; i<=40; i++) + { + TAvdtpSEPInfo info; iGavdp.RegisterSEP(info); + } + break; + } + case KTavsrcOpStartSrc: + { + iOperations->EndOperation(KTavsrcOpStartSrc, KErrNone); + + //reopen GAVDP + StartSrc(); + break; + } + + case KTavsrcOpStopSrc: + { + iOperations->EndOperation(KTavsrcOpStopSrc, KErrNone); + + StopSrc(); + break; + } + case KTavsrcOpDisconnectSrc: + { + iOperations->EndOperation(KTavsrcOpDisconnectSrc, KErrNone); + + DisconnectSrc(); + break; + } + case KTavsrcOpConfigureSEP: + { + TRAPD(err, ConfigureSEPL()); + if (err != KErrNone) + { + iOperations->EndOperation(KTavsrcOpConfigureSEP, err); + } + break; + } + + case KTavsrcOpPacketDropIoctl: + { + iOperations->EndOperation(KTavsrcOpPacketDropIoctl, KErrNone); + + __LOG(_L("Sending packet drop IOCTL\n")); + iPacketDropIoctl = CActivePacketDropIoctl::NewL(iLogConsole, iPendingSockets);//Qualified + iPacketDropIoctl->Start(); + break; + } + + case KTavsrcOpVolumeUp: + { + iOperations->EndOperation(KTavsrcOpVolumeUp, KErrNone); + + iController->Command(ERemConCoreApiVolumeUp); + break; + } + + case KTavsrcOpVolumeDown: + { + iOperations->EndOperation(KTavsrcOpVolumeDown, KErrNone); + + iController->Command(ERemConCoreApiVolumeDown); + break; + } + + case KTavsrcOpBackwards: + { + iOperations->EndOperation(KTavsrcOpBackwards, KErrNone); + + iController->Command(ERemConCoreApiBackward); + break; + } + + case KTavsrcOpForwards: + { + iOperations->EndOperation(KTavsrcOpForwards, KErrNone); + + iController->Command(ERemConCoreApiForward); + break; + } + + case KTavsrcOpPlay: + { + iOperations->EndOperation(KTavsrcOpPlay, KErrNone); + + iController->Command(ERemConCoreApiPlay); + break; + } + + case KTavsrcOpStop: + { + iOperations->EndOperation(KTavsrcOpStop, KErrNone); + + iController->Command(ERemConCoreApiStop); + break; + } + + case KTavsrcOpExit: + { + iOperations->EndOperation(KTavsrcOpExit, KErrNone); + + Stop(); + return; + } + + case KTavsrcOpToggleSafeMode: + { + iOperations->EndOperation(KTavsrcOpToggleSafeMode, KErrNone); + + iOperations->SetSafeMode(!iOperations->SafeMode()); + break; + } + + default: + iActiveConsole->Console().Printf(_L("Unknown command\r\n")); + } + } + else + { + __LOG(_L("Operation not allowed: %d\r\n"), beginOperation); + } + + TestMenu(); + + } + +TInt CAVTestApp::RegisterSEP() + { + TInt err; + + TAvdtpSEPInfo info; + info.SetIsSink(TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(), _L("Sink "))); + info.SetMediaType(TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(), _L("Audio ")) ? + EAvdtpMediaTypeAudio : + EAvdtpMediaTypeVideo); + err = iGavdp.RegisterSEP(info); + + if (err==KErrNone) + { + iLocallyRegisteredSEPs.Append(info); + } + __LOG(_L("Registering SEP [SEID %d] - completed with error %d\n"), info.SEID().SEID(), err); + + if (err==KErrNone) + { + iCurrentLocalSEID = info.SEID(); + + // add some caps, not to all though for testing! + err = iGavdp.BeginConfiguringLocalSEP(info.SEID()); + + __LOG(_L("Begin config Local SEP [SEID %d] - completed with error %d\n"), info.SEID().SEID(), err); + + TAvdtpMediaTransportCapabilities media; + err = iGavdp.AddSEPCapability(media); + __LOG(_L("Add configuration [Category %d] - completed with error %d\n"), media.Category(), err); +/* + TAvdtpReportingCapabilities rep; + err = iGavdp.AddSEPCapability(rep); + __LOG(_L("Add configuration [Category %d] - completed with error %d\n"), rep.Category(), err); + + TAvdtpRecoveryCapabilities rec; + rec.SetRecoveryType(ERFC2733Recovery); + rec.SetMaxWindowSize(5); + rec.SetMinWindowSize(1); + err = iGavdp.AddSEPCapability(rec); + __LOG(_L("Add configuration [Category %d] - completed with error %d\n"), rec.Category(), err); + + TAvdtpContentProtectionCapabilities cp; + cp.SetContentProtectionType(0x1234); + cp.SetContentProtectionData(_L8("A test content protection method")); + err = iGavdp.AddSEPCapability(cp); + */ + if(TTavsrcUtils::GetYNFromUser(iActiveConsole->Console(), _L("SBC "))) + { + TSBCCodecCapabilities sbc; + sbc.SetSamplingFrequencies(E48kHz|E44100Hz|E32kHz|E16kHz); + sbc.SetBlockLengths(EBlockLenFour | EBlockLenEight | EBlockLenTwelve | EBlockLenSixteen); + sbc.SetMinBitpoolValue(2); + sbc.SetMaxBitpoolValue(250); + sbc.SetChannelModes(EJointStereo | EStereo | EMono | EDualChannel); + sbc.SetSubbands(EFourSubbands|EEightSubbands); + sbc.SetAllocationMethods(ELoudness | ESNR); + + // crazy stuff testing + /* + sbc.SetSamplingFrequencies(E16kHz); + sbc.SetBlockLengths(EBlockLenTwelve); + sbc.SetChannelModes(EJointStereo); + sbc.SetSubbands(EFourSubbands); + */ + err = iGavdp.AddSEPCapability(sbc); + + __LOG(_L("Add configuration [Category %d] - completed with error %d\n"), sbc.Category(), err); + } + else + { + TNonSBCCodecCapabilities codec(SymbianBluetoothAV::EAvdtpMediaTypeAudio, SymbianBluetoothAV::EAudioCodecMPEG24AAC); + TBuf8<18> mpeg2aacData; + mpeg2aacData.Append(0x80); // MPEG2 AAC LC + mpeg2aacData.Append(0x01); // 44.1 kHz + mpeg2aacData.Append(0x80); // 48.0 kHz, Channels 1 & 2 + mpeg2aacData.Append(0x80); // VBR, unknown bitrate + mpeg2aacData.Append(0x00); // unknown bitrate + mpeg2aacData.Append(0x00); // unknown bitrate + + codec.SetCodecData(mpeg2aacData); + + err = iGavdp.AddSEPCapability(codec); + + __LOG(_L("Add configuration [Category %d] - completed with error %d\n"), codec.Category(), err); + } + + iRegisteringLocalSEP = ETrue; + iGavdp.CommitSEPConfiguration(); + + __LOG(_L("Commit configuration [SEID %d]\n"), info.SEID().SEID()); + } + return err; + }