Implicit Messaging with Siemens not working
jwhitman1-lmco opened this issue · 18 comments
Apologies for marking this as a bug, it should probably be a 'question', but Git doesn't want to let me switch the labels
I'm new to EIP and I'm trying to open an implicit messaging loop with a Siemens drive device using this eds. I thought I understood things, but when I tried to establish the connection using my understanding of the parameters, I got a 0x13 "not enough data supplied" error from the stack. Thought that was a little strange so I opened up the ImplicitMessagingExample and updated the path with the one on line 371 of that file, or-equaled the t2o network connection parameters to indicate multicast support, and switched the IP address for the one our device is using (and confirmed via ping). Unfortunately, even the example code (with my updates) is returning a 0x13 error.
I don't understand what's going on here...am I missing a nuance in how EIP is supposed to work? Is the stack incompatible with Siemens devices? Do I just need to update some other parameters because something is being finicky under the hood?
Can you shed some light on any of this?
Thanks!
Oh, possibly relevant: Epath class ID is 6, object ID is 1.
Hi,
Sorry for not reaching out sooner. Did you resolve this
After reading this once more, if you're working with Implicit messaging, then EPath shouldn't apply, as EPath is only used to handle data in CIP Objects via explicit messaging.
Please read this response and issue for better understanding about the differences - #36 (comment)
This is not resolved at this time, no.
if you're working with Implicit messaging, then EPath shouldn't apply, as EPath is only used to handle data in CIP Objects via explicit messaging.
I do understand this, and was referring to the EPath displayed when using a ConnectionManager that failed to make a good connection. I think my error may be somewhat consistent with the one haellingsen mentioned though. The 0x13 error shows up during the ForwardOpen command (and mentions there's others that aren't being displayed, but I don't have WireShark to see what they are). I'm using the Connection Path shown for the first (and only) connection in the EDS file I attached in my original post, "20 04 24 67 2C 66 2C 65".
I'm not sure what I'm missing, since there's no explicit reference to either of the assembly objects in the implicit messaging example....
Hi @jwhitman1-lmco,
Can you share all your "eipScanner::cip::connectionManager::ConnectionParameters" as setup in your code?
"I don't have WireShark to see what they are"
Any reasons as to why this is not possible? In general Wireshark will tell you exactly what's wrong (i.e. what you send and what was expected).
Hi @Broekman,
Can you share all your "eipScanner::cip::connectionManager::ConnectionParameters" as setup in your code?
Sure thing; here they are!
parameters.connectionPath = {0x20, 0x04, 0x24, 0x67, 0x2c, 0x66, 0x2c, 0x65};
parameters.o2tRealTimeFromat = true;
parameters.originatorVendorId = 42; /* This was edited; this is the Siemens VID value */
parameters.originatorSerialNumber = 32423;
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P;
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::MULTICAST; /* Added this */
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
parameters.t2oNetworkConnectionParams |= 32; /* I think this is correct....*/
parameters.o2tNetworkConnectionParams |= NetworkConnectinParams::P2P;
parameters.o2tNetworkConnectionParams |= NetworkConnectinParams::SCHEDULED_PRIORITY;
parameters.o2tNetworkConnectionParams |= 32; /* I think this is also correct */
parameters.originatorSerialNumber = 0x12345;
parameters.o2tRPI= 1000000;
parameters.t2oRPI= 1000000;
parameters.transportTypeTrigger |= NetworkConnectionParams::CLASS1;
Does this help?
One thing I note is that I'm not absolutely certain about the size of the network connection parameters. Like I said, I'm very new to this. Do they match with the eds that I attached above?
Any reasons as to why this is not possible? In general Wireshark will tell you exactly what's wrong (i.e. what you send and what was expected).
Because unfortunately the Powers That Be have yet to authorize its use. Getting that authorization will likely take an awful lot of time and migraines on my end.
I strongly, strongly agree with @Broekman regarding debugging with wireshark, and I almost consider it as a necessity with implicit messaging.
Without seeing the packets and errors, it will make debugging infinitely more difficult, especially for people who are trying to solve the issue remotely. It very well could be an error with the library as much as it could be an error with the parameters.
Understood. I'll see if I can get special permission or something. Maybe I'll get lucky for a change, who knows?
UPDATE: Managed to get approval accelerated. I'll be able to post packet capture tomorrow morning (28 APR 2021).
Had to change the extension to upload this, but this is a capture of my creating the object, establishing the explicit connection, then trying ten times to open an implicit connection. Any help would be appreciated...nothing sticks out as obviously erroneous to me, but that could be a lack of familiarity with what 'good' looks like here.
Remove the .txt and this should be a .pcapng file.
EIP_10ImplicitOpens.pcapng.txt
Thank you!
Any chance you guys have some insight on this? Not to jostle your elbow, just checking so I can answer my boss when he asks.
Sorry I haven't had time to look at this as I've been extremely busy with my main work.
I'll try to get to it before the weekend.
Understood, thank you so much. Knowing that will keep a bunch of flak off me.
Just checking, has there been any chance to look at this?
Thought I'd pop in as I encountered a similar issue as above. Hope this helps resolve your issue if you're still having it.
Issue
Like @jwhitman1-lmco, I was unable to get implicit connections working with my device. For my situation, I am trying to connect to an IFM AL1320 IO-Link hub to read sensor status. When I tried to follow the guide to connect, I received the same error:
[INFO] Registered session 352518144
[INFO] Send request: service=0x1 epath=[classId=1 objectId=1]
[INFO] Send request: service=0x54 epath=[classId=6 objectId=1]
[ERROR] Message Router error=0x13 additional statuses
Here's a screenshot of the wireshark capture of the request as well.
At this point my parameters setup looked like this:
eipScanner::cip::connectionManager::ConnectionParameters params;
params.connectionPath = {0x20, 0x04, 0x24, 0xC7, 0x2C, 0x96, 0x2C, 0x64 };
params.o2tRealTimeFormat = true;
params.originatorVendorId = 322;
{
using namespace eipScanner::cip::connectionManager;
params.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P;
params.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
params.t2oNetworkConnectionParams |= NetworkConnectionParams::FIXED;
params.t2oNetworkConnectionParams |= 140;
params.o2tNetworkConnectionParams |= NetworkConnectionParams::P2P;
params.o2tNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
params.o2tNetworkConnectionParams |= NetworkConnectionParams::FIXED;
params.o2tNetworkConnectionParams |= 130;
params.t2oRPI = 10000;
params.o2tRPI = 10000;
params.transportTypeTrigger |= NetworkConnectionParams::CLASS1;
}
implicit_data_connection = conn_man->forwardOpen(session, params);
The excerpt from the EDS file for this connection is as follows:
Connection1 =
0x04010002, $ Trigger and Transport
0x44640405, $ Connnection Parameters
Param19,Param2,Assem150,$ O->T RPI, size, format
Param19,Param1,Assem100,$ T->O RPI, size, format
,, $ proxy config size, format
50,Assem199, $ target config size, format
"Exclusive Owner IO-Acyc-Diag", $ Connection Name
" In/Out Data", $ help string
"20 04 24 C7 2C 96 2C 64"; $ Path
In my parameters, the o2t
connection size is specified with Param2 and evaluates to 140, and t2o
is Param1 evaluating to 130. I just used the default values of the parameters for these values. Changing these didn't seem to have an affect on whether or not the connection was able to be made.
Solution
The issue I was having is from the config specified by Assem199
. My device was looking for more data to be passed through in the connection path because of this. In Chapter 7 of the CIP spec, the details of the configuration option states that these specify the size of the data segment to be passed through appended to the connection path in the Forward_Open
call. Elswhere in the CIP spec it details the bytes of the connection path, and through that I was able to change my connection path to the following:
params.connectionPath = {0x20, 0x04, 0x24, 0xC7, 0x2C, 0x96, 0x2C, 0x64,
0x80, 0x19, // 0x80 specifies the beginning of the data
// segment, 0x19 specifies the number of words in the
// data section. This is equivalent to 25 words (50 bytes).
// This is just a large empty buffer. This is the extra
// data that the device was expecting that caused it to throw error 0x13
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00
};
Since I see your EDS file doesn't specify any extra configurations I don't know if this is your exact problem, but I would guess that you have a similar issue in that your device is expecting some more data passed through the connection path in the data field.
After changing my connection path to the above, I get the following output when configuring the messaging:
[INFO] Send request: service=0x1 epath=[classId=1 objectId=1]
[INFO] Send request: service=0x54 epath=[classId=6 objectId=1]
[INFO] Open IO connection O2T_ID=4231659531 T2O_ID=1671561217 SerialNumber 1
[INFO] Open UDP socket to send data to 192.168.1.250:2222
Normally you would read the assembly specified in the EDS to figure out what each value should be set to, but in my case all zeroes pretty much turned it into a useless device. The configuration values would be used to set up each device that is connected to the IO hub for me.
I am extremely new to the EthernetIP protocol so I don't know how necessary a lot of this stuff is, but this is what I was able to get working after a couple days of banging my head around.
Hi, I would like to chime in on this thread to request more information on the library. I would like to preface this with the fact that I only have a cursory knowledge of CIP-E/IP.
Question: Is there any explicit definition within the library of the formatting of "conectionPath"? All I see is the header file definition of it being a vector<uint8>
within struct ConnectionParameters{}
Is this defined in the CIP manual? Because the random hex numbers contained within the example code make no sense to me. I can decipher what is the Assm ID, but I don't know what the other elements mean.
Any help here would be greatly appreciated!
EDIT:
For context, I am trying to migrate to using this library from a Python implementation we were using before. I am currently getting a Path segment error. I am using wireshark and looking at the differences between the Python library's Forward Open request vs. this implementation, I get the following differences:
It appears the good implementation is has two 8-bit path segments (0x20 and 0x24) while the bad one has two 16-bit (0x21and 0x25)
This is my setup:
`
parameters.connectionPath = {0x20, 0x04, 0x24, 2, 0x2C, 102, 0x2C, 103};
parameters.o2tRealTimeFormat = true;
parameters.connectionSerialNumber = 0x017a;
parameters.originatorVendorId = 0x00ff;
parameters.originatorSerialNumber = 0xffffffff;
parameters.timeoutTicks = 250;
parameters.o2tNetworkConnectionId = 0x002be2bd;
parameters.t2oNetworkConnectionId = 0x00630a04;
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P;
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
parameters.t2oNetworkConnectionParams |= 178; //size of Assm103 = 32
parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::P2P;
parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
parameters.o2tNetworkConnectionParams |= 8; //size of Assm102 = 32
//parameters.originatorSerialNumber = 0x12345;
parameters.o2tRPI = 100000;
parameters.t2oRPI = 100000;
parameters.transportTypeTrigger |= NetworkConnectionParams::CLASS1;
`
Update:
I resolved my issue. The issue was that the library was by default constructing 16-bit path segments when my PLC expected 8-bit.
I found the following example in 8-bit_path_segments.rst
on how to resolve this (set to 8-bit):
#include "MessageRouter.h"
#include "ConnectionManager.h"
using eipScanner::ConnectionManager;
using eipScanner::MessageRouter;
int main()
{
MessageRouter::SPtr mr_ptr = std::make_shared<MessageRouter>(MessageRouter::USE_8_BIT_PATH_SEGMENTS);
ConnectionManager _connectionManager = ConnectionManager(mr_ptr);
/* ConnectionManager now uses 8-bit path segments */
return 0;
}
This did not work. Could have been that I did something wrong, but I doubt it.
So instead I hard-coded the MessageRouter
constructor to 8-bit segments by default:
class MessageRouter {
public:
using SPtr = std::shared_ptr<MessageRouter>;
static constexpr bool USE_8_BIT_PATH_SEGMENTS = true;
/**
* @brief Default constructor
*/
MessageRouter(bool use_8_bit_path_segments=true); // TW: edited this to default to true
Data is now streaming to/from PLC
Hi, everyone. I tried to set the 8-bit path as described in https://eipscanner.readthedocs.io/en/latest/misc/8-bit_path_segments.html, but I get this link error:
'''/usr/bin/ld: CMakeFiles/eip2mqqt.dir/main.cpp.o: warning: relocation against _ZN10eipScanner13MessageRouter23USE_8_BIT_PATH_SEGMENTSE' in read-only section
.text'
/usr/bin/ld: CMakeFiles/eip2mqqt.dir/main.cpp.o: in function main': main.cpp:(.text+0x35f): undefined reference to
eipScanner::MessageRouter::USE_8_BIT_PATH_SEGMENTS'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/eip2mqqt.dir/build.make:97: eip2mqqt] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/eip2mqqt.dir/all] Error 2
make: *** [Makefile:91: all] Error 2'''
What could be the reason?
Thought I'd pop in as I encountered a similar issue as above. Hope this helps resolve your issue if you're still having it.
Issue
Like @jwhitman1-lmco, I was unable to get implicit connections working with my device. For my situation, I am trying to connect to an IFM AL1320 IO-Link hub to read sensor status. When I tried to follow the guide to connect, I received the same error:
[INFO] Registered session 352518144 [INFO] Send request: service=0x1 epath=[classId=1 objectId=1] [INFO] Send request: service=0x54 epath=[classId=6 objectId=1] [ERROR] Message Router error=0x13 additional statuses
Here's a screenshot of the wireshark capture of the request as well.
At this point my parameters setup looked like this:
eipScanner::cip::connectionManager::ConnectionParameters params; params.connectionPath = {0x20, 0x04, 0x24, 0xC7, 0x2C, 0x96, 0x2C, 0x64 }; params.o2tRealTimeFormat = true; params.originatorVendorId = 322; { using namespace eipScanner::cip::connectionManager; params.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P; params.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY; params.t2oNetworkConnectionParams |= NetworkConnectionParams::FIXED; params.t2oNetworkConnectionParams |= 140; params.o2tNetworkConnectionParams |= NetworkConnectionParams::P2P; params.o2tNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY; params.o2tNetworkConnectionParams |= NetworkConnectionParams::FIXED; params.o2tNetworkConnectionParams |= 130; params.t2oRPI = 10000; params.o2tRPI = 10000; params.transportTypeTrigger |= NetworkConnectionParams::CLASS1; } implicit_data_connection = conn_man->forwardOpen(session, params);The excerpt from the EDS file for this connection is as follows:
Connection1 = 0x04010002, $ Trigger and Transport 0x44640405, $ Connnection Parameters Param19,Param2,Assem150,$ O->T RPI, size, format Param19,Param1,Assem100,$ T->O RPI, size, format ,, $ proxy config size, format 50,Assem199, $ target config size, format "Exclusive Owner IO-Acyc-Diag", $ Connection Name " In/Out Data", $ help string "20 04 24 C7 2C 96 2C 64"; $ Path
In my parameters, the
o2t
connection size is specified with Param2 and evaluates to 140, andt2o
is Param1 evaluating to 130. I just used the default values of the parameters for these values. Changing these didn't seem to have an affect on whether or not the connection was able to be made.Solution
The issue I was having is from the config specified by
Assem199
. My device was looking for more data to be passed through in the connection path because of this. In Chapter 7 of the CIP spec, the details of the configuration option states that these specify the size of the data segment to be passed through appended to the connection path in theForward_Open
call. Elswhere in the CIP spec it details the bytes of the connection path, and through that I was able to change my connection path to the following:params.connectionPath = {0x20, 0x04, 0x24, 0xC7, 0x2C, 0x96, 0x2C, 0x64, 0x80, 0x19, // 0x80 specifies the beginning of the data // segment, 0x19 specifies the number of words in the // data section. This is equivalent to 25 words (50 bytes). // This is just a large empty buffer. This is the extra // data that the device was expecting that caused it to throw error 0x13 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };Since I see your EDS file doesn't specify any extra configurations I don't know if this is your exact problem, but I would guess that you have a similar issue in that your device is expecting some more data passed through the connection path in the data field.
After changing my connection path to the above, I get the following output when configuring the messaging:
[INFO] Send request: service=0x1 epath=[classId=1 objectId=1] [INFO] Send request: service=0x54 epath=[classId=6 objectId=1] [INFO] Open IO connection O2T_ID=4231659531 T2O_ID=1671561217 SerialNumber 1 [INFO] Open UDP socket to send data to 192.168.1.250:2222
Normally you would read the assembly specified in the EDS to figure out what each value should be set to, but in my case all zeroes pretty much turned it into a useless device. The configuration values would be used to set up each device that is connected to the IO hub for me.
I am extremely new to the EthernetIP protocol so I don't know how necessary a lot of this stuff is, but this is what I was able to get working after a couple days of banging my head around.
Hi,I have the same problem now.I modified it with your advice, but the routing information threw an exception, it seems that I can't modify it.
ST15_EIP_Ethernet_IP CPU_IO64.eds.txt
Param3 = 0, $ first field shall equal 0 ,, $ path size,path 0x0000, $ descriptor 0xDC, $ data type : Path , $ data size in bytes "Data Configuration Size", $ name "", $ units "Configuration buffer added to the path. Example of the format: 20 0C 21 01", $ help string ,400,"", $ min,max,default data values ,,,, $ mult,dev,base,offset scaling not used ,,,, $ mult,dev,base,offset link not used ; $ decimal places not used
I tried two modifications in the code, but the route threw an exception.
The first kind:
`// Implicit messaging
ConnectionManager connectionManager;
ConnectionParameters parameters;
parameters.connectionPath = { 0x20, 0x04, 0x24, 0x00, 0x2C, 0x01,0X2C,0X00 ,
0x20, 0x0c ,0x21 ,0x01};
parameters.o2tRealTimeFormat = true;
parameters.originatorVendorId = 1;
//parameters.originatorSerialNumber = 32423;
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P;
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
parameters.t2oNetworkConnectionParams |= 64; //size of Assm100 =32
parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::P2P;
parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
parameters.o2tNetworkConnectionParams |= 64; //size of Assm150 = 32
parameters.originatorSerialNumber = 123456789;
parameters.o2tRPI = 50000;//1000000;
parameters.t2oRPI = 50000;//1000000;
parameters.transportTypeTrigger |= NetworkConnectionParams::CLASS1;The second type:
// Implicit messaging
ConnectionManager connectionManager;
ConnectionParameters parameters;
parameters.connectionPath = { 0x20, 0x04, 0x24, 0x00, 0x2C, 0x01,0X2C,0X00 ,
0x80, 0x01 ,0x01};
parameters.o2tRealTimeFormat = true;
parameters.originatorVendorId = 1;
//parameters.originatorSerialNumber = 32423;
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P;
parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
parameters.t2oNetworkConnectionParams |= 64; //size of Assm100 =32
parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::P2P;
parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;
parameters.o2tNetworkConnectionParams |= 64; //size of Assm150 = 32
parameters.originatorSerialNumber = 123456789;
parameters.o2tRPI = 50000;//1000000;
parameters.t2oRPI = 50000;//1000000;
parameters.transportTypeTrigger |= NetworkConnectionParams::CLASS1;`
I'd be most grateful if you could help.