AdsServer Class

Base implementation for an ADS Server.

Inheritance Hierarchy

SystemObject
  TwinCAT.Ads.ServerAdsServer
    TwinCAT.Ads.ServerAdsSymbolicServer

Namespace: TwinCAT.Ads.Server
Assembly: TwinCAT.Ads.Server (in TwinCAT.Ads.Server.dll) Version: 7.0.0+e56d35ccc4675faac24789a4aab60071fc61d470

Syntax

C#

public abstract class AdsServer : IDisposable

The AdsServer type exposes the following members.

Properties

 

Name

Description

AdsServer Class 1:

AmsServer

Gets the the internal AmsServer object.

AdsServer Class 2:

ChannelPortType

Gets the type of the channel port.

AdsServer Class 3:

ChannelProtocol

Gets the actual used channel protocol.

AdsServer Class 4:

Configuration

Gets the configuration.

AdsServer Class 5:

IsConnected

Gets a value indicating whether AdsServer is connected.

AdsServer Class 6:

IsDisconnecting

Indicates, that the AdsServer is actually disconnecting.

AdsServer Class 7:

IsDisposed

Gets a value indicating whether this instance is disposed.

AdsServer Class 8:

IsDynamicPort

Gets a value indicating this AdsServer has a dynamic/unfixed port.

AdsServer Class 9:

LoggerFactory

Gets the logger factory.

AdsServer Class 10:

ServerAddress

The AmsAddress of this server (if connected), or NULL if not yet connected.

AdsServer Class 11:

ServerName

Gets the name of the server.

AdsServer Class 12:

ServerPort

Gets the server port.

AdsServer Class 13:

ServerVersion

Gets the Version of the Server.

AdsServer Class 14:

Timeout

Gets or sets the timeout.

Methods

 

Name

Description

AdsServer Class 15:

AddDeviceNotificationRequest

Sends an ADS Add Device Notification request (synchronous).

AdsServer Class 16:

AddDeviceNotificationRequestAsync

Sends an ADS Add Device Notification request (async)

AdsServer Class 17:

AddDeviceNotificationResponseAsync

Sends an ADS Add Device Notification response.

AdsServer Class 18:

CanLog

Determines whether the used logger is enabled for the specified log level.

AdsServer Class 19:

ConnectServer

Connect this ADS server to the local ADS router.

AdsServer Class 20:

ConnectServerAndWaitAsync

Registers the AdsServer at the router asynchronously.

AdsServer Class 21:

ConnectServerAsync

Connect server as an asynchronous operation.

AdsServer Class 22:

DeleteDeviceNotificationRequest

Sends an ADS Delete Device Notification request (synchronous).

AdsServer Class 23:

DeleteDeviceNotificationRequestAsync

Sends an ADS Delete Device Notification request (async).

AdsServer Class 24:

DeleteDeviceNotificationResponseAsync

Sends an ADS Delete Device Notification response.

AdsServer Class 25:

DeviceNotificationRequestAsync

Sends an ADS Device Notification request asynchronously

AdsServer Class 26:

DeviceNotificationRequestSync

Sends an ADS Device Notification request (sync)

AdsServer Class 27:

Disconnect

Disconnects this ADS server from the local ADS router.

AdsServer Class 28:

Dispose

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

AdsServer Class 29:

Dispose(Boolean)

Releases unmanaged and - optionally - managed resources.

AdsServer Class 30:

Equals

Determines whether the specified object is equal to the current object.
(Inherited from Object)

AdsServer Class 31:

Finalize

Finalizes an instance of the AdsServer class.
(Overrides ObjectFinalize)

AdsServer Class 32:

GetHashCode

Serves as the default hash function.
(Inherited from Object)

AdsServer Class 33:

GetServerName

Gets the name of the server.

AdsServer Class 34:

GetType

Gets the Type of the current instance.
(Inherited from Object)

AdsServer Class 35:

IncrementInvokeId

Increments the InvokeID used by this server.

AdsServer Class 36:

MemberwiseClone

Creates a shallow copy of the current Object.
(Inherited from Object)

AdsServer Class 37:

OnAddDeviceNotificationAsync

Called when an ADS Add Device Notification indication is received.

AdsServer Class 38:

OnAddDeviceNotificationConfirmationAsync

Called when an ADS Add Device Notification confirmation is received.

AdsServer Class 39:

OnBeforeConnected

