1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/USTLIB/USERIAL.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,869 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// Implementation of STDLIB serialports.
1.18 +//
1.19 +//
1.20 +
1.21 +#include "FDESC.H"
1.22 +#include <sys/types.h>
1.23 +#include <string.h> // for memcpy
1.24 +#include <sys/errno.h> // for ENOTSOCK
1.25 +#include <sys/socket.h>
1.26 +#include <sys/ioctl.h>
1.27 +#include <sys/serial.h>
1.28 +#include <c32comm.h>
1.29 +
1.30 +
1.31 +//define this to allow the code to be built for ER5U without most of the notifications
1.32 +//leave commented for all notifications
1.33 +//#define ER5U_NOTIFICATION_SUPPORT_ONLY
1.34 +#ifdef _DEBUG
1.35 +_LIT(KCSerialDescPanic, "CSerialDesc");
1.36 +#endif
1.37 +
1.38 +//
1.39 +//
1.40 +// -----> CSerialTimer (implementation)
1.41 +//
1.42 +//
1.43 +CSerialTimer::CSerialTimer()
1.44 + : CTimer(CActive::EPriorityHigh)
1.45 + // Construct standard-priority active object
1.46 + {};
1.47 +
1.48 +CSerialTimer* CSerialTimer::NewLC(CFileDescBase* aFile)
1.49 + {
1.50 + CSerialTimer* self=new (ELeave) CSerialTimer;
1.51 + CleanupStack::PushL(self);
1.52 + self->ConstructL(aFile);
1.53 + return self;
1.54 + }
1.55 +
1.56 +CSerialTimer* CSerialTimer::NewL(CFileDescBase* aFile)
1.57 + {
1.58 + CSerialTimer* self = NewLC(aFile);
1.59 + CleanupStack::Pop();
1.60 + return self;
1.61 + }
1.62 +
1.63 +void CSerialTimer::ConstructL(CFileDescBase* aFile)
1.64 + {
1.65 + // Base class second-phase construction.
1.66 + CTimer::ConstructL();
1.67 + iFile = aFile;
1.68 + // Add active object to active scheduler
1.69 + CActiveScheduler::Add(this);
1.70 + }
1.71 +
1.72 +
1.73 +CSerialTimer::~CSerialTimer()
1.74 + {
1.75 + // Make sure we're cancelled
1.76 + Cancel();
1.77 + }
1.78 +
1.79 +void CSerialTimer::DoCancel()
1.80 + {
1.81 + // Base class
1.82 + CTimer::DoCancel();
1.83 + }
1.84 +
1.85 +void CSerialTimer::IssueRequest()
1.86 + {
1.87 + // There should never be an outstanding request at this point.
1.88 + __ASSERT_DEBUG(!IsActive(),User::Panic(KCSerialDescPanic,1));
1.89 +
1.90 + // Request
1.91 + CTimer::After(iFile->TimeoutValue()*1000);
1.92 + }
1.93 +
1.94 +void CSerialTimer::RunL()
1.95 + {
1.96 + //the timer has gone off.
1.97 + iFile->ReadCancel();
1.98 + iFile->TimedMessage = NULL;
1.99 + iFile->ReadIsTimed = EFalse;
1.100 + iFile->ReadWasCancelled = ETrue;
1.101 + delete this;
1.102 + }
1.103 +
1.104 +
1.105 +
1.106 +/****/
1.107 +NONSHARABLE_CLASS(CNotifier) : public CActive
1.108 + {
1.109 + public:
1.110 + CNotifier();
1.111 + ~CNotifier();
1.112 + void IssueRequest(TInt aRequest, TInt* aRequestParams=NULL);
1.113 + static CNotifier* NewLC(CSerialDesc* aPort);
1.114 + static CNotifier* NewL(CSerialDesc* aPort);
1.115 + void Construct(CSerialDesc* aPort);
1.116 + void Complete(TInt aVal);
1.117 +
1.118 + private:
1.119 + enum RequestTypes {None, DataAvailable, OutputEmpty, Break, Signals, WriteErrors};
1.120 + void DoCancel();
1.121 + void RunL();
1.122 + CSerialDesc * iSerialPort;
1.123 + enum RequestTypes iRequest;
1.124 + TUint iRequestData;
1.125 + TInt* iRequestParams;
1.126 +
1.127 +} ;
1.128 +
1.129 +CNotifier::CNotifier() : CActive(CActive::EPriorityStandard), iRequest(None), iRequestData(0), iRequestParams(NULL)
1.130 + {
1.131 + }
1.132 +
1.133 +
1.134 +void CNotifier::IssueRequest(TInt aRequest, TInt* aRequestParams)
1.135 + {
1.136 + iRequestParams = aRequestParams;
1.137 +
1.138 +#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
1.139 + if (KNotifyDataAvailable == aRequest)
1.140 + {
1.141 + iRequest = DataAvailable;
1.142 + iSerialPort->NotifyDataAvailable(iStatus);
1.143 + }
1.144 +
1.145 + else if (KNotifyOutputEmpty == aRequest)
1.146 + {
1.147 + iRequest = OutputEmpty;
1.148 + iSerialPort->NotifyOutputEmpty(iStatus);
1.149 + }
1.150 +
1.151 + else if (KNotifyBreakInt == aRequest)
1.152 + {
1.153 + iRequest = Break;
1.154 + iSerialPort->NotifyBreak(iStatus);
1.155 + }
1.156 +
1.157 + else if (aRequest & (KNotifyCD|KNotifyCTS|KNotifyDSR|KNotifyRI)) //signals
1.158 + {
1.159 + TUint signalsRequested = 0;
1.160 +
1.161 + //build up the mask of signals to request
1.162 + if (aRequest & KNotifyCD) signalsRequested |= KSignalDCD;
1.163 + if (aRequest & KNotifyCTS) signalsRequested |= KSignalCTS;
1.164 + if (aRequest & KNotifyDSR) signalsRequested |= KSignalDSR;
1.165 + if (aRequest & KNotifyRI) signalsRequested |= KSignalRNG;
1.166 + iRequest = Signals;
1.167 + iSerialPort->NotifySignalChange(iStatus, iRequestData, signalsRequested);
1.168 + }
1.169 +
1.170 + else
1.171 +#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
1.172 + if (aRequest & (KNotifyFramingError|KNotifyOverrunError|KNotifyParityError))
1.173 + {
1.174 + iRequest = WriteErrors;
1.175 + iSerialPort->NotifyWriteErrors(iStatus, &iRequestData, aRequest);
1.176 + }
1.177 +
1.178 + SetActive();
1.179 + }
1.180 +
1.181 +void CNotifier::RunL()
1.182 + {
1.183 + //now what!
1.184 + //cancel all the others
1.185 + //use iRequest to determine what we are doing here
1.186 +
1.187 + CNotifier** ppn = NULL;
1.188 + switch (iRequest)
1.189 + {
1.190 +#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
1.191 +
1.192 + case DataAvailable:
1.193 + iSerialPort->iNotifyParamPtr[0] = KNotifyDataAvailable;
1.194 + ppn = &iSerialPort->iDataAvailableNotifier;
1.195 + break;
1.196 +
1.197 + case OutputEmpty:
1.198 + iSerialPort->iNotifyParamPtr[0] = KNotifyOutputEmpty;
1.199 + ppn = &iSerialPort->iOutputEmptyNotifier;
1.200 + break;
1.201 +
1.202 + case Break:
1.203 + iSerialPort->iNotifyParamPtr[0] = KNotifyBreakInt;
1.204 + ppn = &iSerialPort->iBreakNotifier;
1.205 + break;
1.206 +
1.207 + case Signals:
1.208 + {
1.209 + ppn = &iSerialPort->iSignalsNotifier;
1.210 + iSerialPort->iNotifyParamPtr[0] = 0;
1.211 + iSerialPort->iNotifyParamPtr[1] = 0;
1.212 + if (iRequestData & KDCDChanged)
1.213 + {
1.214 + iSerialPort->iNotifyParamPtr[0] |= KNotifyCD;
1.215 + iSerialPort->iNotifyParamPtr[1] |= (iRequestData & KSignalDCD);
1.216 + }
1.217 +
1.218 + if (iRequestData & KCTSChanged)
1.219 + {
1.220 + iSerialPort->iNotifyParamPtr[0] |= KNotifyCTS;
1.221 + iSerialPort->iNotifyParamPtr[1] |= (iRequestData & KSignalCTS);
1.222 + }
1.223 +
1.224 + if (iRequestData & KDSRChanged)
1.225 + {
1.226 + iSerialPort->iNotifyParamPtr[0] |= KNotifyDSR;
1.227 + iSerialPort->iNotifyParamPtr[1] |= (iRequestData & KSignalDSR);
1.228 + }
1.229 +
1.230 + if (iRequestData & KRNGChanged)
1.231 + {
1.232 + iSerialPort->iNotifyParamPtr[0] |= KNotifyRI;
1.233 + iSerialPort->iNotifyParamPtr[1] |= (iRequestData & KSignalRNG);
1.234 + }
1.235 +
1.236 + }
1.237 + break;
1.238 +#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
1.239 + case WriteErrors:
1.240 + {
1.241 + iSerialPort->iNotifyParamPtr[0] = iRequestData;
1.242 + iSerialPort->iNotifyParamPtr[1] = 0;
1.243 + ppn = &iSerialPort->iErrorsNotifier;
1.244 + }
1.245 + break;
1.246 +
1.247 + default:
1.248 + __ASSERT_DEBUG(EFalse, User::Panic(KCSerialDescPanic, 1));
1.249 + break;
1.250 + }
1.251 +
1.252 + //cancel all the others
1.253 + iSerialPort->CancelNotifiers(this); //telling it who we are.
1.254 +
1.255 + //and complete the outstanding user request
1.256 + User::RequestComplete(iSerialPort->iNotifyStatus, iStatus.Int());
1.257 + delete this;
1.258 + if (ppn) *ppn = NULL;
1.259 + }
1.260 +
1.261 +void CNotifier::DoCancel()
1.262 + {
1.263 + switch (iRequest)
1.264 + {
1.265 +#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
1.266 +
1.267 + case DataAvailable:
1.268 + iSerialPort->NotifyDataAvailableCancel();
1.269 + break;
1.270 +
1.271 + case OutputEmpty:
1.272 + iSerialPort->NotifyOutputEmptyCancel();
1.273 + break;
1.274 +
1.275 + case Break:
1.276 + iSerialPort->NotifyBreakCancel();
1.277 + break;
1.278 +
1.279 + case Signals:
1.280 + iSerialPort->NotifySignalChangeCancel();
1.281 + break;
1.282 +#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
1.283 + case WriteErrors:
1.284 + iSerialPort->NotifyWriteErrorsCancel();
1.285 + break;
1.286 +
1.287 + default:
1.288 + break;
1.289 + }
1.290 +
1.291 +
1.292 + }
1.293 +
1.294 +
1.295 +void CNotifier::Complete(TInt aVal)
1.296 + {
1.297 + TRequestStatus* ps = &iStatus;
1.298 + User::RequestComplete(ps, aVal);
1.299 + }
1.300 +
1.301 +
1.302 +CNotifier* CNotifier::NewLC(CSerialDesc* aPort)
1.303 + {
1.304 + CNotifier* self=new (ELeave) CNotifier;
1.305 + CleanupStack::PushL(self);
1.306 + self->Construct(aPort);
1.307 + return self;
1.308 + }
1.309 +
1.310 +CNotifier* CNotifier::NewL(CSerialDesc* aPort)
1.311 + {
1.312 + CNotifier* self = NewLC(aPort);
1.313 + CleanupStack::Pop();
1.314 + return self;
1.315 + }
1.316 +
1.317 +void CNotifier::Construct(CSerialDesc* aPort)
1.318 + {
1.319 + iSerialPort = aPort;
1.320 + CActiveScheduler::Add(this) ; // add to active scheduler
1.321 + }
1.322 +
1.323 +CNotifier::~CNotifier()
1.324 + {
1.325 + Cancel();
1.326 + }
1.327 +
1.328 +
1.329 +/****/
1.330 +
1.331 +
1.332 +
1.333 +// The Serial descriptor class
1.334 +
1.335 +TInt CSerialDesc::Open(RCommServ& aSession, const wchar_t* name, int mode, int /*perms*/)
1.336 + {
1.337 + //the name will be a wide version of COM?: or IRCOM?: where ? is a number 1 to 9.
1.338 + //this has already been checked in the call to CFileDescBase open.
1.339 +
1.340 +
1.341 +
1.342 + TInt err = KErrArgument;
1.343 + if (L'C' == name[0])
1.344 + {
1.345 + //serial port
1.346 + //load the comms module we require
1.347 + err = aSession.LoadCommModule(_L("ECUART"));
1.348 + if (KErrAlreadyExists != err && KErrNone != err) //problem
1.349 + return err;
1.350 + //convert the name into an epoc port name
1.351 + //eg COMM::0
1.352 + TBuf<7> epocName(_L("COMM::0"));
1.353 + epocName[6] = (TText)(name[3] - 1);
1.354 +
1.355 + //try opening as a dte or a dce
1.356 + err = iCommPort.Open(aSession, epocName, (enum TCommAccess)mode, ECommRoleDTE);
1.357 + if (err)
1.358 + err = iCommPort.Open(aSession, epocName, (enum TCommAccess)mode, ECommRoleDCE);
1.359 + }
1.360 + else
1.361 + {
1.362 + //IR port
1.363 + err = aSession.LoadCommModule(_L("IrCOMM"));
1.364 + if (KErrAlreadyExists != err && KErrNone != err) //problem
1.365 + return err;
1.366 + //convert the name into an epoc port name
1.367 + //eg COMM::0
1.368 + TBuf<9> epocName(_L("IrCOMM::0"));
1.369 + epocName[8] = (TText)(name[5] - 1);
1.370 +
1.371 + //try opening as a dte or a dce
1.372 + err = iCommPort.Open(aSession, epocName, (enum TCommAccess)mode, ECommRoleDTE);
1.373 + if (err)
1.374 + err = iCommPort.Open(aSession, epocName, (enum TCommAccess)mode, ECommRoleDCE);
1.375 + }
1.376 + return err;
1.377 + }
1.378 +
1.379 +void CSerialDesc::UserClose()
1.380 + {
1.381 + IoctlCancel();
1.382 + }
1.383 +
1.384 +TInt CSerialDesc::FinalClose()
1.385 + {
1.386 + iCommPort.Close();
1.387 + return 0;
1.388 + }
1.389 +
1.390 +
1.391 +
1.392 +
1.393 +TBool CSerialDesc::TimedRead()
1.394 + {
1.395 + //if we have a timeout without a threshold we need an external timer
1.396 + return (-1 != iReadTimeout && -1 == iReadThreshold);
1.397 + }
1.398 +
1.399 +
1.400 +void CSerialDesc::Read(TDes8& aBuf, TRequestStatus& aStatus)
1.401 + {
1.402 + //do a read..
1.403 + //4 different ones
1.404 + if (-1 == iReadThreshold)
1.405 + {
1.406 + iCommPort.ReadOneOrMore(aStatus, aBuf);
1.407 + }
1.408 + else
1.409 + {
1.410 + TInt len = (iReadThreshold < aBuf.MaxLength() ? iReadThreshold : aBuf.MaxLength());
1.411 + if (-1 == iReadTimeout)
1.412 + {
1.413 + //read threshold with no timeout
1.414 + iCommPort.Read(aStatus, aBuf, len);
1.415 + }
1.416 + else
1.417 + {
1.418 + //read threshold and timeout
1.419 + TTimeIntervalMicroSeconds32 timeout(iReadTimeout*1000);
1.420 + iCommPort.Read(aStatus, timeout, aBuf, len);
1.421 + }
1.422 + }
1.423 +
1.424 + }
1.425 +
1.426 +
1.427 +void CSerialDesc::Write (TDes8& aBuf, TRequestStatus& aStatus)
1.428 + {
1.429 + iCommPort.Write(aStatus, aBuf);
1.430 + }
1.431 +
1.432 +
1.433 +void CSerialDesc::Ioctl(int aCmd, void* aParam, TRequestStatus& aStatus)
1.434 + {
1.435 + TInt ret=KErrNone;
1.436 + if (aParam)
1.437 + {
1.438 +
1.439 + aCmd &= ~0x4000; //mask off the queue bit!
1.440 +
1.441 + switch (aCmd)
1.442 + {
1.443 + case COMMIOCTL_SETSIGNALS:
1.444 + {
1.445 + int* param =REINTERPRET_CAST(int*,aParam);
1.446 + TUint setMask = (TUint)param[0];
1.447 + TUint clearMask = (TUint)param[1];
1.448 + iCommPort.SetSignals(setMask, clearMask);
1.449 + }
1.450 + break;
1.451 +
1.452 + case COMMIOCTL_GETSIGNALS:
1.453 + {
1.454 + int* param =REINTERPRET_CAST(int*,aParam);
1.455 + TUint signals = iCommPort.Signals();
1.456 + *param = (int)signals;
1.457 + }
1.458 + break;
1.459 +
1.460 + case COMMIOCTL_SETCONFIG:
1.461 + {
1.462 + SerialConfig * param =REINTERPRET_CAST(SerialConfig *,aParam);
1.463 + TCommConfig cfg;
1.464 +
1.465 + TCommConfigV01& cfg01 =cfg();
1.466 +
1.467 + cfg01.iRate = (enum TBps)param->iRate;
1.468 + cfg01.iDataBits = (enum TDataBits)param->iDataBits;
1.469 + cfg01.iStopBits = (enum TStopBits)param->iStopBits;
1.470 + cfg01.iParity = (enum TParity)param->iParity;
1.471 + cfg01.iHandshake = param->iHandshake;
1.472 + cfg01.iParityError = param->iParityError;
1.473 + cfg01.iFifo = param->iFifo;
1.474 + cfg01.iSpecialRate = param->iSpecialRate;
1.475 + cfg01.iTerminatorCount = param->iTerminatorCount;
1.476 + cfg01.iXonChar = param->iXonChar;
1.477 + cfg01.iXoffChar = param->iXoffChar;
1.478 + cfg01.iParityErrorChar = param->iParityErrorChar;
1.479 + cfg01.iSIREnable = (enum TSir)param->iSIREnable;
1.480 + cfg01.iSIRSettings = param->iSIRSettings;
1.481 +
1.482 + for (int i =0; i < ConfigMaxTerminators; i++)
1.483 + cfg01.iTerminator[i] = param->iTerminator[i];
1.484 +
1.485 + iCommPort.SetConfig(cfg);
1.486 + }
1.487 + break;
1.488 +
1.489 + case COMMIOCTL_GETCONFIG:
1.490 + {
1.491 + SerialConfig * param =REINTERPRET_CAST(SerialConfig *,aParam);
1.492 + TCommConfig cfg;
1.493 + iCommPort.Config(cfg);
1.494 + TCommConfigV01& cfg01 =cfg();
1.495 +
1.496 + param->iRate = (enum Bps)cfg01.iRate;
1.497 + param->iDataBits = (enum DataBits)cfg01.iDataBits;
1.498 + param->iStopBits = (enum StopBits)cfg01.iStopBits;
1.499 + param->iParity = (enum Parity)cfg01.iParity;
1.500 + param->iHandshake = cfg01.iHandshake;
1.501 + param->iParityError = cfg01.iParityError;
1.502 + param->iFifo = cfg01.iFifo;
1.503 + param->iSpecialRate = cfg01.iSpecialRate;
1.504 + param->iTerminatorCount = cfg01.iTerminatorCount;
1.505 + for (int i =0; i < ConfigMaxTerminators; i++)
1.506 + param->iTerminator[i] = cfg01.iTerminator[i];
1.507 + param->iXonChar = cfg01.iXonChar;
1.508 + param->iXoffChar = cfg01.iXoffChar;
1.509 + param->iParityErrorChar = cfg01.iParityErrorChar;
1.510 + param->iSIREnable = (enum Sir)cfg01.iSIREnable;
1.511 + param->iSIRSettings = cfg01.iSIRSettings;
1.512 + }
1.513 + break;
1.514 +
1.515 + case COMMIOCTL_BREAK:
1.516 + {
1.517 + int* param =REINTERPRET_CAST(int*,aParam);
1.518 + TTimeIntervalMicroSeconds32 time(*param);
1.519 + iCommPort.Break(aStatus, time);
1.520 + return;
1.521 + }
1.522 +
1.523 + case COMMIOCTL_SETREADTIMEOUT:
1.524 + {
1.525 + int* param =REINTERPRET_CAST(int*,aParam);
1.526 + iReadTimeout = *param;
1.527 + }
1.528 + break;
1.529 +
1.530 + case COMMIOCTL_GETREADTIMEOUT:
1.531 + {
1.532 + int* param =REINTERPRET_CAST(int*,aParam);
1.533 + *param = iReadTimeout;
1.534 + }
1.535 + break;
1.536 +
1.537 + case COMMIOCTL_SETREADTHRESHOLD:
1.538 + {
1.539 + int* param =REINTERPRET_CAST(int*,aParam);
1.540 + iReadThreshold = *param;
1.541 + }
1.542 + break;
1.543 +
1.544 + case COMMIOCTL_GETREADTHRESHOLD:
1.545 + {
1.546 + int* param =REINTERPRET_CAST(int*,aParam);
1.547 + *param = iReadThreshold;
1.548 + }
1.549 + break;
1.550 +
1.551 + case COMMIOCTL_SETBUFFERLENGTH:
1.552 + {
1.553 + int* param =REINTERPRET_CAST(int*,aParam);
1.554 + iCommPort.SetReceiveBufferLength(TInt(*param));
1.555 + }
1.556 + break;
1.557 +
1.558 + case COMMIOCTL_GETBUFFERLENGTH:
1.559 + {
1.560 + int* param =REINTERPRET_CAST(int*,aParam);
1.561 + *param = iCommPort.ReceiveBufferLength();
1.562 + }
1.563 + break;
1.564 +
1.565 + case COMMIOCTL_NOTIFYSUPPORTED:
1.566 + {
1.567 + int* param =REINTERPRET_CAST(int*,aParam);
1.568 + *param = NotifiesSupported();
1.569 + }
1.570 + break;
1.571 +
1.572 + case REAL_COMMIOCTL_NOTIFY:
1.573 + {
1.574 + int* param =REINTERPRET_CAST(int*,aParam);
1.575 + //if they are supported
1.576 + if (RequestedNotifiesSupported(*param))
1.577 + {
1.578 + //see if we need real notifications or we are to fake them
1.579 + //always use aStatus for the final thing
1.580 + TBool wantDataAvailable = *param & KNotifyDataAvailable;
1.581 + TBool wantOutputEmpty = *param & KNotifyOutputEmpty;
1.582 + TBool wantBreakInt = *param & KNotifyBreakInt;
1.583 + TBool wantSignals = *param & (KNotifyCD|KNotifyCTS|KNotifyDSR|KNotifyRI);
1.584 + TBool wantErrors = *param & (KNotifyFramingError|KNotifyOverrunError|KNotifyParityError);
1.585 +
1.586 + iDataAvailableNotifier = NULL;
1.587 + iOutputEmptyNotifier = NULL;
1.588 + iBreakNotifier = NULL;
1.589 + iSignalsNotifier = NULL;
1.590 + iErrorsNotifier = NULL;
1.591 +
1.592 + TRAPD(tRes,
1.593 + {
1.594 + if (wantDataAvailable) iDataAvailableNotifier = CNotifier::NewL(this);
1.595 + if (wantOutputEmpty) iOutputEmptyNotifier = CNotifier::NewL(this);
1.596 + if (wantBreakInt) iBreakNotifier = CNotifier::NewL(this);
1.597 + if (wantSignals) iSignalsNotifier = CNotifier::NewL(this);
1.598 + if (wantErrors) iErrorsNotifier = CNotifier::NewL(this);
1.599 + });
1.600 +
1.601 + if (KErrNone == tRes)
1.602 + {
1.603 + //smashing, no failure, request those events
1.604 + if (wantDataAvailable) iDataAvailableNotifier->IssueRequest(KNotifyDataAvailable);
1.605 + if (wantOutputEmpty) iOutputEmptyNotifier->IssueRequest(KNotifyOutputEmpty);
1.606 + if (wantBreakInt) iBreakNotifier->IssueRequest(KNotifyBreakInt);
1.607 + if (wantSignals) iSignalsNotifier->IssueRequest(*param & (KNotifyCD|KNotifyCTS|KNotifyDSR|KNotifyRI));
1.608 + if (wantErrors) iErrorsNotifier->IssueRequest(*param & (KNotifyFramingError|KNotifyOverrunError|KNotifyParityError));
1.609 +
1.610 + iRequestedSignals = *param;
1.611 + iNotifyParamPtr = REINTERPRET_CAST(unsigned int*,aParam);
1.612 + iNotifyStatus = &aStatus;
1.613 + aStatus = KRequestPending;
1.614 + return; //on an async call here
1.615 + }
1.616 + else
1.617 + {
1.618 + //deal with the problem
1.619 + //we're going to have to tidy up, delete things etc
1.620 + delete iDataAvailableNotifier;
1.621 + delete iOutputEmptyNotifier;
1.622 + delete iBreakNotifier;
1.623 + delete iSignalsNotifier;
1.624 + delete iErrorsNotifier;
1.625 + iDataAvailableNotifier = NULL;
1.626 + iOutputEmptyNotifier = NULL;
1.627 + iBreakNotifier = NULL;
1.628 + iSignalsNotifier = NULL;
1.629 + iErrorsNotifier = NULL;
1.630 + ret = tRes;
1.631 + }
1.632 +
1.633 + }
1.634 + else
1.635 + {
1.636 + ret = KErrNotSupported;
1.637 + *param &=~NotifiesSupported();
1.638 + }
1.639 + }
1.640 + break;
1.641 +
1.642 +
1.643 + default:
1.644 + ret=KErrNotSupported;
1.645 + break;
1.646 + }
1.647 + }
1.648 + else
1.649 + ret = KErrArgument;
1.650 +
1.651 + Complete(aStatus,ret);
1.652 + }
1.653 +
1.654 +
1.655 +TInt CSerialDesc::IoctlCompletion(int /*aCmd*/, void* /*aParam*/, TInt aStatus)
1.656 + {
1.657 + return aStatus;
1.658 + }
1.659 +
1.660 +
1.661 +void CSerialDesc::ReadCancel()
1.662 + {
1.663 + iCommPort.ReadCancel();
1.664 + }
1.665 +
1.666 +
1.667 +void CSerialDesc::IoctlCancel()
1.668 + {
1.669 + //stop the ioctl if in progress
1.670 + CancelNotifiers(NULL);
1.671 +
1.672 + if (iNotifyStatus)
1.673 + {
1.674 + iNotifyParamPtr[0] = 0;
1.675 + Complete(*iNotifyStatus, -3);
1.676 + }
1.677 +
1.678 + }
1.679 +
1.680 +TInt CSerialDesc::ReadCompletion (TDes8& /*aBuf*/, TInt aStatus)
1.681 + {
1.682 + //The read has completed.
1.683 + //See if we need to signal 'cos it completed with an error and someone is waiting
1.684 + //on a notification. In which case we need to complete the request with the correct results.
1.685 +
1.686 + if ((aStatus < 0) && (iRequestedSignals&(KNotifyFramingError|KNotifyOverrunError|KNotifyParityError))) //we have a signal outstanding we can deal with here
1.687 + {
1.688 + switch (aStatus)
1.689 + {
1.690 + case KErrCommsFrame: //comms framing error
1.691 + if (iRequestedSignals&KNotifyFramingError)
1.692 + Notify(KNotifyFramingError);
1.693 + break;
1.694 +
1.695 + case KErrCommsOverrun: //comms overrrun error
1.696 + if (iRequestedSignals&KNotifyOverrunError)
1.697 + Notify(KNotifyOverrunError);
1.698 + break;
1.699 +
1.700 + case KErrCommsParity: //comms parity error
1.701 + if (iRequestedSignals&KNotifyParityError)
1.702 + Notify(KNotifyParityError);
1.703 + break;
1.704 +
1.705 + default:
1.706 + //an error we don't signal
1.707 + break;
1.708 +
1.709 + }
1.710 + }
1.711 +
1.712 + return aStatus;
1.713 + }
1.714 +
1.715 +TBool CSerialDesc::RequestedNotifiesSupported(TInt aRequested)
1.716 + {
1.717 + //return true if these notifies are OK. 0 if any of them are illegal
1.718 +
1.719 + TInt mask = ~(NotifiesSupported());
1.720 + return !(aRequested&mask);
1.721 + }
1.722 +
1.723 +TInt CSerialDesc::NotifiesSupported()
1.724 + {
1.725 + //return which notifies are supported.
1.726 + //looks like the driver/server is going to have to be interrogated here
1.727 +
1.728 + //start with the ones we can fake
1.729 + TInt supported = KNotifyFramingError|KNotifyOverrunError|KNotifyParityError;
1.730 +
1.731 +#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
1.732 + //get the supported ones from C32
1.733 + TCommCaps2 devCap;
1.734 + TCommCapsV02& deviceCapabilities = devCap();
1.735 + deviceCapabilities.iNotificationCaps = 0;
1.736 + iCommPort.Caps(devCap);
1.737 +
1.738 +
1.739 + //signals
1.740 + if (deviceCapabilities.iNotificationCaps & KNotifySignalsChangeSupported)
1.741 + supported |= (KNotifyCD|KNotifyCTS|KNotifyDSR|KNotifyRI);
1.742 +
1.743 + //break interrupt
1.744 + if (deviceCapabilities.iNotificationCaps & KNotifyBreakSupported)
1.745 + supported |= KNotifyBreakInt;
1.746 +
1.747 +
1.748 + //Data Available
1.749 + if (deviceCapabilities.iNotificationCaps & KNotifyDataAvailableSupported)
1.750 + supported |= KNotifyDataAvailable;
1.751 +
1.752 + //Output Empty
1.753 + if (deviceCapabilities.iNotificationCaps & KNotifyOutputEmptySupported)
1.754 + supported |= KNotifyOutputEmpty;
1.755 +
1.756 +#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
1.757 +
1.758 + return supported;
1.759 + }
1.760 +
1.761 +void CSerialDesc::Notify(TInt aVal)
1.762 + {
1.763 + if (iErrorsNotifier)
1.764 + {
1.765 +// iNotifyParamPtr[0] = aVal;
1.766 + *iRequestDataPtr = aVal;
1.767 + iErrorsNotifier->Complete(0);
1.768 + }
1.769 + }
1.770 +
1.771 +
1.772 +#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
1.773 +void CSerialDesc::NotifyDataAvailable(TRequestStatus& aStatus)
1.774 + {
1.775 + iCommPort.NotifyDataAvailable(aStatus);
1.776 + }
1.777 +
1.778 +void CSerialDesc::NotifyDataAvailableCancel()
1.779 + {
1.780 + iCommPort.NotifyDataAvailableCancel();
1.781 + }
1.782 +
1.783 +void CSerialDesc::NotifyOutputEmpty(TRequestStatus& aStatus)
1.784 + {
1.785 + iCommPort.NotifyOutputEmpty(aStatus);
1.786 + }
1.787 +
1.788 +void CSerialDesc::NotifyOutputEmptyCancel()
1.789 + {
1.790 + iCommPort.NotifyOutputEmptyCancel();
1.791 + }
1.792 +
1.793 +void CSerialDesc::NotifyBreak(TRequestStatus& aStatus)
1.794 + {
1.795 + iCommPort.NotifyBreak(aStatus);
1.796 + }
1.797 +
1.798 +void CSerialDesc::NotifyBreakCancel()
1.799 + {
1.800 + iCommPort.NotifyBreakCancel();
1.801 + }
1.802 +
1.803 +void CSerialDesc::NotifySignalChange(TRequestStatus& aStatus, TUint& aRequestData, TUint aSignalsMask)
1.804 + {
1.805 + iCommPort.NotifySignalChange(aStatus, aRequestData, aSignalsMask);
1.806 + }
1.807 +
1.808 +void CSerialDesc::NotifySignalChangeCancel()
1.809 + {
1.810 + iCommPort.NotifySignalChangeCancel();
1.811 + }
1.812 +#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
1.813 +
1.814 +void CSerialDesc::NotifyWriteErrors(TRequestStatus& aStatus, TUint* aRequestData, TUint aSignalsMask)
1.815 + {
1.816 + iRequestedSignals = aSignalsMask;
1.817 + iRequestDataPtr = aRequestData;
1.818 +// iNotifyParamPtr = aRequestData;
1.819 + aStatus = KRequestPending;
1.820 + }
1.821 +
1.822 +void CSerialDesc::NotifyWriteErrorsCancel()
1.823 + {
1.824 + iErrorsNotifier->Complete(KErrCancel);
1.825 + }
1.826 +
1.827 +TUint CSerialDesc::Signals()
1.828 + {
1.829 + return iCommPort.Signals();
1.830 + }
1.831 +
1.832 +
1.833 +void CSerialDesc::CancelNotifiers(const CNotifier* aCompletedNotifier)
1.834 + {
1.835 +#ifndef ER5U_NOTIFICATION_SUPPORT_ONLY
1.836 + if (iDataAvailableNotifier && (aCompletedNotifier != iDataAvailableNotifier))
1.837 + {
1.838 + iDataAvailableNotifier->Cancel();
1.839 + delete iDataAvailableNotifier;
1.840 + iDataAvailableNotifier = NULL;
1.841 + }
1.842 +
1.843 + if (iOutputEmptyNotifier && (aCompletedNotifier != iOutputEmptyNotifier))
1.844 + {
1.845 + iOutputEmptyNotifier->Cancel();
1.846 + delete iOutputEmptyNotifier;
1.847 + iOutputEmptyNotifier = NULL;
1.848 + }
1.849 +
1.850 + if (iBreakNotifier && (aCompletedNotifier != iBreakNotifier))
1.851 + {
1.852 + iBreakNotifier->Cancel();
1.853 + delete iBreakNotifier;
1.854 + iBreakNotifier = NULL;
1.855 + }
1.856 +
1.857 +
1.858 + if (iSignalsNotifier && (aCompletedNotifier != iSignalsNotifier))
1.859 + {
1.860 + iSignalsNotifier->Cancel();
1.861 + delete iSignalsNotifier;
1.862 + iSignalsNotifier = NULL;
1.863 + }
1.864 +#endif //ER5U_NOTIFICATION_SUPPORT_ONLY
1.865 + if (iErrorsNotifier && (aCompletedNotifier != iErrorsNotifier))
1.866 + {
1.867 + iErrorsNotifier->Cancel();
1.868 + delete iErrorsNotifier;
1.869 + iErrorsNotifier = NULL;
1.870 + }
1.871 + }
1.872 +