General Information



This section provides general information about the OPC Interfaces, and some background information about how the designers of OPC expected these interfaces to be implemented and used.
Version Interoperability Data Access Servers may be compatible with the requirements of Version 1.0a of the specification or with Version 2.0 of the specification or both. Data Access Clients may also be compatible with the requirements of Version 1.0a of the specification or with Version 2.0 of the specification or both.

The best migration strategy for server and client vendors will depend on their particular business situation. For example a vendor who mostly sells his own client and server components as a packaged system and for whom OPC Compatability represents a long term strategy will have less need to support multiple versions of the interfaces.

As a general guideline it is recommended that existing server vendors add version 2.0 support and leave version 1.0 support in place to support existing Version 1.0 Clients.

Data Access Server

Required Interfaces

1.0 2.0
OPCServer    
IUnknown Required Required
IOPCServer Required Required
IOPCCommon N/A Required
IConnectionPointContainer N/A Required
IOPCItemProperties N/A Required
IOPCServerPublicGroups Optional Optional
IOPCBrowseServerAddressSpace Optional Optional
     
OPCGroup    
IUnknown Required Required
IOPCItemMgt Required Required
IOPCGroupStateMgt Required Required
IOPCPublicGroupStateMgt Optional Optional
IOPCSyncIO Required Required
IOPCAsyncIO2 N/A Required
IConnectionPointContainer N/A Required
IOPCAsyncIO Required N/A
IDataObject Required N/A

 

Ownership of memory

Per the COM specification, clients must free all memory associated with ‘out’ or ‘in/out’ parameters. This includes memory that is pointed to by elements within any structures. This is very important for client writers to understand, otherwise they will experience memory leaks that are difficult to find. See the IDL files to determine which parameters are out parameters. The recommended approach is for a client to create a subroutine that is used for freeing each type of structure properly.

Independent of success/failure, the server must always return well defined values for ‘out’ parameters. Releasing the allocated resources is the client’s responsibility.