Handler function that is called, when the AdsServer is connected, but before calling OnConnected.

AdsServer Class 40:

OnConnected

Handler function that is called, when the AdsServer is connected.

AdsServer Class 41:

OnDeleteDeviceNotificationAsync

Called when an ADS Delete Device Notification indication is received.

AdsServer Class 42:

OnDeleteDeviceNotificationConfirmationAsync

Called when an ADS Delete Device Notification confirmation is received.

AdsServer Class 43:

OnDisconnect

Called when the AdsServer is about to be disconnected.

AdsServer Class 44:

OnReadAsync

Called when an ADS Read indication is received.

AdsServer Class 45:

OnReadConfirmationAsync

Called when an ADS Read confirmation is received.

AdsServer Class 46:

OnReadDeviceInfoConfirmationAsync

Called when an ADS Read Device Info confirmation is received.

AdsServer Class 47:

OnReadDeviceStateAsync

Called when an ADS Read State indication is received.

AdsServer Class 48:

OnReadDeviceStateConfirmationAsync

Called when an ADS Read State confirmation is received.

AdsServer Class 49:

OnReadWriteAsync

Called when an ADS Read Write indication is received.

AdsServer Class 50:

OnReadWriteConfirmationAsync

Called when an ADS Read Write confirmation is received.

AdsServer Class 51:

OnRouterNotification

Handler Function for a Router Notification.

AdsServer Class 52:

OnServerConnectionStateChanged

Handles the ServerConnectionStateChanged event.

AdsServer Class 53:

OnSystemServiceRemoved

The TwinCAT System Service was stopped.

AdsServer Class 54:

OnWriteAsync

Called when an ADS Write indication is received.

AdsServer Class 55:

OnWriteConfirmationAsync

Called when an ADS Write confirmation is received.

AdsServer Class 56:

OnWriteControlAsync

Called when an ADS Write Control indication is received.

AdsServer Class 57:

OnWriteControlConfirmationAsync

Called when an ADS Write Control confirmation is received.

AdsServer Class 58:

ReadDeviceInfoRequestAsync

Sends an ADS Read Device Info request asynchronously

AdsServer Class 59:

ReadDeviceInfoRequestSync

Sends an ADS Read Device Info request synchronously.

AdsServer Class 60:

ReadDeviceInfoResponseAsync

Sends an ADS Read Device Info response.

AdsServer Class 61:

ReadDeviceStateRequestAsync

Sends an ADS Read State request (asynchronous)

AdsServer Class 62:

ReadDeviceStateRequestSync

Sends an ADS Read State request (synchronous)

AdsServer Class 63:

ReadDeviceStateResponseAsync

Sends an ADS Read State response.

AdsServer Class 64:

ReadRequest

Sends an ADS Read Request.

AdsServer Class 65:

ReadRequestAsync

Sends an ADS Read Request asynchronously.

AdsServer Class 66:

ReadResponseAsync

Sends an ADS Read response.

AdsServer Class 67:

ReadWriteRequestAsync

Sends an ADS Read Write request.

AdsServer Class 68:

ReadWriteRequestSync

Sends an ADS Read Write request synchronously

AdsServer Class 69:

ReadWriteResponseAsync

Sends an ADS Read Write Response.

AdsServer Class 70:

ToString

Returns a string that represents the current object.
(Inherited from Object)

AdsServer Class 71:

WriteControlRequest

Sends an ADS Write Control request (synchronous)

AdsServer Class 72:

WriteControlRequestAsync

Sends an ADS Write Control request (asynchronous).

AdsServer Class 73:

WriteControlRequestSync

Sends an ADS Write Control request (synchronous).

AdsServer Class 74:

WriteControlResponseAsync

Sends an ADS Write Control response.

AdsServer Class 75:

WriteRequest

Sends an ADS Write request synchronously.

AdsServer Class 76:

WriteRequestAsync

Sends an ADS Write request asynchronously.

AdsServer Class 77:

WriteResponseAsync

Sends an ADS Write response.

Events

 

Name

Description

AdsServer Class 78:

ServerConnectionStateChanged

The connection status has changed

Fields

 

Name

Description

configuration

The configuration

DEFAULT_TIMEOUT

The default timeout of ADS Requests / AmsSend

logger

Actual logger

loggerFactory

The logger factory

serverVersion

The version of the AdsServer

timeout

The timeout

Remarks

