Recent

Author Topic: OPC client with Lazarus  (Read 75694 times)

Truffaldino

  • Newbie
  • Posts: 1
Re: OPC client with Lazarus
« Reply #90 on: January 23, 2025, 01:18:34 pm »
Hello, friends!
Has anyone managed to make an OPCUA component for Lazarus?
The wrapper from this topic is good, but the component is better.  :D

colddudu49

  • Newbie
  • Posts: 1
Re: OPC client with Lazarus
« Reply #91 on: January 29, 2025, 10:24:12 pm »
Has anyone managed to get the wrapper to work correctly in Delphi? Everything works in Lazarus. In Delphi I can connect, read the values, but I can't add a variable on the server and I can't subscribe.
And even when reading values, if I make a second reading request after more than 30 seconds, I get the error: BadSessionIdInvalid.
I suspect there are differences in the configuration structures, but I haven't figured them out in two days.
I would be grateful for any suggestions.
I use the code: https://github.com/fluisgirardi/fpopen62541
Win32. Dll version: 1.2-RC2, 1.2.6

Hello, I'm also using the wrapper in Delphi, the test application connect to server but secure channel is closed.
connect state after connection : UA_SESSIONSTATE_ACTIVATED/UA_SECURECHANNELSTATE_CLOSED.

Can anyone tell me what I am doing wrong?
The same code is working fine in Lazarus
« Last Edit: January 31, 2025, 12:19:50 am by colddudu49 »

LacaK

  • Hero Member
  • *****
  • Posts: 702
Re: OPC client with Lazarus
« Reply #92 on: April 11, 2025, 10:12:47 am »
You must have also others DLLs there (beside libopen62541.dll):
- libgcc_s_sjlj-1.dll,
- libwinpthread-1.dll

Look at http://win-builds.org/1.5.0/packages/ (gcc and winpthreads package) or https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-win32/sjlj/x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0.7z

TheMouseAUS

  • Full Member
  • ***
  • Posts: 101
Re: OPC client with Lazarus
« Reply #93 on: January 09, 2026, 08:20:01 pm »
Does anyone have a working example of using the library as a client connecting to a server that requires username and password? I cant seem to make it work. I have built open62541.so with encryption support as I read somewhere it must be otherwise authentication does not work but I cannot get much further.

Any help would be appreciated. Thanks :-)

TheMouseAUS

  • Full Member
  • ***
  • Posts: 101
Re: OPC client with Lazarus
« Reply #94 on: January 23, 2026, 04:56:43 am »
OK I have spent many days trying to figure this out. This is  what I have come to :-

Build the library with encryption enabled (I chose OpenSSL).

Use create_self-signed.py script to generate the certificate and key for the client with the argument --uri urn:open62541.client <your client uri>
The URI in the cert must the same as clientDescription.applicationUri in the client itself.

Get the server certificate from your server in .der format,  this needs to be added to the trust list on connection.

I was playing around with the examples provided in the open62541 library and I finally got a connection working that sent back the server time.

The example provided was ran as follows ./client_encryption opc.tcp://<IP>:4840 client_cert.der client_key.der server-certificate.der

The code in c is

Code: [Select]

const char *endpointUrl = argv[1];

/* Load certificate and private key */
UA_ByteString certificate = loadFile(argv[2]);
UA_ByteString privateKey  = loadFile(argv[3]);

size_t trustListSize = 0;
if(argc > MIN_ARGS)
    trustListSize = (size_t)argc-MIN_ARGS;
UA_STACKARRAY(UA_ByteString, trustList, trustListSize+1);
for(size_t trustListCount = 0; trustListCount < trustListSize; trustListCount++)
    trustList[trustListCount] = loadFile(argv[trustListCount+4]);

UA_ByteString *revocationList = NULL;
size_t revocationListSize = 0;

UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
cc->securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey,
                                     trustList, trustListSize,
                                     revocationList, revocationListSize);

UA_ByteString_clear(&certificate);
UA_ByteString_clear(&privateKey);

for(size_t deleteCount = 0; deleteCount < trustListSize; deleteCount++) {
    UA_ByteString_clear(&trustList[deleteCount]);
}

cc->clientDescription.applicationUri = UA_STRING_ALLOC("urn:open62541.client");

UA_StatusCode retval = UA_Client_connectUsername(client, endpointUrl, "user", "password");


Moving across to Pascal, this is what I ended up with, I get 'Good' as the response and I can now read data from the server.

Code: [Select]

function LoadStringFromFile(const FileName: string): string;
var
  FS: TFileStream;
  Len: Int64;
begin
  Result := '';
  if FileExists(FileName) then
  begin
    FS := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
    try
      Len := FS.Size;
      SetLength(Result, Len);
      FS.Read(Pointer(Result)^, Len);
    finally
      FS.Free;
    end;
  end;
end;

Var certificate, privateKey, TrustList : UA_ByteString;
    cc: PUA_ClientConfig;
    Client : PUA_Client;
begin
    certificate := _UA_STRING_ALLOC(LoadStringFromFile('client_cert.der'));
    privateKey := _UA_STRING_ALLOC(LoadStringFromFile('client_key.der'));
    TrustList := _UA_STRING_ALLOC(LoadStringFromFile('server-certificate.der'));

    client := UA_Client_new();
    cc := UA_Client_getConfig(client);
    cc^.securityMode:= UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;

    UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey, @TrustList, 1, nil, 0);

    cc^.clientDescription.applicationUri := _UA_STRING_ALLOC('urn:open62541.client');
 
    res := UA_Client_connectUsername(client, 'opc.tcp://'<IPAddress>:4840' , 'user', 'password');
end;

I hope this helps someone else.
« Last Edit: January 24, 2026, 04:45:47 am by TheMouseAUS »

 

TinyPortal © 2005-2018