os/kernelhwsrv/kerneltest/e32test/property/t_prop_ldd.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "t_prop_ldd.h"
sl@0
    17
#include <kernel/kernel.h>
sl@0
    18
#include "nk_priv.h"
sl@0
    19
sl@0
    20
class DPropLDevice : public DLogicalDevice
sl@0
    21
	{
sl@0
    22
public:
sl@0
    23
	DPropLDevice();
sl@0
    24
	virtual TInt Install();
sl@0
    25
	virtual void GetCaps(TDes8& aDes) const;
sl@0
    26
	virtual TInt Create(DLogicalChannelBase*& aChannel);
sl@0
    27
	};
sl@0
    28
sl@0
    29
class DPropLChannel : public DLogicalChannelBase
sl@0
    30
	{
sl@0
    31
public:
sl@0
    32
	DPropLChannel();
sl@0
    33
	~DPropLChannel();
sl@0
    34
sl@0
    35
	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
sl@0
    36
	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
sl@0
    37
sl@0
    38
private:
sl@0
    39
	TInt Basic(RPropChannel::TBasicInfo* aInfo);
sl@0
    40
sl@0
    41
	static void CompleteFn(TAny* aPtr, TInt aReason);
sl@0
    42
	TInt iReason;
sl@0
    43
	NFastSemaphore iSem;
sl@0
    44
sl@0
    45
	};
sl@0
    46
sl@0
    47
DECLARE_STANDARD_LDD()
sl@0
    48
//
sl@0
    49
// Create a new device
sl@0
    50
//
sl@0
    51
	{
sl@0
    52
	return new DPropLDevice;
sl@0
    53
	}
sl@0
    54
sl@0
    55
DPropLDevice::DPropLDevice()
sl@0
    56
//
sl@0
    57
// Constructor
sl@0
    58
//
sl@0
    59
	{
sl@0
    60
	//iUnitsMask=0;
sl@0
    61
	iVersion = TVersion(1,0,1);
sl@0
    62
	// iParseMask = 0;
sl@0
    63
	}
sl@0
    64
sl@0
    65
TInt DPropLDevice::Install()
sl@0
    66
//
sl@0
    67
// Install the device driver.
sl@0
    68
//
sl@0
    69
	{
sl@0
    70
	TInt r = SetName(&KPropLdName);
sl@0
    71
	return r;
sl@0
    72
	}
sl@0
    73
sl@0
    74
void DPropLDevice::GetCaps(TDes8&) const
sl@0
    75
//
sl@0
    76
// Return the Comm capabilities.
sl@0
    77
//
sl@0
    78
	{
sl@0
    79
	}
sl@0
    80
sl@0
    81
TInt DPropLDevice::Create(DLogicalChannelBase*& aChannel)
sl@0
    82
//
sl@0
    83
// Create a channel on the device.
sl@0
    84
//
sl@0
    85
	{
sl@0
    86
	aChannel = new DPropLChannel;
sl@0
    87
	return aChannel ? KErrNone : KErrNoMemory;
sl@0
    88
	}
sl@0
    89
sl@0
    90
DPropLChannel::DPropLChannel() 
sl@0
    91
	{
sl@0
    92
	NKern::FSSetOwner(&iSem, NKern::CurrentThread());
sl@0
    93
	}
sl@0
    94
sl@0
    95
TInt DPropLChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /* aInfo*/ , const TVersion& aVer)
sl@0
    96
//
sl@0
    97
// Create the channel from the passed info.
sl@0
    98
//
sl@0
    99
	{
sl@0
   100
	if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
sl@0
   101
		return KErrNotSupported;
sl@0
   102
	return KErrNone;
sl@0
   103
	}
sl@0
   104
sl@0
   105
DPropLChannel::~DPropLChannel()
sl@0
   106
	{
sl@0
   107
	}
sl@0
   108
sl@0
   109
sl@0
   110
