os/ossrv/genericopenlibs/cstdlib/USTLIB/USERIAL.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) 1997-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 "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
// Implementation of STDLIB serialports.
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "FDESC.H"
sl@0
    19
#include <sys/types.h>
sl@0
    20
#include <string.h>		// for memcpy
sl@0
    21
#include <sys/errno.h>		// for ENOTSOCK
sl@0
    22
#include <sys/socket.h>
sl@0
    23
#include <sys/ioctl.h>
sl@0
    24
#include <sys/serial.h>
sl@0
    25
#include <c32comm.h>
sl@0
    26
sl@0
    27
sl@0
    28
//define this to allow the code to be built for ER5U without most of the notifications
sl@0
    29
//leave commented for all notifications
sl@0
    30
//#define ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
    31
#ifdef _DEBUG
sl@0
    32
_LIT(KCSerialDescPanic, "CSerialDesc");
sl@0
    33
#endif
sl@0
    34
sl@0
    35
//
sl@0
    36
//
sl@0
    37
// -----> CSerialTimer (implementation)
sl@0
    38
//
sl@0
    39
//
sl@0
    40
CSerialTimer::CSerialTimer()
sl@0
    41
	: CTimer(CActive::EPriorityHigh)
sl@0
    42
	  // Construct standard-priority active object
sl@0
    43
	{};
sl@0
    44
sl@0
    45
CSerialTimer* CSerialTimer::NewLC(CFileDescBase* aFile)
sl@0
    46
	{
sl@0
    47
	CSerialTimer* self=new (ELeave) CSerialTimer;
sl@0
    48
	CleanupStack::PushL(self);
sl@0
    49
	self->ConstructL(aFile);
sl@0
    50
	return self;
sl@0
    51
	}
sl@0
    52
sl@0
    53
CSerialTimer* CSerialTimer::NewL(CFileDescBase* aFile)
sl@0
    54
	{
sl@0
    55
	CSerialTimer* self = NewLC(aFile);
sl@0
    56
	CleanupStack::Pop();
sl@0
    57
	return self;
sl@0
    58
	}
sl@0
    59
sl@0
    60
void CSerialTimer::ConstructL(CFileDescBase* aFile)
sl@0
    61
	{
sl@0
    62
	  // Base class second-phase construction.
sl@0
    63
	CTimer::ConstructL();
sl@0
    64
	iFile = aFile;
sl@0
    65
	  // Add active object to active scheduler
sl@0
    66
	CActiveScheduler::Add(this); 
sl@0
    67
	}
sl@0
    68
sl@0
    69
sl@0
    70
CSerialTimer::~CSerialTimer()
sl@0
    71
	{
sl@0
    72
	  // Make sure we're cancelled
sl@0
    73
	Cancel();
sl@0
    74
	}
sl@0
    75
sl@0
    76
void CSerialTimer::DoCancel()
sl@0
    77
	{
sl@0
    78
	  // Base class
sl@0
    79
	CTimer::DoCancel(); 
sl@0
    80
	}
sl@0
    81
sl@0
    82
void CSerialTimer::IssueRequest()
sl@0
    83
	{
sl@0
    84
	  // There should never be an outstanding request at this point.
sl@0
    85
	__ASSERT_DEBUG(!IsActive(),User::Panic(KCSerialDescPanic,1));
sl@0
    86
sl@0
    87
	  // Request
sl@0
    88
	CTimer::After(iFile->TimeoutValue()*1000);
sl@0
    89
	}
sl@0
    90
sl@0
    91
void CSerialTimer::RunL()
sl@0
    92
	{
sl@0
    93
		//the timer has gone off.
sl@0
    94
	iFile->ReadCancel();
sl@0
    95
	iFile->TimedMessage = NULL;
sl@0
    96
	iFile->ReadIsTimed = EFalse;
sl@0
    97
	iFile->ReadWasCancelled = ETrue;
sl@0
    98
	delete this;
sl@0
    99
	}
sl@0
   100
sl@0
   101
sl@0
   102
sl@0
   103
/****/
sl@0
   104
NONSHARABLE_CLASS(CNotifier) : public CActive
sl@0
   105
	{
sl@0
   106
	public:
sl@0
   107
		CNotifier();
sl@0
   108
		~CNotifier();
sl@0
   109
		void IssueRequest(TInt aRequest, TInt* aRequestParams=NULL);
sl@0
   110
		static CNotifier* NewLC(CSerialDesc* aPort);
sl@0
   111
		static CNotifier* NewL(CSerialDesc* aPort);
sl@0
   112
		void Construct(CSerialDesc* aPort);
sl@0
   113
		void Complete(TInt aVal);
sl@0
   114
sl@0
   115
	private:
sl@0
   116
		enum RequestTypes {None, DataAvailable, OutputEmpty, Break, Signals, WriteErrors};
sl@0
   117
		void DoCancel();
sl@0
   118
		void RunL();
sl@0
   119
		CSerialDesc * iSerialPort;
sl@0
   120
		enum RequestTypes iRequest;
sl@0
   121
		TUint iRequestData;
sl@0
   122
		TInt* iRequestParams;
sl@0
   123
sl@0
   124
} ;
sl@0
   125
sl@0
   126
CNotifier::CNotifier() : CActive(CActive::EPriorityStandard), iRequest(None), iRequestData(0), iRequestParams(NULL)
sl@0
   127
	{
sl@0
   128
	}