Note: If the error result is any FAILED error such as E_OUTOFMEMORY , the OPC server should return NULL for all `out' pointers (this is standard COM behavior). This rule also applies to the error arrays (ppErrors) returned by many of the functions below. In general, a robust OPC client should check each out or in/out pointer for NULL prior to freeing it.

Standard Interfaces Per the COM specification, all methods must be implemented on each required interface.

Per the COM specification, any optional interfaces that are supported must have all functions within that interface implemented, even if the implementation is only a stub implementation returning E_NOTIMPL.

Null Strings and Null Pointers Both of these terms are used below. They are NOT the same thing. A NULL Pointer is an invalid pointer (0) which will cause an exception if used. A NUL String is a valid (non zero) pointer to a 1 character array where that character is a NUL (i.e. 0). If a NUL string is returned from a method as an [out] parameter (or as an element of a structure) it must be freed, otherwise the memory containing the NUL will be lost. Also note that a NULL pointer cannot be passed for an [in,string] argument due to COM marshalling restrictions. In this case a pointer to a NUL string should be passed to indicate an omitted parameter. Returned Arrays You will note the syntax size_is(,dwCount) in the IDL used in combination with pointers to pointers. This indicates that the returned item is a pointer to an actual array of the indicated type, rather than a pointer to an array of pointers to items of the indicated type. This simplifies marshaling , creation, and access of the data by the server and client. Public Groups Public groups are optional. The server vendor and the client vendor may elect to support this behavior as appropriate for their application. There are some specific rules that must be adhered to if the public group capability is supported. This are discussed in detail later in the method descriptions but in general:

A public group must have a unique name relative to all other public groups. If a client adds a private group which will later be converted to a public group, the client should insure that this name is unique or an error will occur later in MoveToPublic.

Once a group has been made public, the items within that group can not be changed. If changes need to be made to a public group, a new group must be created with the items (e.g. through the use of CloneGroup), and made public after the modifications to the items are in place

Once a client has connected to a public group, most of that group’ properties (client handles, update rates, etc) will be maintained as unique instance data for that client to group connection.
 

CACHE data, DEVICE data and TimeStamps For the most part the terms CACHE and DEVICE are treated as ‘abstract’ within this specification. That is, reading CACHE or DEVICE data simply affects the described behavior of various interfaces in a well defined way. The implementation details of these capabilities is not dictated by this specification.

In practice, however, it is expected that most servers will read data into some sort of CACHE. Also, most clients will read data from this cache via one of several mechanisms discussed later. Access to DEVICE data is expected to be ‘slow’ and is expected to be used primarily for diagnostics or for particularly critical operations.

The CACHE should reflect the latest value of the data (subject to update rate and deadband optimizations as discussed later) as well as the quality and timestamp. The Timestamp should indicate the time that the value and quality was obtained by the device (if this is available) or the time the server updated or validated the value and quality in its CACHE. Note that if a device or server is checking a value every 10 seconds then the expected behavior would be that the timestamp of that value would be updated every 10 seconds (even if the value is not actually changing). Thus the time stamp reflects the time at which the server knew the corresponding value was accurate.

This is also true regardless of wether the physical device to system interface is exception based. For example suppose it is known that (a) an exception based device is checking values every 0.5 second and that (b) the connection to the device is good and (c) that device sent an update for item FIC101 three minutes ago with a value of 1.234. In this case the value returned from a cache read would be 1.234 and more important, the timestamp returned for this value would be the current time (within 0.5 second) since it is known that the value for the item is in fact still 1.234 as of 0.5 seconds ago.

Time Series Values The OPC Data Access interfaces are designed primarily to take snapshots of current real time process or automation data. The Timestamp returned with those values is intended primarily as an indication of the quality of that ‘current’ data. These interfaces are not really intended to deal with buffered time series data for a single point such as historical data. Asynchronous vs. Synchronous Interfaces Assuming that most clients want to access Cached data, there are several ways for a client to obtain that data from a server. The ACTIVE flags, Deadband and Update Rate These attributes of groups and items can be used to reduce resource use by clients and servers. They are discussed in more detail later under GROUPS. In general, they affect how often the cached data and quality information is updated and how often calls are made to the client’s IAdviseSink or IOPCDataCallback. Errors and return codes The OPC specification describes interfaces and corresponding behavior that an OPC server implements, and an OPC client application depends on. A list of OPC Specific errors and return codes is contained in the summary of OPC error codes section in this specification. For each method described below a list of all possible OPC error codes as well as the most common OLE error codes is included. It is likely that clients will encounter additional error codes such as RPC and Security related codes in practice and they should be prepared to deal with them.

In two cases (Read and Write) it is also allowed for a server to return Vendor Specific error codes. Such codes can be passed to GetErrorString method. This is discussed in more detail later.

In all cases ‘E’ error codes will indicate FAILED type errors and ‘S’ error codes will indicate at least partial success.

Startup Issues After Items are added to a group, it may take some time for the server to actually obtain values for these items. In such cases the client might perform a read (from cache), or establish an AdviseSink or ConnectionPoint based subscription and/or execute a Refresh on such a subscription before the values are available. You will see in the later discussions of subscriptions that an initial callback is expected which contains all values in a Group. The expected behavior in this situation is summarized by saying that as items are added to a group, their initial state should be set to OPC_QUALITY_BAD with a NON_SPECIFIC (00) or optionally a OPC_QUALITY_LAST_KNOWN (14) substate. Any client operation on the group will then behave as it normally would for a group with a mixed set of GOOD and BAD qualities. Note that in the case of the sync read and also asyncio2 operations the server can return vendor specific error information which could indicate a vendor specific error such as "SERVER WAITING FOR INITIAL DATA". VARIANT Data Types and Interoperability In order to promote interoperability, the following rules and recommendations are presented.

Rules:

Recommendations: