commands/pubsub/pubsub.cpp
changeset 0 7f656887cf89
child 60 3ad902ef5222
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // pubsub.cpp
       
     2 // 
       
     3 // Copyright (c) 2008 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <fshell/common.mmh>
       
    14 #include <fshell/memoryaccesscmd.h>
       
    15 
       
    16 #ifdef FSHELL_TRACE_SUPPORT
       
    17 #include <fshell/extrabtrace.h>
       
    18 #include <fshell/btrace_parser.h>
       
    19 #endif
       
    20 
       
    21 #include <fshell/ltkutils.h>
       
    22 #include <fshell/qr3dll.h>
       
    23 
       
    24 using namespace IoUtils;
       
    25 
       
    26 #ifdef FSHELL_TRACE_SUPPORT
       
    27 class CCmdPubsub : public CMemoryAccessCommandBase, public MBtracePubSubObserver
       
    28 	{
       
    29 private: // From MBtracePubSubObserver
       
    30 	void HandlePropertyChangedL(const TBtraceTickCount& aTickCount, TUint aCategory, TUint aKey, TInt aNewValue);
       
    31 	void HandlePropertyChangedL(const TBtraceTickCount& aTickCount, TUint aCategory, TUint aKey, const TDesC8& aNewValue);
       
    32 
       
    33 #else
       
    34 class CCmdPubsub : public CMemoryAccessCommandBase
       
    35 	{
       
    36 #endif
       
    37 public:
       
    38 	static CCommandBase* NewLC();
       
    39 	~CCmdPubsub();
       
    40 
       
    41 private:
       
    42 	CCmdPubsub();
       
    43 	void PrintKey(TUint aCategory, TUint aKey, TBool aFull=EFalse);
       
    44 	template <class KEYTYPE>
       
    45 	void SetKeyL(const KEYTYPE& aVal);
       
    46 	static TInt PropertyChanged(TAny* aSelf);
       
    47 	void GetAllL(TBool aNotify);
       
    48 	TBool IsExcluded(TUint aCat, TUint aKey) const;
       
    49 
       
    50 private: // From CCommandBase.
       
    51 	virtual const TDesC& Name() const;
       
    52 	virtual void DoRunL();
       
    53 	virtual void ArgumentsL(RCommandArgumentList& aArguments);
       
    54 	virtual void OptionsL(RCommandOptionList& aOptions);
       
    55 	void DoCancel();
       
    56 	void RunL();
       
    57 
       
    58 private:
       
    59 	// Arguments
       
    60 	enum TCmd
       
    61 		{
       
    62 		EGet, ESet, EDefine, ENotify
       
    63 		};
       
    64 	TCmd iCommand;
       
    65 	TUid iCategory;
       
    66 	TUint iKey;
       
    67 	// Options
       
    68 	HBufC* iStringVal;
       
    69 	TInt iIntVal;
       
    70 	TBool iForce;
       
    71 
       
    72 	TBool iNotify;
       
    73 	TBool iDefine;
       
    74 
       
    75 	// Other assorted stuff
       
    76 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT
       
    77 	TPropNotifyResult iNotifyResult;
       
    78 #endif
       
    79 #ifdef FSHELL_TRACE_SUPPORT
       
    80 	CBtraceReader* iReader;
       
    81 	CBtracePubSub* iPubSub;
       
    82 #endif
       
    83 	TBool iUseBtrace;
       
    84 	CPropertyManager* iPropertyManager;
       
    85 	RBuf8 iValDescription;
       
    86 	};
       
    87 
       
    88 CCommandBase* CCmdPubsub::NewLC()
       
    89 	{
       
    90 	CCmdPubsub* self = new(ELeave) CCmdPubsub();
       
    91 	CleanupStack::PushL(self);
       
    92 	self->BaseConstructL();
       
    93 	return self;
       
    94 	}
       
    95 
       
    96 CCmdPubsub::~CCmdPubsub()
       
    97 	{
       
    98 	Cancel();
       
    99 	delete iStringVal;
       
   100 #ifdef FSHELL_TRACE_SUPPORT
       
   101 	delete iPubSub;
       
   102 	delete iReader;
       
   103 #endif
       
   104 	delete iPropertyManager;
       
   105 	iValDescription.Close();
       
   106 	}
       
   107 
       
   108 CCmdPubsub::CCmdPubsub()
       
   109 	: CMemoryAccessCommandBase(EManualComplete)
       
   110 	{
       
   111 	}
       
   112 
       
   113 const TDesC& CCmdPubsub::Name() const
       
   114 	{
       
   115 	_LIT(KName, "pubsub");	
       
   116 	return KName;
       
   117 	}
       
   118 
       
   119 void CCmdPubsub::DoRunL()
       
   120 	{
       
   121 #if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
       
   122 	if (iForce || iUseBtrace)
       
   123 		{
       
   124 		// In order to implement the --force option, we talk to the memaccess device driver, which uses an RPropertyRef
       
   125 		// that isn't subject to security checks
       
   126 		LoadMemoryAccessL();
       
   127 		}
       
   128 #endif
       
   129 
       
   130 	iValDescription.CreateL(RProperty::KMaxLargePropertySize);
       
   131 
       
   132 	/*
       
   133 	if (iDelete)
       
   134 		{
       
   135 		if (!iArgList->IsPresent(1))
       
   136 			{
       
   137 			// Delete all not supported for pubsub
       
   138 			PrintError(KErrArgument, _L("You must specify a key for the delete option"));
       
   139 			User::Leave(KErrArgument);
       
   140 			}
       
   141 		else
       
   142 			{
       
   143 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT
       
   144 			if (iForce)
       
   145 				{
       
   146 				err = iMemAccess.DeleteProperty(iCategory, iKey);
       
   147 				}
       
   148 			else
       
   149 #endif
       
   150 				{
       
   151 				err = RProperty::Delete(iCategory, iKey);
       
   152 				}
       
   153 			}
       
   154 		if (err == KErrPermissionDenied)
       
   155 			{
       
   156 			PrintError(err, _L("Delete failed, retry with --force"));
       
   157 			}
       
   158 		User::LeaveIfError(err);
       
   159 		}
       
   160 	*/
       
   161 	if (iCommand == EDefine) iDefine = ETrue;
       
   162 	if (iCommand == ENotify) iNotify = ETrue;
       
   163 
       
   164 	if ((iCommand == ESet) || iDefine)
       
   165 		{
       
   166 		if (iOptions.IsPresent(&iIntVal))
       
   167 			{
       
   168 			// Set int
       
   169 			SetKeyL(iIntVal);
       
   170 			}
       
   171 		else if (iOptions.IsPresent(&iStringVal))
       
   172 			{
       
   173 			// Set string
       
   174 			TPtrC8 data((TUint8*)iStringVal->Ptr(), iStringVal->Size());
       
   175 			SetKeyL(data);
       
   176 			}
       
   177 		else
       
   178 			{
       
   179 			LeaveIfErr(KErrArgument, _L("set/define command requires --int or --string arguments"));
       
   180 			}
       
   181 		}
       
   182 	else if ((iCommand == EGet) || iNotify)
       
   183 		{
       
   184 		// Get
       
   185 		if (!iArguments.IsPresent(1))
       
   186 			LeaveIfErr(KErrArgument, _L("get command requires key and category"));
       
   187 		PrintKey(iCategory.iUid, iKey, ETrue);
       
   188 
       
   189 		if (iNotify)
       
   190 			{
       
   191 #if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
       
   192 			if (iForce || iUseBtrace)
       
   193 				{
       
   194 				//TPckgBuf<SKeyPair> key;
       
   195 				//key().iCat = iCategory.iUid;
       
   196 				//key().iKey = iKey;
       
   197 				//LeaveIfErr(iMemAccess.SetupMassPropertyNotify(key), _L("Couldn't set up notification"));
       
   198 				LeaveIfErr(iMemAccess.SubscribeToProperty(iCategory, iKey, iUseBtrace), _L("Couldn't subscribe to property"));
       
   199 #ifdef FSHELL_TRACE_SUPPORT
       
   200 				if (iUseBtrace)
       
   201 					{
       
   202 					const TInt KFlushInterval = 1000000; // 1s
       
   203 					const TInt KBtraceBufferSize = 1 * 1024 * 1024;
       
   204 					TRAPL(iReader = CBtraceReader::NewL(CBtraceReader::EFlushOnBtraceThreshold, KBtraceBufferSize, KBtraceBufferSize / 2), _L("Couldn't create btrace reader"));
       
   205 					TRAPL(iPubSub = CBtracePubSub::NewL(*iReader), _L("Couldn't create CBtracePubSub"));
       
   206 					TBtraceTickCount now;
       
   207 					now.SetToNow();
       
   208 					iReader->Start(now, KFlushInterval);
       
   209 					iPubSub->NotifyPropertyChangedL(*this);
       
   210 					return; // iPubSub will take it from here
       
   211 					}
       
   212 				else
       
   213 #endif
       
   214 					{
       
   215 					iMemAccess.NotifyPropertyChange(iNotifyResult, iStatus);
       
   216 					SetActive();
       
   217 					}
       
   218 				}
       
   219 			else
       
   220 #endif
       
   221 				{
       
   222 				iPropertyManager = CPropertyManager::NewL(TCallBack(&PropertyChanged, this));
       
   223 				iPropertyManager->ChangeProperty(iCategory.iUid, iKey);
       
   224 				}
       
   225 			return; // Don't complete
       
   226 			}
       
   227 		}
       
   228 	Complete();
       
   229 	}
       
   230 
       
   231 template <class KEYTYPE>
       
   232 void CCmdPubsub::SetKeyL(const KEYTYPE& aVal)
       
   233 	{
       
   234 	if (!iArguments.IsPresent(1))
       
   235 		{
       
   236 		LeaveIfErr(KErrArgument, _L("You must specify a key to set"));
       
   237 		}
       
   238 	TInt err = KErrNone;
       
   239 #if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
       
   240 	if (iForce)
       
   241 		{
       
   242 		err = iMemAccess.SetProperty(iCategory, iKey, aVal);
       
   243 		}
       
   244 	else
       
   245 #endif
       
   246 		{
       
   247 		err = RProperty::Set(iCategory, iKey, aVal);
       
   248 		if (err == KErrArgument)
       
   249 			{
       
   250 			LeaveIfErr(err, _L("Key does not appear to be of the right type"));
       
   251 			}
       
   252 		}
       
   253 
       
   254 #if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
       
   255 	if (err == KErrNotFound && iDefine)
       
   256 		{
       
   257 		if (!iForce)
       
   258 			{
       
   259 			LeaveIfErr(err, _L("Key does not exist, cannot define it unless --force is also specified"));
       
   260 			}
       
   261 		err = iMemAccess.SetProperty(iCategory, iKey, aVal, ETrue);
       
   262 		}
       
   263 #endif
       
   264 	if (err)
       
   265 		{
       
   266 		LeaveIfErr(err, _L("Error setting key"));
       
   267 		}
       
   268 	}
       
   269 
       
   270 void CCmdPubsub::PrintKey(TUint aCategory, TUint aKey, TBool aFull)
       
   271 	{
       
   272 	TUid cat = { aCategory };
       
   273 	TInt valInt;
       
   274 	RBuf8& valDes = iValDescription;
       
   275 	valDes.Zero();
       
   276 	enum TType { EUnknown, EInt, EDes };
       
   277 	TType type = EUnknown;
       
   278 	TInt reallen = 0;
       
   279 
       
   280 	TInt err = KErrNotFound;
       
   281 
       
   282 #if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
       
   283 	if (iForce)
       
   284 		{
       
   285 		err = iMemAccess.GetProperty(cat, aKey, valInt);
       
   286 		if (err == KErrNone)
       
   287 			{
       
   288 			type = EInt;
       
   289 			}
       
   290 		else
       
   291 			{
       
   292 			err = iMemAccess.GetProperty(cat, aKey, valDes, reallen);
       
   293 			type = EDes;
       
   294 			}
       
   295 		}
       
   296 	else
       
   297 #endif
       
   298 		{
       
   299 		// Guess the value type
       
   300 		// Int?
       
   301 		if (type == EUnknown)
       
   302 			{
       
   303 			err = RProperty::Get(cat, aKey, valInt);
       
   304 			if (err != KErrArgument)
       
   305 				{
       
   306 				type = EInt;
       
   307 				}
       
   308 			}
       
   309 		
       
   310 		if (type == EUnknown)
       
   311 			{
       
   312 			// Des?
       
   313 			err = RProperty::Get(cat, aKey, valDes);
       
   314 			if (err != KErrArgument)
       
   315 				{
       
   316 				type = EDes;
       
   317 				}
       
   318 			}
       
   319 		}
       
   320 
       
   321 	switch(err)
       
   322 		{
       
   323 		case KErrNotFound:
       
   324 			PrintError(err, _L("Key 0x%x 0x%x not found"), aCategory, aKey);
       
   325 			break;
       
   326 		case KErrArgument:
       
   327 			PrintError(err, _L("Unknown key type, not int, des8 or des16"));
       
   328 			break;
       
   329 		case KErrPermissionDenied:
       
   330 			PrintError(err, _L("Permission denied on 0x%x 0x%x, retry with --force"), aCategory, aKey);
       
   331 			break;
       
   332 		case KErrNone:
       
   333 			// do nothing
       
   334 			break;
       
   335 		default:
       
   336 			PrintError(err, _L("Unrecognised error returned from RProperty"));
       
   337 			break;
       
   338 		}
       
   339 
       
   340 	if (err == KErrNone)
       
   341 		{
       
   342 		switch (type)
       
   343 			{
       
   344 			case EInt:
       
   345 				Printf(_L("0x%08x 0x%08x TInt: %d (0x%x)\r\n"), aCategory, aKey, valInt, valInt);
       
   346 				break;
       
   347 			case EDes:
       
   348 				{
       
   349 				TPtrC8 des(valDes);
       
   350 				if (!aFull) des.Set(valDes.Left(32)); // Don't print the whole thing, only 2 lines max
       
   351 				Printf(_L("0x%08x 0x%08x TDesC8 hex dump:\r\n"), aCategory, aKey);
       
   352 				LtkUtils::HexDumpToOutput(des, Stdout());
       
   353 				if (des.Length() < valDes.Length()) Write(_L("...\r\n"));
       
   354 				break;
       
   355 				}
       
   356 			default:
       
   357 				break;
       
   358 			}
       
   359 		}
       
   360 	}
       
   361 	
       
   362 void CCmdPubsub::ArgumentsL(RCommandArgumentList& aArguments)
       
   363 	{
       
   364 	aArguments.AppendEnumL((TInt&)iCommand, _L("command"));
       
   365 	aArguments.AppendUintL((TUint&)iCategory.iUid, _L("category"));
       
   366 	aArguments.AppendUintL(iKey, _L("key"));
       
   367 	}
       
   368 
       
   369 void CCmdPubsub::OptionsL(RCommandOptionList& aOptions)
       
   370 	{
       
   371 	aOptions.AppendIntL(iIntVal, _L("int"));
       
   372 	aOptions.AppendStringL(iStringVal, _L("string"));
       
   373 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT
       
   374 	aOptions.AppendBoolL(iForce, _L("force"));
       
   375 #endif
       
   376 #ifdef FSHELL_TRACE_SUPPORT
       
   377 	aOptions.AppendBoolL(iUseBtrace, _L("btrace"));
       
   378 #endif
       
   379 	//aOptions.AppendStringL(iStringVal, '8', _L("set-data"), _L("Sets the specified key to this 8-bit value"));
       
   380 	//aOptions.AppendBoolL(iDelete, 'l', _L("delete"), _L("Deletes the specified property"));
       
   381 	}
       
   382 
       
   383 TInt CCmdPubsub::PropertyChanged(TAny* aSelf)
       
   384 	{
       
   385 	CCmdPubsub* self = static_cast<CCmdPubsub*>(aSelf);
       
   386 	self->PrintKey(self->iCategory.iUid, self->iKey);
       
   387 	return 0;
       
   388 	}
       
   389 
       
   390 EXE_BOILER_PLATE(CCmdPubsub)
       
   391 
       
   392 void CCmdPubsub::DoCancel()
       
   393 	{
       
   394 #if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
       
   395 	iMemAccess.CancelPropertyChange();
       
   396 #endif
       
   397 	}
       
   398 
       
   399 void CCmdPubsub::RunL()
       
   400 	{
       
   401 #if defined (FSHELL_MEMORY_ACCESS_SUPPORT)
       
   402 
       
   403 	TPropNotifyResult notifyResult = iNotifyResult;
       
   404 	// rerequest asap
       
   405 	if (iStatus == KErrNone)
       
   406 		{
       
   407 		iMemAccess.NotifyPropertyChange(iNotifyResult, iStatus);
       
   408 		SetActive();
       
   409 		}
       
   410 
       
   411 	if (notifyResult.iMissedChanges)
       
   412 		{
       
   413 		PrintWarning(_L("Missed %d publish and subscribe notifications"), notifyResult.iMissedChanges);
       
   414 		}
       
   415 
       
   416 	if (notifyResult.iError)
       
   417 		{
       
   418 		Printf(_L("NotifyChange for 0x%08x 0x%x completed with error %d\r\n"), notifyResult.iCategory, notifyResult.iKey, notifyResult.iError);
       
   419 		}
       
   420 	else
       
   421 		{
       
   422 		//Printf(_L("P&S Key changed:\r\n"));
       
   423 		PrintKey(notifyResult.iCategory, notifyResult.iKey);
       
   424 		}
       
   425 #endif
       
   426 	}
       
   427 
       
   428 #ifdef FSHELL_TRACE_SUPPORT
       
   429 void CCmdPubsub::HandlePropertyChangedL(const TBtraceTickCount&, TUint aCategory, TUint aKey, TInt /*aNewValue*/)
       
   430 	{
       
   431 	PrintKey(aCategory, aKey);
       
   432 	}
       
   433 
       
   434 void CCmdPubsub::HandlePropertyChangedL(const TBtraceTickCount&, TUint aCategory, TUint aKey, const TDesC8& /*aNewValue*/)
       
   435 	{
       
   436 	PrintKey(aCategory, aKey);
       
   437 	}
       
   438 #endif