sl@0
   129
sl@0
   130
sl@0
   131
void CNotifier::IssueRequest(TInt aRequest, TInt* aRequestParams)
sl@0
   132
	{
sl@0
   133
	iRequestParams = aRequestParams;
sl@0
   134
	
sl@0
   135
#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   136
	if (KNotifyDataAvailable == aRequest)
sl@0
   137
		{
sl@0
   138
		iRequest = DataAvailable;
sl@0
   139
		iSerialPort->NotifyDataAvailable(iStatus);
sl@0
   140
		}
sl@0
   141
sl@0
   142
	else if (KNotifyOutputEmpty == aRequest)
sl@0
   143
		{
sl@0
   144
		iRequest = OutputEmpty;
sl@0
   145
		iSerialPort->NotifyOutputEmpty(iStatus);
sl@0
   146
		}
sl@0
   147
	
sl@0
   148
	else if (KNotifyBreakInt == aRequest)
sl@0
   149
		{
sl@0
   150
		iRequest = Break;
sl@0
   151
		iSerialPort->NotifyBreak(iStatus);
sl@0
   152
		}
sl@0
   153
	
sl@0
   154
	else if (aRequest & (KNotifyCD|KNotifyCTS|KNotifyDSR|KNotifyRI))	//signals
sl@0
   155
		{
sl@0
   156
		TUint signalsRequested = 0;
sl@0
   157
sl@0
   158
		//build up the mask of signals to request
sl@0
   159
		if (aRequest & KNotifyCD) signalsRequested |=  KSignalDCD;
sl@0
   160
		if (aRequest & KNotifyCTS) signalsRequested |=  KSignalCTS;
sl@0
   161
		if (aRequest & KNotifyDSR) signalsRequested |=  KSignalDSR;
sl@0
   162
		if (aRequest & KNotifyRI) signalsRequested |=  KSignalRNG;
sl@0
   163
		iRequest = Signals;
sl@0
   164
		iSerialPort->NotifySignalChange(iStatus, iRequestData, signalsRequested);
sl@0
   165
		}
sl@0
   166
	
sl@0
   167
	else 
sl@0
   168
#endif	//ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   169
		if (aRequest & (KNotifyFramingError|KNotifyOverrunError|KNotifyParityError))
sl@0
   170
		{
sl@0
   171
		iRequest = WriteErrors;
sl@0
   172
		iSerialPort->NotifyWriteErrors(iStatus, &iRequestData, aRequest);
sl@0
   173
		}
sl@0
   174
		
sl@0
   175
	SetActive();
sl@0
   176
	}
sl@0
   177
sl@0
   178
void CNotifier::RunL()
sl@0
   179
	{
sl@0
   180
	//now what!
sl@0
   181
	//cancel all the others
sl@0
   182
	//use iRequest to determine what we are doing here
sl@0
   183
sl@0
   184
	CNotifier** ppn = NULL;
sl@0
   185
	switch (iRequest)
sl@0
   186
		{
sl@0
   187
#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   188
sl@0
   189
		case DataAvailable:
sl@0
   190
			iSerialPort->iNotifyParamPtr[0] = KNotifyDataAvailable;
sl@0
   191
			ppn = &iSerialPort->iDataAvailableNotifier;
sl@0
   192
			break;
sl@0
   193
sl@0
   194
		case OutputEmpty:
sl@0
   195
			iSerialPort->iNotifyParamPtr[0] = KNotifyOutputEmpty;
sl@0
   196
			ppn = &iSerialPort->iOutputEmptyNotifier;
sl@0
   197
			break;
sl@0
   198
sl@0
   199
		case Break:
sl@0
   200
			iSerialPort->iNotifyParamPtr[0] = KNotifyBreakInt;
sl@0
   201
			ppn = &iSerialPort->iBreakNotifier;
sl@0
   202
			break;
sl@0
   203
sl@0
   204
		case Signals:
sl@0
   205
			{
sl@0
   206
			ppn = &iSerialPort->iSignalsNotifier;
sl@0
   207
			iSerialPort->iNotifyParamPtr[0] = 0;
sl@0
   208
			iSerialPort->iNotifyParamPtr[1] = 0;
sl@0
   209
			if (iRequestData & KDCDChanged)
sl@0
   210
				{
sl@0
   211
				iSerialPort->iNotifyParamPtr[0] |=  KNotifyCD;
sl@0
   212
				iSerialPort->iNotifyParamPtr[1] |=  (iRequestData & KSignalDCD);
sl@0
   213
				}
sl@0
   214
sl@0
   215
			if (iRequestData & KCTSChanged)
sl@0
   216
				{
sl@0
   217
				iSerialPort->iNotifyParamPtr[0] |=  KNotifyCTS;
sl@0
   218
				iSerialPort->iNotifyParamPtr[1] |=  (iRequestData & KSignalCTS);
sl@0
   219
				}
sl@0
   220
sl@0
   221
			if (iRequestData & KDSRChanged)
sl@0
   222
				{
sl@0
   223
				iSerialPort->iNotifyParamPtr[0] |=  KNotifyDSR;
sl@0
   224
				iSerialPort->iNotifyParamPtr[1] |=  (iRequestData & KSignalDSR);
sl@0
   225
				}
sl@0
   226
sl@0
   227
			if (iRequestData & KRNGChanged)
sl@0
   228
				{
sl@0
   229
				iSerialPort->iNotifyParamPtr[0] |=  KNotifyRI;
sl@0
   230
				iSerialPort->iNotifyParamPtr[1] |=  (iRequestData & KSignalRNG);
sl@0
   231
				}
sl@0
   232
sl@0
   233
			}
sl@0
   234
			break;
sl@0
   235
#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   236
		case WriteErrors:
sl@0
   237
			{
sl@0
   238
			iSerialPort->iNotifyParamPtr[0] = iRequestData;
sl@0
   239
			iSerialPort->iNotifyParamPtr[1] = 0;
sl@0
   240
			ppn = &iSerialPort->iErrorsNotifier;
sl@0
   241
			}
sl@0
   242
			break;
sl@0
   243
sl@0
   244
		default:
sl@0
   245
			__ASSERT_DEBUG(EFalse, User::Panic(KCSerialDescPanic, 1));
sl@0
   246
			break;
sl@0
   247
		}
sl@0
   248
sl@0
   249
	//cancel all the others
sl@0
   250
	iSerialPort->CancelNotifiers(this);	//telling it who we are.
sl@0
   251
sl@0
   252
	//and complete the outstanding user request
sl@0
   253
	User::RequestComplete(iSerialPort->iNotifyStatus, iStatus.Int());
sl@0
   254
	delete this;
sl@0
   255
	if (ppn) *ppn = NULL;
sl@0
   256
	}