Derived classes should overwrite the AMS indication methods to react on incoming requests. AMS The confirmation methods should be overwritten to receive replies on asynchronous requests sent by this ADS server.
Important note: Please contact Beckhoff to receive a reserved ADS port number if implementing your own customized AdsServer.

Example

The following sample shows how to derive from the AdsServer class and create your own Customized ADS Server.

C#

class Program
{
    public static void Main(string[] args)
    {
    CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostContext, services) =>
        {
        services.AddHostedService<ServerWorker>();
        });
}

C#

public class ServerWorker : BackgroundService
{
    private readonly ILogger<ServerWorker> _logger;

    public ServerWorker(ILogger<ServerWorker> logger)
    {
    _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken cancel)
    {
    // Instantiate the server
    AdsSampleServer server = new AdsSampleServer(_logger);
    // Connect the server and wait for cancel
    await server.ConnectServerAndWaitAsync(cancel); 
    }
}

C#

/*
 * Extend the AdsServer class to implement your own ADS server.
 */
public class AdsSampleServer : AdsServer
{
    /// <summary>
    /// Fixed ADS Port (to be changed ...)
    /// </summary>
    const ushort ADS_PORT = 42;

    /// <summary>
    /// Fixed Name for the ADS Port (change this ...)
    /// </summary>
    const string ADS_PORT_NAME = "AdsSampleServer_Port42";

    /// <summary>
    /// Some simple data / ProcessImage
    /// </summary>
    private byte[] _dataBuffer = {1, 2, 3, 4};

    /// <summary>
    /// Ads State
    /// </summary>
    private AdsState _adsState = AdsState.Config;
    /// <summary>
    /// Device State
    /// </summary>
    private ushort _deviceState = 0;

    /// <summary>
    /// Notification dictionary, thread safe
    /// </summary>
    private ConcurrentDictionary<uint, NotificationRequestEntry> _notificationTable = new ConcurrentDictionary<uint, NotificationRequestEntry>();

    /// <summary>
    /// Simple counter for different Notification handles here.
    /// </summary>
    private uint _currentNotificationHandle = 0;

    /// <summary>
    /// Logger
    /// </summary>
    private ILogger _logger;

    /* Instantiate an ADS server with a fix ADS port assigned by the ADS router.
    */

    public AdsSampleServer()
    : this(null)
    {
    }

    public AdsSampleServer(ILogger logger) : base(ADS_PORT, ADS_PORT_NAME)
    {
    base.serverVersion = new Version(0, 0, 1);
    _logger = logger;
    }

    /* Overwrite the indication handlers of the AdsServer class for the services your ADS server
     * provides. They are called upon incoming requests. Indications that are not overwritten in
     * this class return the ADS DeviceServiceNotSupported error code to the requester.
     */

    /* Handler function for Write Indication */
    protected override Task<ResultWrite> OnWriteAsync(AmsAddress target, uint invokeId, uint indexGroup, uint indexOffset, ReadOnlyMemory<byte> writeData, CancellationToken cancel)
    {
    ResultWrite result;

    switch (indexGroup)     /* use index group (and offset) to distinguish between the services
                of this server */
    {
        case 0x10000:
        if (writeData.Length == 4)
        {
            writeData.CopyTo(_dataBuffer);
            result = ResultWrite.CreateSuccess();
        }
        else
        {
            result = ResultWrite.CreateError(AdsErrorCode.DeviceInvalidSize);
        }
        break;

        case 0x20000: /* used for the PLC Sample */
        if (writeData.Length == 4)
        {
            uint value = BinaryPrimitives.ReadUInt32LittleEndian(writeData.Span);
            result = ResultWrite.CreateSuccess();
        }
        else
        {
            result = ResultWrite.CreateError(AdsErrorCode.DeviceInvalidSize);
        }

        break;

        default: /* other services are not supported */
        result = ResultWrite.CreateError(AdsErrorCode.DeviceServiceNotSupported);
        break;
    }
    return Task.FromResult(result);
    }

    /* Handler function for Read Indication */
    protected override Task<ResultReadBytes> OnReadAsync(AmsAddress target, uint invokeId, uint indexGroup, uint indexOffset, int readLength, CancellationToken cancel)
    {
    ResultReadBytes result;

    /* Distinguish between services like in OnWriteAsync */
    result = ResultReadBytes.CreateSuccess(_dataBuffer.AsMemory());

    // or Error with ErrorCode
    // result = ResultReadBytes.CreateError(AdsErrorCode.DeviceNotSupported);
    return Task.FromResult(result);
    }

