nimbuscontrols / EIPScanner

Free implementation of EtherNet/IP in C++
https://eipscanner.readthedocs.io/en/latest/
MIT License
224 stars 90 forks source link

Implicit messaging: sending multiple messages #65

Closed chruetli closed 2 years ago

chruetli commented 2 years ago

The device I have to control uses implicit messaging to change runtime parameters. This is a multi stage process:

  1. send message to enable write
  2. send the parameter
  3. send message to disable write

I do not understand how I have to modify the ImplicitMessagingExample.cpp example to send multiple messages. Any ideas?

jadamroth commented 2 years ago

You use setDataToSend() to send data to your adapter. Is that what you're asking?

chruetli commented 2 years ago

Hi Adam

It's part of... Having the following block from the ImplicitMessagingExample.cpp file.

  auto io = connectionManager.forwardOpen(si, parameters);
  if (auto ptr = io.lock()) {
      ptr->setDataToSend(std::vector<uint8_t>{0x00, 0x00, 0x10, 0x05, 0x0, 0x0, 0x80, 0x0});
      ptr->setReceiveDataListener([](auto realTimeHeader, auto sequence, auto data) {
      std::ostringstream ss;
      ss << "secNum=" << sequence << " data=";
      for (auto &byte : data) {
        ss << "[" << std::hex << (int) byte << "]";
      }

      Logger(LogLevel::INFO) << "Received: " << ss.str();
    });

    ptr->setCloseListener([]() {
      Logger(LogLevel::INFO) << "Closed";
    });
  }

  int count = 20;
  while (connectionManager.hasOpenConnections() && count-- > 0) {
    connectionManager.handleConnections(std::chrono::milliseconds(100));
  }

Here we do:

What I need is:

I do not see how this fits into the schema above...

jadamroth commented 2 years ago

Seems to me like you have the order of operations down, so I don't understand the issue.

It's just an example and will not perfectly work with your application out of the box. You'll need to program your application's logic yourself.

Try handling the logic in your listener callback, then close the connection when you want

      ptr->setDataToSend(std::vector<uint8_t>{0x00, 0x00, 0x10, 0x05, 0x0, 0x0, 0x80, 0x0}); // first send
      ptr->setReceiveDataListener([](auto realTimeHeader, auto sequence, auto data) { // listener
          if(data == 'something') // listen and handle logic
              setReceiveDataListener(); // send data again
          else if(data == 'close'){
              setCloseListener([]() {
                  Logger(LogLevel::INFO) << "Closed";
              });
          }
       });
chruetli commented 2 years ago

I finally got it... Thank you!