#define BASIC_ERROR(aRes, aCond) \
sl@0
   111
	{\
sl@0
   112
	if (!(aCond)) \
sl@0
   113
		{ \
sl@0
   114
		Kern::Printf("Test '" #aCond "' fails; r = %d;\n\tfile '" __FILE__ "'; line %d;\n", aRes, __LINE__); \
sl@0
   115
		prop.Close(); \
sl@0
   116
		return EFalse; \
sl@0
   117
		} \
sl@0
   118
	}
sl@0
   119
sl@0
   120
void DPropLChannel::CompleteFn(TAny* aPtr, TInt aReason)
sl@0
   121
	{ // static
sl@0
   122
	DPropLChannel* self = (DPropLChannel*) aPtr;
sl@0
   123
	self->iReason = aReason;
sl@0
   124
	NKern::FSSignal(&self->iSem);
sl@0
   125
	}
sl@0
   126
sl@0
   127
TBool DPropLChannel::Basic(RPropChannel::TBasicInfo* aInfo)
sl@0
   128
	{
sl@0
   129
sl@0
   130
	TUid category = aInfo->iCategory;
sl@0
   131
	TUint key = aInfo->iKey;
sl@0
   132
	TUint count = aInfo->iCount;
sl@0
   133
	RProperty::TType type = aInfo->iType;
sl@0
   134
sl@0
   135
	for (TUint i = 0; i < count; ++i)
sl@0
   136
		{
sl@0
   137
		RPropertyRef prop;
sl@0
   138
		TInt r = prop.Open(category, key);
sl@0
   139
		BASIC_ERROR(r, r == KErrNotFound);
sl@0
   140
		r = prop.Attach(category, key);
sl@0
   141
		BASIC_ERROR(r, r == KErrNone);
sl@0
   142
sl@0
   143
		//	Defines the attributes and access control for a property. This can only be done 
sl@0
   144
		//	once for each property. Subsequent attempts to define the same property will return
sl@0
   145
		//	KErrAlreadyExists.
sl@0
   146
sl@0
   147
		TSecurityPolicy policy;
sl@0
   148
sl@0
   149
		r = prop.Define(type, policy, policy);
sl@0
   150
		BASIC_ERROR(r, r == KErrNone);
sl@0
   151
		r = prop.Define(type, policy, policy);
sl@0
   152
		BASIC_ERROR(r, r == KErrAlreadyExists);
sl@0
   153
		r = prop.Delete();
sl@0
   154
		BASIC_ERROR(r, r == KErrNone);
sl@0
   155
sl@0
   156
		// Define fails with KErrArgument if wrong type or attribute was specified.
sl@0
   157
		r = prop.Define(RProperty::ETypeLimit, policy, policy);
sl@0
   158
		BASIC_ERROR(r, r == KErrArgument);
sl@0
   159
sl@0
   160
		static _LIT_SECURITY_POLICY_PASS(KPassPolicy);
sl@0
   161
		TSecurityPolicy badPolicy;
sl@0
   162
		*(TInt*)&badPolicy = -1;
sl@0
   163
sl@0
   164
		r = prop.Define(type, badPolicy, policy);
sl@0
   165
		BASIC_ERROR(r, r == KErrArgument);
sl@0
   166
		r = prop.Define(type, KPassPolicy, badPolicy);
sl@0
   167
		BASIC_ERROR(r, r == KErrArgument);
sl@0
   168
	
sl@0
   169
		if (type == RProperty::EInt)
sl@0
   170
			{
sl@0
   171
			// Define fails with KErrArgument if aType is TInt and aPreallocate is not 0
sl@0
   172
			r = prop.Define(type, KPassPolicy, KPassPolicy, 16);
sl@0
   173
			BASIC_ERROR(r, r == KErrArgument);
sl@0
   174
sl@0
   175
			// Following defintion the property has a default value, 0 for integer properties
sl@0
   176
			r = prop.Define(RProperty::EInt, KPassPolicy, KPassPolicy);
sl@0
   177
			BASIC_ERROR(r, r == KErrNone);
sl@0
   178
			TInt value;
sl@0
   179
			r = prop.Get(value);
sl@0
   180
			BASIC_ERROR(r, r == KErrNone);
sl@0
   181
			BASIC_ERROR(value, value == 0);
sl@0
   182
			r = prop.Delete();
sl@0
   183
			BASIC_ERROR(r, r == KErrNone);
sl@0
   184
			}
sl@0
   185
		else 
sl@0
   186
			{
sl@0
   187
			// Defne fails with KErrTooBig if aPeallocate is grater than KMaxPropertySize.
sl@0
   188
			r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize);
sl@0
   189
			BASIC_ERROR(r, r == KErrNone);
sl@0
   190
			r = prop.Delete();
sl@0
   191
			BASIC_ERROR(r, r == KErrNone);
sl@0
   192
			r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize+1);
sl@0
   193
			BASIC_ERROR(r, r == KErrTooBig);
sl@0
   194
sl@0
   195
			// Following defintion the property has a default value, zero-length data for byte-array and text 
sl@0
   196
			// properties. 
sl@0
   197
			r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy);
sl@0
   198
			BASIC_ERROR(r, r == KErrNone);
sl@0
   199
			TBuf8<16> buf;
sl@0
   200
			r = prop.Get(buf);
sl@0
   201
			BASIC_ERROR(r, r == KErrNone);
sl@0
   202
			BASIC_ERROR(buf.Size(), buf.Size() == 0);
sl@0
   203
			r = prop.Delete();
sl@0
   204
			BASIC_ERROR(r, r == KErrNone);
sl@0
   205
			}