    /* Handler function for ReadWrite Indication */
    protected override Task<ResultReadWriteBytes> OnReadWriteAsync(AmsAddress target, uint invokeId, uint indexGroup, uint indexOffset, int readLength, ReadOnlyMemory<byte> writeData, CancellationToken cancel)
    {
    ResultReadWriteBytes result;

    /* Distinguish between services like in AdsWriteInd */

    if (readLength == 4 && writeData.Length == 4)
    {
        result = ResultReadWriteBytes.CreateSuccess(_dataBuffer.AsMemory(0, 4));
    }
    else
    {
        result = ResultReadWriteBytes.CreateError(AdsErrorCode.DeviceInvalidSize);
    }

    return Task.FromResult(result);
    }

    /* Handler function for ReadDeviceState Indication */
    protected override Task<ResultReadDeviceState> OnReadDeviceStateAsync(AmsAddress target, uint invokeId, CancellationToken cancel)
    {
    StateInfo state = new StateInfo(_adsState, _deviceState);
    ResultReadDeviceState result = ResultReadDeviceState.CreateSuccess(state);
    return Task.FromResult(result);
    }

    /* Handler function for WriteControl Indication */
    protected override Task<ResultAds> OnWriteControlAsync(AmsAddress target, uint invokeId, AdsState adsState, ushort deviceState, ReadOnlyMemory<byte> data, CancellationToken cancel)
    {
    // Set requested ADS and device status

    _adsState = adsState;
    _deviceState = deviceState;

    ResultAds result = ResultAds.CreateSuccess();
    return Task.FromResult(result);
    }

    /* Handler function for AddDeviceNotification Indication */
    protected override Task<ResultHandle> OnAddDeviceNotificationAsync(AmsAddress target, uint invokeId, uint indexGroup, uint indexOffset, int dataLength, AmsAddress receiver, NotificationSettings settings, CancellationToken cancel)
    {
    /* Create a new notification entry an store it in the notification table */
    NotificationRequestEntry notEntry = new NotificationRequestEntry(receiver, indexGroup, indexOffset, dataLength, settings);

    _notificationTable.AddOrUpdate(_currentNotificationHandle, notEntry, (key, value) => notEntry);
    ResultHandle result = ResultHandle.CreateSuccess(_currentNotificationHandle);

    _currentNotificationHandle++;
    return Task.FromResult(result);

    }

    /* Handler function for DeleteDeviceNotification Indication */
    protected override Task<ResultAds> OnDeleteDeviceNotificationAsync(AmsAddress target, uint invokeId, uint hNotification, CancellationToken cancel)
    {
    ResultAds result;

    /* check if the requested notification handle is still in the notification table */
    if (_notificationTable.ContainsKey(hNotification))
    {
        NotificationRequestEntry entry = null;
        _notificationTable.TryRemove(hNotification, out entry);
        result = ResultAds.CreateSuccess();
    }
    else // notification handle is not in the notification table -> return an error code
        // to the requester
    {
        result =  ResultAds.CreateError(AdsErrorCode.DeviceNotifyHandleInvalid);
    }

    return Task.FromResult(result);
    }

    /* Handler function for DeviceNotification Indication */
    protected override Task<ResultAds> OnDeviceNotificationAsync(AmsAddress sender, NotificationSamplesStamp[] stampHeaders, CancellationToken cancel)
    {
    /*
     * Call notification handlers.
     */
    return Task.FromResult(ResultAds.CreateSuccess());
    }
}

/// <summary>
/// AdsSampleServer Notification request entry
/// </summary>
internal class NotificationRequestEntry
{
    private AmsAddress _sender;     // the AmsNetId of the requester
    private uint _indexGroup;       // the requested index group
    private uint _indexOffset;      // the requested index offset
    private int _length;        // the number of bytes to send
    NotificationSettings _settings; // the notification settings

    internal NotificationRequestEntry(AmsAddress sender,
                      uint indexGroup,
                      uint indexOffset,
                      int dataLength,
                      NotificationSettings settings)
    {
    _sender = sender;
    _indexGroup = indexGroup;
    _indexOffset = indexOffset;
    _length = dataLength;
    _settings = settings;
    }
}

Reference

TwinCAT.Ads.Server Namespace

Beckhoff Automation GmbH & Co. KG 2001-2026