--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/pubsub/pubsub.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,438 @@
+// pubsub.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 <fshell/memoryaccesscmd.h>
+
+#ifdef FSHELL_TRACE_SUPPORT
+#include <fshell/extrabtrace.h>
+#include <fshell/btrace_parser.h>
+#endif
+
+#include <fshell/ltkutils.h>
+#include <fshell/qr3dll.h>
+
+using namespace IoUtils;
+
+#ifdef FSHELL_TRACE_SUPPORT
+class CCmdPubsub : public CMemoryAccessCommandBase, public MBtracePubSubObserver
+ {
+private: // From MBtracePubSubObserver
+ void HandlePropertyChangedL(const TBtraceTickCount& aTickCount, TUint aCategory, TUint aKey, TInt aNewValue);
+ void HandlePropertyChangedL(const TBtraceTickCount& aTickCount, TUint aCategory, TUint aKey, const TDesC8& aNewValue);
+
+#else
+class CCmdPubsub : public CMemoryAccessCommandBase
+ {
+#endif
+public:
+ static CCommandBase* NewLC();
+ ~CCmdPubsub();
+
+private:
+ CCmdPubsub();
+ void PrintKey(TUint aCategory, TUint aKey, TBool aFull=EFalse);
+ template <class KEYTYPE>
+ void SetKeyL(const KEYTYPE& aVal);
+ static TInt PropertyChanged(TAny* aSelf);
+ void GetAllL(TBool aNotify);
+ TBool IsExcluded(TUint aCat, TUint aKey) const;
+
+private: // From CCommandBase.
+ virtual const TDesC& Name() const;
+ virtual void DoRunL();
+ virtual void ArgumentsL(RCommandArgumentList& aArguments);
+ virtual void OptionsL(RCommandOptionList& aOptions);
+ void DoCancel();
+ void RunL();
+
+private:
+ // Arguments
+ enum TCmd
+ {
+ EGet, ESet, EDefine, ENotify
+ };
+ TCmd iCommand;
+ TUid iCategory;
+ TUint iKey;
+ // Options
+ HBufC* iStringVal;
+ TInt iIntVal;
+ TBool iForce;
+
+ TBool iNotify;
+ TBool iDefine;
+
+ // Other assorted stuff
+#ifdef FSHELL_MEMORY_ACCESS_SUPPORT
+ TPropNotifyResult iNotifyResult;
+#endif
+#ifdef FSHELL_TRACE_SUPPORT
+ CBtraceReader* iReader;
+ CBtracePubSub* iPubSub;
+#endif
+ TBool iUseBtrace;
+ CPropertyManager* iPropertyManager;
+ RBuf8 iValDescription;
+ };
+
+CCommandBase* CCmdPubsub::NewLC()
+ {
+ CCmdPubsub* self = new(ELeave) CCmdPubsub();
+ CleanupStack::PushL(self);
+ self->BaseConstructL();
+ return self;
+ }
+
+CCmdPubsub::~CCmdPubsub()
+ {
+ Cancel();
+ delete iStringVal;
+#ifdef FSHELL_TRACE_SUPPORT
+ delete iPubSub;
+ delete iReader;
+#endif
+ delete iPropertyManager;
+ iValDescription.Close();
+ }
+
+CCmdPubsub::CCmdPubsub()
+ : CMemoryAccessCommandBase(EManualComplete)
+ {
+ }
+
+const TDesC& CCmdPubsub::Name() const
+ {
+ _LIT(KName, "pubsub");
+ return KName;
+ }
+
+void CCmdPubsub::DoRunL()
+ {
+#if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
+ if (iForce || iUseBtrace)
+ {
+ // In order to implement the --force option, we talk to the memaccess device driver, which uses an RPropertyRef
+ // that isn't subject to security checks
+ LoadMemoryAccessL();
+ }
+#endif
+
+ iValDescription.CreateL(RProperty::KMaxLargePropertySize);
+
+ /*
+ if (iDelete)
+ {
+ if (!iArgList->IsPresent(1))
+ {
+ // Delete all not supported for pubsub
+ PrintError(KErrArgument, _L("You must specify a key for the delete option"));
+ User::Leave(KErrArgument);
+ }
+ else
+ {
+#ifdef FSHELL_MEMORY_ACCESS_SUPPORT
+ if (iForce)
+ {
+ err = iMemAccess.DeleteProperty(iCategory, iKey);
+ }
+ else
+#endif
+ {
+ err = RProperty::Delete(iCategory, iKey);
+ }
+ }
+ if (err == KErrPermissionDenied)
+ {
+ PrintError(err, _L("Delete failed, retry with --force"));
+ }
+ User::LeaveIfError(err);
+ }
+ */
+ if (iCommand == EDefine) iDefine = ETrue;
+ if (iCommand == ENotify) iNotify = ETrue;
+
+ if ((iCommand == ESet) || iDefine)
+ {
+ if (iOptions.IsPresent(&iIntVal))
+ {
+ // Set int
+ SetKeyL(iIntVal);
+ }
+ else if (iOptions.IsPresent(&iStringVal))
+ {
+ // Set string
+ TPtrC8 data((TUint8*)iStringVal->Ptr(), iStringVal->Size());
+ SetKeyL(data);
+ }
+ else
+ {
+ LeaveIfErr(KErrArgument, _L("set/define command requires --int or --string arguments"));
+ }
+ }
+ else if ((iCommand == EGet) || iNotify)
+ {
+ // Get
+ if (!iArguments.IsPresent(1))
+ LeaveIfErr(KErrArgument, _L("get command requires key and category"));
+ PrintKey(iCategory.iUid, iKey, ETrue);
+
+ if (iNotify)
+ {
+#if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
+ if (iForce || iUseBtrace)
+ {
+ //TPckgBuf<SKeyPair> key;
+ //key().iCat = iCategory.iUid;
+ //key().iKey = iKey;
+ //LeaveIfErr(iMemAccess.SetupMassPropertyNotify(key), _L("Couldn't set up notification"));
+ LeaveIfErr(iMemAccess.SubscribeToProperty(iCategory, iKey, iUseBtrace), _L("Couldn't subscribe to property"));
+#ifdef FSHELL_TRACE_SUPPORT
+ if (iUseBtrace)
+ {
+ const TInt KFlushInterval = 1000000; // 1s
+ const TInt KBtraceBufferSize = 1 * 1024 * 1024;
+ TRAPL(iReader = CBtraceReader::NewL(CBtraceReader::EFlushOnBtraceThreshold, KBtraceBufferSize, KBtraceBufferSize / 2), _L("Couldn't create btrace reader"));
+ TRAPL(iPubSub = CBtracePubSub::NewL(*iReader), _L("Couldn't create CBtracePubSub"));
+ TBtraceTickCount now;
+ now.SetToNow();
+ iReader->Start(now, KFlushInterval);
+ iPubSub->NotifyPropertyChangedL(*this);
+ return; // iPubSub will take it from here
+ }
+ else
+#endif
+ {
+ iMemAccess.NotifyPropertyChange(iNotifyResult, iStatus);
+ SetActive();
+ }
+ }
+ else
+#endif
+ {
+ iPropertyManager = CPropertyManager::NewL(TCallBack(&PropertyChanged, this));
+ iPropertyManager->ChangeProperty(iCategory.iUid, iKey);
+ }
+ return; // Don't complete
+ }
+ }
+ Complete();
+ }
+
+template <class KEYTYPE>
+void CCmdPubsub::SetKeyL(const KEYTYPE& aVal)
+ {
+ if (!iArguments.IsPresent(1))
+ {
+ LeaveIfErr(KErrArgument, _L("You must specify a key to set"));
+ }
+ TInt err = KErrNone;
+#if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
+ if (iForce)
+ {
+ err = iMemAccess.SetProperty(iCategory, iKey, aVal);
+ }
+ else
+#endif
+ {
+ err = RProperty::Set(iCategory, iKey, aVal);
+ if (err == KErrArgument)
+ {
+ LeaveIfErr(err, _L("Key does not appear to be of the right type"));
+ }
+ }
+
+#if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
+ if (err == KErrNotFound && iDefine)
+ {
+ if (!iForce)
+ {
+ LeaveIfErr(err, _L("Key does not exist, cannot define it unless --force is also specified"));
+ }
+ err = iMemAccess.SetProperty(iCategory, iKey, aVal, ETrue);
+ }
+#endif
+ if (err)
+ {
+ LeaveIfErr(err, _L("Error setting key"));
+ }
+ }
+
+void CCmdPubsub::PrintKey(TUint aCategory, TUint aKey, TBool aFull)
+ {
+ TUid cat = { aCategory };
+ TInt valInt;
+ RBuf8& valDes = iValDescription;
+ valDes.Zero();
+ enum TType { EUnknown, EInt, EDes };
+ TType type = EUnknown;
+ TInt reallen = 0;
+
+ TInt err = KErrNotFound;
+
+#if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
+ if (iForce)
+ {
+ err = iMemAccess.GetProperty(cat, aKey, valInt);
+ if (err == KErrNone)
+ {
+ type = EInt;
+ }
+ else
+ {
+ err = iMemAccess.GetProperty(cat, aKey, valDes, reallen);
+ type = EDes;
+ }
+ }
+ else
+#endif
+ {
+ // Guess the value type
+ // Int?
+ if (type == EUnknown)
+ {
+ err = RProperty::Get(cat, aKey, valInt);
+ if (err != KErrArgument)
+ {
+ type = EInt;
+ }
+ }
+
+ if (type == EUnknown)
+ {
+ // Des?
+ err = RProperty::Get(cat, aKey, valDes);
+ if (err != KErrArgument)
+ {
+ type = EDes;
+ }
+ }
+ }
+
+ switch(err)
+ {
+ case KErrNotFound:
+ PrintError(err, _L("Key 0x%x 0x%x not found"), aCategory, aKey);
+ break;
+ case KErrArgument:
+ PrintError(err, _L("Unknown key type, not int, des8 or des16"));
+ break;
+ case KErrPermissionDenied:
+ PrintError(err, _L("Permission denied on 0x%x 0x%x, retry with --force"), aCategory, aKey);
+ break;
+ case KErrNone:
+ // do nothing
+ break;
+ default:
+ PrintError(err, _L("Unrecognised error returned from RProperty"));
+ break;
+ }
+
+ if (err == KErrNone)
+ {
+ switch (type)
+ {
+ case EInt:
+ Printf(_L("0x%08x 0x%08x TInt: %d (0x%x)\r\n"), aCategory, aKey, valInt, valInt);
+ break;
+ case EDes:
+ {
+ TPtrC8 des(valDes);
+ if (!aFull) des.Set(valDes.Left(32)); // Don't print the whole thing, only 2 lines max
+ Printf(_L("0x%08x 0x%08x TDesC8 hex dump:\r\n"), aCategory, aKey);
+ LtkUtils::HexDumpToOutput(des, Stdout());
+ if (des.Length() < valDes.Length()) Write(_L("...\r\n"));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+void CCmdPubsub::ArgumentsL(RCommandArgumentList& aArguments)
+ {
+ aArguments.AppendEnumL((TInt&)iCommand, _L("command"));
+ aArguments.AppendUintL((TUint&)iCategory.iUid, _L("category"));
+ aArguments.AppendUintL(iKey, _L("key"));
+ }
+
+void CCmdPubsub::OptionsL(RCommandOptionList& aOptions)
+ {
+ aOptions.AppendIntL(iIntVal, _L("int"));
+ aOptions.AppendStringL(iStringVal, _L("string"));
+#ifdef FSHELL_MEMORY_ACCESS_SUPPORT
+ aOptions.AppendBoolL(iForce, _L("force"));
+#endif
+#ifdef FSHELL_TRACE_SUPPORT
+ aOptions.AppendBoolL(iUseBtrace, _L("btrace"));
+#endif
+ //aOptions.AppendStringL(iStringVal, '8', _L("set-data"), _L("Sets the specified key to this 8-bit value"));
+ //aOptions.AppendBoolL(iDelete, 'l', _L("delete"), _L("Deletes the specified property"));
+ }
+
+TInt CCmdPubsub::PropertyChanged(TAny* aSelf)
+ {
+ CCmdPubsub* self = static_cast<CCmdPubsub*>(aSelf);
+ self->PrintKey(self->iCategory.iUid, self->iKey);
+ return 0;
+ }
+
+EXE_BOILER_PLATE(CCmdPubsub)
+
+void CCmdPubsub::DoCancel()
+ {
+#if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
+ iMemAccess.CancelPropertyChange();
+#endif
+ }
+
+void CCmdPubsub::RunL()
+ {
+#if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
+
+ TPropNotifyResult notifyResult = iNotifyResult;
+ // rerequest asap
+ if (iStatus == KErrNone)
+ {
+ iMemAccess.NotifyPropertyChange(iNotifyResult, iStatus);
+ SetActive();
+ }
+
+ if (notifyResult.iMissedChanges)
+ {
+ PrintWarning(_L("Missed %d publish and subscribe notifications"), notifyResult.iMissedChanges);
+ }
+
+ if (notifyResult.iError)
+ {
+ Printf(_L("NotifyChange for 0x%08x 0x%x completed with error %d\r\n"), notifyResult.iCategory, notifyResult.iKey, notifyResult.iError);
+ }
+ else
+ {
+ //Printf(_L("P&S Key changed:\r\n"));
+ PrintKey(notifyResult.iCategory, notifyResult.iKey);
+ }
+#endif
+ }
+
+#ifdef FSHELL_TRACE_SUPPORT
+void CCmdPubsub::HandlePropertyChangedL(const TBtraceTickCount&, TUint aCategory, TUint aKey, TInt /*aNewValue*/)
+ {
+ PrintKey(aCategory, aKey);
+ }
+
+void CCmdPubsub::HandlePropertyChangedL(const TBtraceTickCount&, TUint aCategory, TUint aKey, const TDesC8& /*aNewValue*/)
+ {
+ PrintKey(aCategory, aKey);
+ }
+#endif