sl@0
   257
sl@0
   258
void CNotifier::DoCancel()
sl@0
   259
	{
sl@0
   260
	switch (iRequest)
sl@0
   261
		{
sl@0
   262
#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   263
sl@0
   264
		case DataAvailable:
sl@0
   265
			iSerialPort->NotifyDataAvailableCancel();
sl@0
   266
			break;
sl@0
   267
sl@0
   268
		case OutputEmpty:
sl@0
   269
			iSerialPort->NotifyOutputEmptyCancel();
sl@0
   270
			break;
sl@0
   271
sl@0
   272
		case Break:
sl@0
   273
			iSerialPort->NotifyBreakCancel();
sl@0
   274
			break;
sl@0
   275
sl@0
   276
		case Signals:
sl@0
   277
			iSerialPort->NotifySignalChangeCancel();
sl@0
   278
			break;
sl@0
   279
#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   280
		case WriteErrors:
sl@0
   281
			iSerialPort->NotifyWriteErrorsCancel();
sl@0
   282
			break;
sl@0
   283
sl@0
   284
		default:
sl@0
   285
			break;
sl@0
   286
		}
sl@0
   287
sl@0
   288
sl@0
   289
	}
sl@0
   290
sl@0
   291
sl@0
   292
void CNotifier::Complete(TInt aVal)
sl@0
   293
	{
sl@0
   294
	TRequestStatus* ps = &iStatus;
sl@0
   295
	User::RequestComplete(ps, aVal);
sl@0
   296
	}
sl@0
   297
sl@0
   298
sl@0
   299
CNotifier* CNotifier::NewLC(CSerialDesc* aPort)
sl@0
   300
	{
sl@0
   301
	CNotifier* self=new (ELeave) CNotifier;
sl@0
   302
	CleanupStack::PushL(self);
sl@0
   303
	self->Construct(aPort);
sl@0
   304
	return self;
sl@0
   305
	}
sl@0
   306
sl@0
   307
CNotifier* CNotifier::NewL(CSerialDesc* aPort)
sl@0
   308
	{
sl@0
   309
	CNotifier* self = NewLC(aPort);
sl@0
   310
	CleanupStack::Pop();
sl@0
   311
	return self;
sl@0
   312
	}
sl@0
   313
sl@0
   314
void CNotifier::Construct(CSerialDesc* aPort)
sl@0
   315
	{
sl@0
   316
	iSerialPort = aPort;
sl@0
   317
	CActiveScheduler::Add(this) ;  // add to active scheduler
sl@0
   318
	}
sl@0
   319
sl@0
   320
CNotifier::~CNotifier()
sl@0
   321
	{
sl@0
   322
	Cancel();
sl@0
   323
	}
sl@0
   324
sl@0
   325
sl@0
   326
/****/
sl@0
   327
sl@0
   328
sl@0
   329
sl@0
   330
// The Serial descriptor class
sl@0
   331
sl@0
   332
