Added --no-write to gobble, fixed crash in start --timeout.
Also changed help to output one command per line (instead of columnizing) if not attached to a console. It's the same as what ls does.
// lbs.cpp// // Copyright (c) 2008 - 2010 Accenture. All rights reserved.// This component and the accompanying materials are made available// under the terms of the "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:// Accenture - Initial contribution//#include <fshell/common.mmh>#include <lbs.h>#include <lbssatellite.h>#include <LbsErrors.h>#if defined (FSHELL_PLATFORM_S60) || defined (FSHELL_PLATFORM_FOUNDATION)#include <EPos_CPosModules.h>#include <EPos_CPosModuleUpdate.h>#include <EPos_CPosModuleIdList.h> #endif#if !defined (FSHELL_PLATFORM_S60) && !defined (FSHELL_PLATFORM_FOUNDATION)#include <lbs/lbsadmin.h>#endif#include <fshell/ioutils.h>using namespace IoUtils;class CCmdLbs : public CCommandBase {public: void PrintTime(const TTime& aTime, TBool aNewline); static const TDesC* TechnologyTypeToString(TPositionModuleInfo::TTechnologyType aType); static const TDesC* DeviceLocationToString(TPositionModuleInfo::TDeviceLocation aLoc); static const TDesC* CostIndicatorToString(TPositionQuality::TCostIndicator aCost); static const TDesC* PowerConsumptionToString(TPositionQuality::TPowerConsumption aPower); static void CapabilitiesToString(TPositionModuleInfo::TCapabilities aCap, TDes &aDes); static CCommandBase* NewLC(); ~CCmdLbs();private: CCmdLbs(); void PrintModuleDetail(TPositionModuleInfo& aModInfo); void DoListModuleL(); void DoListModuleS60L(); void DoLocation(); void DoEnableModuleL(TBool aEnable = ETrue); #if !defined (FSHELL_PLATFORM_S60) void DoSynchTimeL();#endifprivate: // From CCommandBase. virtual const TDesC& Name() const; virtual void DoRunL(); virtual void ArgumentsL(RCommandArgumentList& aArguments); virtual void OptionsL(RCommandOptionList& aOptions);private: CActiveSchedulerWait* iActiveWait; RPositionServer iPosSrv; RPositioner iPos; TPositionSatelliteInfo iSatelliteInfo; //NOT all LBS modules accept satellite info TPositionInfo iPosInfo; TPositionInfoBase* ipPosInfo; //point to appropriate structure RArray<TBool> iVerbose; TInt iOptModuleIndex; //which module to use (module index, not id) TInt iOptTimeoutSec; //timeout in second, default is 60 second TInt iOptLoops; //how many loops (default 1) enum TLbsCmd { ECmdLocation, ECmdListModule, ECmdListModuleS60, ECmdEnableModule, ECmdDisableModule, ECmdSynchTime //synchronise system time with GPS timestamp }; TLbsCmd iCommand; };CCommandBase* CCmdLbs::NewLC() { CCmdLbs* self = new(ELeave) CCmdLbs(); CleanupStack::PushL(self); self->BaseConstructL(); return self; }CCmdLbs::CCmdLbs() { iOptModuleIndex = -1; iOptTimeoutSec = 300; iOptLoops = 1; iActiveWait = new (ELeave) CActiveSchedulerWait; }CCmdLbs::~CCmdLbs() { iPos.Close(); iPosSrv.Close(); iVerbose.Close(); delete iActiveWait; }////////////////////////////////////////////////////////////////////////////////////////////////////////////const TDesC& CCmdLbs::Name() const { _LIT(KName, "lbs"); return KName; }void CCmdLbs::ArgumentsL(RCommandArgumentList& aArguments) { _LIT(KArgCommand, "command"); aArguments.AppendEnumL((TInt&)iCommand, KArgCommand); }void CCmdLbs::OptionsL(RCommandOptionList& aOptions) { _LIT(KOptVerbose, "verbose"); aOptions.AppendBoolL(iVerbose, KOptVerbose); _LIT(KOptModuleIndex, "module-index"); aOptions.AppendUintL((TUint&)iOptModuleIndex, KOptModuleIndex); _LIT(KOptLoops, "loops"); aOptions.AppendUintL((TUint&)iOptLoops, KOptLoops); _LIT(KOptTimeout, "timeout"); aOptions.AppendUintL((TUint&)iOptTimeoutSec, KOptTimeout); }void CCmdLbs::DoRunL() { Printf(_L("Connecting to RPositionServer...\r\n")); TInt err = iPosSrv.Connect(); LeaveIfErr(err, _L("Cannot connect to position server")); switch(iCommand) { case ECmdLocation: DoLocation(); break; case ECmdListModule: DoListModuleL(); break; case ECmdListModuleS60: DoListModuleS60L(); break; case ECmdEnableModule: DoEnableModuleL(ETrue); break; case ECmdDisableModule: DoEnableModuleL(EFalse); break; case ECmdSynchTime: //TODO There's no way of actually specifying this command#if !defined (FSHELL_PLATFORM_S60) DoSynchTimeL();#else LeaveIfErr(KErrNotSupported, _L("SynchTime not supported on S60"));#endif break; } }void CCmdLbs::DoLocation() { TInt VerboseLevel = iVerbose.Count(); TInt err; TBool bSatelliteCapable = EFalse; TPositionModuleId modId; //which module to use if (iOptModuleIndex != -1) { TPositionModuleInfo modInfo; err = iPosSrv.GetModuleInfoByIndex(iOptModuleIndex, modInfo); LeaveIfErr(err, _L("invalid module index")); modId = modInfo.ModuleId(); } else { //use the default module err = iPosSrv.GetDefaultModuleId(modId); LeaveIfErr(err, _L("Invalid default module")); } TPositionModuleInfo modInfo; err = iPosSrv.GetModuleInfoById(modId, modInfo); TBuf<128> modName; modInfo.GetModuleName(modName); Printf(_L("Openning RPositioner...(Module ID: 0x%X \"%S\")\r\n"), modId.iUid, &modName); err = iPos.Open(iPosSrv, modId); LeaveIfErr(err, _L("Cannot open positioner")); // Set position requestor, it is compulsory on S60 only err = iPos.SetRequestor( CRequestor::ERequestorService , CRequestor::EFormatApplication , _L("FSHELL FLBS COMMAND") ); LeaveIfErr(err, _L("Cannot set requestor")); TPositionUpdateOptions UpdateOption; TTimeIntervalMicroSeconds TimeoutMs = (TInt64)iOptTimeoutSec * (TInt64)1000000; UpdateOption.SetUpdateTimeOut(TimeoutMs); Printf(_L("SetUpdateOptions... Timeout = %d seconds\r\n"), iOptTimeoutSec); err = iPos.SetUpdateOptions(UpdateOption); LeaveIfErr(err, _L("Cannot set update options")); //check if the module is capable of satellite info { TPositionModuleInfo::TCapabilities modCap = modInfo.Capabilities(); bSatelliteCapable = modCap & TPositionModuleInfo::ECapabilitySatellite; if (bSatelliteCapable) { ipPosInfo = &iSatelliteInfo; Printf(_L("This module is capable of receiving satellite information\r\n")); } else ipPosInfo = &iPosInfo; } for (TInt i=0; i<iOptLoops; i++) { TRequestStatus status; TPosition pos; Printf(_L("Calling RPositioner::NotifyPositionUpdate...\r\n")); iPos.NotifyPositionUpdate(*ipPosInfo, status); User::WaitForRequest(status); err = status.Int(); if (err != KErrNone) LeaveIfErr(err, _L("NotifyPositionUpdate encountered an error")); static_cast <TPositionInfo*>(ipPosInfo) -> GetPosition(pos); TTime LocTime = pos.Time(); TReal32 HorizontalAccuracy = pos.HorizontalAccuracy(); TReal32 VerticalAccuracy = pos.VerticalAccuracy(); //print current location information Printf(_L("Altit:%f Latit:%f Longt:%f HAccu:%.2f VAccu:%.2f\r\n"), pos.Altitude(), pos.Latitude(), pos.Longitude(), HorizontalAccuracy, VerticalAccuracy); Printf(_L("Location Signal Time:")); PrintTime(LocTime, ETrue); //if there is satellite information, optionally print it out if (bSatelliteCapable && (VerboseLevel>0) ) { TPositionSatelliteInfo* pSateInfo = static_cast <TPositionSatelliteInfo*> (ipPosInfo); TInt NumSatellitesInView = pSateInfo->NumSatellitesInView(); TInt NumSatellitesUsed = pSateInfo->NumSatellitesUsed(); TTime SatelliteTime = pSateInfo->SatelliteTime(); TReal32 HorizontalDoP = pSateInfo->HorizontalDoP(); TReal32 VerticalDoP = pSateInfo->VerticalDoP(); TReal32 TimeDoP = pSateInfo->TimeDoP(); Printf(_L("Satellite In View:%d Used:%d Time:"), NumSatellitesInView, NumSatellitesUsed ); PrintTime(SatelliteTime, ETrue); Printf(_L("HoriDop:%f VertDop:%f TimeDop:%f \r\n"), HorizontalDoP, VerticalDoP, TimeDoP); //Print each satellite info for (TInt i=0; i<NumSatellitesInView; i++ ) { TSatelliteData SatellliteData; err = pSateInfo->GetSatelliteData((TUint)i, SatellliteData); if (err == KErrNotFound) { Printf(_L("Satellite #%d Not Found\r\n"), i); continue; } else { User::LeaveIfError(err); } TInt SatelliteId = SatellliteData.SatelliteId(); TReal32 Azimuth = SatellliteData.Azimuth(); TReal32 Elevation = SatellliteData.Elevation(); TBool IsUsed = SatellliteData.IsUsed(); TInt SignalStrength = SatellliteData.SignalStrength(); Printf(_L("Satellite #%d, ID:%d Azimuth %.2f Elevation %.2f IsUsed:%d Strenth:%d\r\n"), i, SatelliteId, Azimuth, Elevation, IsUsed, SignalStrength); } } } }void CCmdLbs::DoListModuleL() { TInt err; TUint numModules; TPositionModuleInfo modInfo; err = iPosSrv.GetNumModules(numModules); User::LeaveIfError(err); Printf(_L("%d Modules found\r\n"), numModules); for (TUint i=0 ; i < numModules ; i++) { Printf(_L("============================\r\n")); err = iPosSrv.GetModuleInfoByIndex(i, modInfo); User::LeaveIfError(err); Printf(_L("Module Index: %d\r\n"), i); PrintModuleDetail(modInfo); } Printf(_L("=================================\r\n")); //print default module ID TPositionModuleId DefaultId; err = iPosSrv.GetDefaultModuleId(DefaultId); Printf(_L("Default Module ID 0x%X\r\n"), DefaultId.iUid ); }//S60 proprietary//similar to DoListModuleL, but list module based on S60 API,//and sometimes it gives different results than symbain APIvoid CCmdLbs::DoListModuleS60L() {#ifdef FSHELL_PLATFORM_S60 //TInt err; TUint numModules; CPosModules* pModHand = CPosModules::OpenL(); CleanupStack::PushL(pModHand); CPosModuleIdList* pIdList = pModHand->ModuleIdListL(); CleanupStack::PushL(pIdList); numModules = pIdList->Count(); Printf(_L("%d Modules found\r\n"), numModules); for (TUint i=0 ; i < numModules ; i++) { Printf(_L("============================\r\n")); TPositionModuleId S60modId = (*pIdList) [i]; TPositionModuleInfo S60modInfo; TBuf<128> S60modName; //to store module name pModHand->GetModuleInfoL(S60modId, S60modInfo); S60modInfo.GetModuleName(S60modName); Printf(_L("Module Index: %d\r\n"), i); PrintModuleDetail(S60modInfo); } Printf(_L("=================================\r\n")); CleanupStack::PopAndDestroy(pIdList); CleanupStack::PopAndDestroy(pModHand); #endif }void CCmdLbs::PrintModuleDetail(TPositionModuleInfo& aModInfo) { //TInt err; TBool bAvailable = aModInfo.IsAvailable(); TPositionModuleId modId; modId = aModInfo.ModuleId(); TBuf<128> modName; aModInfo.GetModuleName(modName); //==quality TPositionQuality modQuality; aModInfo.GetPositionQuality(modQuality); TTimeIntervalMicroSeconds firstFix = modQuality.TimeToFirstFix(); TTimeIntervalMicroSeconds nextFix = modQuality.TimeToNextFix(); TReal32 horiAccu = modQuality.HorizontalAccuracy(); TReal32 vertAccu = modQuality.VerticalAccuracy(); TPositionQuality::TCostIndicator cost = modQuality.CostIndicator(); TPositionQuality::TPowerConsumption power = modQuality.PowerConsumption(); //////////////////////////////////////////////////////////////// TPositionModuleInfo::TTechnologyType modType = aModInfo.TechnologyType(); TPositionModuleInfo::TDeviceLocation modLoc = aModInfo.DeviceLocation(); TPositionModuleInfo::TCapabilities modCap = aModInfo.Capabilities(); TVersion modVersion = aModInfo.Version(); TVersionName VersionName = modVersion.Name(); //TPositionClassFamily aClassType; //modInfo.ClassesSupported(aClassType); Printf(_L("Module Id:0x%X, Name:\"%S\" Available:%d \r\n"), modId.iUid, &modName, bAvailable); Printf(_L("Type:%S Version:%S\r\n"), TechnologyTypeToString(modType), &VersionName ); Printf(_L("Location:%S\r\n"), DeviceLocationToString (modLoc)); Printf(_L("Quality first fix:%Ld next fix:%Ld \r\n"), firstFix.Int64(), nextFix.Int64()); Printf(_L("Horizontal Accuracy:%f Vertical Accuray:%f \r\n"), horiAccu, vertAccu); Printf(_L("Cost Indicator:%S\r\n"), CostIndicatorToString(cost)); Printf(_L("Power Consumption:%S\r\n"), PowerConsumptionToString(power)); TBuf<256> CapString; CapabilitiesToString(modCap, CapString); Printf(_L("Capabilities:%S\r\n"), &CapString); }//it is a S60 proprietary function//void CCmdLbs::DoEnableModuleL(TBool aEnable) { TInt err; TBuf<128> modName; //to store module name TPositionModuleInfo modInfo; TPositionModuleId modId = TUid::Null(); //which module to use TBool bIsCurAvail; if (iOptModuleIndex != -1) { err = iPosSrv.GetModuleInfoByIndex(iOptModuleIndex, modInfo); LeaveIfErr(err, _L("invalid module index")); modId = modInfo.ModuleId(); } else { LeaveIfErr(KErrArgument, _L("Need to specify a module")); } bIsCurAvail = modInfo.IsAvailable(); modInfo.GetModuleName(modName); TPtrC AvailNow = (bIsCurAvail)?_L("Yes"):_L("No"); Printf(_L("Module Id=0x%08x Name:\"%S\" Current Availability:%S \r\n"), modId.iUid, &modName, &AvailNow); //modInfo.SetIsAvailable(ETrue); //Note: this has no effect on S60 platform#ifdef FSHELL_PLATFORM_S60 CPosModules* pModHand = CPosModules::OpenL(); CleanupStack::PushL(pModHand); //diagnosis code: to verify the information given by S60 API matches Symbian API { CPosModuleIdList* pIdList = pModHand->ModuleIdListL(); CleanupStack::PushL(pIdList); TPositionModuleId S60modId = (*pIdList) [iOptModuleIndex]; TPositionModuleInfo S60modInfo; TBuf<128> S60modName; //to store module name pModHand->GetModuleInfoL(S60modId, S60modInfo); S60modInfo.GetModuleName(S60modName); RDebug::Print(_L("S60 LBS module name:%S"), &S60modName); CleanupStack::PopAndDestroy(pIdList); } CPosModuleUpdate* pModUpdate = CPosModuleUpdate::NewLC(); TBool bNewAvail = aEnable; pModUpdate->SetUpdateAvailability(bNewAvail); TRAP(err, pModHand->UpdateModuleL(modId, *pModUpdate)); LeaveIfErr(err, _L("Could not update module information") ); CleanupStack::PopAndDestroy(pModUpdate); CleanupStack::PopAndDestroy(pModHand); #endif //verify if the change has take effect { err = iPosSrv.GetModuleInfoByIndex(iOptModuleIndex, modInfo); LeaveIfErr(err, _L("invalid module index")); modId = modInfo.ModuleId(); bIsCurAvail = modInfo.IsAvailable(); TPtrC NewAvail = (bIsCurAvail)?_L("Yes"):_L("No"); Printf(_L("Module Id=0x%08x Name:\"%S\" New Availability:%S \r\n"), modId.iUid, &modName, &NewAvail); } }#if !defined (FSHELL_PLATFORM_S60)void CCmdLbs::DoSynchTimeL() { // Set LBS setting to allow manual clock adjustment //This may not be set by default CLbsAdmin* admin = CLbsAdmin::NewL(); CleanupStack::PushL(admin); CLbsAdmin::TClockAdjust clockAdjust; User::LeaveIfError(admin->Get(KLbsSettingAllowManualClockAdjust,clockAdjust)); admin->Set(KLbsSettingAllowManualClockAdjust,CLbsAdmin::EClockAdjustOn); CleanupStack::PopAndDestroy(admin); }#endifEXE_BOILER_PLATE(CCmdLbs)void CCmdLbs::PrintTime(const TTime& aTime, TBool aNewline) { TTime NullTime = Time::NullTTime(); if (aTime == NullTime) { Printf(_L("(NullTime)")); } else { _LIT8(KDateTimeFormat, "%d-%02d-%02d %02d:%02d:%02d"); TDateTime dt = aTime.DateTime(); Printf(KDateTimeFormat, dt.Year(), dt.Month()+1, dt.Day()+1, dt.Hour(), dt.Minute(), dt.Second()); } if (aNewline) Printf(_L("\r\n")); }#define CASE_LIT(x) case x: { _LIT(KName, #x); return &KName; }const TDesC* CCmdLbs::TechnologyTypeToString(TPositionModuleInfo::TTechnologyType aType) { switch(aType) { CASE_LIT(TPositionModuleInfo::ETechnologyUnknown); CASE_LIT(TPositionModuleInfo::ETechnologyTerminal); CASE_LIT(TPositionModuleInfo::ETechnologyNetwork); CASE_LIT(TPositionModuleInfo::ETechnologyAssisted); default: { _LIT(KUnknown, "Unknown"); return &KUnknown; } } }const TDesC* CCmdLbs::DeviceLocationToString(TPositionModuleInfo::TDeviceLocation aLoc) { switch(aLoc) { CASE_LIT(TPositionModuleInfo::EDeviceUnknown); CASE_LIT(TPositionModuleInfo::EDeviceInternal); CASE_LIT(TPositionModuleInfo::EDeviceExternal); default: { _LIT(KUnknown, "Unknown"); return &KUnknown; } } }const TDesC* CCmdLbs::CostIndicatorToString(TPositionQuality::TCostIndicator aCost) { switch(aCost) { CASE_LIT(TPositionQuality::ECostUnknown); CASE_LIT(TPositionQuality::ECostZero); CASE_LIT(TPositionQuality::ECostPossible); CASE_LIT(TPositionQuality::ECostCharge); default: { _LIT(KUnknown, "Unknown"); return &KUnknown; } } }const TDesC* CCmdLbs::PowerConsumptionToString(TPositionQuality::TPowerConsumption aPower) { switch(aPower) { CASE_LIT(TPositionQuality::EPowerUnknown); CASE_LIT(TPositionQuality::EPowerZero); CASE_LIT(TPositionQuality::EPowerLow); CASE_LIT(TPositionQuality::EPowerMedium); CASE_LIT(TPositionQuality::EPowerHigh); default: { _LIT(KUnknown, "Unknown"); return &KUnknown; } } }#define CAPFLAG(x) if (aCap & TPositionModuleInfo::x) { aDes += _L(#x); aDes += _L("|");}void CCmdLbs::CapabilitiesToString(TPositionModuleInfo::TCapabilities aCap, TDes &aDes) { aDes.SetLength(0); //if (aCap & TPositionModuleInfo::ECapabilityNone) aDes += _L("ECapabilityNone|"); CAPFLAG(ECapabilityNone); CAPFLAG(ECapabilityHorizontal); CAPFLAG(ECapabilityVertical); CAPFLAG(ECapabilitySpeed); CAPFLAG(ECapabilityDirection); CAPFLAG(ECapabilitySatellite); CAPFLAG(ECapabilityCompass); CAPFLAG(ECapabilityNmea); CAPFLAG(ECapabilityAddress); CAPFLAG(ECapabilityBuilding); CAPFLAG(ECapabilityMedia); }