diff -r 000000000000 -r dfb7c4ff071f serialserver/c32serialserver/CCOMM/CC_CLI.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/serialserver/c32serialserver/CCOMM/CC_CLI.CPP Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,1675 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif + +#include "CS_STD.H" +#include "C32LOG.H" + +/** @file + * + * Implements the client side code of C32, including RCommServ and RComm + */ + + +const TUint KDefaultMessageSlots = 16; //< number of slots in the Client/Server message buffer + + +// +// implementation of RCommServ +// + + +EXPORT_C RCommServ::RCommServ() +/** Default constructor. +@capability None +*/ + { + } + + +EXPORT_C TInt RCommServ::Connect() +/** Connects a client process to the comms server. + +Use this function to open a session to the Comms server. +Default number of message slots is defined in KDefaultMessageSlots. + +Notes: + +1. RHandleBase + provides the necessary Close() function, which should be called when the server + session is no longer required. Note that the kernel completes the Close() function immediately + and so RCommServ resources still used by this client may not yet have been released at the time + the Close() returns. A consequence of this is that an attempt to open a port previously opened + for exclusive use in a session that is still closing might fail. +2. Older versions of Symbian OS specified that a call to "StartC32" was required before a call to + this Connect(). However, C32 Serial server is now started automatically during device boot + so this is not necessary unless the application is to run in a non-standard GUI environment. + + +@return System-wide error code +@capability None +*/ + { + TInt r = CreateSession(KCommServerName(), Version(), KDefaultMessageSlots); + if (r==KErrNotFound) + { + // attempt to start the comms system. This is normally done on device boot but to support + // any old test environments we still try here as well. This is a deprecated behaviour that + // results in warnings in the log file + r = StartC32(); + if (r==KErrNone) + r=CreateSession(KCommServerName(), Version(), KDefaultMessageSlots); + } + return(r); + } + + +EXPORT_C TVersion RCommServ::Version() const +/** Returns the client side version number. + +Use this function to get the version number. The version number may be +incremented in future releases of the comms server. If extra features are +added in such releases, the version number may be used by application programs +as a basis for assessing the capabilities of the comms server. Version-specific +functions will be marked as such in the SDK documentation. + +@return Version number. +@capability None +*/ + { + return(TVersion(KEC32MajorVersionNumber, KEC32MinorVersionNumber, KEC32BuildVersionNumber)); + } + +EXPORT_C TInt RCommServ::LoadCommModule(const TDesC& aFileName) +/** Loads a comms module. + +Use this function to load a CSY comms module. These are protocol modules that C32 Serial Server uses to +understand how to handle a particular port. + +Notes: + +1. There is no need for an extension, as ".CSY" is automatically appended by + this function. + +2. This function only loads CSYs that have been installed correctly into one of the system's /sys/bin directories + +3. If the module has already been loaded by another client, this function will increment + the reference to the module. + +4. It is not an error to load the same module twice or more, although there is no practical + application for this ability. On each subsequent load for the same module the reference count + is simply incremented. When the session is closed, all module references are removed including + references from repeated loading of the same module. + +5. There is no limit to the number of modules that can be loaded from within a single session. + +With the exception of some hardware configurations, four modules are normally available as standard: + + ECUART is used to address appropriate serial ports in RS232 mode. It is normally customised for a device. + + IRCOMM drives the infrared port in infrared mode. + + BTCOMM drives the Bluetooth emulated serial port. + + ECACM drives the USB port(s). + +@param aFileName Name of the file to load as a module, optionally containing the ".CSY" extension. +The filename may include the full path including drive letter for the CSY. +@return KErrNone if the load operation is successful; KErrServerTerminated if the server no longer present; + KErrServerBusy if there are no message slots available; KErrNoMemory if there is insufficient memory available; + KErrBadLibraryEntryPoint if the CSY fails the consistency check; KErrNotFound if the CSY or other component + or service required to load it is not found; other return codes are possible from the CSY itself. +@capability None +*/ + { + // No means to insert a 16-bit string into an 8-bit string, so all is 16-bit + C32_STATIC_LOG2(KC32Client,_L("RCommServ::LoadCommModule() : %S"), &aFileName); + + TIpcArgs args(&aFileName); + return SendReceive(ECommLoadCommModule, args); + } + + +EXPORT_C TInt RCommServ::UnloadCommModule(const TDesC& aName) +/** Remove this client's reference to the named communications module. If this is the +last client to reference the communications module, the module is unloaded. + +Note: + +There is no need to unload a comms module when the connection to the +server is closed, as this is done automatically by the C32 Server. For example, the following code will not result in a leak: +@code + _LIT(KCSYName,"ECUART"); + RCommServ commSession; + if (commSession.Connect() == KErrNone) + { + TInt ret = commSession.LoadCommModule(KCSYName); + commSession.Close(); + } +@endcode + +@param aName Name of the module to unload described in Port Prefix format. This may not necessarily be +the same name as that used to load the module. +Examples: +The ECUART module, where supplied, is loaded via "ECUART" or "ECUART.CSY" but unloaded via "COMM". +The infrared module, where supplied, is loaded via "IRCOMM.CSY" or "IRCOMM" but unloaded only via "IRCOMM". +@return System wide error code. + +*/ + { + C32_STATIC_LOG2(KC32Client,_L("RCommServ::UnloadCommModule() : %S"), &aName); + + TIpcArgs args(&aName); + return SendReceive(ECommCloseCommModule, args); + } + + +EXPORT_C TInt RCommServ::NumPorts(TInt& aCount) +/** Get the number of unique comms modules (CSYs) loaded into C32. + +This number includes modules loaded by other sessions. + +@param aCount On return, holds the number of loaded CSYs +@return System wide error code. +@capability None +*/ + { + TPckg num(aCount); + TIpcArgs args(&num); + return SendReceive(ECommNumPorts,args); + } + + +EXPORT_C TInt RCommServ::GetPortInfo(const TDesC& aName, TSerialInfo& aInfo) +/** Gets static information about the available serial ports for a particular comms module. + +This variant enables the comms module to be specified in Port Prefix format or by filename. + +There is no wildcard support. + +Notes: + +1. This API only returns static information about the available ports as they were when the module loaded, so +ports listed as available may actually be in use exclusively by another client at the time of this call. + +2. The information returned does not account for any security restrictions on ports, and so does not check +whether the client has the capabilities to open all the advertised ports. + +@param aName The name of the comms module in Port Prefix format (eg "COMM" for RS232), +or the filename of the CSY as supplied to LoadCommModule() excluding + the ".CSY" extension (eg "ECUART" for RS232). The supplied name will be truncated to be KMaxPortName (16) characters long. +@param aInfo On return, contains information about the ports available, including +the high and low unit numbers and their name in Port Prefix format. +@return KErrNone, if the send operation is successful; +KErrServerTerminated, if the server is no longer present; +KErrServerBusy, if there are no message slots available; +KErrNoMemory, if there is insufficient memory available. +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L("RCommServ::GetPortInfo() for comms module : %S"), &aName); + TPckg portDesc(aInfo); + TIpcArgs args(&portDesc,&aName); + return SendReceive(ECommPortInfoByName, args); + } + + +EXPORT_C TInt RCommServ::GetPortInfo(TInt aIndex, TDes& aModuleName, TSerialInfo& aInfo) +/** Gets static information about the available serial ports for a particular comms module. + +This variant enables the comms module to be specified by an index number +from 0, enabling iteration through the loaded comms modules. Call NumPorts() to obtain +the current number of loaded comms modules. + +Notes: + +1. This API only returns static information about the available ports as they were when the module loaded, so +ports listed as available may actually be in use exclusively by another client at the time of this call. + +2. The information returned does not account for any security restrictions on ports, and so does not check +whether the client has the capabilities to open all the advertised ports. + +3. If another C32 client unloads a CSY module, the index of each of + the remaining modules may change. If + a client is attempting to iterate through all the open modules when this occurs, the iteration may miss + a module or receive KErrNotFound unexpectedly. This behaviour can be detected by + observing that the value returned by NumPorts() changes. + + + +@param aIndex Index number of the comms module, starting at 0. +@param aModuleName On return, contains the name of the comms module referred +to by aIndex. This name is expressed as the filename without the path or extension, and the case is +not specified since it is determined by the first request to LoadCommModule. + +@param aInfo On return, contains information about the ports available, including +the high and low unit numbers and their name. +@return KErrNone, if the send operation is successful; +KErrServerTerminated, if the server is no longer present; +KErrServerBusy, if there are no message slots available; +KErrNoMemory, if there is insufficient memory available. +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RCommServ::GetPortInfo() for comms module of index number : %d"), aIndex); + TPckg portDesc(aInfo); + TIpcArgs args(&portDesc,&aModuleName,aIndex); + return SendReceive(ECommPortInfoByNumber, args); + } + + +EXPORT_C TInt RCommServ::__DbgMarkHeap() +/** Sets a heap mark in the comm server + +Only valid for Debug builds. + +@return System wide error code. +@capability None +*/ + { +#ifdef _DEBUG + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommDbgMarkHeap, args); +#else + return KErrNone; +#endif + } + + +EXPORT_C TInt RCommServ::__DbgCheckHeap(TInt aCount) +/** Checks the heap mark in the comm server + +Only valid for Debug builds. +@capability None +*/ + { +#ifdef _DEBUG + TIpcArgs args(aCount); + return SendReceive(ECommDbgCheckHeap, args); +#else + (void)aCount; // not used for Release builds + return KErrNone; +#endif + } + + +EXPORT_C TInt RCommServ::__DbgMarkEnd(TInt aCount) +/** Sets the heap mark end in the comm server + +Only valid for Debug builds. +@capability None +*/ + { +#ifdef _DEBUG + TIpcArgs args(aCount); + return SendReceive(ECommDbgMarkEnd, args); +#else + (void)aCount; // not used for Release builds + return KErrNone; +#endif + } + + +EXPORT_C TInt RCommServ::__DbgFailNext(TInt aCount) +/** Emulates a single fail next heap allocation in the comm server. +If C32 is running multiple threads the same request is passed to each thread. Each C32 thread +will only act on this request if it has not already been configured for heap failures via CMI files. + +@param aCount Specifies that after aCount-1 successful allocations the failure will occur on the next +allocation - ie the failure will occur on the aCount allocation attempt. + A value less than zero cancels any outstanding failure request. A value of zero is equivalent to a value + of one - ie, fail on the next attempt. + +Only valid for Debug builds. +@capability None +*/ + { +#ifdef _DEBUG + TIpcArgs args(aCount); + return SendReceive(ECommDbgFailNext,args); +#else + (void)aCount; // not used for Release builds + return KErrNone; +#endif + } + + +EXPORT_C TInt RCommServ::__DbgSetTraceMask(TC32Trace aMask) +/** The functionality of this API has been removed. + +Where tracing is required, please refer to the Comms Infrastructure documentation +on logging. + +@param aMask This value is not used. +@return Always KErrNone. +@capability None +*/ + { +#ifdef _DEBUG + (void)aMask; // aMask is of no use + // At one time this function would send ECommDbgSetDebugPrintMask to the server, but + // the server hasn't supported this function since at least the last release of EPOC5. + return KErrNone; +#else + (void)aMask; // not used for Release builds + return KErrNone; +#endif + } + +EXPORT_C TInt RCommServ::CreateThreadInCommProc(const TDesC&, const TDesC&, TThreadFunction, TInt aStackSize, TInt aHeapMinSize, TInt aHeapMaxSize) +/** This functionality has been withdrawn since the introduction of Platform Security. + +This API has been replaced with a more secure and controlled model for loading threads + into the Comms process, known as the Configurator. The Configurator requires a Comms Provider Module + (DLL) to be available that provides the code for the thread to execute, and a configuration file + that describes to the Configurator how to manage the Comms Provider Module. + Further information on this is only available in documentation libraries that include the Configurator documentation. + +@param aLibraryName This value is not used. +@param aThreadName This value is not used. +@param aFunction This value is not used. +@param aStackSize A negative value will result in a panic. +@param aHeapMinSize A value less than KMinHeapSize will result in a panic. +@param aHeapMaxSize A value less than aHeapMinSize will result in a panic. +@return Always KErrNotSupported. +@capability CommDD (Deprecate) +*/ + +/* Please refer to the Rootserver component documentation for more information. +*/ + + { + C32_STATIC_LOG(KC32Warning,_L8("WARNING: Call to deprecated function CreateThreadInCommProc.")); + + _LIT(KCommClientPanic,"Comm client"); // panic the client here rather than panicking the C32 server + // thread + __ASSERT_ALWAYS(aStackSize>=0,User::Panic(KCommClientPanic,EThrdStackSizeNegative)); + __ASSERT_ALWAYS(aHeapMinSize>=KMinHeapSize,User::Panic(KCommClientPanic,EThreadHeapMinTooSmall)); + __ASSERT_ALWAYS(aHeapMaxSize>=aHeapMinSize,User::Panic(KCommClientPanic,EThreadHeapMaxLessThanMin)); + + return KErrNotSupported; + } + +TBool RCommServ::IsServerThreadL() +/** + * Return TRUE if this thread is the C32 main thread + * + * @note This function is not as water tight as it could be. This is due to a limitation + * in our ability to get the thread name. Under non-WINS builds the thread name is + * (even after we rename it) a combination of process name, OS data and thread name. + * Therefore we search for a thread name ending in "CommServer" and belonging to + * the C32 process. If another process started a thread in C32 via the + * CreateThreadInCommProc() call with a name ending in "CommServer" then this + * function may start to produce incorrect results. + * + * @return ETrue if this is the C32 main server thread + */ + { + TInt res = KErrNone; + TFullName name; + + // + // Find the Process ID of the C32 process. Note that WINS builds run the C32 'process' + // as a thread and not a separate process. + // +#ifndef __WINS__ + _LIT(KCommProcessName, "C32exe*"); + + RProcess cpProcess; + TFindProcess findCp(KCommProcessName); + res = findCp.Next(name); + __ASSERT_ALWAYS(res==KErrNone,User::Invariant()); + res = cpProcess.Open(findCp); + (void) User::LeaveIfError(res); + + TProcessId cpid = cpProcess.Id(); + cpProcess.Close(); + + // + // A quick short cut. Is this process C32? If not then this thread cannot be the + // server thread. + // + if (RProcess().Id() != cpid) + { + return (EFalse); + } +#endif + + // + // Search for the the C32 comm server thread. For non-WINS builds get the Process + // ID of the thread and confirm it matches the C32 Process ID. + // + RThread ctThread; + //thread name comes from C32.cmi file. + _LIT(KCommThreadName, "CCommServer"); + TFindThread findCt(KCommThreadName); + while((res=findCt.Next(name))==KErrNone) + { + (void)User::LeaveIfError(ctThread.Open(KCommThreadName)); // ignoring return value +#ifdef __WINS__ + break; +#else + if((res=ctThread.Process(cpProcess))!=KErrNone) + { + ctThread.Close(); + User::Leave(res); + } + TProcessId pid=cpProcess.Id(); + cpProcess.Close(); + + // + // We already know that this process is the C32 process. Does the found thread + // belong to C32? If so then ctThread is the C32 main thread. + // + if(pid==cpid) + { + break; + } + ctThread.Close(); +#endif + } + if (res==KErrNotFound) + return EFalse; // if the C32 thread is not running, then this thread cannot be it! + (void)User::LeaveIfError(res); // ignoring return value + + // + // Is this thread the C32 Comm Server thread that we just found? + // + TBool match=(ctThread.Id()==RThread().Id()); + ctThread.Close(); + + return match; // Return TRUE if this thread is the C32 main thread + } + +// +// implementation of RComm +// + +EXPORT_C RComm::RComm() +/** Constructor */ + : iSignalsNotification(NULL,0,0) + ,iFlowNotification(NULL,0,0) + { + } + + +EXPORT_C TInt RComm::Open(RCommServ& aServer, const TDesC& aName, TCommAccess aMode) +/** Opens a serial port, for one of the three modes indicated by the TCommAccess +argument. + +The TCommAccess argument may dictate exclusive use of the RComm, +shared use (thereby giving permission for the port to be shared by other RComm +objects) or pre-emptable use (allowing another client to pre-empt this session +with an open request in one of the other two modes). The request will fail if +the port does not exist, or if it has been opened in exclusive mode elsewhere. +If the port has been opened in shared mode elsewhere, the request will fail if +a subsequent attempt is made to open it in exclusive mode. +A client opening a port in pre-emptive mode must be prepared to have its +outstanding requests errored with KErrCancel if another client opens the port +in either ECommShared or ECommExclusive mode. In this case the port handle +will effectively be transferred from the pre-emptable client to the new client. + +The first variant (this) will open the port in DTE role, that is, the lines +are configured as for a port of a computer. For instance, the signal lines +DTR and RTS are outputs while the other signals (DCD,CTS,DSR,RING) are inputs. + +The second variant allows the port to be opened in either DTE role or DCE +role. This latter role means that the lines are configured as for a port of +a modem. DTR and RTS are inputs while the other signals are outputs. + +The request to open in either role will fail with KErrLocked if the port has +already been opened in the opposite role elsewhere. + +@code +Signal constant DTE role DCE role +---------------------------------------- +KSignalCTS input output +KSignalDSR input output +KSignalDCD input output +KSignalRNG input output +KSignalRTS output input +KSignalDTR output input +@endcode + +Note: + +1. On some earlier versions of C32 the port number was limited to one digit, +i.e. from 0 to 9. This restriction is now removed, and the number +of ports is now only limited by the CSY and/or the Device Drivers up to a maximum +of KMaxTUint ports. + +2. This API checks that the client has the correct capabilities to open the port, while +the RCommServ APIs do not. So a CSY that allowed the client to interrogate it via RCommServ::GetPortInfo() +and load it via RCommServ::LoadCommModule() may still reject the same client's call to this API. + +3. There are a number of distinct steps that must be performed +before being able to issue an Open() request for a serial port. +For convenience these are listed here: + +a. Load the physical device driver, which interacts directly with the hardware at the +lowest level (usually via User::LoadPhysicalDevice()). + +b. Load the logical device driver, which provides the comms server with a consistent +interface to the hardware (usually via User::LoadLogicalDevice()). + +c. Connect to the C32 Serial Server using RCommServ + +d. Load a specific Comms Module (.CSY) by filename via RCommServ::LoadCommModule. + +In some environments the physical and logical device drivers are loaded as part of device boot. + + + +@param aServer The comms server session. +@param aName The name of the port (e.g. "COMM::0") +@param aMode The mode in which the port is opened. There is no default. +@return System-wide error code: KErrNone if successful; KErrPermissionDenied if +the port given in aName is wrong or if the request fails the CSY's own security check; + KErrNotSupported if this port is not +supported by the CSY or the hardware; KErrLocked if the port has already been +opened; KErrAccessDenied if the device driver encounteres a problem opening the hardware port. + +@capability Dependent +*/ + { + C32_STATIC_LOG5(KC32Client,_L("RComm::Open(), aServer 0x%x, (port) aName = %S, (port open) aMode = %d (%S)"), &aServer, &aName, aMode, &TC32Log::CommAccessStr16(aMode)); + iSignalsNotification.Set(NULL,0,0); + iFlowNotification.Set(NULL,0,0); + + TCommRole role = ECommRoleDTE; + TIpcArgs args(&aName,aMode,role); + RSessionBase& s = aServer; + return CreateSubSession(s,ECommOpen, args); + } + +// +// Version 02 extension to the RComm API +// + +EXPORT_C TInt RComm::Open(RCommServ& aServer, const TDesC& aName, TCommAccess aMode, TCommRole aRole) +/** Opens a serial port, as described for the other Open() variant. + +This variant allows the port to be opened in either DTE role or DCE role. DCE +role means that the lines are configured as for a port of a modem. DTR and RTS +are inputs while the other signals are outputs. + +@param aServer The comms server session +@param aName The name of the port +@param aMode The mode in which the port is opened. There is no default. +@param aRole DTE/DCE role +@return System-wide error code: KErrNone if successful; KErrPermissionDenied if +the port given in aName is wrong; KErrNotSupported if this port is not supported +by the CSY or the hardware; KErrLocked if the port has already been opened +in the opposite role elsewhere. +@capability Dependent +*/ + { + C32_STATIC_LOG7(KC32Client,_L("RComm::Open(), aServer 0x%x, (port) aName %S, (port open) aMode = %d (%S), (port) aRole = %d (%S)"), &aServer, &aName, aMode, &TC32Log::CommAccessStr16(aMode), aRole, &TC32Log::CommRoleStr16(aRole)); + TIpcArgs args(&aName,aMode,aRole); + RSessionBase &s = aServer; + return CreateSubSession(s,ECommOpen, args); + } + + +// +// Version 02 extension to the RComm API +// + + +EXPORT_C void RComm::OpenWhenAvailable(TRequestStatus& aStatus, RCommServ& aServer, const TDesC& aName) +/** Opens a serial port when it is freed by another client. + +When a client has a port open in either exclusive or shared mode, another +client may use this function to gain access to the port when the owning +client closes its handle. Upon closure, the asynchronous OpenWhenAvailable() +function will complete. The port role, DTE or DCE, will not be changed by +this request and so the role will be inherited from the previous session. +Furthermore, the port will automatically opened in ECommPreemptable mode. +This can be subsequently upgraded to ECommShared or ECommExclusive mode +using the SetAccessMode() function. + +If client submits an OpenWhenAvailable() request and then attempts +to execute an action, for example a read or write request, before the +OpenWhenAvailable has completed, the action will fail with the KErrNotReady +error code. + +The server can only support one OpenWhenAvailable request per port. For +example, if client A has a port open in exclusive mode and client B has +an OpenWhenAvailable request pending, then client C's OpenWhenAvailable +request will fail with the KErrAccessDenied error code. + +The server is designed to support the OpenWhenAvailable request dispatched +from a different RCommServ session than the one actively using the port. +This is not viewed as a major disadvantage since, in practice, the two +clients will normally be running in different threads, and quite probably +different processes. + +If the port is available immediately, it will be opened with DTE role. + +@param aStatus The request status used to contain completion information for the function. +@param aServer The comms server session. +@param aName The name of the port. +@return System wide error code: see return values of RComm::Open(). +@capability Dependent +*/ + { + OpenWhenAvailable(aStatus, aServer, aName, ECommRoleDTE); + } + + +EXPORT_C void RComm::OpenWhenAvailable(TRequestStatus& aStatus, RCommServ& aServer, const TDesC& aName, TCommRole aRole) +/** Opens a serial port when freed. + +Same as the other OpenWhenAvailable() but here you can specify the preferred +role in case the port is free when you want to open it. If the port is already +opened by another client, you will get the same role when it becomes available. + +@param aStatus The request status used to contain completion information for + the function. +@param aServer The comms server session. +@param aName The name of the port. +@param aRole Preferred role (DTE or DCE). +@return TInt A system wide error code: see return values of RComm::Open(). +@capability Dependent +*/ + { + + C32_STATIC_LOG5(KC32Client,_L("RComm::OpenWhenAvailable(), aServer 0x%x, (port) aName = %S, (port) aRole = %d (%S)"), &aServer, &aName, aRole, &TC32Log::CommRoleStr16(aRole)); + TIpcArgs args(&aName,TIpcArgs::ENothing,aRole); + RSessionBase& s = aServer; + TInt ret = CreateSubSession(s, ECommOpenWhenAvailable, args); + + if(ret != KErrNone) + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status, ret); + return; + } + + args.Set(0,ECommPreemptable); + SendReceive(ECommSetAccess, args, aStatus); + } + + +EXPORT_C void RComm::OpenWhenAvailableCancel() +/** Cancels an OpenWhenAvailable() pending request. +@capability None +*/ + { + if (SendReceive(ECommOpenWhenAvailableCancel) == KErrNone) + { + Close(); + } + } + + +EXPORT_C void RComm::Read(TRequestStatus& aStatus, TDes8& aDes) +/** Reads data from a serial port. + +All reads from the serial device use 8-bit descriptors as data buffers, even +on a Unicode system. + +The length of the TDes8 is set to zero on entry, which means that buffers +can be reused without having to be zeroed first. + +The number of bytes to read is set to the maximum length of the descriptor. + +If a read is issued with a data length of zero the Read() completes immediately +with the side effect that the serial hardware is powered up. + +If a read terminates with KErrTimedOut and the descriptor is not empty, +it will contain valid data. Its length should therefore be tested. + +The behaviour of this API after a call to NotifyDataAvailable() is not prescribed +and so different CSY's behave differently. IrComm will allow a successful completion of this API +after a call to NotifyDataAvailable(), while ECUART and ECACM will complete the request with KErrInUse. + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code. +@param aDes A buffer to store the incoming data. The maximum length of the +descriptor is the number of bytes to be read. +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::Read(), Request to read max number of bytes %d"), aDes.MaxLength()); + aDes.SetLength(0); + TIpcArgs args(&aDes,aDes.MaxLength(),0); + SendReceive(ECommRead, args, aStatus); + } + + +EXPORT_C void RComm::Read(TRequestStatus& aStatus, TDes8& aDes, TInt aLength) +/** Reads a specified number of bytes from a serial port. + +Overloaded version of Read() with explicit length. + +All reads from the serial device use 8-bit descriptors as data buffers, even +on a Unicode system. + +The length of the TDes8 is set to zero on entry, which means that buffers +can be reused without having to be zeroed first. + +The number of bytes to read is set to aLength. + +If a read is issued with a data length of zero (aLength=0) the Read() completes +immediately with the side effect that the serial hardware is powered up. + +If a read terminates with KErrTimedOut and the descriptor is not empty, +it will contain valid data. Its length should therefore be tested. + +The behaviour of this API after a call to NotifyDataAvailable() is not prescribed +and so different CSY's behave differently. IrComm will allow a successful completion of this API +after a call to NotifyDataAvailable(), while ECUART and ECACM will complete the request with KErrInUse. + +@param aStatus The request status used to contain completion information for + the function. On completion, contains a system-wide error code. +@param aDes A buffer to store the incoming data. +@param aLength An explicit length of data to be read. This length must be + between 0 and the MaxLength of the descriptor both included. +@capability None +*/ + { + C32_STATIC_LOG3(KC32Client,_L8("RComm::Read(), bytes to read = %d, given buffer's max length %d"), aLength, aDes.MaxLength()); + if((aLength <= aDes.MaxLength()) && (aLength >= 0)) + { + aDes.SetLength(0); + TIpcArgs args(&aDes,aLength,0); + SendReceive(ECommRead, args, aStatus); + } + else + {//Complete the request due to invalid length + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrArgument); + } + } + + +EXPORT_C void RComm::Read(TRequestStatus& aStatus, TTimeIntervalMicroSeconds32 aTimeOut, TDes8& aDes) +/** Reads data from a serial port only if it arrives before a specified time-out. + +Overloaded version of Read() with timeout. + +All reads from the serial device use 8-bit descriptors as data buffers, even +on a Unicode system. + +The length of the TDes8 is set to zero on entry, which means that buffers +can be reused without having to be zeroed first. + +The number of bytes to read is set to the maximum length of the descriptor. + +If a read is issued with a data length of zero the Read() completes immediately +but with the side effect that the serial hardware is powered up. + +When a Read() terminates with KErrTimedOut, different protocol modules can +show different behaviours. Some may write any data received into the aDes +buffer, while others may return just an empty descriptor. In the case of a +returned empty descriptor use ReadOneOrMore() to read any data left in the +buffer. + +The behaviour of this API after a call to NotifyDataAvailable() is not prescribed +and so different CSY's behave differently. IrComm will allow a successful completion of this API +after a call to NotifyDataAvailable(), while ECUART and ECACM will complete the request with KErrInUse. + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code. +@param aTimeOut The time-out value for reads in microseconds. If data fails +to arrive before the specified number of microseconds, a KErrTimedOut status +is returned. +@param aDes A buffer to store the incoming data. The maximum length of the +descriptor is the default for the number of bytes to be read. +@capability None +*/ + { + C32_STATIC_LOG3(KC32Client,_L8("RComm::Read(), aTimeOut = %d, Max Length = %d"), aTimeOut.Int(), aDes.MaxLength()); + aDes.SetLength(0); + TIpcArgs args(&aDes,aDes.MaxLength(),aTimeOut.Int()); + SendReceive(ECommRead, args, aStatus); + } + + +EXPORT_C void RComm::Read(TRequestStatus& aStatus, TTimeIntervalMicroSeconds32 aTimeOut, TDes8& aDes, TInt aLength) +/** Read data from a serial port (before the time-out). + +Reads a specified number of bytes from a serial port only if they arrive before +a specified time-out. Overloaded version of Read() with timeout and explicit +length. + +All reads from the serial device use 8-bit descriptors as data buffers, even +on a Unicode system. + +The length of the TDes8 is set to zero on entry, which means that buffers +can be reused without having to be zeroed first. + +The number of bytes to read is set to aLength. + +If a read is issued with a data length of zero the Read() completes immediately +but with the side effect that the serial hardware is powered up. + +When a Read() terminates with KErrTimedOut, different protocol modules can +show different behaviours. Some may write any data received into the aDes +buffer, while others may return just an empty descriptor. In the case of a +returned empty descriptor use ReadOneOrMore() to read any data left in the +buffer. + +The behaviour of this API after a call to NotifyDataAvailable() is not prescribed +and so different CSY's behave differently. IrComm will allow a successful completion of this API +after a call to NotifyDataAvailable(), while ECUART and ECACM will complete the request with KErrInUse. + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code. +@param aTimeOut The time-out value for reads in microseconds. If data fails +to arrive before the specified number of microseconds, a KErrTimedOut status +is returned. +@param aDes A buffer to store the incoming data. +@param aLength An explicit length of data to be read This length must be +between 0 and the MaxLength of the descriptor both included. + +@capability None +*/ + { + C32_STATIC_LOG4(KC32Client,_L8("RComm::Read(), aTimeOut = %d, bytes to read = %d, Max Length of buffer = %d"), aTimeOut.Int(), aLength, aDes.MaxLength()); + if((aLength <= aDes.MaxLength()) && (aLength >= 0)) + { + aDes.SetLength(0); + TIpcArgs args(&aDes,aLength,aTimeOut.Int()); + SendReceive(ECommRead, args, aStatus); + } + else + {//Complete the request due to invalid length + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrArgument); + } + } + + +EXPORT_C void RComm::ReadOneOrMore(TRequestStatus& aStatus, TDes8& aDes) +/** Read any bytes in the buffer or wait until one arrives. + +Reads data from a serial port, but with slightly different behaviour to Read(). +If there is data in the serial driver's buffer when ReadOneOrMore() is called, +it will read as much data as possible (up to the maximum length of the supplied +buffer) and return immediately. If there is no data in the buffer, the request +will complete as soon as one or more bytes arrive at the serial hardware. + +The behaviour of this API after a call to NotifyDataAvailable() is not prescribed +and so different CSY's behave differently. IrComm will allow a successful completion of this API +after a call to NotifyDataAvailable(), while ECUART and ECACM will complete the request with KErrInUse. + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code +@param aDes A buffer to store the incoming data. The maximum length of the descriptor +is the default for the number of bytes to be read. When the request completes this will +hold data read from the input buffer. +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::ReadOneOrMore(), buffer's max length = %d"), aDes.MaxLength()); + TIpcArgs args(&aDes,-aDes.MaxLength(),0); + // Note: specifying negative length here to indicate OneOrMore + // see RMaxComm::ReadOneOrMore in ECUART.CPP + SendReceive(ECommRead, args, aStatus); + } + + +EXPORT_C TInt RComm::ReadCancel() +/** Cancels any pending Read() or ReadOneOrMore() operations. + +The cancelled request will still terminate with its TRequestStatus set to +any value other than KErrPending. While this is most likely to be KErrCancel, +it is nevertheless possible for the cancellation to have been issued after +the asynchronous request had already terminated for some other reason. +@capability None +*/ + + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommReadCancel, args); + } + + +EXPORT_C TInt RComm::QueryReceiveBuffer() const +/** Gets the number of bytes currently waiting in the driver's input buffer. +A return value of zero means the buffer is empty. + +It is not possible to find out exactly how many bytes are currently in the +driver's output buffer waiting to be transmitted. However, this is not an +issue since it is easy to ensure that the output buffer is empty. If +the KConfigWriteBufferedComplete bit (set via the TCommConfigV01 structure's iHandshake field) is clear, +then all write requests will delay +completion until the data has completely cleared the driver's output buffer. +If the KConfigWriteBufferedComplete bit is set, a write of zero bytes to a port +which has data in the output buffer is guaranteed to delay completion until +the buffer has been fully drained. + +@return The number of bytes currently waiting to be read from the receive +buffer. +@capability None +*/ +{ + TUint bufferSize; + TPtr8 s((TUint8 *)&bufferSize, sizeof(bufferSize)); + TIpcArgs args(&s); + TInt ret = SendReceive(ECommQueryReceiveBuffer,args); + if(ret != KErrNone) + { + return ret; + } + else + { + return bufferSize; + } +} + + +EXPORT_C TInt RComm::ResetBuffers(TUint aFlags) +/** Resets the transmit and receive serial port buffers independently. + +aFlags is a bitmask, so setting KCommResetRx|KCommResetTx (the default) resets +both buffers and all data in them is lost. This is the default value, so this +is what happens if the function is called without a parameter. + +This function should not be called when there are pending reads or writes. + +@param aFlags KCommResetRx to reset the receive buffer KCommResetTx to reset +the transmit buffer +@capability None +*/ + { + TIpcArgs args(aFlags); + return SendReceive(ECommResetBuffers, args); + } + + +EXPORT_C void RComm::Write(TRequestStatus& aStatus, const TDesC8& aDes) +/** Writes data to a serial port. + +All writes to the serial device use 8-bit descriptors as data buffers, even +on a Unicode system. + +The number of bytes to write is set to the maximum length of the descriptor. + +When a Write() is issued with a data length of zero it cannot complete until +the current handshaking configuration and the state of input control lines +indicate that it is possible for data to be immediately written to the serial +line, even though no data is to be written. This functionality is useful when +determining when serial devices come on line, and checking that the output +buffer is empty (if the KConfigWriteBufferedComplete bit is set). + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code. +@param aDes A descriptor containing the data to be written to the serial port. +@capability None +*/ + { + TIpcArgs args(&aDes,aDes.Length(),0); + SendReceive(ECommWrite,args,aStatus); + } + + +EXPORT_C void RComm::Write(TRequestStatus& aStatus, const TDesC8& aDes, TInt aLength) +/** Writes a specified number of bytes to a serial port. + +All writes to the serial device use 8-bit descriptors as data buffers, even +on a Unicode system. + +The number of bytes to write is set to aLength. + +When a Write() is issued with a data length of zero it cannot complete until +the current handshaking configuration and the state of input control lines +indicate that it is possible for data to be immediately written to the serial +line, even though no data is to be written. This functionality is useful when +determining when serial devices come on line, and checking that the output +buffer is empty (if the KConfigWriteBufferedComplete bit is set). + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code. +@param aDes A descriptor containing the data to be written to the serial port. +@param aLength The number of bytes to write. This length must be between 0 +and the length of the descriptor both included. +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::Write(), (bytes to write) aLength = %d"), aLength); + if((aLength <= aDes.Length()) && (aLength >= 0)) + { + TIpcArgs args(&aDes,aLength,0); + SendReceive(ECommWrite, args, aStatus); + } + else + {//Complete the request due to invalid length + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrArgument); + } + } + + +EXPORT_C void RComm::Write(TRequestStatus& aStatus, TTimeIntervalMicroSeconds32 aTimeOut, const TDesC8& aDes) +/** Writes data to a serial port within a specified time-out. + +All writes to the serial device use 8-bit descriptors as data buffers, even +on a Unicode system. + +The number of bytes to write is set to the maximum length of the descriptor. + +When a Write() is issued with a data length of zero it cannot complete until +the current handshaking configuration and the state of input control lines +indicate that it is possible for data to be immediately written to the serial +line, even though no data is to be written. This functionality is useful when +determining when serial devices come on line, and checking that the output +buffer is empty (if the KConfigWriteBufferedComplete bit is set). + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code. +@param aTimeOut The write will terminate after aTimeout microseconds if the +data requested has not been sent. A KErrTimedOut status is returned. +@param aDes A descriptor containing the data to be written to the serial port. +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::Write(), aTimeOut = %d (microseconds)"), aTimeOut.Int()); + TIpcArgs args(&aDes,aDes.Length(),aTimeOut.Int()); + SendReceive(ECommWrite,args, aStatus); + } + + +EXPORT_C void RComm::Write(TRequestStatus& aStatus, TTimeIntervalMicroSeconds32 aTimeOut, const TDesC8& aDes, TInt aLength) +/** Writes a specified number of bytes to a serial port within a specified +time-out. + +All writes to the serial device use 8-bit descriptors as data buffers, even +on a Unicode system. + +The number of bytes to write is set to aLength. + +When a Write() is issued with a data length of zero it cannot complete until +the current handshaking configuration and the state of input control lines +indicate that it is possible for data to be immediately written to the serial +line. This functionality is useful when determining when serial devices come +on line, and checking that the output buffer is empty (if +the KConfigWriteBufferedComplete bit is set). + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code +@param aTimeOut The write will terminate after aTimeout microseconds if the +data requested has not been sent. A KErrTimedOut status is returned. +@param aDes A descriptor containing the data to be written to the serial port. +@param aLength The number of bytes to write. This length must be between 0 +and the maximum length of the descriptor both included. +@capability None +*/ + { + C32_STATIC_LOG3(KC32Client,_L8("RComm::Write(), aTimeOut = %d (microseconds), (bytes to write) aLength = %d"), aTimeOut.Int(), aLength); + if((aLength <= aDes.Length()) && (aLength >= 0)) + { + TIpcArgs args(&aDes,aLength,aTimeOut.Int()); + SendReceive(ECommWrite, args, aStatus); + } + else + {//Complete the request due to invalid length + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrArgument); + } + } + + +EXPORT_C TInt RComm::WriteCancel() +/** Cancels any pending Write() operations. + +The cancelled request will still terminate with its TRequestStatus set, to +any value other than KErrPending. While this is most likely to be KErrCancel, +it is nevertheless possible for the cancellation to have been issued after +the asynchronous request had already terminated for some other reason. + +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommWriteCancel, args); + } + + +EXPORT_C void RComm::Break(TRequestStatus& aStatus, TTimeIntervalMicroSeconds32 aTime) +/** Sets a break condition for a specified time. + +A break condition on a line is when a data line is held permanently high for +an indeterminate period which must be greater than the time normally taken +to transmit two characters. It is sometimes used as an error signal between +computers and other devices attached to them over RS232 lines. + +Notes: + +Setting breaks is not supported on the integral ARM serial hardware. +EPOC has no support for detecting received breaks. +There is no way to detects whether setting a break is supported using Caps(). + +@param aStatus The request status used to contain completion information for +the function. On completion, contains a system-wide error code. +@param aTime A timed break period in microseconds. + +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::Break(), for aTime = %d (microseconds)"), aTime.Int()); + TIpcArgs args(aTime.Int()); + SendReceive(ECommBreak, args, aStatus); + } + + +EXPORT_C TInt RComm::BreakCancel() +/** Cancels any pending Break() operations. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommBreakCancel,args); + } + + +EXPORT_C TInt RComm::Cancel() +/** Cancels any pending reads and writes. + +A panic will result if an attempt is made to reconfigure a port if there are +any pending reads or writes. Use this function before configuring a port if +there is any doubt as to whether it is safe to do so. It isn't necessary +to call Cancel() before closing a port as this is done automatically. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommCancel, args); + } + + +EXPORT_C TInt RComm::Config(TDes8& aConfig) const +/** Reads the current configuration of the serial port. + +It isn't essential to read an existing configuration in order to set a new +one. However, calling this function is a useful way of initializing a TCommConfig +structure and thus avoiding the overhead of having to explicitly set every +member. If a port were being shared between difference processes, it would +also be good manners to save an existing configuration before using the port +in order than it might be restored when you have finished with it. + +@param aConfig On return, a TCommConfig package buffer holding the configuration +settings +@capability None +*/ + { + TIpcArgs args(&aConfig); + return SendReceive(ECommConfig, args); + } + + +EXPORT_C TInt RComm::SetConfig(const TDesC8& aConfig) +/** Sets the configuration of the serial port. + +It is not possible to reconfigure the capabilities of ports while they are +being used. In particular, if any client attempts to reconfigure a port when +there are pending reads or writes a KErrInUse error code will be returned. + +@param aConfig New configuration settings packaged in a TCommConfig +@return System-wide error code: KErrInUse if there is a pending read or write on +the port, otherwise system-wide error codes +@capability None +*/ + { + TIpcArgs args(&aConfig); + return SendReceive(ECommSetConfig, args); + } + + +EXPORT_C TInt RComm::Caps(TDes8& aCaps) const +/** Reads the capabilities of the serial port. + +As the serial driver can control a range of different physical devices with +differing capabilities, it could be considered important from the point of +view of the operating system to be able to read these capabilities before +attempting to configure the port. In practice however, program development +is likely to be targeted at a specific hardware configuration, and interrogation +of a device to ascertain its capabilities isn't normally necessary. + +@param aCaps On return this descriptor will contain either a packaged TCommCapsV01 +structure or a packaged TCommCapsV02 structure corresponding to the capabilities +of the serial device and of the CSY module, depending on the size of the descriptor +passed in to the function. +@capability None +*/ + { + TIpcArgs args(&aCaps); + return SendReceive(ECommCaps, args); + } + + +EXPORT_C TInt RComm::Mode(TCommServerConfig& aConfig) const +/** Gets server buffering mode. + +@param aConfig A packaged TCommServerConfigV01 structure which will hold the +required information on return. +@capability None +*/ + { + TIpcArgs args(&aConfig); + return SendReceive(ECommGetMode, args); + } + + +EXPORT_C TInt RComm::SetMode(const TCommServerConfig& aConfig) +/** Sets the server buffering mode. + +This function can be used to set either buffering mode, and if partial buffering +is being used, it can also set the size of the buffer that the server will use. +These items are packaged up into the TCommServerConfig descriptor. + +The default of full buffering is nearly always going to be the quicker option, +as only a single client-server data transfer is ever needed. The mode should +not be changed by an application without a very good reason (such as memory +constraints) otherwise performance is liable to suffer. + +@param aConfig A packaged TCommServerConfigV01 structure to be set. +@return System-wide error code +@capability None +*/ + { + TIpcArgs args(&aConfig); + return SendReceive(ECommSetMode, args); + } + + +EXPORT_C TUint RComm::Signals(TUint aSignalMask) const +/** Reads the serial port control lines. + +Reads the status of the RS232 input and output lines (RTS, CTS, DSR, DCD, DTR). +They are bit-masked into a single integer and one or all of them can be read +at any time. + +Not all of the input lines are guaranteed to be available on all serial devices. + +@param aSignalMask Bitmask of lines to read. It defaults to all lines (0x3f +as only the top six bits of this integer are valid). A different value can +be specified as aSignalMask if specific information is required: for instance, +Signals(KSignalDSR) could be used to find out if a modem were connected to +the serial port. +@return An integer with the bits set to reflect the status of the handshaking +lines +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::Signals(), aSignalMask = %d"), aSignalMask); + TUint signals; + TPtr8 s((TUint8 *)&signals, sizeof(signals)); + TIpcArgs args(&s); + SendReceive(ECommSignals, args); + return signals & aSignalMask; + } + + +EXPORT_C TInt RComm::SetSignalsToMark(TUint aSignalMask) +/** Sets the specified RS232 output lines. + +Using this function, either of the RS232 output lines (DTR and RTS) can be +set manually. + +For many applications, these lines will be read and set under driver +control as determined by the handshaking options selected. + +@param aSignalMask Bitmask of handshaking lines +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::SetSignalsToMark(), aSignalMask = %d"), aSignalMask); + TIpcArgs args(aSignalMask); + return SendReceive(ECommSetSignalsToMark, args); + } + + +EXPORT_C TInt RComm::SetSignalsToSpace(TUint aSignalMask) +/** Clears RS232 output lines. + +Using this function, either of the RS232 output lines (DTR and RTS) can be +cleared manually. + +For many applications, these lines will be read and set under driver +control as determined by the handshaking options selected. + +@param aSignalMask Bitmask of handshaking lines +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::SetSignalsToSpace(), aSignalMask = %d"), aSignalMask); + TIpcArgs args(aSignalMask); + return SendReceive(ECommSetSignalsToSpace, args); + } + + +EXPORT_C TInt RComm::ReceiveBufferLength() const +/** Gets the size of the serial port buffers. + +Despite its name, this function returns the size of both the receive and +transmit buffers, which are (obviously) always the same size. + +@return The current size of both the receive and transmit buffers in bytes. +@capability None +*/ + { + TInt bufferSize; + TPtr8 s((TUint8 *)&bufferSize,sizeof(bufferSize)); + + TIpcArgs args(&s); + TInt ret = SendReceive(ECommReceiveBufferLength, args); + if(ret != KErrNone) + { + return ret; + } + else + { + return bufferSize; + } + } + + +EXPORT_C TInt RComm::SetReceiveBufferLength(TInt aLength) +/** Sets the size of the serial port receive and transmit buffers. + +Notes: + +There is no error code returned by this function. If the buffer is set to +too large a figure, the request is simply ignored. If you are in any doubt +about the success of a SetReceiveBufferLength request, you should examine +the returned value from ReceiveBufferLength. + +It isn't always essential to set a buffer size as there is a generous default +of 1024. + +Changing the size of the receive buffer is the only way to tailor the operation +of flow control in Symbian OS as the exact position of the high water mark +is not configurable. + +@param aLength The required size of the receive and transmit buffers in bytes. +@capability None +*/ + { + C32_STATIC_LOG2(KC32Client,_L8("RComm::SetReceiveBufferLength(), aLength = %d"), aLength); + TIpcArgs args(aLength); + return SendReceive(ECommSetReceiveBufferLength,args); + } + + +EXPORT_C void RComm::Close() +/** Closes a serial port. +If the session is closed without having closed all the open ports via calls to this function, then the session close +will close all remaining ports opened by the session. +@capability None +*/ + { + CloseSubSession(ECommClose); + } + + +#ifdef _DEBUG_DEVCOMM +EXPORT_C TInt RComm::DebugInfo(TDes8& aDes) +/** Dump debug info. + + @param aDes Description of the debug information. +@capability None +*/ + { + TIpcArgs args(&aDes); + return SendReceive(ECommDbgDoDumpDebugInfo,args); + } +#endif + + +// +// Extensions to the RComm API starts from here +// + + +EXPORT_C void RComm::NotifySignalChange(TRequestStatus& aStatus, TUint& aSignals, TUint aSignalMask) +/** Notifies the client when one of the signals change. + +@param aStatus Asynchronous completion status +@param aSignals On return, the new set of signals. The bottom five bits contain +a mask of the signals that are set (using the Signal line constants). The +top four bits store which signal has changed (using the Signal line changed +constants). +@param aSignalMask Bitmaks of the signals to monitor. The default is all signals. +See also KSignalDTEOutputs and KSignalDTEInputs. +@capability None +*/ + { + C32_STATIC_LOG3(KC32Client,_L8("RComm::NotifySignalChange(), aSignals = %d, aSignalMask = %d"), aSignals, aSignalMask); + iSignalsNotification.Set((TUint8*)&aSignals, sizeof(TUint), sizeof(TUint)); + TIpcArgs args(&iSignalsNotification,aSignalMask); + SendReceive(ECommNotifySignals, args, aStatus); + } + + +EXPORT_C TInt RComm::NotifySignalChangeCancel() const +/** Cancels a NotifySignalChange() request. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommNotifySignalsCancel, args); + } + + +EXPORT_C void RComm::NotifyConfigChange(TRequestStatus& aStatus, TDes8& aNewConfig) const +/** Notifies the client when the port configuration (data rate, character width, +stop bits, handshaking, or parity) of the remote end changes. + +@param aStatus On return, system wide error code for asynchronous function. +@param aNewConfig On completion, a packaged TCommNotificationV01. +@capability None +*/ + { + TIpcArgs args(&aNewConfig); + SendReceive(ECommNotifyConfigChange, args, aStatus); + } + + +EXPORT_C TInt RComm::NotifyConfigChangeCancel() const +/** Cancels a NotifyConfigChange() request. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommNotifyConfigChangeCancel, args); + } + + +EXPORT_C void RComm::NotifyFlowControlChange(TRequestStatus& aStatus, TFlowControl& aFlowControl) +/** Notifies the client when the flow control between the CSY and the external +device changes. + +@param aStatus On return, system wide error code for asynchronous function. +@param aFlowControl On completion, new flow control status. +@capability None +*/ + { + iFlowNotification.Set((TUint8*)&aFlowControl, sizeof(TFlowControl), sizeof(TFlowControl)); + TIpcArgs args(&iFlowNotification); + SendReceive(ECommNotifyFlowControl, args, aStatus); + } + + +EXPORT_C TInt RComm::NotifyFlowControlChangeCancel() const +/** Cancels a NotifyFlowControlChange() request. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommNotifyFlowControlCancel, args); + } + + +EXPORT_C TInt RComm::GetFlowControlStatus(TFlowControl& aFlowControl) const +/** Gets the current status of flow control between the port and the third party +(external PC or internal signalling stack). + +@param aFlowControl On return, flow control status +@return System-wide error code +@capability None +*/ + { + TPckg len(aFlowControl); + TIpcArgs args(&len); + return SendReceive(ECommGetFlowControl, args); + } + + + + +EXPORT_C void RComm::NotifyBreak(TRequestStatus& aStatus) const +/** Notifies the client when a break occurs: the remote end has held the communication +line high for a certain number of bits to indicate a break condition. + +@param aStatus On return, system wide error code for asynchronous function. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + SendReceive(ECommNotifyBreak,args,aStatus); + } + + +EXPORT_C TInt RComm::NotifyBreakCancel() const +/** Cancels a NotifyBreak() request. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommNotifyBreakCancel, args); + } + + +EXPORT_C TInt RComm::GetRole(TCommRole& aRole) const +/** Gets current DCE/DTE role. + +@param aRole On return, current DCE/DTE role +@return System-wide error code +@capability None +*/ + { + TPckg len(aRole); + TIpcArgs args(&len); + return SendReceive(ECommGetRole, args); + } + + +EXPORT_C void RComm::NotifyDataAvailable(TRequestStatus& aStatus) const +/** Notifies the client when data is available to be read from the input buffer. + +This API allows the client to delay creation of the buffer receiving the data until the data +has arrived. This allows the client to query the size of the data waiting before creating the buffer, +and simplifies the client's buffer management since it is only needed during the subsequent Read() calls. + +The behaviour of this API after a call to Read() or ReadOneOrMore() is not prescribed +and so different CSY's behave differently. IrComm will allow a successful completion of this API +after a call to Read() or readOneOrMore(), while ECUART and ECACM will complete the request with KErrInUse. + +@param aStatus On return, a system wide error code. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + SendReceive(ECommNotifyDataAvailable,args, aStatus); + } + + +EXPORT_C TInt RComm::NotifyDataAvailableCancel() const +/** Cancels a NotifyDataAvailable() request. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommNotifyDataAvailableCancel,args); + } + + +EXPORT_C void RComm::NotifyOutputEmpty(TRequestStatus& aStatus) const +/** Notifies the client when the transmit buffer is emptied. + +@param aStatus On return, system wide error code for asynchronous function. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + SendReceive(ECommNotifyOutputEmpty,args,aStatus); + } + + +EXPORT_C TInt RComm::NotifyOutputEmptyCancel() const +/** Cancels a NotifyOutputEmpty() request. +@capability None +*/ + { + TIpcArgs args(TIpcArgs::ENothing); + return SendReceive(ECommNotifyOutputEmptyCancel,args); + } + + +EXPORT_C TInt RComm::SetAccessMode(TCommAccess aNewMode) +/** Upgrades the mode of a port handle from pre-emptive mode to shared or exclusive +mode. + +Notes: + +If a client attempts to change the mode of a port that is already in either +shared or exclusive modes, the request will fail with the KErrNotSupported +error code. + +Clients should not attempt to change the access mode to pre-emptive, the behaviour +in this case is unpredictable. + +@param aNewMode The value of the new port mode, either ECommShared or ECommExclusive. +@return System-wide error code. +@capability None +*/ + { + C32_STATIC_LOG3(KC32Client,_L8("RComm::SetAccessMode(), aNewMode = %d (%S)"), aNewMode, &TC32Log::CommAccessStr(aNewMode)); + TIpcArgs args(aNewMode); + return SendReceive(ECommSetAccess, args); + } + +#ifdef _DEBUG +EXPORT_C TInt RComm::DebugState( TCommDebugInfo& aInfo ) +/** Returns the debug state. + +@return aInfo debug info to be returned to. +@capability None +*/ + { + TPckg x(aInfo); + TIpcArgs args(&x); + return SendReceive(ECommDebugState, args); + } +#else +EXPORT_C TInt RComm::DebugState( TCommDebugInfo& /*aInfo*/ ) +/** Debug state information. Only implemented for DEBUG builds. */ + { + return 0; + } +#endif + + +// EOF - CC_CLI.CPP