TInt CSerialDesc::Open(RCommServ& aSession, const wchar_t* name, int mode, int /*perms*/)
sl@0
   333
	{
sl@0
   334
	//the name will be a wide version of COM?: or IRCOM?: where ? is a number 1 to 9.
sl@0
   335
	//this has already been checked in the call to CFileDescBase open.
sl@0
   336
sl@0
   337
	
sl@0
   338
	
sl@0
   339
	TInt err = KErrArgument;
sl@0
   340
	if (L'C' == name[0])
sl@0
   341
		{
sl@0
   342
		//serial port
sl@0
   343
		//load the comms module we require
sl@0
   344
		err = aSession.LoadCommModule(_L("ECUART"));
sl@0
   345
		if (KErrAlreadyExists != err && KErrNone != err)	//problem
sl@0
   346
			return err;
sl@0
   347
		//convert the name into an epoc port name
sl@0
   348
		//eg COMM::0
sl@0
   349
		TBuf<7> epocName(_L("COMM::0"));
sl@0
   350
		epocName[6] = (TText)(name[3] - 1);
sl@0
   351
sl@0
   352
		//try opening as a dte or a dce
sl@0
   353
		err = iCommPort.Open(aSession, epocName, (enum TCommAccess)mode, ECommRoleDTE);
sl@0
   354
		if (err) 			
sl@0
   355
			err = iCommPort.Open(aSession, epocName, (enum TCommAccess)mode, ECommRoleDCE);
sl@0
   356
		}
sl@0
   357
	else
sl@0
   358
		{
sl@0
   359
		//IR port
sl@0
   360
		err = aSession.LoadCommModule(_L("IrCOMM"));
sl@0
   361
		if (KErrAlreadyExists != err && KErrNone != err)	//problem
sl@0
   362
			return err;
sl@0
   363
		//convert the name into an epoc port name
sl@0
   364
		//eg COMM::0
sl@0
   365
		TBuf<9> epocName(_L("IrCOMM::0"));
sl@0
   366
		epocName[8] = (TText)(name[5] - 1);
sl@0
   367
sl@0
   368
		//try opening as a dte or a dce
sl@0
   369
		err = iCommPort.Open(aSession, epocName, (enum TCommAccess)mode, ECommRoleDTE);
sl@0
   370
		if (err) 			
sl@0
   371
			err = iCommPort.Open(aSession, epocName, (enum TCommAccess)mode, ECommRoleDCE);
sl@0
   372
		}
sl@0
   373
	return err;
sl@0
   374
	}
sl@0
   375
sl@0
   376
void CSerialDesc::UserClose()
sl@0
   377
	{
sl@0
   378
	IoctlCancel();
sl@0
   379
	}
sl@0
   380
sl@0
   381
TInt CSerialDesc::FinalClose()
sl@0
   382
	{
sl@0
   383
	iCommPort.Close();
sl@0
   384
	return 0;
sl@0
   385
	}
sl@0
   386
sl@0
   387
sl@0
   388
sl@0
   389
sl@0
   390
TBool CSerialDesc::TimedRead()
sl@0
   391
	{
sl@0
   392
		//if we have a timeout without a threshold we need an external timer
sl@0
   393
		return (-1 != iReadTimeout && -1 == iReadThreshold);
sl@0
   394
	}
sl@0
   395
sl@0
   396
sl@0
   397
void CSerialDesc::Read(TDes8& aBuf, TRequestStatus& aStatus)
sl@0
   398
	{
sl@0
   399
	//do a read..
sl@0
   400
	//4 different ones
sl@0
   401
	if (-1 == iReadThreshold)
sl@0
   402
		{
sl@0
   403
		iCommPort.ReadOneOrMore(aStatus, aBuf);
sl@0
   404
		}
sl@0
   405
	else
sl@0
   406
		{
sl@0
   407
		TInt len = (iReadThreshold < aBuf.MaxLength() ? iReadThreshold : aBuf.MaxLength());
sl@0
   408
		if (-1 == iReadTimeout)
sl@0
   409
			{
sl@0
   410
			//read threshold with no timeout
sl@0
   411
			iCommPort.Read(aStatus, aBuf, len);
sl@0
   412
			}
sl@0
   413
		else
sl@0
   414
			{
sl@0
   415
			//read threshold and timeout
sl@0
   416
			TTimeIntervalMicroSeconds32 timeout(iReadTimeout*1000);
sl@0
   417
			iCommPort.Read(aStatus, timeout, aBuf, len);
sl@0
   418
			}
sl@0
   419
		}
sl@0
   420
sl@0
   421
	}
sl@0
   422
sl@0
   423
sl@0
   424
void CSerialDesc::Write (TDes8& aBuf, TRequestStatus& aStatus)
sl@0
   425
	{
sl@0
   426
	iCommPort.Write(aStatus, aBuf);
sl@0
   427
	}
sl@0
   428
sl@0
   429
sl@0
   430