sl@0
   206
sl@0
   207
		// Pending subscriptions for this property will not be completed until a new value is published.
sl@0
   208
		TPropertySubsRequest subs(CompleteFn, this);
sl@0
   209
		iReason = KRequestPending;
sl@0
   210
		r = prop.Subscribe(subs);
sl@0
   211
		r = prop.Define(type, KPassPolicy, KPassPolicy);
sl@0
   212
		BASIC_ERROR(r, r == KErrNone);
sl@0
   213
		BASIC_ERROR(iReason, iReason == KRequestPending);
sl@0
   214
		r = prop.Delete();
sl@0
   215
		BASIC_ERROR(r, r == KErrNone);
sl@0
   216
		NKern::FSWait(&iSem);
sl@0
   217
		BASIC_ERROR(iReason, iReason == KErrNotFound);
sl@0
   218
sl@0
   219
		// If the property has not been defined Delete() fails with KErrNotFound.
sl@0
   220
		r = prop.Delete();
sl@0
   221
		BASIC_ERROR(r, r == KErrNotFound);
sl@0
   222
sl@0
   223
		// When deleted any pending subscriptions for the property will be completed with KErrNotFound.
sl@0
   224
		r = prop.Define(type, KPassPolicy, KPassPolicy);
sl@0
   225
		BASIC_ERROR(r, r == KErrNone);
sl@0
   226
		iReason = KRequestPending;
sl@0
   227
		r = prop.Subscribe(subs);
sl@0
   228
		BASIC_ERROR(r, r == KErrNone);
sl@0
   229
		BASIC_ERROR(iReason, iReason == KRequestPending);
sl@0
   230
		r = prop.Delete();
sl@0
   231
		BASIC_ERROR(r, r == KErrNone);
sl@0
   232
		NKern::FSWait(&iSem);
sl@0
   233
		BASIC_ERROR(iReason, iReason == KErrNotFound);
sl@0
   234
sl@0
   235
		// Any new request will not complete until the property is defined and published again.
sl@0
   236
		iReason = KRequestPending;
sl@0
   237
		r = prop.Subscribe(subs);
sl@0
   238
		BASIC_ERROR(r, r == KErrNone);
sl@0
   239
		BASIC_ERROR(iReason, iReason == KRequestPending);
sl@0
   240
		r = prop.Define(type, KPassPolicy, KPassPolicy);
sl@0
   241
		BASIC_ERROR(r, r == KErrNone);
sl@0
   242
		BASIC_ERROR(iReason, iReason == KRequestPending);
sl@0
   243
		if (type == RProperty::EInt)
sl@0
   244
			{
sl@0
   245
			r = prop.Set(1);
sl@0
   246
			BASIC_ERROR(r, r == KErrNone);
sl@0
   247
			}
sl@0
   248
		else
sl@0
   249
			{
sl@0
   250
			TBuf8<16> buf((TUint8*) "Foo");
sl@0
   251
			r = prop.Set(buf);
sl@0
   252
			BASIC_ERROR(r, r == KErrNone);
sl@0
   253
			}
sl@0
   254
		NKern::FSWait(&iSem);
sl@0
   255
		BASIC_ERROR(iReason, iReason == KErrNone);
sl@0
   256
		r = prop.Delete();
sl@0
   257
		BASIC_ERROR(r, r == KErrNone);
sl@0
   258
sl@0
   259
		// If the property has not been defined Set()/Get() fail with KErrNotFound.
sl@0
   260
			{
sl@0
   261
			TInt value;
sl@0
   262
			TBuf8<16> buf;
sl@0
   263
			if (type == RProperty::EInt)
sl@0
   264
				{
sl@0
   265
				r = prop.Get(value);
sl@0
   266
				BASIC_ERROR(r, r == KErrNotFound);
sl@0
   267
				r = prop.Set(value);
sl@0
   268
				BASIC_ERROR(r, r == KErrNotFound);
sl@0
   269
				}
sl@0
   270
			else
sl@0
   271
				{
sl@0
   272
				r = prop.Get(buf);
sl@0
   273
				BASIC_ERROR(r, r == KErrNotFound);
sl@0
   274
				r = prop.Set(buf);
sl@0
   275
				BASIC_ERROR(r, r == KErrNotFound);
sl@0
   276
				}
sl@0
   277
			}
