Copied Modbus-CAPL and added VisualStudio project VCSignalProtocolDLL
This commit is contained in:
		
							parent
							
								
									41ba4a3fd5
								
							
						
					
					
						commit
						f26088b1eb
					
				
					 36 changed files with 17624 additions and 0 deletions
				
			
		
							
								
								
									
										4832
									
								
								Modbus-DLL/MakeConfig.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4832
									
								
								Modbus-DLL/MakeConfig.cfg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										7343
									
								
								Modbus-DLL/ModbusNet.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7343
									
								
								Modbus-DLL/ModbusNet.cfg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										529
									
								
								Modbus-DLL/include/CAPL/MakeConfig.can
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										529
									
								
								Modbus-DLL/include/CAPL/MakeConfig.can
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,529 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "include/ModbusUdpClientCommon.cin"
 | 
				
			||||||
 | 
						#include "include/ModbusFunctions.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct device
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char Ip[16];
 | 
				
			||||||
 | 
							char IpLsb[4];
 | 
				
			||||||
 | 
							char IpNet[4];
 | 
				
			||||||
 | 
							enum Vendor Vendor;
 | 
				
			||||||
 | 
							word SerialCode;
 | 
				
			||||||
 | 
							word DeviceCode;
 | 
				
			||||||
 | 
							struct deviceIOs DeviceIOs;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char[16] gIps[long];
 | 
				
			||||||
 | 
						char gScanFirstIp[16];
 | 
				
			||||||
 | 
						char gScanLastIp[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char fnSysvar[40];		// Filename of Sysvars
 | 
				
			||||||
 | 
						char fnDbc[40];			// Filename of DBC
 | 
				
			||||||
 | 
						char name[20];			// Name of project
 | 
				
			||||||
 | 
						dword ips[50];			// detected IPs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						file f;
 | 
				
			||||||
 | 
						byte gIpNets[long];
 | 
				
			||||||
 | 
						struct device gIpsSorted[long];
 | 
				
			||||||
 | 
						dword gScanFirst, gScanLast;
 | 
				
			||||||
 | 
						word ADi, ADn, ADl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						byte gMaxTransmissionCount;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on preStart
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// List of IPs of devices go here
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						strncpy(gIps[0], "192.168.1.3", 16);
 | 
				
			||||||
 | 
						strncpy(gIps[2], "192.168.1.4", 16);
 | 
				
			||||||
 | 
						strncpy(gIps[3], "192.168.1.8", 16);
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Scan a range of IPs for devices. Start and Stop go here
 | 
				
			||||||
 | 
						// Please note: Currelty .255 will be skipped!
 | 
				
			||||||
 | 
						strncpy(gScanFirstIp, "192.168.1.2", 16);
 | 
				
			||||||
 | 
						strncpy(gScanLastIp, "192.168.1.10", 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Name of the project
 | 
				
			||||||
 | 
						strncpy(name, "Modbus", elCount(name));
 | 
				
			||||||
 | 
						// Paths to the generated files relative to .cfg
 | 
				
			||||||
 | 
						strncpy(fnSysvar, "include/SysVars/generated.vsysvar", elCount(fnSysvar));
 | 
				
			||||||
 | 
						strncpy(fnDbc, "include/DBC/generated.dbc", elCount(fnDbc));
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						OutputDebugLevel = Error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on start
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gMaxTransmissionCount = @sysvar::Config::Modbus::MaxTransmissionCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gIps.Size() == 0)
 | 
				
			||||||
 | 
							DetectDevices();
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							MakeIpNets();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <PutString>
 | 
				
			||||||
 | 
					void PutString(file f, char str[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						f.PutString(str, strlen(str));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <PutString>
 | 
				
			||||||
 | 
					void PutString(file f, word d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char str[6];
 | 
				
			||||||
 | 
						ltoa(d, str, 10);
 | 
				
			||||||
 | 
						f.PutString(str, strlen(str));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <PutString>
 | 
				
			||||||
 | 
					void PutString(file f, byte d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char str[4];
 | 
				
			||||||
 | 
						ltoa(d, str, 10);
 | 
				
			||||||
 | 
						f.PutString(str, strlen(str));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Step 1: Detect active devices and collect IP addresses
 | 
				
			||||||
 | 
					/// <Step1>
 | 
				
			||||||
 | 
					void DetectDevices()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						@sysvar::Config::Modbus::MaxTransmissionCount = 1;
 | 
				
			||||||
 | 
						write("Scanning from %s to %s with timeout of %d ms", gScanFirstIp, gScanLastIp, @sysvar::Config::Modbus::RequestTimeout);
 | 
				
			||||||
 | 
						gScanFirst = ipGetAddressAsNumber(gScanFirstIp);
 | 
				
			||||||
 | 
						gScanLast = ipGetAddressAsNumber(gScanLastIp);
 | 
				
			||||||
 | 
						write("%d.%d.%d.%d  ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24);
 | 
				
			||||||
 | 
						ModbusConnectTo(gScanFirst, @sysvar::Config::Modbus::Port);
 | 
				
			||||||
 | 
						ModbusReadBits(0, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <Step1>
 | 
				
			||||||
 | 
					void DetectDevicesNext()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// next IP
 | 
				
			||||||
 | 
						// 0xFE...... --> Skip xxx.xxx.xxx.255 which is broadcast address in 192.168.xxx.0 nets
 | 
				
			||||||
 | 
						if ((gScanFirst & 0xFFFFFF00) == 0xFEFFFF00)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gScanFirst &= 0x000000FF;
 | 
				
			||||||
 | 
							gScanFirst += 0x00000001;
 | 
				
			||||||
 | 
							write("%d.%d.%d.%d  ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if ((gScanFirst & 0xFFFF0000) == 0xFEFF0000)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gScanFirst &= 0x0000FFF;
 | 
				
			||||||
 | 
							gScanFirst += 0x00000100;
 | 
				
			||||||
 | 
							write("%d.%d.%d.%d  ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if ((gScanFirst & 0xFF000000) == 0xFE000000)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gScanFirst &= 0x00FFFFFF;
 | 
				
			||||||
 | 
							gScanFirst += 0x00010000;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							write("%d.%d.%d.%d  ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gScanFirst += 0x01000000;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (gScanFirst == gScanLast)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							@sysvar::Config::Modbus::MaxTransmissionCount = gMaxTransmissionCount;
 | 
				
			||||||
 | 
							MakeIpNets();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						writeEx(1, 1, ".");
 | 
				
			||||||
 | 
						gRemoteIP = gScanFirst;		// Don't open new socket, it takes too much time.
 | 
				
			||||||
 | 
						ModbusReadBits(0, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <Step1>
 | 
				
			||||||
 | 
					void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DetectDevicesNext();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <Step1>
 | 
				
			||||||
 | 
					void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ipGetAddressAsString(gScanFirst, gIps[gScanFirst], 16);
 | 
				
			||||||
 | 
						DetectDevicesNext();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Step 2: Sort into subnets
 | 
				
			||||||
 | 
					// Sort the IPs from gIps to gIpsSorted and add their subnet to gIpNets
 | 
				
			||||||
 | 
					/// <Step2>
 | 
				
			||||||
 | 
					void MakeIpNets()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long ipNum;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gIps.Size() == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							stop();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (long i : gIps)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ipNum = ipGetAddressAsNumber(gIps[i]);						// convert IP to dword
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							gIpNets[(ipNum >> 16) & 0xFF] = 1;							// add subnet
 | 
				
			||||||
 | 
							ips[gIpsSorted.size()] = ipNum;								// add ip to array
 | 
				
			||||||
 | 
							strncpy(gIpsSorted[ipNum].IP, gIps[i], 16);					// copy to new array
 | 
				
			||||||
 | 
							ltoa((ipNum >> 16) & 0xFF, gIpsSorted[ipNum].IpNet, 10);	// add .IpNet
 | 
				
			||||||
 | 
							ltoa((ipNum >> 24) & 0xFF, gIpsSorted[ipNum].IpLsb, 10);	// add .IpLsb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							gIps.Remove(i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AnalyzeDevices();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Step 3: Retreive configuration of devices
 | 
				
			||||||
 | 
					/// <Step3>
 | 
				
			||||||
 | 
					void AnalyzeDevices()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ADn = 0;
 | 
				
			||||||
 | 
						ADi = 0;
 | 
				
			||||||
 | 
						ADl = gIpsSorted.Size();
 | 
				
			||||||
 | 
						write("Analyzing %s...", gIpsSorted[ips[ADi]].Ip);
 | 
				
			||||||
 | 
						gIpsSorted[ips[ADi]].Vendor = Wago;
 | 
				
			||||||
 | 
						if (gRemoteIP != INVALID_IP)
 | 
				
			||||||
 | 
							gRemoteIP = ips[ADi];
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ModbusConnectTo(ips[ADi], @sysvar::Config::Modbus::Port);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2011, 1);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2012, 1);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2030, 65);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2031, 64);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2032, 64);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2033, 63);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <Step3>
 | 
				
			||||||
 | 
					void AnalyzeDevicesNext()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (++ADi >= ADl)		// we have analyzed all devices
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							MakeFiles();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ADn = 0;
 | 
				
			||||||
 | 
						gRemoteIP = ips[ADi];
 | 
				
			||||||
 | 
						write("Analyzing %s...", gIpsSorted[ips[ADi]].Ip);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2011, 1);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2012, 1);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2030, 65);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2031, 64);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2032, 64);
 | 
				
			||||||
 | 
						ModbusReadRegisters(0x2033, 63);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <Step3>
 | 
				
			||||||
 | 
					void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (error)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case FinalTimeout:
 | 
				
			||||||
 | 
								writeLineEx(0, 3, "Error while analyzing %s! The device did not respond! Ignoring...", gIpsSorted[ips[ADi]].IP);
 | 
				
			||||||
 | 
								gQueueAck.Clear();
 | 
				
			||||||
 | 
								gQueuePending.Clear();
 | 
				
			||||||
 | 
								gQueueSent.Clear();
 | 
				
			||||||
 | 
								gIpsSorted.Remove(ips[ADi]);
 | 
				
			||||||
 | 
								AnalyzeDevicesNext();
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case Exception:
 | 
				
			||||||
 | 
								writeLineEx(0, 3, "Error while analyzing %s! The device respond with exception code %d! Ignoring...", gIpsSorted[ips[ADi]].IP, ex);
 | 
				
			||||||
 | 
								gQueueAck.Clear();
 | 
				
			||||||
 | 
								gQueuePending.Clear();
 | 
				
			||||||
 | 
								gQueueSent.Clear();
 | 
				
			||||||
 | 
								gIpsSorted.Remove(ips[ADi]);
 | 
				
			||||||
 | 
								AnalyzeDevicesNext();
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <Step3>
 | 
				
			||||||
 | 
					void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct ModbusReqRead mbreq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						byte i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (mbreq.Address)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case 0x2011:
 | 
				
			||||||
 | 
								gIpsSorted[ips[ADi]].serialCode = mbres.Data[0];
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x2012:
 | 
				
			||||||
 | 
								gIpsSorted[ips[ADi]].deviceCode = mbres.Data[0];
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x2030:
 | 
				
			||||||
 | 
							case 0x2031:
 | 
				
			||||||
 | 
							case 0x2032:
 | 
				
			||||||
 | 
							case 0x2033:
 | 
				
			||||||
 | 
								for (i = 0; i < mbreq.Count; i++)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (mbres.Data[i] == 0x0000)
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									ParseDeviceCode(mbres.Data[i], gIpsSorted[ips[ADi]].Vendor, gIpsSorted[ips[ADi]].DeviceIOs);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (++ADn == 6)
 | 
				
			||||||
 | 
							AnalyzeDevicesNext();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Step 4: Create the files with the queried data
 | 
				
			||||||
 | 
					/// <Step4>
 | 
				
			||||||
 | 
					void MakeFiles()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GenSysvars();
 | 
				
			||||||
 | 
						GenDbc();
 | 
				
			||||||
 | 
						stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Generate the SysVars XML
 | 
				
			||||||
 | 
					/// <Step4>
 | 
				
			||||||
 | 
					void GenSysvars()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						write("GenSysvars() -> %s", fnSysvar);
 | 
				
			||||||
 | 
						f.Open(fnSysvar, 0, 0);	// rewrite file in ASCII
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PutString(f, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
 | 
				
			||||||
 | 
						PutString(f, "<systemvariables version=\"4\">\n");
 | 
				
			||||||
 | 
						PutString(f, "  <namespace name=\"\" comment=\"\">\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PutString(f, "    <namespace name=\"Config\" comment=\"\">\n");
 | 
				
			||||||
 | 
						PutString(f, "      <namespace name=\"Modbus\" comment=\"\">\n");
 | 
				
			||||||
 | 
						PutString(f, "        <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"ms\" name=\"RequestTimeout\" comment=\"The maximum duration for a Modbus-UDP/-TCP request in milliseconds. After timeout a retransmission may be started (see MaxRetransmissionCount).    Use `ping` to get the maximum latency to a device, double it and add 2-3 ms for processing.\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
								PutString(f, (word)@sysvar::Config::Modbus::RequestTimeout);
 | 
				
			||||||
 | 
								PutString(f, "\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"1000\" maxValuePhys=\"1000\" />\n");
 | 
				
			||||||
 | 
						PutString(f, "        <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"Port\" comment=\"\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
								PutString(f, (word)@sysvar::Config::Modbus::Port);
 | 
				
			||||||
 | 
								PutString(f, "\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"65535\" maxValuePhys=\"65535\" />\n");
 | 
				
			||||||
 | 
						PutString(f, "        <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"times\" name=\"MaxTransmissionCount\" comment=\"How often a retransmission of a request will be sent until it gets discarded and an error is thrown.\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
								PutString(f, (byte)@sysvar::Config::Modbus::MaxTransmissionCount);
 | 
				
			||||||
 | 
								PutString(f, "\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"10\" maxValuePhys=\"10\" />\n");
 | 
				
			||||||
 | 
						PutString(f, "      </namespace>\n");
 | 
				
			||||||
 | 
						PutString(f, "      <namespace name=\"TcpIp\" comment=\"\">\n");
 | 
				
			||||||
 | 
						PutString(f, "        <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"AdapterIndex\" comment=\"Index of network interface to use\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"2\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"20\" maxValuePhys=\"20\" />\n");
 | 
				
			||||||
 | 
						PutString(f, "      </namespace>\n");
 | 
				
			||||||
 | 
						PutString(f, "    </namespace>\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (long net : gIpNets)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							byte nett;
 | 
				
			||||||
 | 
							nett = net;
 | 
				
			||||||
 | 
							PutString(f, "    <namespace name=\"Ethernet");
 | 
				
			||||||
 | 
									PutString(f, nett);
 | 
				
			||||||
 | 
									PutString(f, "\" comment=\"Subnet: 192.168.");
 | 
				
			||||||
 | 
									PutString(f, nett);
 | 
				
			||||||
 | 
									PutString(f, ".\">\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (long ipN : gIpsSorted)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (((ipN >> 16) & 0xFF) != net)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								PutString(f, "      <namespace name=\"Client_");
 | 
				
			||||||
 | 
										//PutString(f, netS);
 | 
				
			||||||
 | 
										//PutString(f, "_");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].IpLsb);
 | 
				
			||||||
 | 
										PutString(f, "\" comment=\"Server with ip address '");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].Ip);
 | 
				
			||||||
 | 
										PutString(f, "'\">\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Namespace Config
 | 
				
			||||||
 | 
								PutString(f, "        <namespace name=\"Config\" comment=\"Configuration section for this server\">\n");
 | 
				
			||||||
 | 
								// IP
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"IP\" comment=\"The IP address of this server\" bitcount=\"8\" isSigned=\"true\" encoding=\"65001\" type=\"string\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].Ip);
 | 
				
			||||||
 | 
										PutString(f, "\" />\n");
 | 
				
			||||||
 | 
								// Intveral
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"ms\" name=\"Interval\" comment=\"The interval with which the device will be queried\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"100\" minValue=\"10\" minValuePhys=\"10\" maxValue=\"10000\" maxValuePhys=\"10000\" />\n");
 | 
				
			||||||
 | 
								PutString(f, "        </namespace>\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//Namespace Info
 | 
				
			||||||
 | 
								PutString(f, "        <namespace name=\"Info\" comment=\"Some information about the device\">\n");
 | 
				
			||||||
 | 
								// Vendor
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"Vendor\" comment=\"The vendor of the device\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, (byte)gIpsSorted[ipN].Vendor);
 | 
				
			||||||
 | 
										PutString(f, "\">\n");
 | 
				
			||||||
 | 
										PutString(f, "            <valuetable definesMinMax=\"true\">\n");
 | 
				
			||||||
 | 
										PutString(f, "              <valuetableentry value=\"2\" description=\"BuR\" />\n");
 | 
				
			||||||
 | 
										PutString(f, "              <valuetableentry value=\"23\" description=\"Wago\" />\n");
 | 
				
			||||||
 | 
										PutString(f, "            </valuetable>\n");
 | 
				
			||||||
 | 
										PutString(f, "          </variable>\n");
 | 
				
			||||||
 | 
								// SerialCode
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"SerialCode\" comment=\"The serial code of the server\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].SerialCode);
 | 
				
			||||||
 | 
										PutString(f, "\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"10000\" maxValuePhys=\"10000\" />\n");
 | 
				
			||||||
 | 
								// DeviceCode
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"DeviceCode\" comment=\"The device code of the server\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceCode);
 | 
				
			||||||
 | 
										PutString(f, "\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"10000\" maxValuePhys=\"10000\" />\n");
 | 
				
			||||||
 | 
								// Modules
 | 
				
			||||||
 | 
								gIpsSorted[ipN].DeviceIOs.Modules[strlen(gIpsSorted[ipN].DeviceIOs.Modules)-1] = 0;
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"Modules\" comment=\"The type and number of inputs of modules that are connected to the server\" bitcount=\"8\" isSigned=\"true\" encoding=\"65001\" type=\"string\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.Modules);
 | 
				
			||||||
 | 
										PutString(f, "\" />\n");
 | 
				
			||||||
 | 
								// InputRegisters
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"InputRegisters\" comment=\"Number of input registers\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.InputRegisters);
 | 
				
			||||||
 | 
										PutString(f, "\" minValue=\"0\" minValuePhys=\"0\" maxValue=\"123\" maxValuePhys=\"123\" />\n");
 | 
				
			||||||
 | 
								// InputBits
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"InputBits\" comment=\"Number of input bits\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.InputBits);
 | 
				
			||||||
 | 
										PutString(f, "\" minValue=\"0\" minValuePhys=\"0\" maxValue=\"2000\" maxValuePhys=\"2000\" />\n");
 | 
				
			||||||
 | 
								// OutputRegisters
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"OutputRegisters\" comment=\"Number of output registers\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.OutputRegisters);
 | 
				
			||||||
 | 
										PutString(f, "\" minValue=\"0\" minValuePhys=\"0\" maxValue=\"123\" maxValuePhys=\"123\" />\n");
 | 
				
			||||||
 | 
								// OutputBits
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"OutputBits\" comment=\"Number of output bits\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.OutputBits);
 | 
				
			||||||
 | 
										PutString(f, "\" minValue=\"0\" minValuePhys=\"0\" maxValue=\"2000\" maxValuePhys=\"2000\" />\n");
 | 
				
			||||||
 | 
								PutString(f, "        </namespace>\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Namespace Data
 | 
				
			||||||
 | 
								PutString(f, "        <namespace name=\"Data\" comment=\"The actual process image\">\n");
 | 
				
			||||||
 | 
								// InputRegisters
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"InputRegisters\" comment=\"The values of the input registers\" bitcount=\"9\" isSigned=\"true\" encoding=\"65001\" type=\"intarray\" arrayLength=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.InputRegisters);
 | 
				
			||||||
 | 
										PutString(f, "\" />\n");
 | 
				
			||||||
 | 
								// InputBits
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"InputBits\" comment=\"The state of the input bits\" bitcount=\"2\" isSigned=\"true\" encoding=\"65001\" type=\"intarray\" arrayLength=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.InputBits);
 | 
				
			||||||
 | 
										PutString(f, "\" />\n");
 | 
				
			||||||
 | 
								// OutputRegisters
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"OutputRegisters\" comment=\"The values of the output registers. Write here and the values will be sent to the device\" bitcount=\"9\" isSigned=\"true\" encoding=\"65001\" type=\"intarray\" arrayLength=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.OutputRegisters);
 | 
				
			||||||
 | 
										PutString(f, "\" />\n");
 | 
				
			||||||
 | 
								// OutputBits
 | 
				
			||||||
 | 
								PutString(f, "          <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"OutputBits\" comment=\"The state of the output bits. Write here and the values will be sent to the device\" bitcount=\"2\" isSigned=\"true\" encoding=\"65001\" type=\"intarray\" arrayLength=\"");
 | 
				
			||||||
 | 
										PutString(f, gIpsSorted[ipN].DeviceIOs.OutputBits);
 | 
				
			||||||
 | 
										PutString(f, "\" />\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								PutString(f, "        </namespace>\n");
 | 
				
			||||||
 | 
								PutString(f, "      </namespace>\n");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							PutString(f, "    </namespace>\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PutString(f, "  </namespace>\n");
 | 
				
			||||||
 | 
						PutString(f, "</systemvariables>\n");
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						f.Close();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Generate the Database
 | 
				
			||||||
 | 
					/// <Step4>
 | 
				
			||||||
 | 
					void GenDbc()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						write("GenDbc() -> %s", fnDbc);
 | 
				
			||||||
 | 
						f.Open(fnDbc, 0, 0);	// rewrite file in ASCII
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PutString(f, "VERSION \"\"\n\n\n");
 | 
				
			||||||
 | 
						PutString(f, "NS_ :\n");
 | 
				
			||||||
 | 
						PutString(f, "	NS_DESC_\n");
 | 
				
			||||||
 | 
						PutString(f, "	CM_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BA_DEF_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BA_\n");
 | 
				
			||||||
 | 
						PutString(f, "	VAL_\n");
 | 
				
			||||||
 | 
						PutString(f, "	CAT_DEF_\n");
 | 
				
			||||||
 | 
						PutString(f, "	CAT_\n");
 | 
				
			||||||
 | 
						PutString(f, "	FILTER\n");
 | 
				
			||||||
 | 
						PutString(f, "	BA_DEF_DEF_\n");
 | 
				
			||||||
 | 
						PutString(f, "	EV_DATA_\n");
 | 
				
			||||||
 | 
						PutString(f, "	ENVVAR_DATA_\n");
 | 
				
			||||||
 | 
						PutString(f, "	SGTYPE_\n");
 | 
				
			||||||
 | 
						PutString(f, "	SGTYPE_VAL_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BA_DEF_SGTYPE_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BA_SGTYPE_\n");
 | 
				
			||||||
 | 
						PutString(f, "	SIG_TYPE_REF_\n");
 | 
				
			||||||
 | 
						PutString(f, "	VAL_TABLE_\n");
 | 
				
			||||||
 | 
						PutString(f, "	SIG_GROUP_\n");
 | 
				
			||||||
 | 
						PutString(f, "	SIG_VALTYPE_\n");
 | 
				
			||||||
 | 
						PutString(f, "	SIGTYPE_VALTYPE_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BO_TX_BU_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BA_DEF_REL_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BA_REL_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BA_DEF_DEF_REL_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BU_SG_REL_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BU_EV_REL_\n");
 | 
				
			||||||
 | 
						PutString(f, "	BU_BO_REL_\n");
 | 
				
			||||||
 | 
						PutString(f, "	SG_MUL_VAL_\n");
 | 
				
			||||||
 | 
						PutString(f, "\n");
 | 
				
			||||||
 | 
						PutString(f, "BS_:\n");
 | 
				
			||||||
 | 
						PutString(f, "\nBU_:");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (long ipN : gIpsSorted)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							PutString(f, " Client_");
 | 
				
			||||||
 | 
									//PutString(f, gIpsSorted[ipN].IpNet);
 | 
				
			||||||
 | 
									//PutString(f, "_");
 | 
				
			||||||
 | 
									PutString(f, gIpsSorted[ipN].IpLsb);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						PutString(f, "\n\n\n\n");
 | 
				
			||||||
 | 
						PutString(f, "BA_DEF_ BU_  \"NodeLayerModules\" STRING ;\n");
 | 
				
			||||||
 | 
						PutString(f, "BA_DEF_  \"DBName\" STRING ;\n");
 | 
				
			||||||
 | 
						PutString(f, "BA_DEF_  \"BusType\" STRING ;\n");
 | 
				
			||||||
 | 
						PutString(f, "BA_DEF_DEF_  \"NodeLayerModules\" \"Ethernet_IL.DLL\";\n");
 | 
				
			||||||
 | 
						PutString(f, "BA_DEF_DEF_  \"DBName\" \"\";\n");
 | 
				
			||||||
 | 
						PutString(f, "BA_DEF_DEF_  \"BusType\" \"Ethernet\";\n");
 | 
				
			||||||
 | 
						PutString(f, "BA_ \"BusType\" \"Ethernet\";\n");
 | 
				
			||||||
 | 
						PutString(f, "BA_ \"DBName\" \"");
 | 
				
			||||||
 | 
								PutString(f, name);
 | 
				
			||||||
 | 
								PutString(f, "\";\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						f.Close();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusClientPanics(enum FatalErrors reason)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeLineEx(0, 4, "<%NODE_NAME%> FATAL! %d", reason);
 | 
				
			||||||
 | 
						switch(reason)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case ParsingBuffer:
 | 
				
			||||||
 | 
							case ModbusPackageWasSplit:
 | 
				
			||||||
 | 
							case DeviceCodeUnknown:
 | 
				
			||||||
 | 
							case VendorIdUnknown:
 | 
				
			||||||
 | 
							case ConnectionError:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteBitFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteRegisterFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteMasksFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusReadWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteBitSuccess(struct ModbusResConfirmSingle mbc){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteRegisterSuccess(struct ModbusResConfirmSingle mbc){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteBitsSuccess(struct ModbusResConfirmMultiple mbc){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteRegistersSuccess(struct ModbusResConfirmMultiple mbc){}
 | 
				
			||||||
 | 
					/// <zzzModbus>
 | 
				
			||||||
 | 
					void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbc){}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								Modbus-DLL/include/CAPL/MakeConfig.cbf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Modbus-DLL/include/CAPL/MakeConfig.cbf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										246
									
								
								Modbus-DLL/include/CAPL/ModbusClient.can
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								Modbus-DLL/include/CAPL/ModbusClient.can
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,246 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "include\ModbusUdpClientCommon.cin"
 | 
				
			||||||
 | 
						#include "include\ModbusFunctions.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						msTimer gtRead;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get information of local network interface such like ip address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on preStart
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeClear(0);
 | 
				
			||||||
 | 
						setStartdelay(10);
 | 
				
			||||||
 | 
						OutputDebugLevel = Warning;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on start
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ModbusInit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Read serial code, additional stuff is done in OnModbusReceiveRegisters
 | 
				
			||||||
 | 
						// This has to be done by MakeConfig to properly size the arrays
 | 
				
			||||||
 | 
						//ModbusReadRegisters(0x2011, 1);
 | 
				
			||||||
 | 
						//ModbusReadRegisters(0x2012, 1);
 | 
				
			||||||
 | 
						//ModbusReadRegisters(0x2030, 65);
 | 
				
			||||||
 | 
						//ModbusReadRegisters(0x2031, 64);
 | 
				
			||||||
 | 
						//ModbusReadRegisters(0x2032, 64);
 | 
				
			||||||
 | 
						//ModbusReadRegisters(0x2033, 63);
 | 
				
			||||||
 | 
						if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits > 0)
 | 
				
			||||||
 | 
							ModbusReadBits(0x200, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits);
 | 
				
			||||||
 | 
						if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters > 0)
 | 
				
			||||||
 | 
							ModbusReadRegisters(0x200, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setTimerCyclic(gtRead, 1, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Modbus events ----------------------------------------------------------------------
 | 
				
			||||||
 | 
					void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (error)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case Exception:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case Timeout:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case FinalTimeout:
 | 
				
			||||||
 | 
								sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
 | 
				
			||||||
 | 
								for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits; i++)
 | 
				
			||||||
 | 
									@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputBits[i] = -1;
 | 
				
			||||||
 | 
								sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						byte i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (error)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case Exception:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case Timeout:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case FinalTimeout:
 | 
				
			||||||
 | 
								sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
 | 
				
			||||||
 | 
								for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters; i++)
 | 
				
			||||||
 | 
									@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i] = -1;
 | 
				
			||||||
 | 
								sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnModbusWriteBitFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusWriteRegisterFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusWriteMasksFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusReadWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusWriteBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch(mbreq.Address)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case 0x200:		// set output bits
 | 
				
			||||||
 | 
								sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
 | 
				
			||||||
 | 
								for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits; i++)
 | 
				
			||||||
 | 
									@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i] = bitStatus[i];
 | 
				
			||||||
 | 
								sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:		// set input bits
 | 
				
			||||||
 | 
								sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
 | 
				
			||||||
 | 
								for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits; i++)
 | 
				
			||||||
 | 
									@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputBits[i] = bitStatus[i];
 | 
				
			||||||
 | 
								sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct ModbusReqRead mbreq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char str[20*5];
 | 
				
			||||||
 | 
						long fehler;
 | 
				
			||||||
 | 
						byte i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (mbreq.Address)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case 0x200:		// set output registers
 | 
				
			||||||
 | 
								sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters");
 | 
				
			||||||
 | 
								for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters; i++)
 | 
				
			||||||
 | 
									@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i] = mbres.Data[i];
 | 
				
			||||||
 | 
								sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x000:		// set output registers
 | 
				
			||||||
 | 
								sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
 | 
				
			||||||
 | 
								for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters; i++)
 | 
				
			||||||
 | 
									@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i] = mbres.Data[i];
 | 
				
			||||||
 | 
								sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								// Not recognized
 | 
				
			||||||
 | 
								dbin_to_strhex(mbres.Data, str);
 | 
				
			||||||
 | 
								writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveRegisters: Received %d bytes at 0x%04X: %s", mbres.ByteCount, mbreq.Address, str);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnModbusWriteBitSuccess(struct ModbusResConfirmSingle mbc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusWriteRegisterSuccess(struct ModbusResConfirmSingle mbc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusWriteBitsSuccess(struct ModbusResConfirmMultiple mbc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusWriteRegistersSuccess(struct ModbusResConfirmMultiple mbc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnModbusClientPanics(enum FatalErrors reason)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeLineEx(0, 4, "<%NODE_NAME%> FATAL! %d", reason);
 | 
				
			||||||
 | 
						switch(reason)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case ParsingBuffer:
 | 
				
			||||||
 | 
							case ModbusPackageWasSplit:
 | 
				
			||||||
 | 
							case DeviceCodeUnknown:
 | 
				
			||||||
 | 
							case VendorIdUnknown:
 | 
				
			||||||
 | 
								runError(1001, reason);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ConnectionError:
 | 
				
			||||||
 | 
								gtRead.Cancel();
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Key events -------------------------------------------------------------------------
 | 
				
			||||||
 | 
					on timer gtRead
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters > 0)
 | 
				
			||||||
 | 
							ModbusReadRegisters(0x0000, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters);
 | 
				
			||||||
 | 
						if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits > 0)
 | 
				
			||||||
 | 
							ModbusReadBits(@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters * 2, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						word firstBitAddr, count, i;
 | 
				
			||||||
 | 
						byte bitStatus[1968];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						firstBitAddr = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters * 2;
 | 
				
			||||||
 | 
						count = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < count; i++)
 | 
				
			||||||
 | 
							bitStatus[i] = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ModbusWriteBitsB(firstBitAddr, count, bitStatus);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						word count, i;
 | 
				
			||||||
 | 
						word regValues[123];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						count = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < count; i++)
 | 
				
			||||||
 | 
							regValues[i] = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ModbusWriteRegisters(0x000, count, regValues);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (@this <= 0)
 | 
				
			||||||
 | 
							gtRead.Cancel();
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							setTimerCyclic(gtRead, @this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on key '+'
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
 | 
				
			||||||
 | 
						for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits; i++)
 | 
				
			||||||
 | 
							@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i] = 1;
 | 
				
			||||||
 | 
						sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					on key '-'
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
 | 
				
			||||||
 | 
						for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits; i++)
 | 
				
			||||||
 | 
							@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i] = 0;
 | 
				
			||||||
 | 
						sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								Modbus-DLL/include/CAPL/ModbusClient.cbf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Modbus-DLL/include/CAPL/ModbusClient.cbf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Modbus-DLL/include/CAPL/ModbusClientUDP.cbf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Modbus-DLL/include/CAPL/ModbusClientUDP.cbf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										263
									
								
								Modbus-DLL/include/CAPL/include/Common.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								Modbus-DLL/include/CAPL/include/Common.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,263 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum DebugLvl { 
 | 
				
			||||||
 | 
							Debug		= 0x00,
 | 
				
			||||||
 | 
							AlgoDebug	= 0x02,
 | 
				
			||||||
 | 
							ConnDebug	= 0x04,
 | 
				
			||||||
 | 
							MbDebug		= 0x07,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Info		= 0x10,
 | 
				
			||||||
 | 
							AlgoInfo	= 0x12,
 | 
				
			||||||
 | 
							ConnInfo	= 0x14,
 | 
				
			||||||
 | 
							MbInfo		= 0x17,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Warning		= 0x20,
 | 
				
			||||||
 | 
							AlgoWarning	= 0x22,
 | 
				
			||||||
 | 
							ConnWarning	= 0x24,
 | 
				
			||||||
 | 
							MbWarning	= 0x27,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Error		= 0x30,
 | 
				
			||||||
 | 
							AlgoError	= 0x32,
 | 
				
			||||||
 | 
							ConnError	= 0x34,
 | 
				
			||||||
 | 
							MbError		= 0x37
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
						char DebugLvlStr[4][8] = {"Debug", "Info", "Warning", "Error"};
 | 
				
			||||||
 | 
						enum DebugLvl OutputDebugLevel = Debug;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbgFormat(byte lVl, char msg[], char format[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						strncpy(msg, "<%NODE_NAME%> ", elCount(msg));
 | 
				
			||||||
 | 
						strncat(msg, DebugLvlStr[lVl], elCount(msg));
 | 
				
			||||||
 | 
						strncat(msg, ": ", elCount(msg));
 | 
				
			||||||
 | 
						strncat(msg, format, elCount(msg)-strlen(msg));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, string);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], char string1[], char string2[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, string1, string2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], long num, char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, num, string);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], char string[], long num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, string, num);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], long num1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, num1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, num1, num2, string);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, num1, num2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, long num3)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, num1, num2, num3);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, long num3, long num4)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, num1, num2, num3, num4);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// <writeDbg>
 | 
				
			||||||
 | 
					void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, long num3, long num4, long num5, long num6)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char msg[500];
 | 
				
			||||||
 | 
						byte lVl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lvl < OutputDebugLevel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						lVl = (byte)lvl >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbgFormat(lVl, msg, format);
 | 
				
			||||||
 | 
						writeLineEx(1, lVl, msg, num1, num2, num3, num4, num5, num6);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bin_to_strhex(byte bin[], char result[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char hex_str[17] = "0123456789ABCDEF";
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
						word binsz;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						binsz = elCount(bin);
 | 
				
			||||||
 | 
						if (binsz > 20)
 | 
				
			||||||
 | 
							binsz = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < binsz; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							result[i * 3 + 0] = hex_str[bin[i] >> 4  ];
 | 
				
			||||||
 | 
							result[i * 3 + 1] = hex_str[bin[i] & 0x0F];
 | 
				
			||||||
 | 
							result[i * 3 + 2] = ' ';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (elCount(bin) > 20)	// trailing "..."
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							result[56] = '.';
 | 
				
			||||||
 | 
							result[57] = '.';
 | 
				
			||||||
 | 
							result[58] = '.';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result[binsz * 3 - 1] = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hbin_to_strhex(byte bin[], char result[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char hex_str[17] = "0123456789ABCDEF";
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
						word binsz;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						binsz = elCount(bin);
 | 
				
			||||||
 | 
						if (binsz > 20)
 | 
				
			||||||
 | 
							binsz = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < binsz; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							result[i * 2 + 0] = hex_str[bin[i] & 0x0F];
 | 
				
			||||||
 | 
							result[i * 2 + 1] = ' ';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (elCount(bin) > 20)	// trailing "..."
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							result[36] = '.';
 | 
				
			||||||
 | 
							result[37] = '.';
 | 
				
			||||||
 | 
							result[38] = '.';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result[binsz * 2 - 1] = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dbin_to_strhex(word bin[], char result[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char hex_str[17] = "0123456789ABCDEF";
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
						word binsz;
 | 
				
			||||||
 | 
						byte offset;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						binsz = elCount(bin);
 | 
				
			||||||
 | 
						if (binsz > 20)
 | 
				
			||||||
 | 
							binsz = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < binsz; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							result[i * 5 + 0] = hex_str[(bin[i] >> 12) & 0x0F];
 | 
				
			||||||
 | 
							result[i * 5 + 1] = hex_str[(bin[i] >>  8) & 0x0F];
 | 
				
			||||||
 | 
							result[i * 5 + 2] = hex_str[(bin[i] >>  4) & 0x0F];
 | 
				
			||||||
 | 
							result[i * 5 + 3] = hex_str[(bin[i]      ) & 0x0F];
 | 
				
			||||||
 | 
							result[i * 5 + 4] = ' ';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (elCount(bin) > 20)	// trailing "..."
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							result[96] = '.';
 | 
				
			||||||
 | 
							result[97] = '.';
 | 
				
			||||||
 | 
							result[98] = '.';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result[(byte)(binsz * 2.5) - 1] = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										167
									
								
								Modbus-DLL/include/CAPL/include/EilCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								Modbus-DLL/include/CAPL/include/EilCommon.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,167 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "Common.cin"
 | 
				
			||||||
 | 
						#include "TcpUdpCommon.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long gPacket;
 | 
				
			||||||
 | 
						msTimer gtArp;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						byte gLocalMac[6];
 | 
				
			||||||
 | 
						byte gRemoteMac[6];
 | 
				
			||||||
 | 
						dword gLocalIP = 0xC0A80101;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word EilConnectTo(char Remote_IP[], word remotePort)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dword remoteIp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Convert IP string to Number
 | 
				
			||||||
 | 
						remoteIp = IpGetAddressAsNumber(Remote_IP);
 | 
				
			||||||
 | 
						if (remoteIp == INVALID_IP)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "EilConnectTo: invalid server Ip address!");
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return ipGetLastError();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return EilConnectTo(remoteIp, remotePort);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word EilConnectTo(dword remoteIp, word remotePort)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long error;
 | 
				
			||||||
 | 
						byte broadcastMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (EthGetMacId(gLocalMac) != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gSocketState = ERROR;
 | 
				
			||||||
 | 
							error = EthGetLastError();
 | 
				
			||||||
 | 
							writeDbg(ConnError, "EthGetMacId: Could not get local MAC! %d", error);
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TCP/IP API gives IP in little endian but EIL uses big endian
 | 
				
			||||||
 | 
						gRemotePort = remotePort;
 | 
				
			||||||
 | 
						gRemoteIP = (remoteIp >> 24) | (remoteIp >> 8) & 0x0000FF00 | (remoteIp << 8) & 0x00FF0000 | (remoteIp << 24);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gPacket != 0)
 | 
				
			||||||
 | 
							ModbusDisconnect();
 | 
				
			||||||
 | 
						// Try to create an ARP packet that gets the MAC from remote server
 | 
				
			||||||
 | 
						gPacket = EthInitPacket("arp");
 | 
				
			||||||
 | 
						if (gPacket == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gSocketState = ERROR;
 | 
				
			||||||
 | 
							error = EthGetLastError();
 | 
				
			||||||
 | 
							writeDbg(ConnError, "EthInitPacket: Could not create ARP package! %d", error);
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EthSetTokenData(gPacket,	"eth",	"source"				, elCount(gLocalMac), gLocalMac);
 | 
				
			||||||
 | 
						EthSetTokenData(gPacket,	"eth",	"destination"			, elCount(broadcastMac), broadcastMac);
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"arp",	"hwType"				, 1);			// Ethernet
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"arp",	"protType"				, 0x0800);		// IPv4
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"arp",	"hwSize"				, 6);			// Ethernet addr size
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"arp",	"protSize"				, 4);			// IP addr size
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"arp",	"operation"				, 1);
 | 
				
			||||||
 | 
						EthSetTokenData(gPacket,	"arp",	"hwSourceAddr"			, elCount(gLocalMac), gLocalMac);
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"arp",	"protSourceAddr"		, gLocalIP);
 | 
				
			||||||
 | 
						//EthSetTokenData(gPacket,	"arp",	"hwDestinationAddr"		, elCount(gLocalMac), gLocalMac);
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"arp",	"protDestinationAddr"	, gRemoteIP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EthReceivePacket("OnEthReceivePacket");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EthCompletePacket(gPacket);
 | 
				
			||||||
 | 
						EthOutputPacket(gPacket);
 | 
				
			||||||
 | 
						EthReleasePacket(gPacket);
 | 
				
			||||||
 | 
						gSocketState = NULL;
 | 
				
			||||||
 | 
						gtArp.set(@sysvar::Config::Modbus::RequestTimeout);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EilConnectTo2()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gPacket = EthInitPacket("udp");
 | 
				
			||||||
 | 
						if (gPacket == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gSocketState = ERROR;
 | 
				
			||||||
 | 
							writeDbg(ConnError, "EthInitPacket: Could not create UDP packet: %d", EthGetLastError());
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EthSetTokenData(gPacket,	"eth",	"source"				, elCount(gLocalMac), gLocalMac);
 | 
				
			||||||
 | 
						EthSetTokenData(gPacket,	"eth",	"destination"			, elCount(gRemoteMac), gRemoteMac);
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"ipv4",	"source"				, gLocalIP);
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"ipv4",	"destination"			, gRemoteIP);
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"udp",	"source"				, 23456);
 | 
				
			||||||
 | 
						EthSetTokenInt(gPacket,		"udp",	"destination"			, 502);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gSocketState = OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EilDisconnect()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (gPacket != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							EthReleasePacket(gPacket);
 | 
				
			||||||
 | 
							gPacket = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						gSocketState = CLOSED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EilRecv()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					byte EilSnd(byte buffer[], word length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char str[20*3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (gSocketState)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case CLOSED:
 | 
				
			||||||
 | 
								EilConnectTo(gRemoteIP, gRemotePort);
 | 
				
			||||||
 | 
								if (gSocketState != OK)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									writeDbg(ConnWarning, "EilSnd: Reconnecting failed! Doing nothing.");
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case OK:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								writeDbg(ConnWarning, "EilSnd: Socket status is not OK! Doing nothing.");
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bin_to_strhex(buffer, str);
 | 
				
			||||||
 | 
						writeDbg(ConnDebug, "EilSnd: %s (Länge: %d)", str, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EthResizeToken(gPacket,		"udp",	"data"	, length*8);
 | 
				
			||||||
 | 
						EthSetTokenData(gPacket,	"udp",	"data"	, length, buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EthCompletePacket(gPacket);
 | 
				
			||||||
 | 
						EthOutputPacket(gPacket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long EilGetLastConnectionError(char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						EthGetLastErrorText(elCount(string), string);
 | 
				
			||||||
 | 
						return EthGetLastError();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on timer gtArp
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gSocketState = ERROR;
 | 
				
			||||||
 | 
						writeDbg(ConnError, "No (valid) ARP response detected. The host seems to be offline!");
 | 
				
			||||||
 | 
						OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										786
									
								
								Modbus-DLL/include/CAPL/include/ModbusClientCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										786
									
								
								Modbus-DLL/include/CAPL/include/ModbusClientCommon.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,786 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					// Additionally include ModbusTcpCommon.cin or ModbusUdpCommon.cin
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "ModbusStructs.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const word gMaxPacketLength = __size_of(struct ModbusReqWriteRegisters);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						msTimer gtRobin;				// Timer that sends the packets and watches for timeouts
 | 
				
			||||||
 | 
						word gTxID = 0x0000;			// Transaction Identifier for Modbus. Used as index for gQueue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Global storage for pending and sent requests, associated by TxID
 | 
				
			||||||
 | 
						struct QueueElement
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							word TimeoutTicks;
 | 
				
			||||||
 | 
							byte Timeouts;
 | 
				
			||||||
 | 
							word Length;
 | 
				
			||||||
 | 
							byte Buffer[gMaxPacketLength];
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						struct QueueElement gQueuePending[long, 2];
 | 
				
			||||||
 | 
						struct QueueElement gQueueSent[long, 2];
 | 
				
			||||||
 | 
						struct QueueElement gQueueAck[long, 2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char ModbusExceptions[11][72] = {
 | 
				
			||||||
 | 
							"Illegal func code (0x01). The function code is unknown by the server",
 | 
				
			||||||
 | 
							"Illegal data address (0x02). Please check your configuration",
 | 
				
			||||||
 | 
							"Illegal data value (0x03)",
 | 
				
			||||||
 | 
							"Server failure (0x04). The server failed during execution",
 | 
				
			||||||
 | 
							"Acknowledge (0x05). The server needs more time to generate the response",
 | 
				
			||||||
 | 
							"Server busy (0x06). The request could not be accepted",
 | 
				
			||||||
 | 
							"",
 | 
				
			||||||
 | 
							"",
 | 
				
			||||||
 | 
							"",
 | 
				
			||||||
 | 
							"Gateway problem (0x0A). Gateway paths not available",
 | 
				
			||||||
 | 
							"Gateway problem (0x0B). The targeted device failed to respond"
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusInit()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char ip[16];
 | 
				
			||||||
 | 
						sysGetVariableString("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config", "IP", ip, elCount(ip));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbInfo, "Connecting to %s:%d", ip, @sysvar::Config::Modbus::Port);
 | 
				
			||||||
 | 
						ModbusConnectTo(ip, @sysvar::Config::Modbus::Port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusMakeHeader(struct ModbusApHeader mbap, word length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						mbap.TxID = gTxID++;		// [2] Transaction ID
 | 
				
			||||||
 | 
						mbap.Protocol = 0x0000;		// [2] Protocol ID = 0 = Modbus
 | 
				
			||||||
 | 
						mbap.Length = length - __offset_of(struct ModbusApHeader, UnitID);	// [2] Length; Number of bytes following
 | 
				
			||||||
 | 
						mbap.UnitID = 0xFF;			// [1] Unit identifier; not relevant
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// REGION: ModbusReadBits -------------------------------------------------------------
 | 
				
			||||||
 | 
					/// <ModbusReadBits>
 | 
				
			||||||
 | 
					void ModbusReadBits(word address, word count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const byte length = __size_of(struct ModbusReqRead);
 | 
				
			||||||
 | 
						const byte funcCode = 0x01;
 | 
				
			||||||
 | 
						byte buffer[length];
 | 
				
			||||||
 | 
						struct ModbusReqRead mbr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ModbusMakeHeader(mbr.Header, length);
 | 
				
			||||||
 | 
						// Payload
 | 
				
			||||||
 | 
						mbr.Header.FuncCode = funcCode;	// [1] Function Code; 1: Read Coils (DI), 2: Read Discret Inputs (DIO), seems to be the same for WAGO 750-881
 | 
				
			||||||
 | 
						mbr.Address = address;			// [2] Start address
 | 
				
			||||||
 | 
						mbr.Count = count;				// [2] Number of items; 1:max 2000=0x7D0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Sending 'Read Bits' (0x01) command. Addr: 0x%04X, Count: %d", address, count);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						memcpy_h2n(buffer, mbr);
 | 
				
			||||||
 | 
						ModbusSend(buffer, length, mbr.Header.TxID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusReadBits>
 | 
				
			||||||
 | 
					void OnModbusReceiveBits(byte buffer[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusResReceiveBits mbres;
 | 
				
			||||||
 | 
						struct ModbusReqRead mbreq;
 | 
				
			||||||
 | 
						byte bitStatus[1968];
 | 
				
			||||||
 | 
						word numBits;
 | 
				
			||||||
 | 
						byte i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_n2h(mbres, buffer);
 | 
				
			||||||
 | 
						memcpy_n2h(mbreq, gQueueAck[mbres.Header.TxID].Buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Received %d bits from 0x%04X", mbreq.Count, mbreq.Address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < mbres.ByteCount; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (j = 0; j < 8; j++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								bitStatus[8*i+j] = (mbres.Data[i] >> j) & 0x01;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OnModbusReadBitsSuccess(mbres, bitStatus, mbreq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusReadBits>
 | 
				
			||||||
 | 
					void OnModbusReceiveBitsException(struct ModbusApHeader mbap, enum ModbusException ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(MbError, "Received an Exception while reading bits: %s", ModbusExceptions[ex-1]);
 | 
				
			||||||
 | 
						OnModbusReadBitsFailed(Exception, ex, mbap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// REGION: ModbusReadRegisters -------------------------------------------------------
 | 
				
			||||||
 | 
					/// <ModbusReadRegisters>
 | 
				
			||||||
 | 
					void ModbusReadRegisters(word address, word count)	// 16 bit
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const byte length = __size_of(struct ModbusReqRead);
 | 
				
			||||||
 | 
						const byte funcCode = 0x03;
 | 
				
			||||||
 | 
						byte buffer[length];
 | 
				
			||||||
 | 
						struct ModbusReqRead mbr;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						ModbusMakeHeader(mbr.Header, length);
 | 
				
			||||||
 | 
						// Payload
 | 
				
			||||||
 | 
						mbr.Header.FuncCode = funcCode;	// [1] Function Code; 3: Read Holding Registers (AI), 4: Read Input Registers (AIO), seems to be the same for WAGO 750-881
 | 
				
			||||||
 | 
						mbr.Address = address;			// [2] Start address
 | 
				
			||||||
 | 
						mbr.Count = count;				// [2] Number of items; 1:max 125=0x7D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Sending 'Read Registers' (0x03) command. Addr: 0x%04X, Count: %d", address, count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_h2n(buffer, mbr);
 | 
				
			||||||
 | 
						ModbusSend(buffer, length, mbr.Header.TxID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusReadRegisters>
 | 
				
			||||||
 | 
					void OnModbusReceiveRegisters(byte buffer[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusResReceiveRegisters mbres;
 | 
				
			||||||
 | 
						struct ModbusReqRead mbreq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_n2h(mbres, buffer);
 | 
				
			||||||
 | 
						memcpy_n2h(mbreq, gQueueAck[mbres.Header.TxID].Buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Received %d registers from 0x%04X", mbreq.Count, mbreq.Address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OnModbusReadRegistersSuccess(mbres, mbreq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusReadRegisters>
 | 
				
			||||||
 | 
					void OnModbusReceiveRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(MbError, "Received an Exception while reading registers: %s", ModbusExceptions[ex-1]);
 | 
				
			||||||
 | 
						OnModbusReadRegistersFailed(Exception, ex, mbap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// REGION: ModbusWriteBit -------------------------------------------------------------
 | 
				
			||||||
 | 
					/// <ModbusWriteBit>
 | 
				
			||||||
 | 
					void ModbusWriteBit(word address, byte value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const byte length = __size_of(struct ModbusReqWriteSingle);
 | 
				
			||||||
 | 
						const byte funcCode = 0x05;
 | 
				
			||||||
 | 
						byte buffer[length];
 | 
				
			||||||
 | 
						struct ModbusReqWriteSingle mbw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value >= 1)
 | 
				
			||||||
 | 
							value = 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ModbusMakeHeader(mbw.Header, length);
 | 
				
			||||||
 | 
						// Payload
 | 
				
			||||||
 | 
						mbw.Header.FuncCode = funcCode;	// [1] Function Code; 5: Write Single Coil (DO)
 | 
				
			||||||
 | 
						mbw.Address = address;			// [2] Output address
 | 
				
			||||||
 | 
						mbw.Value = value << 8;			// [2] Output value (0x0000: Off, 0xFF00: On)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(Debug, "Sending 'Write Bit' (0x05) command. Addr: 0x%04X, Value: 0x%02X", address, value);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						memcpy_h2n(buffer, mbw);
 | 
				
			||||||
 | 
						ModbusSend(buffer, length, mbw.Header.TxID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteBit>
 | 
				
			||||||
 | 
					void OnModbusConfirmBit(byte buffer[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusResConfirmSingle mbc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_n2h(mbc, buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Set bit at 0x%04X to %d", mbc.Address, mbc.Value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OnModbusWriteBitSuccess(mbc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteBit>
 | 
				
			||||||
 | 
					void OnModbusConfirmBitException(struct ModbusApHeader mbap, enum ModbusException ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(MbError, "Received an Exception while writing bit: %s", ModbusExceptions[ex-1]);
 | 
				
			||||||
 | 
						OnModbusWriteBitFailed(Exception, ex, mbap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// REGION: ModbusWriteRegister ------------------------------------------------------
 | 
				
			||||||
 | 
					/// <ModbusWriteRegister>
 | 
				
			||||||
 | 
					void ModbusWriteRegister(word address, int value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const byte length = __size_of(struct ModbusReqWriteSingle);
 | 
				
			||||||
 | 
						const byte funcCode = 0x06;
 | 
				
			||||||
 | 
						byte buffer[length];
 | 
				
			||||||
 | 
						struct ModbusReqWriteSingle mbw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ModbusMakeHeader(mbw.Header, length);
 | 
				
			||||||
 | 
						// Payload
 | 
				
			||||||
 | 
						mbw.Header.FuncCode = funcCode;	// [1] Function Code; 5: Write Single Register (AO)
 | 
				
			||||||
 | 
						mbw.Address = address;			// [2] Output address
 | 
				
			||||||
 | 
						mbw.Value = value;				// [2] Output value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Sending 'Write Register' (0x06) command. Addr: 0x%04X, Value: 0x%02X", address, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_h2n(buffer, mbw);
 | 
				
			||||||
 | 
						ModbusSend(buffer, length, mbw.Header.TxID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteRegister>
 | 
				
			||||||
 | 
					void OnModbusConfirmRegister(byte buffer[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusResConfirmSingle mbc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_n2h(mbc, buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Set register at 0x%04X to %d", mbc.Address, mbc.Value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OnModbusWriteRegisterSuccess(mbc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteRegister>
 | 
				
			||||||
 | 
					void OnModbusConfirmRegisterException(struct ModbusApHeader mbap, enum ModbusException ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(MbError, "Received an Exception while writing register: %s", ModbusExceptions[ex-1]);
 | 
				
			||||||
 | 
						OnModbusWriteRegisterFailed(Exception, ex, mbap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// REGION: ModbusWriteBits ----------------------------------------------------------
 | 
				
			||||||
 | 
					/// <ModbusWriteBits>
 | 
				
			||||||
 | 
					void ModbusWriteBits(word address, word count, byte values[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const word maxLength = __size_of(struct ModbusReqWriteBits);
 | 
				
			||||||
 | 
						const byte funcCode = 0x0F;
 | 
				
			||||||
 | 
						byte buffer[maxLength];
 | 
				
			||||||
 | 
						struct ModbusReqWriteBits mbw;
 | 
				
			||||||
 | 
						byte dataLength;
 | 
				
			||||||
 | 
						byte overallLength;
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dataLength = _ceil(count / 8.0);
 | 
				
			||||||
 | 
						overallLength = maxLength - 1968/8 + dataLength;
 | 
				
			||||||
 | 
						ModbusMakeHeader(mbw.Header, overallLength);
 | 
				
			||||||
 | 
						// Payload
 | 
				
			||||||
 | 
						mbw.Header.FuncCode = funcCode;	// [1] Function Code; 15: Write Multiple Bits (DOs)
 | 
				
			||||||
 | 
						mbw.Address = address;			// [2] Output address
 | 
				
			||||||
 | 
						mbw.Count = count;				// [2] Number of items; 1:max 1968=0x7B0
 | 
				
			||||||
 | 
						mbw.ByteCount = dataLength;		// [1] Number of bytes; = ceil(count/8)
 | 
				
			||||||
 | 
						memcpy(mbw.Data, values, dataLength);	// this is 1 memcpy too much -.-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Sending 'Write Bits' (0x0F) command. Addr: 0x%04X, Count: %d", address, count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_h2n(buffer, mbw);
 | 
				
			||||||
 | 
						ModbusSend(buffer, overallLength, mbw.Header.TxID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteBits>
 | 
				
			||||||
 | 
					void ModbusWriteBitsB(word address, word count, byte values[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						byte buffer[2];	// length
 | 
				
			||||||
 | 
						word length;
 | 
				
			||||||
 | 
						dword ellCount;
 | 
				
			||||||
 | 
						dword i;
 | 
				
			||||||
 | 
						dword j;
 | 
				
			||||||
 | 
						char str1[20*2], str2[20*3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = (word)_ceil(count / 8.0);
 | 
				
			||||||
 | 
						writeDbg(AlgoDebug, "ModbusWriteBitsB: count: %d; length: %d", count, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (count % 8 != 0)
 | 
				
			||||||
 | 
							length--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < length; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							buffer[i] = 0;
 | 
				
			||||||
 | 
							for (j = 0; j < 8; j++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								buffer[i] |= (values[i*8 + j] & 0x01) << j;
 | 
				
			||||||
 | 
								writeDbg(AlgoDebug, "ModbusWriteBitsB: j: %d; indx: %d; value: %d; mask: %X", j, i*8 + j, values[i*8 + j], (0x01 << j));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							writeDbg(AlgoDebug, "ModbusWriteBitsB: %d: %X", i, buffer[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for (j = 0; j < count % 8; j++)	// wont be executed if there is no remainder
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(AlgoDebug, "ModbusWriteBitsB: j: %d; indx: %d; value: %d; mask: %X", j, (length-1)*8 + j, values[(length-1)*8 + j], (0x01 << j));
 | 
				
			||||||
 | 
							buffer[length] |= (values[(length)*8 + j] & 0x01) << j;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						writeDbg(AlgoDebug, "ModbusWriteBitsB: %d: %X", length-1, buffer[length-1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hbin_to_strhex(values, str1);
 | 
				
			||||||
 | 
						bin_to_strhex(buffer, str2);
 | 
				
			||||||
 | 
						writeDbg(AlgoDebug, "ModbusWriteBitsB: Encoded %s to %s", str1, str2);
 | 
				
			||||||
 | 
						ModbusWriteBits(address, count, buffer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteBits>
 | 
				
			||||||
 | 
					void OnModbusConfirmBits(byte buffer[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusResConfirmMultiple mbc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_n2h(mbc, buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Updated &d bits at 0x%04X", mbc.Count, mbc.Address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OnModbusWriteBitsSuccess(mbc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteBits>
 | 
				
			||||||
 | 
					void OnModbusConfirmBitsException(struct ModbusApHeader mbap, enum ModbusException ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(MbError, "Received an Exception while writing bits: %s", ModbusExceptions[ex-1]);
 | 
				
			||||||
 | 
						OnModbusWriteBitsFailed(Exception, ex, mbap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// REGION: ModbusWriteRegisters -------------------------------------------------------
 | 
				
			||||||
 | 
					/// <ModbusWriteRegisters>
 | 
				
			||||||
 | 
					void ModbusWriteRegisters(word address, word count, word values[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const word maxLength = __size_of(struct ModbusReqWriteRegisters);
 | 
				
			||||||
 | 
						const byte funcCode = 0x10;
 | 
				
			||||||
 | 
						byte buffer[maxLength];
 | 
				
			||||||
 | 
						struct ModbusReqWriteRegisters mbw;
 | 
				
			||||||
 | 
						byte dataLength;
 | 
				
			||||||
 | 
						word overallLength;
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dataLength = 2 * count;
 | 
				
			||||||
 | 
						overallLength = maxLength - 2*123 + dataLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ModbusMakeHeader(mbw.Header, overallLength);
 | 
				
			||||||
 | 
						// Payload
 | 
				
			||||||
 | 
						mbw.Header.FuncCode = funcCode;	// [1] Function Code; 16: Write Multiple Registers (AOs)
 | 
				
			||||||
 | 
						mbw.Address = address;			// [2] Output address
 | 
				
			||||||
 | 
						mbw.Count = count;				// [2] Number of items; 1:max 123=0x7B
 | 
				
			||||||
 | 
						mbw.ByteCount = dataLength;		// [1] Number of bytes; = 2 * count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < dataLength; i++)
 | 
				
			||||||
 | 
							mbw.Data[i] = values[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_h2n(buffer, mbw);
 | 
				
			||||||
 | 
						ModbusSend(buffer, overallLength, mbw.Header.TxID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteRegisters>
 | 
				
			||||||
 | 
					void OnModbusConfirmRegisters(byte buffer[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusResConfirmMultiple mbc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_n2h(mbc, buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Updated &d registers at 0x%04X", mbc.Count, mbc.Address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OnModbusWriteRegistersSuccess(mbc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteRegisters>
 | 
				
			||||||
 | 
					void OnModbusConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(MbError, "Received an Exception while writing registers: %s", ModbusExceptions[ex-1]);
 | 
				
			||||||
 | 
						OnModbusWriteRegistersFailed(Exception, ex, mbap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// REGION: ModbusWriteMasks ------------------------------------------------------------
 | 
				
			||||||
 | 
					/// <ModbusWriteMasks>
 | 
				
			||||||
 | 
					void ModbusWriteMasks(word address, word and, word or)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const word length = __size_of(struct ModbusReqWriteMasks);
 | 
				
			||||||
 | 
						const byte funcCode = 0x16;
 | 
				
			||||||
 | 
						byte buffer[length];
 | 
				
			||||||
 | 
						struct ModbusReqWriteMasks mbw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ModbusMakeHeader(mbw.Header, length);
 | 
				
			||||||
 | 
						// Payload
 | 
				
			||||||
 | 
						mbw.Header.FuncCode = funcCode;	// [1] Function Code; 22: Mask Write Registers (AO)
 | 
				
			||||||
 | 
						mbw.Address = address;			// [2] Output address
 | 
				
			||||||
 | 
						mbw.And = and;					// [2] AND mask
 | 
				
			||||||
 | 
						mbw.Or = or;					// [2] OR mask
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_h2n(buffer, mbw);
 | 
				
			||||||
 | 
						ModbusSend(buffer, length, mbw.Header.TxID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteMasks>
 | 
				
			||||||
 | 
					void OnModbusConfirmMasks(byte buffer[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusResConfirmMasks mbc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_n2h(mbc, buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Applied masks at 0x%04X", mbc.Address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OnModbusWriteMasksSuccess(mbc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusWriteMasks>
 | 
				
			||||||
 | 
					void OnModbusConfirmMasksException(struct ModbusApHeader mbap, enum ModbusException ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(MbError, "Received an Exception while applying masks: %s", ModbusExceptions[ex-1]);
 | 
				
			||||||
 | 
						OnModbusWriteMasksFailed(Exception, ex, mbap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// REGION: ModbusReadWriteRegisters -------------------------------------------------------
 | 
				
			||||||
 | 
					/// <ModbusReadWriteRegisters>
 | 
				
			||||||
 | 
					void ModbusReadWriteRegisters(word readAddress, word readCount, word writeAddress, word writeCount, int values[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const word maxLength = __size_of(struct ModbusReqReadWriteRegisters);
 | 
				
			||||||
 | 
						const byte funcCode = 0x17;
 | 
				
			||||||
 | 
						byte buffer[maxLength];
 | 
				
			||||||
 | 
						struct ModbusReqReadWriteRegisters mbw;
 | 
				
			||||||
 | 
						byte dataLength;
 | 
				
			||||||
 | 
						word overallLength;
 | 
				
			||||||
 | 
						word i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dataLength = 2 * writeCount;
 | 
				
			||||||
 | 
						overallLength = maxLength - 2*121 + dataLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ModbusMakeHeader(mbw.Header, overallLength);
 | 
				
			||||||
 | 
						// Payload
 | 
				
			||||||
 | 
						mbw.Header.FuncCode = funcCode;	// [1] Function Code; 16: Write Multiple Registers (AOs)
 | 
				
			||||||
 | 
						mbw.ReadAddress = readAddress;	// [2] Input address
 | 
				
			||||||
 | 
						mbw.ReadCount = readCount;		// [2] Number of items; 1:max 125=0x7D
 | 
				
			||||||
 | 
						mbw.WriteAddress = writeAddress;// [2] Output address
 | 
				
			||||||
 | 
						mbw.WriteCount = writeCount;	// [2] Number of items; 1:max 121=0x79
 | 
				
			||||||
 | 
						mbw.ByteCount = dataLength;		// [1] Number of bytes; = 2 * count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < dataLength; i++)
 | 
				
			||||||
 | 
							mbw.Data[i] = values[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_h2n(buffer, mbw);
 | 
				
			||||||
 | 
						ModbusSend(buffer, overallLength, mbw.Header.TxID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusReadWriteRegisters>
 | 
				
			||||||
 | 
					void OnModbusReceiveConfirmRegisters(byte buffer[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusResReceiveRegisters mbres;
 | 
				
			||||||
 | 
						struct ModbusReqRead mbreq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy_n2h(mbres, buffer);
 | 
				
			||||||
 | 
						memcpy_n2h(mbreq, gQueueAck[mbres.Header.TxID].Buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(MbDebug, "Wrote some registers and received %d registers from 0x%04X", mbreq.Count, mbreq.Address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OnModbusReadRegistersSuccess(mbres, mbreq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <ModbusReadWriteRegisters>
 | 
				
			||||||
 | 
					void OnModbusReceiveConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(MbError, "Received an Exception while reading and writing registers: %s", ModbusExceptions[ex-1]);
 | 
				
			||||||
 | 
						OnModbusWriteRegistersFailed(Exception, ex, mbap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// REGION: OnModbusReceive ------------------------------------------------------------
 | 
				
			||||||
 | 
					/// <-OnModbusReceive>
 | 
				
			||||||
 | 
					void OnModbusReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(ConnDebug, "OnModbusReceive: Received %d bytes", size);
 | 
				
			||||||
 | 
						if (result == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (size == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// Size of zero indicates that the socket was closed by the communication peer.
 | 
				
			||||||
 | 
								writeDbg(ConnWarning, "OnModbusReceive: Socket closed by peer");
 | 
				
			||||||
 | 
								ModbusDisconnect();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// Sucessfully received some bytes over the TCP/IP connection.
 | 
				
			||||||
 | 
								OnModbusReceive2(buffer, size);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gIpLastErr = ModbusGetLastConnectionError(gIpLastErrStr);
 | 
				
			||||||
 | 
							writeDbg(ConnError, "OnModbusReceive error (%d): %s", gIpLastErr, gIpLastErrStr);
 | 
				
			||||||
 | 
							ModbusDisconnect();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <-OnModbusReceive>
 | 
				
			||||||
 | 
					void OnModbusReceive2(byte buffer[], dword size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusApHeader mbap;
 | 
				
			||||||
 | 
						int offset;
 | 
				
			||||||
 | 
						char str[3*20];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (size < 8)						// No complete Modbus Application Header
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						offset = 0;
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnDebug, "OnModbusReceive2: Offset pre = %d", offset);
 | 
				
			||||||
 | 
							memcpy_n2h(mbap, buffer, offset);
 | 
				
			||||||
 | 
							OnModbusReceive2OnePacket(buffer, offset, mbap);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							offset += __offset_of(struct ModbusApHeader, UnitID) + mbap.Length;
 | 
				
			||||||
 | 
							writeDbg(ConnDebug, "OnModbusReceive2: offset post = %d. %d <= %d?", offset, offset, size-8);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						while(offset <= size-8);			// We need at least 8 bytes for a new packet
 | 
				
			||||||
 | 
						writeDbg(ConnDebug, "OnModbusReceive2: yes. finished");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (offset != size)	// Can be removed.
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							bin_to_strhex(buffer, str);
 | 
				
			||||||
 | 
							writeDbg(ConnError, "OnModbusReceive2: Error while going through receive buffer. Our final offset is %d, but the size of the buffer is %d! Buffer: %s", offset, size, str);
 | 
				
			||||||
 | 
							OnModbusClientPanics(ParsingBuffer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <-OnModbusReceive>
 | 
				
			||||||
 | 
					void OnModbusReceive2OnePacket(byte buffer[], int offset, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Test transaction identifier?
 | 
				
			||||||
 | 
						// Test unit/device identifier?
 | 
				
			||||||
 | 
						word i;					// counter
 | 
				
			||||||
 | 
						word length;			// length of current packet
 | 
				
			||||||
 | 
						byte mbuffer[__size_of(struct ModbusResReceiveRegisters)];		// second buffer where we copy the message. This way the user won't overwrite other packages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = __offset_of(struct ModbusApHeader, UnitID) + mbap.Length;
 | 
				
			||||||
 | 
						// We cannot check this properly anymore. We have to trust the TCP/UDP stack and the sender... *sigh*
 | 
				
			||||||
 | 
						if (mbap.Protocol != 0)						// Protocol is not Modbus (0x0000). Wayne.
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnDebug, "OnModbusReceive2OnePacket: packet is no Modbus packet: Protocol = %d", mbap.Protocol);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (elCount(buffer) < offset + length)		// packet larger than the (rest of the) buffer
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "OnModbusReceive2OnePacket: packet did not fit into Buffer: buffer length = %d, packet length = %d, offset = %d", elCount(buffer), __offset_of(struct ModbusApHeader, UnitID) + mbap.Length, offset);
 | 
				
			||||||
 | 
							// I REALLY don't want to assemble the two package fragments.
 | 
				
			||||||
 | 
							OnModbusClientPanics(ModbusPackageWasSplit);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// MBAP Header is OK :) Go on
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (!gQueueSent.ContainsKey(mbap.TxID))		// We don't wait for this message!
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//write("Received TxID: %d", mbap.TxID);
 | 
				
			||||||
 | 
						memcpy(gQueueAck[mbap.TxID], gQueueSent[mbap.TxID]);
 | 
				
			||||||
 | 
						gQueueSent.Remove(mbap.TxID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mbap.FuncCode > 0x80)					// Oh no, we got a exception!
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							OnModbusReceive2Exceptions(buffer[offset+08], mbap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							gQueueAck.Remove(mbap.TxID);			// Remove from acknowledge queue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Copy the message
 | 
				
			||||||
 | 
						memcpy_off(mbuffer, 0, buffer, offset, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Let's give the PDU to the corresponding function
 | 
				
			||||||
 | 
						switch (mbap.FuncCode)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case 0x01:
 | 
				
			||||||
 | 
							case 0x02:
 | 
				
			||||||
 | 
								OnModbusReceiveBits(mbuffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x03:
 | 
				
			||||||
 | 
							case 0x04:
 | 
				
			||||||
 | 
								OnModbusReceiveRegisters(mbuffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x05:
 | 
				
			||||||
 | 
								OnModbusConfirmBit(mbuffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x06:
 | 
				
			||||||
 | 
								OnModbusConfirmRegister(mbuffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x0F:
 | 
				
			||||||
 | 
								OnModbusConfirmBits(mbuffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x10:
 | 
				
			||||||
 | 
								OnModbusConfirmRegisters(mbuffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x16:
 | 
				
			||||||
 | 
								OnModbusConfirmMasks(mbuffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x17:
 | 
				
			||||||
 | 
								OnModbusReceiveConfirmRegisters(mbuffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								writeDbg(MbError, "OnModbusReceive2OnePacket: We received funcCode 0x%X!?", mbap.FuncCode);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gQueueAck.Remove(mbap.TxID);		// Remove from acknowledge queue
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <-OnModbusReceive>
 | 
				
			||||||
 | 
					void OnModbusReceive2Exceptions(byte exCode, struct ModbusApHeader mbap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum ModbusException ex;
 | 
				
			||||||
 | 
						ex = (enum ModbusException)exCode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (mbap.FuncCode)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case 0x81:
 | 
				
			||||||
 | 
							case 0x82:
 | 
				
			||||||
 | 
								OnModbusReceiveBitsException(mbap, ex);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x83:
 | 
				
			||||||
 | 
							case 0x84:
 | 
				
			||||||
 | 
								OnModbusReceiveRegistersException(mbap, ex);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x85:
 | 
				
			||||||
 | 
								OnModbusConfirmBitException(mbap, ex);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x86:
 | 
				
			||||||
 | 
								OnModbusConfirmRegisterException(mbap, ex);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x8F:
 | 
				
			||||||
 | 
								OnModbusConfirmBitsException(mbap, ex);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x90:
 | 
				
			||||||
 | 
								OnModbusConfirmRegistersException(mbap, ex);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x96:
 | 
				
			||||||
 | 
								OnModbusConfirmMasksException(mbap, ex);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 0x97:
 | 
				
			||||||
 | 
								OnModbusReceiveConfirmRegistersException(mbap, ex);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// REGION: ModbusSend -----------------------------------------------------------------
 | 
				
			||||||
 | 
					/// <-ModbusSend>
 | 
				
			||||||
 | 
					void ModbusSend(byte buffer[], word length, word TxID)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct QueueElement qe;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qe.Length = length;
 | 
				
			||||||
 | 
						memcpy(qe.Buffer, buffer, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy(gQueuePending[TxID], qe);
 | 
				
			||||||
 | 
						writeDbg(ConnDebug, "Appended packet 0x%04X to pending queue", TxID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gQueuePending.Size() == 1 && gQueueSent.Size() == 0 && gSocketState == OK)	// start timer if connection established
 | 
				
			||||||
 | 
							ModbusStartQueue();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusStartQueue()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						writeDbg(ConnDebug, "Starting Timer gtRobin");
 | 
				
			||||||
 | 
						setTimerCyclic(gtRobin, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <-ModbusSend>
 | 
				
			||||||
 | 
					on timer gtRobin
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ModbusApHeader mbap;
 | 
				
			||||||
 | 
						enum ModbusRequestError reqError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeDbg(ConnDebug, "gtRobin: Queue Sent: %d, Queue Pending: %d, Queue Ack: %d", gQueueSent.Size(), gQueuePending.Size(), gQueueAck.Size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// First: check timeouts = packets that were sent in previous run and not removed by response
 | 
				
			||||||
 | 
						for (long TxID : gQueueSent)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (++gQueueSent[TxID].TimeoutTicks < @sysvar::Config::Modbus::RequestTimeout)		// not timed out yet
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
																												// timed out!
 | 
				
			||||||
 | 
							if (++gQueueSent[TxID].Timeouts < @sysvar::Config::Modbus::MaxTransmissionCount)	// if we may resend it
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								writeDbg(ConnInfo, "Packet 0x%04X timed out! Retrying...", TxID);
 | 
				
			||||||
 | 
								gQueueSent[TxID].TimeoutTicks = 0;
 | 
				
			||||||
 | 
								ModbusSnd(gQueueSent[TxID].Buffer, gQueueSent[TxID].Length);					// resend it
 | 
				
			||||||
 | 
								reqError = Timeout;
 | 
				
			||||||
 | 
								ModbusRecv();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else																				// we will NOT resend it
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								writeDbg(ConnWarning, "Packet 0x%04X timed out! Giving up", TxID);
 | 
				
			||||||
 | 
								reqError = FinalTimeout;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							memcpy_n2h(mbap, gQueueSent[TxID].Buffer);
 | 
				
			||||||
 | 
							switch(mbap.FuncCode)											// throw an "error" in each case
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								case ReadBits1:
 | 
				
			||||||
 | 
								case ReadBits2:
 | 
				
			||||||
 | 
									OnModbusReadBitsFailed(reqError, None, mbap);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case ReadRegisters1:
 | 
				
			||||||
 | 
								case ReadRegisters2:
 | 
				
			||||||
 | 
									OnModbusReadRegistersFailed(reqError, None, mbap);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case WriteBit:
 | 
				
			||||||
 | 
									OnModbusWriteBitFailed(reqError, None, mbap);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case WriteRegister:
 | 
				
			||||||
 | 
									OnModbusWriteRegisterFailed(reqError, None, mbap);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case WriteBits:
 | 
				
			||||||
 | 
									OnModbusWriteBitsFailed(reqError, None, mbap);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case WriteRegisters:
 | 
				
			||||||
 | 
									OnModbusWriteRegistersFailed(reqError, None, mbap);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case MaskRegister:
 | 
				
			||||||
 | 
									OnModbusWriteMasksFailed(reqError, None, mbap);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case ReadWriteRegisters:
 | 
				
			||||||
 | 
									OnModbusReadWriteRegistersFailed(reqError, None, mbap);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if (reqError == FinalTimeout)									// remove the packet from queue
 | 
				
			||||||
 | 
								gQueueSent.Remove(TxID);									// wait until here to let the methods access the request
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Second: send new packets
 | 
				
			||||||
 | 
						for (long TxID : gQueuePending)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (gQueueSent.Size() > 4)		// Wago 750-881 cannot handle more than 5 messages at a time :(
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// if packet was sent or the socket is not currently being opened
 | 
				
			||||||
 | 
							if (ModbusSnd(gQueuePending[TxID].Buffer, gQueuePending[TxID].Length) == 0 || gSocketState != NULL)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								memcpy(gQueueSent[TxID], gQueuePending[TxID]);				// move packet to sent queue
 | 
				
			||||||
 | 
								gQueuePending.Remove(TxID);
 | 
				
			||||||
 | 
								ModbusRecv();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gSocketState == ERROR || gQueueSent.Size() == 0 && gQueuePending.Size() == 0)	// Stop timer to reduce latency of first packet
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnDebug, "Stopping Timer gtRobin");
 | 
				
			||||||
 | 
							this.Cancel();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<breakpoints>
 | 
				
			||||||
 | 
					  <breakpoint Active="true" HaltsSimulation="true" AbsoluteLine="352" Function="" RelativeLine="9" />
 | 
				
			||||||
 | 
					</breakpoints>
 | 
				
			||||||
							
								
								
									
										64
									
								
								Modbus-DLL/include/CAPL/include/ModbusEilClientCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Modbus-DLL/include/CAPL/include/ModbusEilClientCommon.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "EilCommon.cin"
 | 
				
			||||||
 | 
						#include "ModbusClientCommon.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusConnectTo(char Remote_IP[], word Remote_Port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						EilConnectTo(Remote_IP, Remote_Port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusConnectTo(dword Remote_IP, word Remote_Port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						EilConnectTo(Remote_IP, Remote_Port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					byte ModbusSnd(byte buffer[], word length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return EilSnd(buffer, length);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusRecv()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						EilRecv();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusDisconnect()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						EilDisconnect();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long ModbusGetLastConnectionError(char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return EilGetLastConnectionError(string);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnEthReceivePacket(long channel, long dir, long packet)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						byte buffer[gMaxPacketLength];
 | 
				
			||||||
 | 
						long size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dir == TX)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (EthGetTokenInt(packet, "arp", "protSourceAddr") == gRemoteIP)		// this was our ARP package
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (EthGetTokenData(packet, "arp", "hwSourceAddr", elCount(gRemoteMac), gRemoteMac) == 6)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								gtArp.Cancel();
 | 
				
			||||||
 | 
								writeDbg(ConnDebug, "Remote Mac: %02X:%02X:%02X:%02X:%02X:%02X", gRemoteMac[0], gRemoteMac[1], gRemoteMac[2], gRemoteMac[3], gRemoteMac[4], gRemoteMac[5]);
 | 
				
			||||||
 | 
								EilConnectTo2();		// create the UDP package
 | 
				
			||||||
 | 
								ModbusStartQueue();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (EthGetTokenInt(packet, "ipv4", "protocol") == 0x11 && EthGetTokenInt(packet, "ipv4", "source") == gRemoteIP)	// if this is a UDP package from our server
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						size = EthGetThisData(0, gMaxPacketLength, buffer);
 | 
				
			||||||
 | 
						OnModbusReceive(0, 0, EthGetTokenInt(packet, "ipv4", "source"), gRemoteIP, buffer, size);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										86
									
								
								Modbus-DLL/include/CAPL/include/ModbusFunctions.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Modbus-DLL/include/CAPL/include/ModbusFunctions.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,86 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum Vendor
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							BuR = 2,
 | 
				
			||||||
 | 
							Wago = 23
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct deviceIOs
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							byte InputRegisters;
 | 
				
			||||||
 | 
							word InputBits;
 | 
				
			||||||
 | 
							byte OutputRegisters;
 | 
				
			||||||
 | 
							word OutputBits;
 | 
				
			||||||
 | 
							char Modules[1024];
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ParseDeviceCode(word dev, enum Vendor vendor, struct deviceIOs dios)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						byte input;
 | 
				
			||||||
 | 
						byte numChannels;
 | 
				
			||||||
 | 
						char module[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch(vendor)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case Wago:		// if this is a Wago device
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (dev & 0x8000)					// Digital Module
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									numChannels = (dev >> 8) & 0x007F;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (dev & 0x0001)				// Input Module
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										input = 1;
 | 
				
			||||||
 | 
										strncpy(module, "DI%d,", elCount(module));
 | 
				
			||||||
 | 
										dios.InputBits += numChannels;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else if (dev & 0x0002)			// Output Module
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										input = 0;
 | 
				
			||||||
 | 
										strncpy(module, "DO%d,", elCount(module));
 | 
				
			||||||
 | 
										dios.OutputBits += numChannels;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else							// blööd
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										writeDbg(AlgoError, "ParseDeviceCode: Device code 0x%X cannot be decoded", dev);
 | 
				
			||||||
 | 
										OnModbusClientPanics(DeviceCodeUnknown);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									switch (dev)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										case 881:					// devices that have no inputs/outputs
 | 
				
			||||||
 | 
											return;
 | 
				
			||||||
 | 
										case 477:					// devices that have 2 outputs
 | 
				
			||||||
 | 
											input = 0;
 | 
				
			||||||
 | 
											numChannels = 2;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										default:					// unknown device. Ouch!
 | 
				
			||||||
 | 
											writeDbg(AlgoInfo, "Connected device: 750-%d", dev);
 | 
				
			||||||
 | 
											return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (input)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										strncpy(module, "AI%d,", elCount(module));
 | 
				
			||||||
 | 
										dios.InputRegisters += numChannels;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										strncpy(module, "AO%d,", elCount(module));
 | 
				
			||||||
 | 
										dios.OutputRegisters += numChannels;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;	// switch(vendor)
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								writeDbg(AlgoError, "ParseDeviceCode: Unknown vendor id: %d", vendor);
 | 
				
			||||||
 | 
								OnModbusClientPanics(VendorIdUnknown);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						snprintf(module, elCount(module), module, numChannels);
 | 
				
			||||||
 | 
						strncat(dios.Modules, module, elCount(dios.Modules));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										146
									
								
								Modbus-DLL/include/CAPL/include/ModbusStructs.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								Modbus-DLL/include/CAPL/include/ModbusStructs.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,146 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// A normal Modbus Application Header. Every Modbus Packet begins with these 7 (+FuncCode) Bytes
 | 
				
			||||||
 | 
						_align(1) struct ModbusApHeader
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							word TxID;
 | 
				
			||||||
 | 
							word Protocol;
 | 
				
			||||||
 | 
							word Length;
 | 
				
			||||||
 | 
							byte UnitID;
 | 
				
			||||||
 | 
							byte FuncCode;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Read Data from the host. We only need the start address and the number of bits/registers we want to read
 | 
				
			||||||
 | 
						_align(1) struct ModbusReqRead
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word Address;
 | 
				
			||||||
 | 
							word Count;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Write a single value to a bit/register
 | 
				
			||||||
 | 
						_align(1) struct ModbusReqWriteSingle
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word Address;
 | 
				
			||||||
 | 
							word Value;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Write several values to a bit/register starting with Address
 | 
				
			||||||
 | 
						_align(1) struct ModbusReqWriteBits
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word Address;
 | 
				
			||||||
 | 
							word Count;
 | 
				
			||||||
 | 
							byte ByteCount;
 | 
				
			||||||
 | 
							byte Data[246];		// Max length: 1968 bits
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Write several values to bits starting with Address
 | 
				
			||||||
 | 
						_align(1) struct ModbusReqWriteRegisters
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word Address;
 | 
				
			||||||
 | 
							word Count;
 | 
				
			||||||
 | 
							byte ByteCount;
 | 
				
			||||||
 | 
							word Data[123];		// Max length: 123 registers
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Write AND and OR masks to a holding register
 | 
				
			||||||
 | 
						_align(1) struct ModbusReqWriteMasks
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word Address;
 | 
				
			||||||
 | 
							word And;
 | 
				
			||||||
 | 
							word Or;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Read and write multiple registers
 | 
				
			||||||
 | 
						_align(1) struct ModbusReqReadWriteRegisters
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word ReadAddress;
 | 
				
			||||||
 | 
							word ReadCount;
 | 
				
			||||||
 | 
							word WriteAddress;
 | 
				
			||||||
 | 
							word WriteCount;
 | 
				
			||||||
 | 
							byte ByteCount;
 | 
				
			||||||
 | 
							word Data[121];		// Max length: 123-2 registers
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Receive several bit values
 | 
				
			||||||
 | 
						_align(1) struct ModbusResReceiveBits
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							byte ByteCount;
 | 
				
			||||||
 | 
							byte Data[250];		// Max length: 2000 bits
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Receive several register values
 | 
				
			||||||
 | 
						_align(1) struct ModbusResReceiveRegisters
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							byte ByteCount;
 | 
				
			||||||
 | 
							word Data[125];		// Max length: 125 registers
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Confirm the write of a single bit/register
 | 
				
			||||||
 | 
						_align(1) struct ModbusResConfirmSingle
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word Address;
 | 
				
			||||||
 | 
							int Value;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Confirm the write of several bits/registers
 | 
				
			||||||
 | 
						_align(1) struct ModbusResConfirmMultiple
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word Address;
 | 
				
			||||||
 | 
							word Count;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						// Confirm the write of AND and OR mask
 | 
				
			||||||
 | 
						_align(1) struct ModbusResConfirmMasks
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct ModbusApHeader Header;
 | 
				
			||||||
 | 
							word Address;
 | 
				
			||||||
 | 
							word And;
 | 
				
			||||||
 | 
							word Or;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum ModbusRequestError
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Exception,
 | 
				
			||||||
 | 
							Timeout,
 | 
				
			||||||
 | 
							FinalTimeout
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
						enum ModbusException
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							None = 0x00,
 | 
				
			||||||
 | 
							IllegalFuncCode = 0x01,
 | 
				
			||||||
 | 
							IllegalDataAddress = 0x02,
 | 
				
			||||||
 | 
							IllegalDataValue = 0x03,
 | 
				
			||||||
 | 
							ServerFailure = 0x04,
 | 
				
			||||||
 | 
							Acknowledge = 0x05,
 | 
				
			||||||
 | 
							ServerBusy = 0x06,
 | 
				
			||||||
 | 
							GatewayPathsNA = 0x0A,
 | 
				
			||||||
 | 
							TargetOffline = 0x0B
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						enum ModbusFuncCode
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ReadBits1 = 0x01,
 | 
				
			||||||
 | 
							ReadBits2 = 0x02,
 | 
				
			||||||
 | 
							ReadRegisters1 = 0x03,
 | 
				
			||||||
 | 
							ReadRegisters2 = 0x04,
 | 
				
			||||||
 | 
							WriteBit = 0x05,
 | 
				
			||||||
 | 
							WriteRegister = 0x06,
 | 
				
			||||||
 | 
							WriteBits = 0x0F,
 | 
				
			||||||
 | 
							WriteRegisters = 0x10,
 | 
				
			||||||
 | 
							MaskRegister = 0x16,
 | 
				
			||||||
 | 
							ReadWriteRegisters = 0x17
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum FatalErrors
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ParsingBuffer = 0x00,
 | 
				
			||||||
 | 
							ModbusPackageWasSplit = 0x01,
 | 
				
			||||||
 | 
							DeviceCodeUnknown = 0x02,
 | 
				
			||||||
 | 
							VendorIdUnknown = 0x03,
 | 
				
			||||||
 | 
							ConnectionError = 0x04
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								Modbus-DLL/include/CAPL/include/ModbusTcpClientCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Modbus-DLL/include/CAPL/include/ModbusTcpClientCommon.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "TcpCommon.cin"
 | 
				
			||||||
 | 
						#include "ModbusClientCommon.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusConnectTo(char Remote_IP[], word Remote_Port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TcpConnectTo(Remote_IP, Remote_Port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusConnectTo(dword Remote_IP, word Remote_Port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TcpConnectTo(Remote_IP, Remote_Port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusDisconnect()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TcpDisconnect();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					byte ModbusSnd(byte buffer[], word length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return TcpSnd(buffer, length);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusRecv()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TcpRecv();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long ModbusGetLastConnectionError(char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return TcpGetLastConnectionError(string);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnTcpReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						OnModbusReceive(socket, result, address, port, buffer, size);
 | 
				
			||||||
 | 
						if (result == 0 && size != 0)
 | 
				
			||||||
 | 
							TcpRecv();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								Modbus-DLL/include/CAPL/include/ModbusUdpClientCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Modbus-DLL/include/CAPL/include/ModbusUdpClientCommon.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "UdpCommon.cin"
 | 
				
			||||||
 | 
						#include "ModbusClientCommon.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusConnectTo(char Remote_IP[], word Remote_Port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						UdpConnectTo(Remote_IP, Remote_Port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusConnectTo(dword Remote_IP, word Remote_Port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						UdpConnectTo(Remote_IP, Remote_Port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusDisconnect()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						UdpDisconnect();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					byte ModbusSnd(byte buffer[], word length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return UdpSnd(buffer, length);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModbusRecv()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						UdpRecv();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long ModbusGetLastConnectionError(char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return UdpGetLastConnectionError(string);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnUdpReceiveFrom(dword socket, long result, dword address, dword port, byte buffer[], dword size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						OnModbusReceive(socket, result, address, port, buffer, size);
 | 
				
			||||||
 | 
						if (result == 0 && size != 0)
 | 
				
			||||||
 | 
							UdpRecv();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										204
									
								
								Modbus-DLL/include/CAPL/include/TcpCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								Modbus-DLL/include/CAPL/include/TcpCommon.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,204 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "Common.cin"
 | 
				
			||||||
 | 
						#include "TcpUdpCommon.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TcpSocket gSocket;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word TcpOpenSocket()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						byte i;
 | 
				
			||||||
 | 
						CHAR errorText[200];
 | 
				
			||||||
 | 
						long error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (EthGetAdapterStatus() != 2)			// Not connected
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "TcpOpenSocket: Adapter status not ok: %d!", EthGetAdapterStatus());
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return INVALID_IP;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Try to open socket
 | 
				
			||||||
 | 
						i = 0;
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gSocket = TcpSocket::Open(0, 0);
 | 
				
			||||||
 | 
							error = gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
							if (error != 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								gSocket.GetLastSocketErrorAsString(errorText, elcount(errorText));
 | 
				
			||||||
 | 
								writeDbg(ConnInfo, "TcpOpenSocket: could not open socket: (%d) %s", error, errorText);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						while (error != 0 && i++ < 9);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (error != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "TcpOpenSocket: could not open socket: (%d) %s", error, errorText);
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnInfo, "Tcp socket opened.");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word TcpConnectTo(char Remote_IP[], word remotePort)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dword remoteIp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Convert IP string to Number
 | 
				
			||||||
 | 
						remoteIp = IpGetAddressAsNumber(Remote_IP);
 | 
				
			||||||
 | 
						if (remoteIp == INVALID_IP)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "TcpConnectTo: invalid server Ip address: %s", Remote_IP);
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return TcpConnectTo(remoteIp, remotePort);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word TcpConnectTo(dword remoteIp, word remotePort)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long fehler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Try to open a socket
 | 
				
			||||||
 | 
						fehler = TcpOpenSocket();
 | 
				
			||||||
 | 
						if (fehler != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gSocketState = ERROR;
 | 
				
			||||||
 | 
							return fehler;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gRemoteIP = remoteIp;
 | 
				
			||||||
 | 
						gRemotePort = remotePort;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Connect to Server
 | 
				
			||||||
 | 
						if (gSocket.Connect(remoteIp, remotePort) != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fehler = gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (fehler != WSAEWOULDBLOCK)		// OnTcpConnect will be called otherwise
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								writeDbg(ConnError, "TcpConnectTo: No connection established: %d", fehler);
 | 
				
			||||||
 | 
								gSocketState = ERROR;
 | 
				
			||||||
 | 
								OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
								return fehler;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnInfo, "TcpConnectTo: Successfully connected to server");
 | 
				
			||||||
 | 
							gSocketState = OK;
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OnTcpConnect(dword socket, long result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (result != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
 | 
				
			||||||
 | 
							writeDbg(ConnError, "OnTcpConnect: (%d) %s", gSocket.GetLastSocketError(), gIpLastErrStr);
 | 
				
			||||||
 | 
							gSocketState = ERROR;
 | 
				
			||||||
 | 
								OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnInfo, "OnTcpConnect: Successfully connected to server");
 | 
				
			||||||
 | 
							gSocketState = OK;
 | 
				
			||||||
 | 
							ModbusStartQueue();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TcpDisconnect()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gSocket.Close();
 | 
				
			||||||
 | 
						gSocketState = CLOSED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TcpRecv()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gSocketState != OK)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnWarning, "TcpRecv: Socket status is not OK! Doing nothing.");
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						result = gSocket.Receive(gRxBuffer, elcount(gRxBuffer));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (result != 0)	// Calling OnTcpReceive otherwise
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gIpLastErr = gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (gIpLastErr != WSA_IO_PENDING)	// Calling OnTcpReceive otherwise
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
 | 
				
			||||||
 | 
								writeDbg(ConnError, "TcpReceive: (%d) %s", gIpLastErr, gIpLastErrStr);
 | 
				
			||||||
 | 
								TcpDisconnect();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word TcpSnd(byte buffer[], word length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char str[20*3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (gSocketState)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case CLOSED:
 | 
				
			||||||
 | 
								TcpConnectTo(gRemoteIP, gRemotePort);
 | 
				
			||||||
 | 
								if (gSocketState != OK)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									writeDbg(ConnError, "TcpSnd: Reconnecting failed!");
 | 
				
			||||||
 | 
									OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case OK:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								writeDbg(ConnError, "TcpSnd: Socket status is not OK! Doing nothing.");
 | 
				
			||||||
 | 
								OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bin_to_strhex(buffer, str);
 | 
				
			||||||
 | 
						writeDbg(ConnDebug, "TcpSnd: %s (Länge: %d)", str, length);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (gSocket.Send(buffer, length) != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gIpLastErr = gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (gIpLastErr != WSA_IO_PENDING)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
 | 
				
			||||||
 | 
								writeDbg(ConnError, "TcpSnd: (%d) %s", gIpLastErr, gIpLastErrStr);
 | 
				
			||||||
 | 
								TcpDisconnect();
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long TcpGetLastConnectionError(char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gSocket.GetLastSocketErrorAsString(string, elCount(string));
 | 
				
			||||||
 | 
						return gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								Modbus-DLL/include/CAPL/include/TcpUdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Modbus-DLL/include/CAPL/include/TcpUdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const long	WSA_IO_PENDING		= 997;
 | 
				
			||||||
 | 
						const long	WSAEWOULDBLOCK		= 10035;
 | 
				
			||||||
 | 
						const dword INVALID_IP			= 0xffffffff;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						long gIpLastErr					= 0;
 | 
				
			||||||
 | 
						char gIpLastErrStr[512]			= "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum SocketState { NULL, OK, ERROR, CLOSED };
 | 
				
			||||||
 | 
						enum SocketState gSocketState = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dword gRemoteIP		= INVALID_IP;
 | 
				
			||||||
 | 
						word gRemotePort	= 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						byte gRxBuffer[8192];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										166
									
								
								Modbus-DLL/include/CAPL/include/UdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								Modbus-DLL/include/CAPL/include/UdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,166 @@
 | 
				
			||||||
 | 
					/*@!Encoding:1252*/
 | 
				
			||||||
 | 
					includes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#include "Common.cin"
 | 
				
			||||||
 | 
						#include "TcpUdpCommon.cin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						UdpSocket gSocket;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word UdpOpenSocket()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						byte i;
 | 
				
			||||||
 | 
						char errorText[200];
 | 
				
			||||||
 | 
						long error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (EthGetAdapterStatus() != 2)			// Not connected
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "UdpOpenSocket: Adapter status not ok: %d!", EthGetAdapterStatus());
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return INVALID_IP;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Try to open socket
 | 
				
			||||||
 | 
						i = 0;
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gSocket = UdpSocket::Open(0, 0);
 | 
				
			||||||
 | 
							error = gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
							if (error != 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								gSocket.GetLastSocketErrorAsString(errorText, elcount(errorText));
 | 
				
			||||||
 | 
								writeDbg(ConnInfo, "UdpOpenSocket: could not open socket: (%d) %s", error, errorText);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						while (error != 0 && i++ < 9);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (error != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "UdpOpenSocket: could not open socket: (%d) %s", error, errorText);
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnInfo, "Udp socket opened.");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word UdpConnectTo(char Remote_IP[], word remotePort)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dword remoteIp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Convert IP string to Number
 | 
				
			||||||
 | 
						remoteIp = IpGetAddressAsNumber(Remote_IP);
 | 
				
			||||||
 | 
						if (remoteIp == INVALID_IP)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "UdpConnectTo: invalid server Ip address: %s", Remote_IP);
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return UdpConnectTo(remoteIp, remotePort);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word UdpConnectTo(dword remoteIp, word remotePort)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long fehler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Try to open a socket
 | 
				
			||||||
 | 
						fehler = UdpOpenSocket();
 | 
				
			||||||
 | 
						if (fehler != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gSocketState = ERROR;
 | 
				
			||||||
 | 
							return fehler;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gRemoteIP = remoteIp;
 | 
				
			||||||
 | 
						gRemotePort = remotePort;
 | 
				
			||||||
 | 
						gSocketState = OK;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void UdpDisconnect()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gSocket.Close();
 | 
				
			||||||
 | 
						gSocketState = CLOSED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void UdpRecv()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gSocketState != OK)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							writeDbg(ConnError, "UdpRecv: Socket status is not OK! Doing nothing.");
 | 
				
			||||||
 | 
							OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						result = gSocket.ReceiveFrom(gRxBuffer, elCount(gRxBuffer));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (result != 0)	// Calling OnUdpReceive otherwise
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gIpLastErr = gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (gIpLastErr != WSA_IO_PENDING)	// Calling OnUdpReceive otherwise
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elCount(gIpLastErrStr));
 | 
				
			||||||
 | 
								writeDbg(ConnError, "UdpReceiveFrom: (%d) %s", gIpLastErr, gIpLastErrStr);
 | 
				
			||||||
 | 
								UdpDisconnect();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					byte UdpSnd(byte buffer[], word length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char str[20*3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (gSocketState)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case CLOSED:
 | 
				
			||||||
 | 
								UdpConnectTo(gRemoteIP, gRemotePort);
 | 
				
			||||||
 | 
								if (gSocketState != OK)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									writeDbg(ConnError, "UdpSnd: Reconnecting failed!");
 | 
				
			||||||
 | 
									OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case OK:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								writeDbg(ConnError, "UdpSnd: Socket status is not OK! Doing nothing.");
 | 
				
			||||||
 | 
								OnModbusClientPanics(ConnectionError);
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bin_to_strhex(buffer, str);
 | 
				
			||||||
 | 
						writeDbg(ConnDebug, "UdpSnd: %s (Länge: %d)", str, length);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (gSocket.SendTo(gRemoteIP, gRemotePort, buffer, length) != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							gIpLastErr = gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (gIpLastErr != WSA_IO_PENDING)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
 | 
				
			||||||
 | 
								writeDbg(ConnError, "UdpSnd error (%d): %s", gIpLastErr, gIpLastErrStr);
 | 
				
			||||||
 | 
								UdpDisconnect();
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long UdpGetLastConnectionError(char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gSocket.GetLastSocketErrorAsString(string, elCount(string));
 | 
				
			||||||
 | 
						return gSocket.GetLastSocketError();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								Modbus-DLL/include/DBC/MakeConfig.dbc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								Modbus-DLL/include/DBC/MakeConfig.dbc
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,49 @@
 | 
				
			||||||
 | 
					VERSION ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NS_ : 
 | 
				
			||||||
 | 
						NS_DESC_
 | 
				
			||||||
 | 
						CM_
 | 
				
			||||||
 | 
						BA_DEF_
 | 
				
			||||||
 | 
						BA_
 | 
				
			||||||
 | 
						VAL_
 | 
				
			||||||
 | 
						CAT_DEF_
 | 
				
			||||||
 | 
						CAT_
 | 
				
			||||||
 | 
						FILTER
 | 
				
			||||||
 | 
						BA_DEF_DEF_
 | 
				
			||||||
 | 
						EV_DATA_
 | 
				
			||||||
 | 
						ENVVAR_DATA_
 | 
				
			||||||
 | 
						SGTYPE_
 | 
				
			||||||
 | 
						SGTYPE_VAL_
 | 
				
			||||||
 | 
						BA_DEF_SGTYPE_
 | 
				
			||||||
 | 
						BA_SGTYPE_
 | 
				
			||||||
 | 
						SIG_TYPE_REF_
 | 
				
			||||||
 | 
						VAL_TABLE_
 | 
				
			||||||
 | 
						SIG_GROUP_
 | 
				
			||||||
 | 
						SIG_VALTYPE_
 | 
				
			||||||
 | 
						SIGTYPE_VALTYPE_
 | 
				
			||||||
 | 
						BO_TX_BU_
 | 
				
			||||||
 | 
						BA_DEF_REL_
 | 
				
			||||||
 | 
						BA_REL_
 | 
				
			||||||
 | 
						BA_DEF_DEF_REL_
 | 
				
			||||||
 | 
						BU_SG_REL_
 | 
				
			||||||
 | 
						BU_EV_REL_
 | 
				
			||||||
 | 
						BU_BO_REL_
 | 
				
			||||||
 | 
						SG_MUL_VAL_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BS_:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BU_: MakeConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BA_DEF_ BU_  "NodeLayerModules" STRING ;
 | 
				
			||||||
 | 
					BA_DEF_  "DBName" STRING ;
 | 
				
			||||||
 | 
					BA_DEF_  "BusType" STRING ;
 | 
				
			||||||
 | 
					BA_DEF_DEF_  "NodeLayerModules" "ETHERNET_IL.dll";
 | 
				
			||||||
 | 
					BA_DEF_DEF_  "DBName" "";
 | 
				
			||||||
 | 
					BA_DEF_DEF_  "BusType" "Ethernet";
 | 
				
			||||||
 | 
					BA_ "BusType" "Ethernet";
 | 
				
			||||||
 | 
					BA_ "DBName" "MakeConfig";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										165
									
								
								Modbus-DLL/include/DBC/MakeConfig.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								Modbus-DLL/include/DBC/MakeConfig.ini
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,165 @@
 | 
				
			||||||
 | 
					[View_Vehicles]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,150,
 | 
				
			||||||
 | 
					[View_Vehicle]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,
 | 
				
			||||||
 | 
					[View_VehicleNetworks]
 | 
				
			||||||
 | 
					HIDDEN=3,5,
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,
 | 
				
			||||||
 | 
					DEFINITIONS=2,3,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,100,150,100,100,
 | 
				
			||||||
 | 
					[View_VehicleNetwork]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,125,150,100,
 | 
				
			||||||
 | 
					[View_VehicleNetworkTxMessages]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,55,100,50,100,100,100,150,
 | 
				
			||||||
 | 
					[View_VehicleNetworkSignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,100,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_VehicleControlUnit]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,125,150,100,
 | 
				
			||||||
 | 
					[View_VehicleGateways]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,
 | 
				
			||||||
 | 
					[View_VehicleGatewaySignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,125,125,125,125,125,
 | 
				
			||||||
 | 
					[View_Networks]
 | 
				
			||||||
 | 
					HIDDEN=2,4,
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,
 | 
				
			||||||
 | 
					DEFINITIONS=2,3,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,100,150,100,100,
 | 
				
			||||||
 | 
					[View_Network]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,150,100,
 | 
				
			||||||
 | 
					[View_NetworkTxMessages]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,55,100,50,100,100,100,150,
 | 
				
			||||||
 | 
					[View_NetworkTxSignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,100,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NetworkNodeGroup]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,150,100,
 | 
				
			||||||
 | 
					[View_Ecus]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,150,
 | 
				
			||||||
 | 
					[View_Ecu]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,150,100,
 | 
				
			||||||
 | 
					[View_EnvVars]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_EnvVar]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeGroups]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,150,
 | 
				
			||||||
 | 
					[View_NodeGroup]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,55,150,
 | 
				
			||||||
 | 
					[View_Nodes]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,150,100,
 | 
				
			||||||
 | 
					[View_Node]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeTxMessages]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,55,100,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeTxMsg]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeTxSignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeRxSignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeTxSigs]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeRxSigs]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_Messages]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,55,100,50,100,100,100,150,
 | 
				
			||||||
 | 
					[View_Message]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_Signals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_ValueTables]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,150,
 | 
				
			||||||
 | 
					[View_AttrDefs]
 | 
				
			||||||
 | 
					HIDDEN=6,
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,100,50,50,100,150,
 | 
				
			||||||
							
								
								
									
										47
									
								
								Modbus-DLL/include/DBC/generated.dbc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Modbus-DLL/include/DBC/generated.dbc
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					VERSION ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NS_ :
 | 
				
			||||||
 | 
						NS_DESC_
 | 
				
			||||||
 | 
						CM_
 | 
				
			||||||
 | 
						BA_DEF_
 | 
				
			||||||
 | 
						BA_
 | 
				
			||||||
 | 
						VAL_
 | 
				
			||||||
 | 
						CAT_DEF_
 | 
				
			||||||
 | 
						CAT_
 | 
				
			||||||
 | 
						FILTER
 | 
				
			||||||
 | 
						BA_DEF_DEF_
 | 
				
			||||||
 | 
						EV_DATA_
 | 
				
			||||||
 | 
						ENVVAR_DATA_
 | 
				
			||||||
 | 
						SGTYPE_
 | 
				
			||||||
 | 
						SGTYPE_VAL_
 | 
				
			||||||
 | 
						BA_DEF_SGTYPE_
 | 
				
			||||||
 | 
						BA_SGTYPE_
 | 
				
			||||||
 | 
						SIG_TYPE_REF_
 | 
				
			||||||
 | 
						VAL_TABLE_
 | 
				
			||||||
 | 
						SIG_GROUP_
 | 
				
			||||||
 | 
						SIG_VALTYPE_
 | 
				
			||||||
 | 
						SIGTYPE_VALTYPE_
 | 
				
			||||||
 | 
						BO_TX_BU_
 | 
				
			||||||
 | 
						BA_DEF_REL_
 | 
				
			||||||
 | 
						BA_REL_
 | 
				
			||||||
 | 
						BA_DEF_DEF_REL_
 | 
				
			||||||
 | 
						BU_SG_REL_
 | 
				
			||||||
 | 
						BU_EV_REL_
 | 
				
			||||||
 | 
						BU_BO_REL_
 | 
				
			||||||
 | 
						SG_MUL_VAL_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BS_:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BU_: Client_2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BA_DEF_ BU_  "NodeLayerModules" STRING ;
 | 
				
			||||||
 | 
					BA_DEF_  "DBName" STRING ;
 | 
				
			||||||
 | 
					BA_DEF_  "BusType" STRING ;
 | 
				
			||||||
 | 
					BA_DEF_DEF_  "NodeLayerModules" "Ethernet_IL.DLL";
 | 
				
			||||||
 | 
					BA_DEF_DEF_  "DBName" "";
 | 
				
			||||||
 | 
					BA_DEF_DEF_  "BusType" "Ethernet";
 | 
				
			||||||
 | 
					BA_ "BusType" "Ethernet";
 | 
				
			||||||
 | 
					BA_ "DBName" "Modbus";
 | 
				
			||||||
							
								
								
									
										165
									
								
								Modbus-DLL/include/DBC/generated.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								Modbus-DLL/include/DBC/generated.ini
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,165 @@
 | 
				
			||||||
 | 
					[View_Vehicles]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,150,
 | 
				
			||||||
 | 
					[View_Vehicle]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,
 | 
				
			||||||
 | 
					[View_VehicleNetworks]
 | 
				
			||||||
 | 
					HIDDEN=3,5,
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,
 | 
				
			||||||
 | 
					DEFINITIONS=2,3,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,100,150,100,100,
 | 
				
			||||||
 | 
					[View_VehicleNetwork]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,125,150,100,
 | 
				
			||||||
 | 
					[View_VehicleNetworkTxMessages]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,55,100,50,100,100,100,150,
 | 
				
			||||||
 | 
					[View_VehicleNetworkSignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,100,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_VehicleControlUnit]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,125,150,100,
 | 
				
			||||||
 | 
					[View_VehicleGateways]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,
 | 
				
			||||||
 | 
					[View_VehicleGatewaySignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,125,125,125,125,125,
 | 
				
			||||||
 | 
					[View_Networks]
 | 
				
			||||||
 | 
					HIDDEN=2,4,
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,
 | 
				
			||||||
 | 
					DEFINITIONS=2,3,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,100,150,100,100,
 | 
				
			||||||
 | 
					[View_Network]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,150,100,
 | 
				
			||||||
 | 
					[View_NetworkTxMessages]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,55,100,50,100,100,100,150,
 | 
				
			||||||
 | 
					[View_NetworkTxSignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,100,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NetworkNodeGroup]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,150,100,
 | 
				
			||||||
 | 
					[View_Ecus]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,150,
 | 
				
			||||||
 | 
					[View_Ecu]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,150,100,
 | 
				
			||||||
 | 
					[View_EnvVars]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_EnvVar]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeGroups]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,150,
 | 
				
			||||||
 | 
					[View_NodeGroup]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,55,150,
 | 
				
			||||||
 | 
					[View_Nodes]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,
 | 
				
			||||||
 | 
					DEFINITIONS=1,
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,150,100,
 | 
				
			||||||
 | 
					[View_Node]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeTxMessages]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,55,100,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeTxMsg]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeTxSignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeRxSignals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeTxSigs]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_NodeRxSigs]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_Messages]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,55,100,50,100,100,100,150,
 | 
				
			||||||
 | 
					[View_Message]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,125,100,50,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_Signals]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,6,7,8,9,10,11,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,50,100,100,100,50,50,50,50,100,100,150,
 | 
				
			||||||
 | 
					[View_ValueTables]
 | 
				
			||||||
 | 
					HIDDEN=
 | 
				
			||||||
 | 
					ORDER=0,1,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,150,
 | 
				
			||||||
 | 
					[View_AttrDefs]
 | 
				
			||||||
 | 
					HIDDEN=6,
 | 
				
			||||||
 | 
					ORDER=0,1,2,3,4,5,
 | 
				
			||||||
 | 
					DEFINITIONS=
 | 
				
			||||||
 | 
					COLUMNWIDTHS=125,100,100,50,50,100,150,
 | 
				
			||||||
							
								
								
									
										44
									
								
								Modbus-DLL/include/SysVars/generated.vsysvar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Modbus-DLL/include/SysVars/generated.vsysvar
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<systemvariables version="4">
 | 
				
			||||||
 | 
					  <namespace name="" comment="">
 | 
				
			||||||
 | 
					    <namespace name="Config" comment="">
 | 
				
			||||||
 | 
					      <namespace name="Modbus" comment="">
 | 
				
			||||||
 | 
					        <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="ms" name="RequestTimeout" comment="The maximum duration for a Modbus-UDP/-TCP request in milliseconds. After timeout a retransmission may be started (see MaxRetransmissionCount).    Use `ping` to get the maximum latency to a device, double it and add 2-3 ms for processing." bitcount="32" isSigned="true" encoding="65001" type="int" startValue="7" minValue="1" minValuePhys="1" maxValue="1000" maxValuePhys="1000" />
 | 
				
			||||||
 | 
					        <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="Port" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="502" minValue="1" minValuePhys="1" maxValue="65535" maxValuePhys="65535" />
 | 
				
			||||||
 | 
					        <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="times" name="MaxTransmissionCount" comment="How often a retransmission of a request will be sent until it gets discarded and an error is thrown." bitcount="32" isSigned="true" encoding="65001" type="int" startValue="2" minValue="1" minValuePhys="1" maxValue="10" maxValuePhys="10" />
 | 
				
			||||||
 | 
					      </namespace>
 | 
				
			||||||
 | 
					      <namespace name="TcpIp" comment="">
 | 
				
			||||||
 | 
					        <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="AdapterIndex" comment="Index of network interface to use" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="2" minValue="1" minValuePhys="1" maxValue="20" maxValuePhys="20" />
 | 
				
			||||||
 | 
					      </namespace>
 | 
				
			||||||
 | 
					    </namespace>
 | 
				
			||||||
 | 
					    <namespace name="Ethernet1" comment="Subnet: 192.168.1.">
 | 
				
			||||||
 | 
					      <namespace name="Client_2" comment="Server with ip address '192.168.1.2'">
 | 
				
			||||||
 | 
					        <namespace name="Config" comment="Configuration section for this server">
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="IP" comment="The IP address of this server" bitcount="8" isSigned="true" encoding="65001" type="string" startValue="192.168.1.2" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="ms" name="Interval" comment="The interval with which the device will be queried" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="100" minValue="10" minValuePhys="10" maxValue="10000" maxValuePhys="10000" />
 | 
				
			||||||
 | 
					        </namespace>
 | 
				
			||||||
 | 
					        <namespace name="Info" comment="Some information about the device">
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="true" valueSequence="false" unit="" name="Vendor" comment="The vendor of the device" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="23">
 | 
				
			||||||
 | 
					            <valuetable definesMinMax="true">
 | 
				
			||||||
 | 
					              <valuetableentry value="2" description="BuR" />
 | 
				
			||||||
 | 
					              <valuetableentry value="23" description="Wago" />
 | 
				
			||||||
 | 
					            </valuetable>
 | 
				
			||||||
 | 
					          </variable>
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="true" valueSequence="false" unit="" name="SerialCode" comment="The serial code of the server" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="750" minValue="1" minValuePhys="1" maxValue="10000" maxValuePhys="10000" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="true" valueSequence="false" unit="" name="DeviceCode" comment="The device code of the server" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="881" minValue="1" minValuePhys="1" maxValue="10000" maxValuePhys="10000" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="true" valueSequence="false" unit="" name="Modules" comment="The type and number of inputs of modules that are connected to the server" bitcount="8" isSigned="true" encoding="65001" type="string" startValue="DI2,DO16" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="true" valueSequence="false" unit="" name="InputRegisters" comment="Number of input registers" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="123" maxValuePhys="123" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="true" valueSequence="false" unit="" name="InputBits" comment="Number of input bits" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="2" minValue="0" minValuePhys="0" maxValue="2000" maxValuePhys="2000" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="true" valueSequence="false" unit="" name="OutputRegisters" comment="Number of output registers" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="123" maxValuePhys="123" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="true" valueSequence="false" unit="" name="OutputBits" comment="Number of output bits" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="16" minValue="0" minValuePhys="0" maxValue="2000" maxValuePhys="2000" />
 | 
				
			||||||
 | 
					        </namespace>
 | 
				
			||||||
 | 
					        <namespace name="Data" comment="The actual process image">
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="InputRegisters" comment="The values of the input registers" bitcount="9" isSigned="true" encoding="65001" type="intarray" arrayLength="0" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="InputBits" comment="The state of the input bits" bitcount="2" isSigned="true" encoding="65001" type="intarray" arrayLength="2" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="OutputRegisters" comment="The values of the output registers. Write here and the values will be sent to the device" bitcount="9" isSigned="true" encoding="65001" type="intarray" arrayLength="0" />
 | 
				
			||||||
 | 
					          <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="OutputBits" comment="The state of the output bits. Write here and the values will be sent to the device" bitcount="2" isSigned="true" encoding="65001" type="intarray" arrayLength="16" />
 | 
				
			||||||
 | 
					        </namespace>
 | 
				
			||||||
 | 
					      </namespace>
 | 
				
			||||||
 | 
					    </namespace>
 | 
				
			||||||
 | 
					  </namespace>
 | 
				
			||||||
 | 
					</systemvariables>
 | 
				
			||||||
							
								
								
									
										1118
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/Include/IPBPacketAPI.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1118
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/Include/IPBPacketAPI.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										9
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/Stdafx.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/Stdafx.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
 | 
					  StdAfx.cpp
 | 
				
			||||||
 | 
					  -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (c) 2009 Vector Informatik GmbH. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ------------------------------------------------------------------- */ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "StdAfx.h"
 | 
				
			||||||
							
								
								
									
										21
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/Stdafx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/Stdafx.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
 | 
					  StdAfx.h
 | 
				
			||||||
 | 
					  -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (c) 2009 Vector Informatik GmbH. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ------------------------------------------------------------------- */ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Library includes
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Project specific includes
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/IPBPacketAPI.h"
 | 
				
			||||||
							
								
								
									
										481
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/VCSignalProtocol.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										481
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/VCSignalProtocol.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,481 @@
 | 
				
			||||||
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
 | 
					  VCSignalProtocol.h
 | 
				
			||||||
 | 
					  -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (c) Vector Informatik GmbH. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ------------------------------------------------------------------- */ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "StdAfx.h"
 | 
				
			||||||
 | 
					#include "VCSignalProtocol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Implementaiton of VExampleSignalProtocol
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//----------------------------------------------------------------------
 | 
				
			||||||
 | 
					//! Constructor
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VCSignalProtocol::VCSignalProtocol() :
 | 
				
			||||||
 | 
					  mProtocolId( NIPB::kNil ),
 | 
				
			||||||
 | 
					  mContentId ( 0    )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// IProtocol
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Initialize the protocol
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					  Register the protocol and its tokens at the IPB Packet Lib.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  \param protocolManager The protocol manager for this protocol. The pointer can be stored and is valid
 | 
				
			||||||
 | 
					                         during the whole lifetime of the IProtocol object.
 | 
				
			||||||
 | 
					  \param networkModel    The network model for this protocol. The pointer can be stored and is valid
 | 
				
			||||||
 | 
					                         during the whole lifetime of the IProtocol object.
 | 
				
			||||||
 | 
					  \param modelCreator    Define network model entities with this object. Pointer is only valid during this call.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::Initialize( NIPB::IProtocolManager /*in*/ *protocolManager, NIPB::INetworkModel /*in*/ *networkModel, NIPB::INetworkModelCreator /*in*/ *modelCreator )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (protocolManager == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (networkModel    == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (modelCreator    == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mProtocolManager = protocolManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NIPB::ITokenDefinitionCreator *protocol = 0;
 | 
				
			||||||
 | 
					  if (modelCreator->DefineProtocol( "vc-sig", &mProtocolId, &protocol ) == NIPB::kOK)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    modelCreator->DefineProtocolField( protocol, "contentId", &mContentId, 0 );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Denitialize the protocol
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					  \param protocolManager The protocol manager for this protocol. The pointer is invalid after Deinitialize.
 | 
				
			||||||
 | 
					  \param networkModel    The network model for this protocol. The pointer is invalid after Deinitialize.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::Deinitialize( NIPB::IProtocolManager /*in*/ * /*protocolManager*/, NIPB::INetworkModel /*in*/ * /*networkModel*/ )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Returns the textual designator of the protocol
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					    The designator is used to access the protocol in CAPL (via Nodelayer) or the GUI of CANoe/CANalyzer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \param bufferSize   Length of 'buffer'. Must not > 0
 | 
				
			||||||
 | 
					    \param buffer       The designator is copied to this buffer. Must not be 0
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::GetDesignator( unsigned long /*in*/ bufferSize, char /*out**/ *buffer )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (bufferSize == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (buffer     == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  strcpy_s( buffer, bufferSize, "vc-sig" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Unique token identifier of the protocol
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					    The VTokenId of the protocol is registerd on startup during defintion of the protocol token.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \param identifier  A pointer to a VTokenId, which retrieves the identifier. Must not be 0
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::GetIdentifier( NIPB::VTokenId /*out*/ *identifier )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (identifier == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *identifier = mProtocolId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Returns specific encoder for a token ID
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					    The IEncoder is used to access a token within a IPacket.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \param tokenId  Token identifier for which the encoder is requested.
 | 
				
			||||||
 | 
					    \param encoder  Returns a pointer to the encoder. Must not be 0.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::GetEncoder( NIPB::VTokenId /*in*/ tokenId, NIPB::IEncoder /*out*/ **encoder )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (encoder == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (tokenId == mContentId)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return mProtocolManager->GetEncoder( NIPB::kEncoderUnsignedLE, encoder );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return NIPB::kEncodingNotSupported;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Initialize a specific protocol during creation of a new packet
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					    Use this method to setup a protocol within a packet.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \param packet           The packet where the protocol should be setup. Must not be 0.
 | 
				
			||||||
 | 
					    \param protocolTypeId   Type ID for a specific type of the protocol, i.e ARP request or ARP response
 | 
				
			||||||
 | 
					    \param topProtocolToken Points to the top most protocol within the packet.
 | 
				
			||||||
 | 
					    \param protocolToken    This strucuture must be filled in InitProtocol.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::InitProtocol( NIPB::IPacket /*in*/ *packet, NIPB::VTokenId /*in*/ /*protocolTypeId*/, const NIPB::VProtocolToken /*in*/ * /*topProtocolToken*/, NIPB::VProtocolToken /*out*/ *vc_sig )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (mProtocolManager == 0)    return NIPB::kInternalError;
 | 
				
			||||||
 | 
					  if (packet           == 0)    return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NIPB::VResult result            = NIPB::kError;
 | 
				
			||||||
 | 
					  BYTE          broadcastMacId[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Init Ethernet protocol
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  NIPB::VProtocolToken eth;
 | 
				
			||||||
 | 
					  if ((result = mProtocolManager->GetProtocolByIndex( packet, 0, ð )) != NIPB::kOK)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  SetTokenData( eth, NIPB::kEthDestination, 6, broadcastMacId ); // Set destination MAC ID to Broadcast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Init IPv4 protocol
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  NIPB::VProtocolToken ipv4;
 | 
				
			||||||
 | 
					  if ((result = mProtocolManager->InitProtocol( packet, NIPB::kIPv4, 0, &ipv4 )) != NIPB::kOK)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  SetTokenUnsigned( ipv4, NIPB::kIPv4Destination, 4, 0xFFFFFFFF ); // Set destination IP address to Broadcast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Init UDP protocol
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  NIPB::VProtocolToken udp;
 | 
				
			||||||
 | 
					  if ((result = mProtocolManager->InitProtocol( packet, NIPB::kUDP, 0, &udp )) != NIPB::kOK)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  SetTokenUnsigned( udp, NIPB::kUDPSource     , 2, 40001 ); // Set source port
 | 
				
			||||||
 | 
					  SetTokenUnsigned( udp, NIPB::kUDPDestination, 2, 40001 ); // Set destination port
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Init VCSig protocol
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  if (result == (mProtocolManager->ResizeToken( &udp, kHeaderBitLength, 0 )))
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    vc_sig->tokenId         = mProtocolId;
 | 
				
			||||||
 | 
					    vc_sig->protocol        = this;
 | 
				
			||||||
 | 
					    vc_sig->packet          = packet;
 | 
				
			||||||
 | 
					    vc_sig->headerBitOffset = udp.bitOffset;
 | 
				
			||||||
 | 
					    vc_sig->headerBitLength = kHeaderBitLength;
 | 
				
			||||||
 | 
					    vc_sig->bitOffset       = udp.bitOffset + kHeaderBitLength;
 | 
				
			||||||
 | 
					    vc_sig->bitLength       = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SetTokenUnsigned( *vc_sig, mContentId, 4, 0xFFFFFFFF ); // Set invalid content ID
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Complete the protocol at the end of creation/modification of a packet.
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					  In this function the checksum or length field of a protocol can be calculated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  \param packet   The packet to complete
 | 
				
			||||||
 | 
					  \param protocol Points to the protocol token for this protocol
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::CompleteProtocol( NIPB::IPacket /*in*/ *packet, const NIPB::VProtocolToken /*in*/ *vc_sig )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (packet          == 0)           return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (vc_sig          == 0)           return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (vc_sig->tokenId != mProtocolId) return NIPB::kError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Parse a received packet.
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					    The method is called, when a packet is parsed. During parsing the VProtocols structure is initialzed
 | 
				
			||||||
 | 
					    with the protocol information, whiche are returnd with 'protocolToken'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \param packet            The packet to parse.
 | 
				
			||||||
 | 
					    \param topProtocolToken  Points to the top most, already parsed protocol within the packet.
 | 
				
			||||||
 | 
					    \param errorWriter       Use this interface to returne parsing errors, i.e wrong checksum
 | 
				
			||||||
 | 
					    \param nextProcotolId    Return the VTokenId of the next protocol.
 | 
				
			||||||
 | 
					    \param protocolToken     Fill this strucutre to setup the VProtocols structure.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::ParsePacket( NIPB::IPacket /*in*/ *packet, const NIPB::VProtocolToken /*in*/ *topProtocolToken, NIPB::IFormatter /*in*/ * /*errorWriter*/, NIPB::VTokenId /*out*/ *nextProcotolId, NIPB::VProtocolToken /*out*/ *protocolToken )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (packet                    == 0   ) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (nextProcotolId            == 0   ) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (protocolToken             == 0   ) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (topProtocolToken          == 0   ) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (topProtocolToken->tokenId != NIPB::kUDP) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NIPB::VResult     result       = NIPB::kError;
 | 
				
			||||||
 | 
					  const BYTE       *packetData   = 0;
 | 
				
			||||||
 | 
					  ULONG             packetLength = 0;
 | 
				
			||||||
 | 
					  NIPB::VProtocols *protocols    = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (   ((result = packet->GetDataSize( &packetLength       )) == NIPB::kOK)
 | 
				
			||||||
 | 
					      && ((result = packet->GetDataPtr ( (void**)&packetData )) == NIPB::kOK) 
 | 
				
			||||||
 | 
					      && ((result = packet->GetProtocols( &protocols         )) == NIPB::kOK) 
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    result = NIPB::kPacketParseError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (BI2BY(topProtocolToken->bitLength) >= kHeaderLength)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      protocolToken->tokenId         = mProtocolId;
 | 
				
			||||||
 | 
					      protocolToken->protocol        = this;
 | 
				
			||||||
 | 
					      protocolToken->packet          = packet;
 | 
				
			||||||
 | 
					      protocolToken->headerBitOffset = topProtocolToken->bitOffset;
 | 
				
			||||||
 | 
					      protocolToken->headerBitLength = kHeaderBitLength;
 | 
				
			||||||
 | 
					      protocolToken->bitOffset       = kHeaderBitLength + topProtocolToken->bitOffset;
 | 
				
			||||||
 | 
					      protocolToken->bitLength       = topProtocolToken->bitLength - kHeaderBitLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      protocols->contentId           = GetContentId( packetData, packetLength, *protocolToken );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      *nextProcotolId = 0;
 | 
				
			||||||
 | 
					       result = NIPB::kOK;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Return a token of a protocol.
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					  The function must fill the 'token' with the information of the request 'tokenId'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  \param protocolToken  Points the the VProtocolToken for the protocol.
 | 
				
			||||||
 | 
					  \param tokenId        The identifier of the requested token.
 | 
				
			||||||
 | 
					  \param token          Points to a VToken, which must be fille by this function.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::GetToken( const NIPB::VProtocolToken /*in*/ *protocolToken, NIPB::VTokenId /*in*/ tokenId, NIPB::VToken /*out*/ *token )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (token                  == 0)           return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (protocolToken          == 0)           return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (protocolToken->tokenId != mProtocolId) return NIPB::kTokenNotFound;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if (tokenId == mContentId)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return MakeHeaderToken( protocolToken, mContentId, 0, 32, token );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (tokenId == NIPB::kData)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return MakePayloadToken( protocolToken, NIPB::kData, 0, protocolToken->bitLength, token );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (tokenId == NIPB::kHeader)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return MakeHeaderToken( protocolToken, NIPB::kHeader, 0, protocolToken->bitLength, token );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return NIPB::kTokenNotFound;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Build a tree with information of the protocol.
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					    The function is used in CANoe/CANalyzer in the detail view of the trace window to build
 | 
				
			||||||
 | 
					    a tree with protocols and fields.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \param protocolToken  Protocol token of this protocol
 | 
				
			||||||
 | 
					    \param type           Inspection type
 | 
				
			||||||
 | 
					    \param inspector      IPacketInspectore to create the output.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocol::InspectProtocol ( const NIPB::VProtocolToken /*in*/ *protocolToken, NIPB::VInspectionType /*in*/ type, NIPB::IPacketInspector /*in*/ *inspector )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (protocolToken         == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (protocolToken->packet == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (inspector             == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NIPB::VResult result       = NIPB::kError;
 | 
				
			||||||
 | 
					  const BYTE   *packetData   = 0;
 | 
				
			||||||
 | 
					  ULONG         packetLength = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (   ((result = protocolToken->packet->GetDataSize( &packetLength       )) == NIPB::kOK)
 | 
				
			||||||
 | 
					      && ((result = protocolToken->packet->GetDataPtr ( (void**)&packetData )) == NIPB::kOK) )
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    switch(type)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      //
 | 
				
			||||||
 | 
					      // Protocol Info column
 | 
				
			||||||
 | 
					      //
 | 
				
			||||||
 | 
					    case NIPB::kInspectionInfoColumn:
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					      //
 | 
				
			||||||
 | 
					      // Detail View
 | 
				
			||||||
 | 
					      //
 | 
				
			||||||
 | 
					    case NIPB::kInspectionDetailTree:
 | 
				
			||||||
 | 
					      // UDP
 | 
				
			||||||
 | 
					      if (inspector->BeginToken( mProtocolId, 0, 0) == NIPB::kOK)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        NIPB::IFormatter *formatter = 0;
 | 
				
			||||||
 | 
					        if (inspector->SelectField( NIPB::kFieldLabel, &formatter ) == NIPB::kOK)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          formatter->FormatString( "vc-sig" );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Source port
 | 
				
			||||||
 | 
					        ULONG val = GetContentId( packetData, packetLength, *protocolToken );
 | 
				
			||||||
 | 
					        FormatUnsigned( inspector, "contentId", mContentId, val, 4 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inspector->EndToken();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Methods
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Returns the content ID
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					ULONG VCSignalProtocol::GetContentId( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ULONG offset = BI2BY(protocol.headerBitOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (offset+4 < packetLength)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return *((ULONG*)&packetData[offset]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Fill a VToken structure.
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					NIPB::VResult VCSignalProtocol::MakeHeaderToken( const NIPB::VProtocolToken /*in*/ *protocolToken, NIPB::VTokenId /*in*/ tokenId, ULONG /*in*/ offset, ULONG /*in*/ length, NIPB::VToken /*out*/ *token )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (token         == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (protocolToken == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  token->protocol  = protocolToken->protocol;
 | 
				
			||||||
 | 
					  token->packet    = protocolToken->packet;
 | 
				
			||||||
 | 
					  token->tokenId   = tokenId;
 | 
				
			||||||
 | 
					  token->bitOffset = offset + protocolToken->headerBitOffset;
 | 
				
			||||||
 | 
					  token->bitLength = length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Fill a VToken structure.
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					NIPB::VResult VCSignalProtocol::MakePayloadToken( const NIPB::VProtocolToken /*in*/ *protocolToken, NIPB::VTokenId /*in*/ tokenId, ULONG /*in*/ offset, ULONG /*in*/ length, NIPB::VToken /*out*/ *token )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (token         == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (protocolToken == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  token->protocol  = protocolToken->protocol;
 | 
				
			||||||
 | 
					  token->packet    = protocolToken->packet;
 | 
				
			||||||
 | 
					  token->tokenId   = tokenId;
 | 
				
			||||||
 | 
					  token->bitOffset = offset + protocolToken->bitOffset;
 | 
				
			||||||
 | 
					  token->bitLength = length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Format a unsigned token.
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					void VCSignalProtocol::FormatUnsigned( NIPB::IPacketInspector *inspector, LPCTSTR label, NIPB::VTokenId tokenId, ULONG value, ULONG valueLength )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if ((inspector) && (inspector->BeginToken( tokenId, 0, 0) == NIPB::kOK))
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    NIPB::IFormatter *formatter = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (inspector->SelectField( NIPB::kFieldLabel, &formatter ) == NIPB::kOK)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      formatter->FormatString( label );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (inspector->SelectField( NIPB::kFieldValue, &formatter ) == NIPB::kOK)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      formatter->FormatUnsigned( value, valueLength, 0 );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    inspector->EndToken();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Set the value of a unsigned token.
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					NIPB::VResult VCSignalProtocol::SetTokenUnsigned( NIPB::VProtocolToken &protocolToken, NIPB::VTokenId tokenId, ULONG valueLength, ULONG value )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (protocolToken.protocol == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NIPB::VResult result  = NIPB::kError;
 | 
				
			||||||
 | 
					  NIPB::VToken  token;
 | 
				
			||||||
 | 
					  if ((result = protocolToken.protocol->GetToken( &protocolToken, tokenId, &token)) == NIPB::kOK)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    NIPB::IEncoder *encoder = 0;
 | 
				
			||||||
 | 
					    if (((result = token.protocol->GetEncoder( tokenId, &encoder )) == NIPB::kOK) && (encoder))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      result = encoder->Encode( &token, 0, NIPB::kEncodingUnsigned, valueLength, &value );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Set the data of a data token.
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					NIPB::VResult VCSignalProtocol::SetTokenData( NIPB::VProtocolToken &protocolToken, NIPB::VTokenId tokenId, ULONG dataLength, const BYTE *data )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (protocolToken.protocol == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NIPB::VResult result  = NIPB::kError;
 | 
				
			||||||
 | 
					  NIPB::VToken  token;
 | 
				
			||||||
 | 
					  if ((result = protocolToken.protocol->GetToken( &protocolToken, tokenId, &token)) == NIPB::kOK)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    NIPB::IEncoder *encoder = 0;
 | 
				
			||||||
 | 
					    if (((result = token.protocol->GetEncoder( tokenId, &encoder )) == NIPB::kOK) && (encoder))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      result = encoder->Encode( &token, 0, NIPB::kEncodingData, dataLength, data );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										76
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/VCSignalProtocol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/VCSignalProtocol.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,76 @@
 | 
				
			||||||
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
 | 
					  VCSignalProtocol.h
 | 
				
			||||||
 | 
					  -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (c) Vector Informatik GmbH. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ------------------------------------------------------------------- */ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Signal protocol class
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					    This class implements the NIPB::IProtocol interface. It handles a
 | 
				
			||||||
 | 
					    proprietary signal protocol for the Vector Conecept Car Ethernet
 | 
				
			||||||
 | 
					    Network.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The protocol is located within a UDP protocol and uses the UDP
 | 
				
			||||||
 | 
					    ports 40001. The first 32bit of the UDP payload are the content ID.
 | 
				
			||||||
 | 
					    The 32-bit content ID represents the header of this Signal protocol.
 | 
				
			||||||
 | 
					    The payload of this protocol is interpreted by the DBC.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					class VCSignalProtocol : 
 | 
				
			||||||
 | 
					  public NIPB::IProtocol
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  static const ULONG kHeaderLength    = 4;
 | 
				
			||||||
 | 
					  static const ULONG kHeaderBitLength = 32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Construction
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  VCSignalProtocol();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // IProtocol
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  VDECL Initialize      ( NIPB::IProtocolManager /*in*/ *protocolManager, NIPB::INetworkModel /*in*/ *networkModel, NIPB::INetworkModelCreator /*in*/ *modelCreator );
 | 
				
			||||||
 | 
					  VDECL Deinitialize    ( NIPB::IProtocolManager /*in*/ *protocolManager, NIPB::INetworkModel /*in*/ *networkModel );
 | 
				
			||||||
 | 
					  VDECL GetDesignator   ( unsigned long /*in*/ bufferSize, char /*out**/ *buffer );
 | 
				
			||||||
 | 
					  VDECL GetIdentifier   ( NIPB::VTokenId /*out*/ *identifier );
 | 
				
			||||||
 | 
					  VDECL GetEncoder      ( NIPB::VTokenId /*in*/ tokenId, NIPB::IEncoder /*out*/ **encoder );
 | 
				
			||||||
 | 
					  VDECL InitProtocol    ( NIPB::IPacket /*in*/ *packet, NIPB::VTokenId /*in*/ protocolTypeId, const NIPB::VProtocolToken /*in*/ *topProtocolToken, NIPB::VProtocolToken /*out*/ *protocolToken);
 | 
				
			||||||
 | 
					  VDECL CompleteProtocol( NIPB::IPacket /*in*/ *packet, const NIPB::VProtocolToken /*in*/ *udp );
 | 
				
			||||||
 | 
					  VDECL ParsePacket     ( NIPB::IPacket /*in*/ *packet, const NIPB::VProtocolToken /*in*/ *topProtocolToken, NIPB::IFormatter /*in*/ *errorWriter, NIPB::VTokenId /*out*/ *nextProcotolId, NIPB::VProtocolToken /*out*/ *protocolToken );
 | 
				
			||||||
 | 
					  VDECL GetToken        ( const NIPB::VProtocolToken /*in*/ *protocolToken, NIPB::VTokenId /*in*/ tokenId, NIPB::VToken /*out*/ *token );
 | 
				
			||||||
 | 
					  VDECL InspectProtocol ( const NIPB::VProtocolToken /*in*/ *protocolToken, NIPB::VInspectionType /*in*/ type, NIPB::IPacketInspector /*in*/ *inspector );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Methods
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  ULONG GetContentId( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static NIPB::VResult MakeHeaderToken( const NIPB::VProtocolToken /*in*/ *protocolToken, NIPB::VTokenId /*in*/ tokenId, ULONG /*in*/ offset, ULONG /*in*/ length, NIPB::VToken /*out*/ *token );
 | 
				
			||||||
 | 
					  static NIPB::VResult MakePayloadToken( const NIPB::VProtocolToken /*in*/ *protocolToken, NIPB::VTokenId /*in*/ tokenId, ULONG /*in*/ offset, ULONG /*in*/ length, NIPB::VToken /*out*/ *token );
 | 
				
			||||||
 | 
					  static void          FormatUnsigned( NIPB::IPacketInspector *inspector, LPCTSTR label, NIPB::VTokenId tokenId, ULONG value, ULONG valueLength );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static NIPB::VResult SetTokenUnsigned( NIPB::VProtocolToken &protocolToken, NIPB::VTokenId tokenId, ULONG valueLength, ULONG value );
 | 
				
			||||||
 | 
					  static NIPB::VResult SetTokenData( NIPB::VProtocolToken &protocolToken, NIPB::VTokenId tokenId, ULONG dataLength, const BYTE *data );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Attributes
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  NIPB::VTokenId          mProtocolId;      //!< Token ID of this protocol
 | 
				
			||||||
 | 
					  NIPB::VTokenId          mContentId;       //!< Token ID of the 'contentID' field
 | 
				
			||||||
 | 
					  NIPB::IProtocolManager *mProtocolManager;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,86 @@
 | 
				
			||||||
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
 | 
					  VCSignalProtocolAddOn.h
 | 
				
			||||||
 | 
					  -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (c) Vector Informatik GmbH. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ------------------------------------------------------------------- */ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "StdAfx.h"
 | 
				
			||||||
 | 
					#include "VCSignalProtocolAddOn.h"
 | 
				
			||||||
 | 
					#include "VCSignalProtocol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Implementaiton of VCSignalProtocolAddOn
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VCSignalProtocolAddOn *VCSignalProtocolAddOn::sInstance = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//----------------------------------------------------------------------
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VCSignalProtocolAddOn::VCSignalProtocolAddOn()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  sInstance = this;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//----------------------------------------------------------------------
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VCSignalProtocolAddOn& VCSignalProtocolAddOn::Instance()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (sInstance == 0) throw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return *sInstance;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// IProtocolAddOn
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//----------------------------------------------------------------------
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocolAddOn::CreateProtocol( const char /*in*/ *protocolSymbol, NIPB::IProtocol /*out*/ **protocol )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (protocol       == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					  if (protocolSymbol == 0) return NIPB::kInvalidArg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *protocol = new VCSignalProtocol();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//----------------------------------------------------------------------
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					VDEF VCSignalProtocolAddOn::ReleaseProtocol( NIPB::IProtocol /*in*/ *protocol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  VCSignalProtocol *prot = dynamic_cast<VCSignalProtocol*>( protocol );
 | 
				
			||||||
 | 
					  delete prot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NIPB::kOK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Public Methods
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//----------------------------------------------------------------------
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					void VCSignalProtocolAddOn::Release()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  delete this;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
 | 
					  VCSignalProtocolAddOn.h
 | 
				
			||||||
 | 
					  -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (c) Vector Informatik GmbH. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ------------------------------------------------------------------- */ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Factory for the VCSignalProtocol
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					    This class is registered at the NIPB::IAddOnRegistrar registrar. It
 | 
				
			||||||
 | 
					    is responsible to create a instance of the VCSignalProtocol, when needed.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					class VCSignalProtocolAddOn : 
 | 
				
			||||||
 | 
					  public NIPB::IProtocolAddOn
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Construction
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  VCSignalProtocolAddOn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static VCSignalProtocolAddOn& Instance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // IProtocolAddOn
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  VDECL CreateProtocol( const char /*in*/ *protocolSymbol, NIPB::IProtocol /*out*/ **protocol );
 | 
				
			||||||
 | 
					  VDECL ReleaseProtocol( NIPB::IProtocol /*in*/ *protocol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Methods
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  void Release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Attributes
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  static VCSignalProtocolAddOn *sInstance;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,69 @@
 | 
				
			||||||
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
 | 
					  VCSignalProtocolDLL.cpp
 | 
				
			||||||
 | 
					  -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (c) 2009 Vector Informatik GmbH. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ------------------------------------------------------------------- */ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "StdAfx.h"
 | 
				
			||||||
 | 
					#include "VCSignalProtocolDLL.h"
 | 
				
			||||||
 | 
					#include "VCSignalProtocolAddOn.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Reply new ProtocolManager instance
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					    This function is called on loading of this DLL by the IPB Packet API.
 | 
				
			||||||
 | 
					    It must register the protocol of this DLL.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					STDAPI DllRegisterAddOn( NIPB::IAddOnRegistrar* registrar )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (registrar == NULL)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return E_INVALIDARG;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // register the signal protocol at the IPB Packet Lib. For the protocol
 | 
				
			||||||
 | 
					  // UDP with source port 40001 is used.
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  if (registrar->RegisterProtocol( "vc-sig", new VCSignalProtocolAddOn(), "udp", 40001, 0xFFFFFFFF ) != NIPB::kOK)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    VCSignalProtocolAddOn::Instance().Release();
 | 
				
			||||||
 | 
					    return NIPB::kError;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return S_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					//! Return interface version
 | 
				
			||||||
 | 
					/*! 
 | 
				
			||||||
 | 
					    This DLL must support a proper version of the IBP Packet API.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					STDAPI DllGetApiVersion( unsigned long /*out*/*major, unsigned long /*out*/*minor, unsigned long /*out*/*structVersion )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (major)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *major = IPB_PACKET_LIB_INTERFACE_VERSION_MAJOR;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (minor)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *minor = IPB_PACKET_LIB_INTERFACE_VERSION_MINOR;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (structVersion)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *structVersion = IPB_PACKET_LIB_STRUCT_VERSION;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return S_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					; VCSignalProtocolDLL.def : Declares the module parameters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LIBRARY      "VCSignalProtocolDLL.DLL"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORTS
 | 
				
			||||||
 | 
					  DllGetApiVersion PRIVATE
 | 
				
			||||||
 | 
					  DllRegisterAddOn PRIVATE
 | 
				
			||||||
							
								
								
									
										10
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/VCSignalProtocolDLL.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Modbus-DLL/include/VCSignalProtocolDLL/VCSignalProtocolDLL.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
 | 
					  VCSignalProtocolDLL.h
 | 
				
			||||||
 | 
					  -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (c) 2009 Vector Informatik GmbH. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ------------------------------------------------------------------- */ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Microsoft Visual Studio Solution File, Format Version 9.00
 | 
				
			||||||
 | 
					# Visual Studio 2005
 | 
				
			||||||
 | 
					Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCSignalProtocolDLL", "VCSignalProtocolDLL.vcproj", "{0015F4D0-0830-408B-97FB-D9748FD43623}"
 | 
				
			||||||
 | 
					EndProject
 | 
				
			||||||
 | 
					Global
 | 
				
			||||||
 | 
						GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
				
			||||||
 | 
							Debug|Win32 = Debug|Win32
 | 
				
			||||||
 | 
							Release|Win32 = Release|Win32
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
				
			||||||
 | 
							{0015F4D0-0830-408B-97FB-D9748FD43623}.Debug|Win32.ActiveCfg = Debug|Win32
 | 
				
			||||||
 | 
							{0015F4D0-0830-408B-97FB-D9748FD43623}.Debug|Win32.Build.0 = Debug|Win32
 | 
				
			||||||
 | 
							{0015F4D0-0830-408B-97FB-D9748FD43623}.Release|Win32.ActiveCfg = Release|Win32
 | 
				
			||||||
 | 
							{0015F4D0-0830-408B-97FB-D9748FD43623}.Release|Win32.Build.0 = Release|Win32
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(SolutionProperties) = preSolution
 | 
				
			||||||
 | 
							HideSolutionNode = FALSE
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
					EndGlobal
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,261 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="Windows-1252"?>
 | 
				
			||||||
 | 
					<VisualStudioProject
 | 
				
			||||||
 | 
						ProjectType="Visual C++"
 | 
				
			||||||
 | 
						Version="8,00"
 | 
				
			||||||
 | 
						Name="VCSignalProtocolDLL"
 | 
				
			||||||
 | 
						ProjectGUID="{0015F4D0-0830-408B-97FB-D9748FD43623}"
 | 
				
			||||||
 | 
						RootNamespace="VCSignalProtocolDLL"
 | 
				
			||||||
 | 
						Keyword="ManagedCProj"
 | 
				
			||||||
 | 
						>
 | 
				
			||||||
 | 
						<Platforms>
 | 
				
			||||||
 | 
							<Platform
 | 
				
			||||||
 | 
								Name="Win32"
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</Platforms>
 | 
				
			||||||
 | 
						<ToolFiles>
 | 
				
			||||||
 | 
						</ToolFiles>
 | 
				
			||||||
 | 
						<Configurations>
 | 
				
			||||||
 | 
							<Configuration
 | 
				
			||||||
 | 
								Name="Debug|Win32"
 | 
				
			||||||
 | 
								OutputDirectory="debug"
 | 
				
			||||||
 | 
								IntermediateDirectory="debug"
 | 
				
			||||||
 | 
								ConfigurationType="2"
 | 
				
			||||||
 | 
								CharacterSet="2"
 | 
				
			||||||
 | 
								ManagedExtensions="0"
 | 
				
			||||||
 | 
								>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCPreBuildEventTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCCustomBuildTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCXMLDataGeneratorTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCWebServiceProxyGeneratorTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCMIDLTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCCLCompilerTool"
 | 
				
			||||||
 | 
									AdditionalOptions="/analyze"
 | 
				
			||||||
 | 
									Optimization="0"
 | 
				
			||||||
 | 
									AdditionalIncludeDirectories=".,source,common"
 | 
				
			||||||
 | 
									PreprocessorDefinitions="WIN32;_DEBUG"
 | 
				
			||||||
 | 
									RuntimeLibrary="3"
 | 
				
			||||||
 | 
									UsePrecompiledHeader="2"
 | 
				
			||||||
 | 
									WarningLevel="4"
 | 
				
			||||||
 | 
									DebugInformationFormat="3"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCManagedResourceCompilerTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCResourceCompilerTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCPreLinkEventTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCLinkerTool"
 | 
				
			||||||
 | 
									AdditionalDependencies="$(NoInherit)"
 | 
				
			||||||
 | 
									OutputFile="..\VCSignalProtocol.dll"
 | 
				
			||||||
 | 
									LinkIncremental="2"
 | 
				
			||||||
 | 
									ModuleDefinitionFile="VCSignalProtocolDLL.def"
 | 
				
			||||||
 | 
									GenerateDebugInformation="true"
 | 
				
			||||||
 | 
									AssemblyDebug="1"
 | 
				
			||||||
 | 
									TargetMachine="1"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCALinkTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCManifestTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCXDCMakeTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCBscMakeTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCFxCopTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCAppVerifierTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCWebDeploymentTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCPostBuildEventTool"
 | 
				
			||||||
 | 
									CommandLine=""
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
							</Configuration>
 | 
				
			||||||
 | 
							<Configuration
 | 
				
			||||||
 | 
								Name="Release|Win32"
 | 
				
			||||||
 | 
								OutputDirectory="release"
 | 
				
			||||||
 | 
								IntermediateDirectory="release"
 | 
				
			||||||
 | 
								ConfigurationType="2"
 | 
				
			||||||
 | 
								CharacterSet="2"
 | 
				
			||||||
 | 
								ManagedExtensions="0"
 | 
				
			||||||
 | 
								WholeProgramOptimization="1"
 | 
				
			||||||
 | 
								>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCPreBuildEventTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCCustomBuildTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCXMLDataGeneratorTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCWebServiceProxyGeneratorTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCMIDLTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCCLCompilerTool"
 | 
				
			||||||
 | 
									AdditionalOptions="/analyze"
 | 
				
			||||||
 | 
									AdditionalIncludeDirectories=".,source,common"
 | 
				
			||||||
 | 
									PreprocessorDefinitions="WIN32;NDEBUG"
 | 
				
			||||||
 | 
									RuntimeLibrary="2"
 | 
				
			||||||
 | 
									UsePrecompiledHeader="2"
 | 
				
			||||||
 | 
									WarningLevel="4"
 | 
				
			||||||
 | 
									DebugInformationFormat="3"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCManagedResourceCompilerTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCResourceCompilerTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCPreLinkEventTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCLinkerTool"
 | 
				
			||||||
 | 
									AdditionalDependencies="$(NoInherit)"
 | 
				
			||||||
 | 
									OutputFile="..\VCSignalProtocol.dll"
 | 
				
			||||||
 | 
									LinkIncremental="1"
 | 
				
			||||||
 | 
									ModuleDefinitionFile="VCSignalProtocolDLL.def"
 | 
				
			||||||
 | 
									GenerateDebugInformation="true"
 | 
				
			||||||
 | 
									TargetMachine="1"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCALinkTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCManifestTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCXDCMakeTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCBscMakeTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCFxCopTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCAppVerifierTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCWebDeploymentTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
								<Tool
 | 
				
			||||||
 | 
									Name="VCPostBuildEventTool"
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
							</Configuration>
 | 
				
			||||||
 | 
						</Configurations>
 | 
				
			||||||
 | 
						<References>
 | 
				
			||||||
 | 
							<AssemblyReference
 | 
				
			||||||
 | 
								RelativePath="System.dll"
 | 
				
			||||||
 | 
								AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
							<AssemblyReference
 | 
				
			||||||
 | 
								RelativePath="System.Data.dll"
 | 
				
			||||||
 | 
								AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
							<AssemblyReference
 | 
				
			||||||
 | 
								RelativePath="System.XML.dll"
 | 
				
			||||||
 | 
								AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
 | 
				
			||||||
 | 
							/>
 | 
				
			||||||
 | 
						</References>
 | 
				
			||||||
 | 
						<Files>
 | 
				
			||||||
 | 
							<Filter
 | 
				
			||||||
 | 
								Name="DLL"
 | 
				
			||||||
 | 
								>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\Stdafx.cpp"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
									<FileConfiguration
 | 
				
			||||||
 | 
										Name="Debug|Win32"
 | 
				
			||||||
 | 
										>
 | 
				
			||||||
 | 
										<Tool
 | 
				
			||||||
 | 
											Name="VCCLCompilerTool"
 | 
				
			||||||
 | 
											UsePrecompiledHeader="1"
 | 
				
			||||||
 | 
										/>
 | 
				
			||||||
 | 
									</FileConfiguration>
 | 
				
			||||||
 | 
									<FileConfiguration
 | 
				
			||||||
 | 
										Name="Release|Win32"
 | 
				
			||||||
 | 
										>
 | 
				
			||||||
 | 
										<Tool
 | 
				
			||||||
 | 
											Name="VCCLCompilerTool"
 | 
				
			||||||
 | 
											UsePrecompiledHeader="1"
 | 
				
			||||||
 | 
										/>
 | 
				
			||||||
 | 
									</FileConfiguration>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\Stdafx.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\VCSignalProtocolDLL.cpp"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\VCSignalProtocolDLL.def"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\VCSignalProtocolDLL.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
							</Filter>
 | 
				
			||||||
 | 
							<Filter
 | 
				
			||||||
 | 
								Name="Protocol"
 | 
				
			||||||
 | 
								>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\VCSignalProtocol.cpp"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\VCSignalProtocol.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\VCSignalProtocolAddOn.cpp"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\VCSignalProtocolAddOn.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
							</Filter>
 | 
				
			||||||
 | 
							<Filter
 | 
				
			||||||
 | 
								Name="Include"
 | 
				
			||||||
 | 
								>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath=".\Include\IPBPacketAPI.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
							</Filter>
 | 
				
			||||||
 | 
						</Files>
 | 
				
			||||||
 | 
						<Globals>
 | 
				
			||||||
 | 
						</Globals>
 | 
				
			||||||
 | 
					</VisualStudioProject>
 | 
				
			||||||
		Loading…
	
		Reference in a new issue