void CSerialDesc::Ioctl(int aCmd, void* aParam, TRequestStatus& aStatus)
sl@0
   431
	{
sl@0
   432
	TInt ret=KErrNone;
sl@0
   433
	if (aParam)
sl@0
   434
		{
sl@0
   435
		
sl@0
   436
		aCmd &= ~0x4000;	//mask off the queue bit!
sl@0
   437
sl@0
   438
		switch (aCmd)
sl@0
   439
			{
sl@0
   440
			case COMMIOCTL_SETSIGNALS:
sl@0
   441
				{
sl@0
   442
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   443
				TUint setMask = (TUint)param[0];
sl@0
   444
				TUint clearMask = (TUint)param[1];
sl@0
   445
				iCommPort.SetSignals(setMask, clearMask);
sl@0
   446
				}
sl@0
   447
				break;
sl@0
   448
sl@0
   449
			case COMMIOCTL_GETSIGNALS:
sl@0
   450
				{
sl@0
   451
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   452
				TUint signals = iCommPort.Signals();
sl@0
   453
				*param = (int)signals;
sl@0
   454
				}
sl@0
   455
				break;
sl@0
   456
sl@0
   457
			case COMMIOCTL_SETCONFIG:	
sl@0
   458
				{
sl@0
   459
				SerialConfig * param =REINTERPRET_CAST(SerialConfig *,aParam);
sl@0
   460
				TCommConfig cfg;
sl@0
   461
sl@0
   462
				TCommConfigV01& cfg01 =cfg();
sl@0
   463
				
sl@0
   464
				cfg01.iRate = (enum TBps)param->iRate; 
sl@0
   465
				cfg01.iDataBits = (enum TDataBits)param->iDataBits;
sl@0
   466
				cfg01.iStopBits = (enum TStopBits)param->iStopBits; 
sl@0
   467
				cfg01.iParity = (enum TParity)param->iParity; 
sl@0
   468
				cfg01.iHandshake = param->iHandshake;
sl@0
   469
				cfg01.iParityError = param->iParityError;
sl@0
   470
				cfg01.iFifo = param->iFifo;
sl@0
   471
				cfg01.iSpecialRate = param->iSpecialRate;
sl@0
   472
				cfg01.iTerminatorCount = param->iTerminatorCount;
sl@0
   473
				cfg01.iXonChar = param->iXonChar; 
sl@0
   474
				cfg01.iXoffChar = param->iXoffChar; 
sl@0
   475
				cfg01.iParityErrorChar = param->iParityErrorChar; 
sl@0
   476
				cfg01.iSIREnable = (enum TSir)param->iSIREnable; 
sl@0
   477
				cfg01.iSIRSettings = param->iSIRSettings;
sl@0
   478
sl@0
   479
				for (int i =0; i < ConfigMaxTerminators; i++)
sl@0
   480
					cfg01.iTerminator[i] = param->iTerminator[i];
sl@0
   481
sl@0
   482
				iCommPort.SetConfig(cfg);
sl@0
   483
				}
sl@0
   484
				break;
sl@0
   485
sl@0
   486
			case COMMIOCTL_GETCONFIG:	
sl@0
   487
				{
sl@0
   488
				SerialConfig * param =REINTERPRET_CAST(SerialConfig *,aParam);
sl@0
   489
				TCommConfig cfg;
sl@0
   490
				iCommPort.Config(cfg);
sl@0
   491
				TCommConfigV01& cfg01 =cfg();
sl@0
   492
				
sl@0
   493
				param->iRate = (enum Bps)cfg01.iRate;
sl@0
   494
				param->iDataBits = (enum DataBits)cfg01.iDataBits;
sl@0
   495
				param->iStopBits = (enum StopBits)cfg01.iStopBits;
sl@0
   496
				param->iParity = (enum Parity)cfg01.iParity;
sl@0
   497
				param->iHandshake = cfg01.iHandshake;
sl@0
   498
				param->iParityError = cfg01.iParityError;
sl@0
   499
				param->iFifo = cfg01.iFifo;
sl@0
   500
				param->iSpecialRate = cfg01.iSpecialRate;
sl@0
   501
				param->iTerminatorCount = cfg01.iTerminatorCount;
sl@0
   502
				for (int i =0; i < ConfigMaxTerminators; i++)
sl@0
   503
					param->iTerminator[i] = cfg01.iTerminator[i];
sl@0
   504
				param->iXonChar = cfg01.iXonChar;
sl@0
   505
				param->iXoffChar = cfg01.iXoffChar;
sl@0
   506
				param->iParityErrorChar = cfg01.iParityErrorChar;
sl@0
   507
				param->iSIREnable = (enum Sir)cfg01.iSIREnable;
sl@0
   508
				param->iSIRSettings = cfg01.iSIRSettings;
sl@0
   509
				}
sl@0
   510
				break;
sl@0
   511
sl@0
   512
			case COMMIOCTL_BREAK:	
sl@0
   513
				{
sl@0
   514
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   515
				TTimeIntervalMicroSeconds32 time(*param);
sl@0
   516
				iCommPort.Break(aStatus, time);
sl@0
   517
				return;
sl@0
   518
				}
sl@0
   519
sl@0
   520
			case COMMIOCTL_SETREADTIMEOUT:
sl@0
   521
				{
sl@0
   522
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   523
				iReadTimeout = *param;
sl@0
   524
				}
sl@0
   525
				break;
sl@0
   526
sl@0
   527
			case COMMIOCTL_GETREADTIMEOUT:
sl@0
   528
				{
sl@0
   529
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   530
				*param = iReadTimeout;
sl@0
   531
				}
sl@0
   532
				break;
sl@0
   533
sl@0
   534
			case COMMIOCTL_SETREADTHRESHOLD:
sl@0
   535
				{
sl@0
   536
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   537
				iReadThreshold = *param;
sl@0
   538
				}
sl@0
   539
				break;
sl@0
   540
sl@0
   541
			case COMMIOCTL_GETREADTHRESHOLD:
sl@0
   542
				{
sl@0
   543
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   544
				*param = iReadThreshold;
sl@0
   545
				}
sl@0
   546
				break;
sl@0
   547
sl@0
   548
			case COMMIOCTL_SETBUFFERLENGTH:
sl@0
   549
				{
sl@0
   550
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   551
				iCommPort.SetReceiveBufferLength(TInt(*param));
sl@0
   552
				}
sl@0
   553
				break;
sl@0
   554
sl@0
   555
			case COMMIOCTL_GETBUFFERLENGTH:
sl@0
   556
				{
sl@0
   557
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   558
				*param = iCommPort.ReceiveBufferLength();
sl@0
   559
				}
sl@0
   560
				break;
sl@0
   561
sl@0
   562
			case COMMIOCTL_NOTIFYSUPPORTED:
sl@0
   563
				{
sl@0
   564
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   565
				*param = NotifiesSupported();
sl@0
   566
				}
sl@0
   567
				break;
sl@0
   568
sl@0
   569
			case REAL_COMMIOCTL_NOTIFY:
sl@0
   570
				{
sl@0
   571
				int* param =REINTERPRET_CAST(int*,aParam);
sl@0
   572
				//if they are supported
sl@0
   573
				if (RequestedNotifiesSupported(*param))
sl@0
   574
					{
sl@0
   575
					//see if we need real notifications or we are to fake them
sl@0
   576
					//always use aStatus for the final thing
sl@0
   577
					TBool wantDataAvailable = *param & KNotifyDataAvailable;
sl@0
   578
					TBool wantOutputEmpty = *param & KNotifyOutputEmpty;
sl@0
   579
					TBool wantBreakInt = *param & KNotifyBreakInt;
sl@0
   580
					TBool wantSignals = *param & (KNotifyCD|KNotifyCTS|KNotifyDSR|KNotifyRI);
sl@0
   581
					TBool wantErrors = *param & (KNotifyFramingError|KNotifyOverrunError|KNotifyParityError);
sl@0
   582
sl@0
   583
					iDataAvailableNotifier = NULL;
sl@0
   584
					iOutputEmptyNotifier = NULL;
sl@0
   585
					iBreakNotifier = NULL;
sl@0
   586
					iSignalsNotifier = NULL;
sl@0
   587
					iErrorsNotifier = NULL;
sl@0
   588
sl@0
   589
					TRAPD(tRes,
sl@0
   590
						{
sl@0
   591
						if (wantDataAvailable) iDataAvailableNotifier = CNotifier::NewL(this);
sl@0
   592
						if (wantOutputEmpty) iOutputEmptyNotifier = CNotifier::NewL(this);
sl@0
   593
						if (wantBreakInt) iBreakNotifier = CNotifier::NewL(this);
sl@0
   594
						if (wantSignals) iSignalsNotifier = CNotifier::NewL(this);
sl@0
   595
						if (wantErrors) iErrorsNotifier = CNotifier::NewL(this);
sl@0
   596
						});
sl@0
   597
					
sl@0
   598
					if (KErrNone == tRes)
sl@0
   599
						{
sl@0
   600
						//smashing, no failure, request those events
sl@0
   601
						if (wantDataAvailable) iDataAvailableNotifier->IssueRequest(KNotifyDataAvailable);
sl@0
   602
						if (wantOutputEmpty) iOutputEmptyNotifier->IssueRequest(KNotifyOutputEmpty);
sl@0
   603
						if (wantBreakInt) iBreakNotifier->IssueRequest(KNotifyBreakInt);
sl@0
   604
						if (wantSignals) iSignalsNotifier->IssueRequest(*param & (KNotifyCD|KNotifyCTS|KNotifyDSR|KNotifyRI));
sl@0
   605
						if (wantErrors) iErrorsNotifier->IssueRequest(*param & (KNotifyFramingError|KNotifyOverrunError|KNotifyParityError));
sl@0
   606
sl@0
   607
						iRequestedSignals = *param;
sl@0
   608
						iNotifyParamPtr = REINTERPRET_CAST(unsigned int*,aParam);
sl@0
   609
						iNotifyStatus = &aStatus;
sl@0
   610
						aStatus = KRequestPending;
sl@0
   611
						return;			//on an async call here
sl@0
   612
						}
sl@0
   613
					else
sl@0
   614
						{
sl@0
   615
						//deal with the problem
sl@0
   616
						//we're going to have to tidy up, delete things etc
sl@0
   617
						delete iDataAvailableNotifier;
sl@0
   618
						delete iOutputEmptyNotifier;
sl@0
   619
						delete iBreakNotifier;
sl@0
   620
						delete iSignalsNotifier;
sl@0
   621
						delete iErrorsNotifier;
sl@0
   622
						iDataAvailableNotifier = NULL;
sl@0
   623
						iOutputEmptyNotifier = NULL;
sl@0
   624
						iBreakNotifier = NULL;
sl@0
   625
						iSignalsNotifier = NULL;
sl@0
   626
						iErrorsNotifier = NULL;
sl@0
   627
						ret = tRes;
sl@0
   628
						}
sl@0
   629
sl@0
   630
					}
sl@0
   631
				else
sl@0
   632
					{
sl@0
   633
					ret = KErrNotSupported;
sl@0
   634
					*param &=~NotifiesSupported();
sl@0
   635
					}
sl@0
   636
				}
sl@0
   637
				break;
sl@0
   638
sl@0
   639
				
sl@0
   640
			default:
sl@0
   641
				ret=KErrNotSupported;
sl@0
   642
				break;
sl@0
   643
			}
sl@0
   644
		}
sl@0
   645
		else
sl@0
   646
			ret = KErrArgument;
sl@0
   647
 
sl@0
   648
	Complete(aStatus,ret);
sl@0
   649
	}