sl@0
   278
sl@0
   279
		r = prop.Define(type, KPassPolicy, KPassPolicy);
sl@0
   280
		BASIC_ERROR(r, r == KErrNone);
sl@0
   281
sl@0
   282
		// If the property is larger than KMaxPropertySize Set() fails with KErrTooBig
sl@0
   283
			{
sl@0
   284
			if (type ==  RProperty::EByteArray)
sl@0
   285
				{
sl@0
   286
				TBuf8<RProperty::KMaxPropertySize + 1> buf(RProperty::KMaxPropertySize + 1);
sl@0
   287
				r = prop.Set(buf);
sl@0
   288
				BASIC_ERROR(r, r == KErrTooBig);
sl@0
   289
				}
sl@0
   290
			}
sl@0
   291
sl@0
   292
		// When type of operation mismatch with the property type Set()/Get() fails with KErrArgument.
sl@0
   293
			{
sl@0
   294
			if (type !=  RProperty::EInt)
sl@0
   295
				{
sl@0
   296
				TInt value;
sl@0
   297
				r = prop.Get(value);
sl@0
   298
				BASIC_ERROR(r, r == KErrArgument);
sl@0
   299
				r = prop.Set(value);
sl@0
   300
				BASIC_ERROR(r, r == KErrArgument);
sl@0
   301
				}
sl@0
   302
			else
sl@0
   303
				{
sl@0
   304
				TBuf8<16> buf;
sl@0
   305
				r = prop.Get(buf);
sl@0
   306
				BASIC_ERROR(r, r == KErrArgument);
sl@0
   307
				r = prop.Set(buf);
sl@0
   308
				BASIC_ERROR(r, r == KErrArgument);
sl@0
   309
				}
sl@0
   310
			}
sl@0
   311
sl@0
   312
		// Get/Set
sl@0
   313
		if (type == RProperty::EInt)
sl@0
   314
			{
sl@0
   315
			r = prop.Set(1);
sl@0
   316
			BASIC_ERROR(r, r == KErrNone);
sl@0
   317
			TInt value = 0;
sl@0
   318
			r = prop.Get(value);
sl@0
   319
			BASIC_ERROR(r, r == KErrNone);
sl@0
   320
			BASIC_ERROR(value, value == 1);
sl@0
   321
			}
sl@0
   322
		else 
sl@0
   323
			{
sl@0
   324
			TBuf8<16> ibuf((TUint8*)"Foo");
sl@0
   325
			TBuf8<16> obuf;
sl@0
   326
			r = prop.Set(ibuf);
sl@0
   327
			BASIC_ERROR(r, r == KErrNone);
sl@0
   328
			r = prop.Get(obuf);
sl@0
   329
			BASIC_ERROR(r, r == KErrNone);
sl@0
   330
			r = obuf.Compare(ibuf);
sl@0
   331
			BASIC_ERROR(r, r == 0);
sl@0
   332
			}
sl@0
   333
sl@0
   334
		// If the supplied buffer is too small Get() fails with KErrOverflow and the truncated value is reported.
sl@0
   335
		if (type == RProperty::EByteArray)
sl@0
   336
			{
sl@0
   337
			TBuf8<16> ibuf((TUint8*) "0123456789012345");
sl@0
   338
			TBuf8<16> obuf((TUint8*) "abcdefghigklmnop");
sl@0
   339
			TPtr8 optr((TUint8*) obuf.Ptr(), 0, 15);
sl@0
   340
			r = prop.Set(ibuf);
sl@0
   341
			BASIC_ERROR(r, r == KErrNone);
sl@0
   342
			r = prop.Get(optr);
sl@0
   343
			BASIC_ERROR(r, r == KErrOverflow);
sl@0
   344
			BASIC_ERROR(optr.Length(), optr.Length() == 15); 
sl@0
   345
			BASIC_ERROR(obuf[14], obuf[14] == '4'); 
sl@0
   346
			BASIC_ERROR(obuf[15], obuf[15] == 'p');
sl@0
   347
			}
sl@0
   348
sl@0
   349
		// The calling thread will have the specified request status signalled when the property is next updated.
sl@0
   350
		iReason = KRequestPending;
sl@0
   351
		r = prop.Subscribe(subs);
sl@0
   352
		BASIC_ERROR(r, r == KErrNone);
sl@0
   353
		BASIC_ERROR(iReason, iReason == KRequestPending);
