AdsServer Class

Base implementation for an ADS Server.

Inheritance Hierarchy

System.Object
  TwinCAT.Ads.Server.AdsServer
    TwinCAT.Ads.Server.AdsSymbolicServer
Namespace:  TwinCAT.Ads.Server
Assembly:  TwinCAT.Ads.Server (in TwinCAT.Ads.Server.dll) Version: 6.0.328+39e3229

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:

IsConnected

Gets a value indicating whether AdsServer is connected.

AdsServer Class 3:

IsDisconnecting

Indicates, that the AdsServer is actually disconnecting.

AdsServer Class 4:

IsDisposed

Gets a value indicating whether this instance is disposed.

AdsServer Class 5:

IsDynamicPort

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

AdsServer Class 6:

Logger

Gets the logger object.

AdsServer Class 7:

ServerAddress

The AMS address of this server.

AdsServer Class 8:

ServerName

Gets the name of the server.

AdsServer Class 9:

ServerPort

Gets the server port.

AdsServer Class 10:

ServerVersion

Gets the Version of the Server.

Methods

 

Name

Description

AdsServer Class 11:

AddDeviceNotificationRequest

Sends an ADS Add Device Notification request (synchronous).

AdsServer Class 12:

AddDeviceNotificationRequestAsync

Sends an ADS Add Device Notification request (async)

AdsServer Class 13:

AddDeviceNotificationResponseAsync

Sends an ADS Add Device Notification response.

AdsServer Class 14:

ConnectServer

Connect this ADS server to the local ADS router.

AdsServer Class 15:

ConnectServerAndWaitAsync

Registers the AdsServer at the router asynchronously.

AdsServer Class 16:

DeleteDeviceNotificationRequest

Sends an ADS Delete Device Notification request (synchronous).

AdsServer Class 17:

DeleteDeviceNotificationRequestAsync

Sends an ADS Delete Device Notification request (async).

AdsServer Class 18:

DeleteDeviceNotificationResponseAsync

Sends an ADS Delete Device Notification response.

AdsServer Class 19:

DeviceNotificationRequestAsync

Sends an ADS Device Notification request asynchronously

AdsServer Class 20:

DeviceNotificationRequestSync

Sends an ADS Device Notification request (sync)

AdsServer Class 21:

Disconnect

Disconnects this ADS server from the local ADS router.

AdsServer Class 22:

Dispose.

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

AdsServer Class 23:

Dispose(Boolean)

Releases unmanaged and - optionally - managed resources.

AdsServer Class 24:

Equals

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

AdsServer Class 25:

Finalize

Finalizes an instance of the AdsServer class. (Overrides Object.Finalize..)

AdsServer Class 26:

GetHashCode

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

AdsServer Class 27:

GetServerName

Gets the name of the server.

AdsServer Class 28:

GetType

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

AdsServer Class 29:

MemberwiseClone

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

AdsServer Class 30:

OnAddDeviceNotificationAsync

Called when an ADS Add Device Notification indication is received.

AdsServer Class 31:

OnAddDeviceNotificationConfirmationAsync

Called when an ADS Add Device Notification confirmation is received.

AdsServer Class 32:

OnBeforeConnected

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

AdsServer Class 33:

OnConnected

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

AdsServer Class 34:

OnDeleteDeviceNotificationAsync

Called when an ADS Delete Device Notification indication is received.

AdsServer Class 35:

OnDeleteDeviceNotificationConfirmationAsync

Called when an ADS Delete Device Notification confirmation is received.

AdsServer Class 36:

OnDisconnect

Called when the AdsServer is about to be disconnected.

AdsServer Class 37:

OnReadAsync

Called when an ADS Read indication is received.

AdsServer Class 38:

OnReadConfirmationAsync

Called when an ADS Read confirmation is received.

AdsServer Class 39:

OnReadDeviceInfoConfirmationAsync

Called when an ADS Read Device Info confirmation is received.

AdsServer Class 40:

OnReadDeviceStateAsync

Called when an ADS Read State indication is received.

AdsServer Class 41:

OnReadDeviceStateConfirmationAsync

Called when an ADS Read State confirmation is received.

AdsServer Class 42:

OnReadWriteAsync

Called when an ADS Read Write indication is received.

AdsServer Class 43:

OnReadWriteConfirmationAsync

Called when an ADS Read Write confirmation is received.

AdsServer Class 44:

OnRouterNotification

Handler Function for a Router Notification.

AdsServer Class 45:

OnServerConnectionStateChanged

Handles the ServerConnectionStateChanged event.

AdsServer Class 46:

OnWriteAsync

Called when an ADS Write indication is received.

AdsServer Class 47:

OnWriteConfirmationAsync

Called when an ADS Write confirmation is received.

AdsServer Class 48:

OnWriteControlAsync

Called when an ADS Write Control indication is received.

AdsServer Class 49:

OnWriteControlConfirmationAsync

Called when an ADS Write Control confirmation is received.

AdsServer Class 50:

ReadDeviceInfoRequestAsync

Sends an ADS Read Device Info request asynchronously

AdsServer Class 51:

ReadDeviceInfoRequestSync

Sends an ADS Read Device Info request synchronously.

AdsServer Class 52:

ReadDeviceInfoResponseAsync

Sends an ADS Read Device Info response.

AdsServer Class 53:

ReadDeviceStateRequestAsync

Sends an ADS Read State request (asynchronous)

AdsServer Class 54:

ReadDeviceStateRequestSync

Sends an ADS Read State request (synchronous)

AdsServer Class 55:

ReadDeviceStateResponseAsync

Sends an ADS Read State response.

AdsServer Class 56:

ReadRequest

Sends an ADS Read Request.

AdsServer Class 57:

ReadRequestAsync

Sends an ADS Read Request asynchronously.

AdsServer Class 58:

ReadResponseAsync

Sends an ADS Read response.

AdsServer Class 59:

ReadWriteRequestAsync

Sends an ADS Read Write request.

AdsServer Class 60:

ReadWriteRequestSync

Sends an ADS Read Write request synchronously

AdsServer Class 61:

ReadWriteResponseAsync

Sends an ADS Read Write Response.

AdsServer Class 62:

ToString

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

AdsServer Class 63:

WriteControlRequest

Sends an ADS Write Control request (synchronous)

AdsServer Class 64:

WriteControlRequestAsync

Sends an ADS Write Control request (asynchronous).

AdsServer Class 65:

WriteControlRequestSync

Sends an ADS Write Control request (synchronous).

AdsServer Class 66:

WriteControlResponseAsync

Sends an ADS Write Control response.

AdsServer Class 67:

WriteRequest

Sends an ADS Write request synchronously.

AdsServer Class 68:

WriteRequestAsync

Sends an ADS Write request asynchronously.

AdsServer Class 69:

WriteResponseAsync

Sends an ADS Write response.

Events

 

Name

Description

AdsServer Class 70:

ServerConnectionStateChanged

The connection status has changed

Fields

 

Name

Description

serverVersion

The version of the AdsServer

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.

Examples

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