sl@0
   650
sl@0
   651
sl@0
   652
TInt CSerialDesc::IoctlCompletion(int /*aCmd*/, void* /*aParam*/, TInt aStatus)
sl@0
   653
	{
sl@0
   654
	return aStatus;
sl@0
   655
	}
sl@0
   656
sl@0
   657
sl@0
   658
void CSerialDesc::ReadCancel()
sl@0
   659
	{
sl@0
   660
	iCommPort.ReadCancel();
sl@0
   661
	}
sl@0
   662
sl@0
   663
sl@0
   664
void CSerialDesc::IoctlCancel()
sl@0
   665
	{
sl@0
   666
	//stop the ioctl if in progress
sl@0
   667
	CancelNotifiers(NULL);
sl@0
   668
sl@0
   669
	if (iNotifyStatus)
sl@0
   670
		{
sl@0
   671
		iNotifyParamPtr[0] = 0;
sl@0
   672
		Complete(*iNotifyStatus, -3);
sl@0
   673
		}
sl@0
   674
sl@0
   675
	}
sl@0
   676
sl@0
   677
TInt CSerialDesc::ReadCompletion (TDes8& /*aBuf*/, TInt aStatus)
sl@0
   678
	{
sl@0
   679
	//The read has completed.  
sl@0
   680
	//See if we need to signal 'cos it completed with an error and someone is waiting 
sl@0
   681
	//on a notification.  In which case we need to complete the request with the correct results.
sl@0
   682
	
sl@0
   683
	if ((aStatus < 0) && (iRequestedSignals&(KNotifyFramingError|KNotifyOverrunError|KNotifyParityError)))	//we have a signal outstanding we can deal with here
sl@0
   684
		{
sl@0
   685
		switch (aStatus)
sl@0
   686
			{
sl@0
   687
			case KErrCommsFrame:	//comms framing error
sl@0
   688
				if (iRequestedSignals&KNotifyFramingError)
sl@0
   689
					Notify(KNotifyFramingError);
sl@0
   690
				break;
sl@0
   691
sl@0
   692
			case KErrCommsOverrun:	//comms overrrun error
sl@0
   693
 				if (iRequestedSignals&KNotifyOverrunError)
sl@0
   694
					Notify(KNotifyOverrunError);
sl@0
   695
				break;
sl@0
   696
sl@0
   697
			case KErrCommsParity:	//comms parity error
sl@0
   698
 				if (iRequestedSignals&KNotifyParityError)
sl@0
   699
					Notify(KNotifyParityError);
sl@0
   700
				break;
sl@0
   701
			
sl@0
   702
			default:
sl@0
   703
				//an error we don't signal
sl@0
   704
				break;
sl@0
   705
sl@0
   706
			}
sl@0
   707
		}
sl@0
   708
	
sl@0
   709
	return aStatus;
sl@0
   710
	}