sl@0
   354
		if (type == RProperty::EInt)
sl@0
   355
			{
sl@0
   356
			r = prop.Set(1);
sl@0
   357
			BASIC_ERROR(r, r == KErrNone);
sl@0
   358
			}
sl@0
   359
		else
sl@0
   360
			{
sl@0
   361
			TBuf8<16> buf((TUint8*) "Foo");
sl@0
   362
			r = prop.Set(buf);
sl@0
   363
			BASIC_ERROR(r, r == KErrNone);
sl@0
   364
			}
sl@0
   365
		NKern::FSWait(&iSem);
sl@0
   366
		BASIC_ERROR(iReason, iReason == KErrNone);
sl@0
   367
sl@0
   368
		r = prop.Delete();
sl@0
   369
		BASIC_ERROR(r, r == KErrNone);
sl@0
   370
sl@0
   371
		// Cancel an outstanding subscription request.
sl@0
   372
		// If it has not already completed, the request is completed with KErrCancelled.
sl@0
   373
		iReason = KRequestPending;
sl@0
   374
		r = prop.Subscribe(subs);
sl@0
   375
		BASIC_ERROR(r, r == KErrNone);
sl@0
   376
		BASIC_ERROR(iReason, iReason == KRequestPending);
sl@0
   377
		prop.Cancel(subs);		
sl@0
   378
		NKern::FSWait(&iSem);
sl@0
   379
		BASIC_ERROR(iReason, iReason == KErrCancel);
sl@0
   380
sl@0
   381
		r = prop.Define(type, KPassPolicy, KPassPolicy);
sl@0
   382
		BASIC_ERROR(r, r == KErrNone);
sl@0
   383
sl@0
   384
		iReason = KRequestPending;
sl@0
   385
		r = prop.Subscribe(subs);
sl@0
   386
		BASIC_ERROR(r, r == KErrNone);
sl@0
   387
		BASIC_ERROR(iReason, iReason == KRequestPending);
sl@0
   388
		if (type == RProperty::EInt)
sl@0
   389
			{
sl@0
   390
			r = prop.Set(1);
sl@0
   391
			BASIC_ERROR(r, r == KErrNone);
sl@0
   392
			}
sl@0
   393
		else
sl@0
   394
			{
sl@0
   395
			TBuf8<16> buf((TUint8*) "Foo");
sl@0
   396
			r = prop.Set(buf);
sl@0
   397
			BASIC_ERROR(r, r == KErrNone);
sl@0
   398
			}
sl@0
   399
		NKern::FSWait(&iSem);
sl@0
   400
		BASIC_ERROR(iReason, iReason == KErrNone);
sl@0
   401
		prop.Cancel(subs);		
sl@0
   402
		BASIC_ERROR(iReason, iReason == KErrNone);
sl@0
   403
sl@0
   404
		iReason = KRequestPending;
sl@0
   405
		r = prop.Subscribe(subs);
sl@0
   406
		BASIC_ERROR(r, r == KErrNone);
sl@0
   407
		BASIC_ERROR(iReason, iReason == KRequestPending);
sl@0
   408
		prop.Cancel(subs);		
sl@0
   409
		NKern::FSWait(&iSem);
sl@0
   410
		BASIC_ERROR(iReason, iReason == KErrCancel);
sl@0
   411
sl@0
   412
		r = prop.Delete();
sl@0
   413
		BASIC_ERROR(r, r == KErrNone);
sl@0
   414
sl@0
   415
		prop.Close();
sl@0
   416
		}
sl@0
   417
	return ETrue;
sl@0
   418
	}
sl@0
   419
sl@0
   420
//
sl@0
   421
// Client requests.
sl@0
   422
//
sl@0
   423
TBool DPropLChannel::Request(TInt aFunction, TAny* a1, TAny*)
sl@0
   424
	{
sl@0
   425
	TBool r;
sl@0
   426
	switch (aFunction)
sl@0
   427
		{
sl@0
   428
		case RPropChannel::EBasicTests:
sl@0
   429
			RPropChannel::TBasicInfo info;
sl@0
   430
			kumemget32(&info, a1, sizeof(info));
sl@0
   431
			NKern::ThreadEnterCS();
sl@0
   432
			r = Basic(&info);
sl@0
   433
			NKern::ThreadLeaveCS();
sl@0
   434
			break;	
sl@0
   435
		default:
sl@0
   436
			r = EFalse;
sl@0
   437
			break;
sl@0
   438
		}
sl@0
   439
	return r;
sl@0
   440
	}