sl@0
   711
sl@0
   712
TBool CSerialDesc::RequestedNotifiesSupported(TInt aRequested)
sl@0
   713
	{
sl@0
   714
	//return true if these notifies are OK.  0 if any of them are illegal
sl@0
   715
sl@0
   716
	TInt mask = ~(NotifiesSupported());
sl@0
   717
	return !(aRequested&mask);
sl@0
   718
	}
sl@0
   719
sl@0
   720
TInt CSerialDesc::NotifiesSupported()
sl@0
   721
	{
sl@0
   722
	//return which notifies are supported.
sl@0
   723
	//looks like the driver/server is going to have to be interrogated here
sl@0
   724
sl@0
   725
	//start with the ones we can fake
sl@0
   726
	TInt supported = KNotifyFramingError|KNotifyOverrunError|KNotifyParityError;
sl@0
   727
	
sl@0
   728
#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   729
	//get the supported ones from C32
sl@0
   730
	TCommCaps2 devCap;
sl@0
   731
	TCommCapsV02& deviceCapabilities = devCap();
sl@0
   732
	deviceCapabilities.iNotificationCaps = 0;
sl@0
   733
	iCommPort.Caps(devCap);
sl@0
   734
sl@0
   735
sl@0
   736
	//signals
sl@0
   737
	if (deviceCapabilities.iNotificationCaps & KNotifySignalsChangeSupported)
sl@0
   738
		supported |= (KNotifyCD|KNotifyCTS|KNotifyDSR|KNotifyRI);
sl@0
   739
sl@0
   740
	//break interrupt
sl@0
   741
	if (deviceCapabilities.iNotificationCaps & KNotifyBreakSupported)
sl@0
   742
		supported |= KNotifyBreakInt;
sl@0
   743
sl@0
   744
sl@0
   745
	//Data Available
sl@0
   746
	if (deviceCapabilities.iNotificationCaps & KNotifyDataAvailableSupported)
sl@0
   747
		supported |= KNotifyDataAvailable;
sl@0
   748
sl@0
   749
	//Output Empty
sl@0
   750
	if (deviceCapabilities.iNotificationCaps & KNotifyOutputEmptySupported)
sl@0
   751
		supported |= KNotifyOutputEmpty;
sl@0
   752
sl@0
   753
#endif  //ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   754
sl@0
   755
	return supported;
sl@0
   756
	}
sl@0
   757
sl@0
   758
void CSerialDesc::Notify(TInt aVal)
sl@0
   759
	{
sl@0
   760
	if (iErrorsNotifier)
sl@0
   761
		{
sl@0
   762
//		iNotifyParamPtr[0] = aVal;
sl@0
   763
		*iRequestDataPtr = aVal;
sl@0
   764
		iErrorsNotifier->Complete(0);
sl@0
   765
		}
sl@0
   766
	}
sl@0
   767
sl@0
   768
sl@0
   769
#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   770
void CSerialDesc::NotifyDataAvailable(TRequestStatus& aStatus)
sl@0
   771
	{
sl@0
   772
	iCommPort.NotifyDataAvailable(aStatus);
sl@0
   773
	}
sl@0
   774
sl@0
   775
void CSerialDesc::NotifyDataAvailableCancel()
sl@0
   776
	{
sl@0
   777
	iCommPort.NotifyDataAvailableCancel();
sl@0
   778
	}
sl@0
   779
sl@0
   780
void CSerialDesc::NotifyOutputEmpty(TRequestStatus& aStatus)
sl@0
   781
	{
sl@0
   782
	iCommPort.NotifyOutputEmpty(aStatus);
sl@0
   783
	}
sl@0
   784
sl@0
   785
void CSerialDesc::NotifyOutputEmptyCancel()
sl@0
   786
	{
sl@0
   787
	iCommPort.NotifyOutputEmptyCancel();
sl@0
   788
	}
sl@0
   789
sl@0
   790
void CSerialDesc::NotifyBreak(TRequestStatus& aStatus)
sl@0
   791
	{
sl@0
   792
	iCommPort.NotifyBreak(aStatus);
sl@0
   793
	}
sl@0
   794
sl@0
   795
void CSerialDesc::NotifyBreakCancel()
sl@0
   796
	{
sl@0
   797
	iCommPort.NotifyBreakCancel();
sl@0
   798
	}
sl@0
   799
sl@0
   800
void CSerialDesc::NotifySignalChange(TRequestStatus& aStatus, TUint& aRequestData, TUint aSignalsMask)
sl@0
   801
	{
sl@0
   802
	iCommPort.NotifySignalChange(aStatus, aRequestData, aSignalsMask);
sl@0
   803
	}
sl@0
   804
sl@0
   805
void CSerialDesc::NotifySignalChangeCancel()
sl@0
   806
	{
sl@0
   807
	iCommPort.NotifySignalChangeCancel();
sl@0
   808
	}
sl@0
   809
#endif  //ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   810
sl@0
   811
void CSerialDesc::NotifyWriteErrors(TRequestStatus& aStatus, TUint* aRequestData, TUint aSignalsMask)
sl@0
   812
	{
sl@0
   813
	iRequestedSignals = aSignalsMask;
sl@0
   814
	iRequestDataPtr = aRequestData;
sl@0
   815
//	iNotifyParamPtr = aRequestData;
sl@0
   816
	aStatus = KRequestPending;
sl@0
   817
	}
sl@0
   818
sl@0
   819
void CSerialDesc::NotifyWriteErrorsCancel()
sl@0
   820
	{
sl@0
   821
	iErrorsNotifier->Complete(KErrCancel);
sl@0
   822
	}
sl@0
   823
sl@0
   824
TUint CSerialDesc::Signals()
sl@0
   825
	{
sl@0
   826
	return iCommPort.Signals();
sl@0
   827
	}
sl@0
   828
sl@0
   829
sl@0
   830
void CSerialDesc::CancelNotifiers(const CNotifier* aCompletedNotifier)
sl@0
   831
	{
sl@0
   832
#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   833
	if (iDataAvailableNotifier && (aCompletedNotifier != iDataAvailableNotifier))
sl@0
   834
		{
sl@0
   835
		iDataAvailableNotifier->Cancel();
sl@0
   836
		delete iDataAvailableNotifier;
sl@0
   837
		iDataAvailableNotifier = NULL;
sl@0
   838
		}
sl@0
   839
sl@0
   840
	if (iOutputEmptyNotifier && (aCompletedNotifier != iOutputEmptyNotifier))
sl@0
   841
		{
sl@0
   842
		iOutputEmptyNotifier->Cancel();
sl@0
   843
		delete iOutputEmptyNotifier;
sl@0
   844
		iOutputEmptyNotifier = NULL;
sl@0
   845
		}
sl@0
   846
	
sl@0
   847
	if (iBreakNotifier && (aCompletedNotifier != iBreakNotifier))
sl@0
   848
		{
sl@0
   849
		iBreakNotifier->Cancel();
sl@0
   850
		delete iBreakNotifier;
sl@0
   851
		iBreakNotifier = NULL;
sl@0
   852
		}
sl@0
   853
sl@0
   854
sl@0
   855
	if (iSignalsNotifier && (aCompletedNotifier != iSignalsNotifier))
sl@0
   856
		{
sl@0
   857
		iSignalsNotifier->Cancel();
sl@0
   858
		delete iSignalsNotifier;
sl@0
   859
		iSignalsNotifier = NULL;
sl@0
   860
		}
sl@0
   861
#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
sl@0
   862
	if (iErrorsNotifier && (aCompletedNotifier != iErrorsNotifier))
sl@0
   863
		{
sl@0
   864
		iErrorsNotifier->Cancel();
sl@0
   865
		delete iErrorsNotifier;
sl@0
   866
		iErrorsNotifier = NULL;
sl@0
   867
		}
sl@0
   868
	}
sl@0
   869