Initial EtherNet/IP support
This commit is contained in:
parent
0d0e2f0715
commit
a95ce61356
|
@ -0,0 +1,189 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2019 Thiago Alves
|
||||
// This file is part of the OpenPLC Software Stack.
|
||||
//
|
||||
// OpenPLC is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// OpenPLC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with OpenPLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
//------
|
||||
//
|
||||
// This file has all the EtherNet/IP functions supported by the OpenPLC. If any
|
||||
// other function is to be added to the project, it must be added here
|
||||
// Thiago Alves, Apr 2019
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ladder.h"
|
||||
|
||||
#define ENIP_MIN_LENGTH 28
|
||||
|
||||
struct enip_header
|
||||
{
|
||||
unsigned char *command;//[2];
|
||||
unsigned char *length;//[2];
|
||||
unsigned char *session_handle;//[4];
|
||||
unsigned char *status;//[4];
|
||||
unsigned char *sender_context;//[8];
|
||||
unsigned char *options;//[4];
|
||||
unsigned char *data;
|
||||
};
|
||||
|
||||
struct enip_data
|
||||
{
|
||||
unsigned char *interface_handle;
|
||||
unsigned char *timeout;
|
||||
unsigned char *item_count;
|
||||
|
||||
unsigned char *item1_id;
|
||||
unsigned char *item1_length;
|
||||
unsigned char *item1_data;
|
||||
|
||||
unsigned char *item2_id;
|
||||
unsigned char *item2_length;
|
||||
unsigned char *item2_data;
|
||||
};
|
||||
|
||||
|
||||
thread_local unsigned char enip_session[4];
|
||||
|
||||
int respondToError(unsigned char *buffer, int buffer_size, int error_code)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int parseEnipHeader(unsigned char *buffer, int buffer_size, struct enip_header *header)
|
||||
{
|
||||
//verify if message is big enough
|
||||
if (buffer_size < ENIP_MIN_LENGTH)
|
||||
return -1;
|
||||
|
||||
header->command = &buffer[0];
|
||||
header->length = &buffer[2];
|
||||
header->session_handle = &buffer[4];
|
||||
header->status = &buffer[8];
|
||||
header->sender_context = &buffer[12];
|
||||
header->options = &buffer[20];
|
||||
/*
|
||||
memcpy(header->command, &buffer[0], 2);
|
||||
memcpy(header->length, &buffer[2], 2);
|
||||
memcpy(header->session_handle, &buffer[4], 4);
|
||||
memcpy(header->status, &buffer[8], 4);
|
||||
memcpy(header->sender_context, &buffer[12], 8);
|
||||
memcpy(header->options, &buffer[20], 4);
|
||||
*/
|
||||
header->data = &buffer[24];
|
||||
|
||||
uint16_t enip_data_size = ((uint16_t)header->length[1] << 8) | (uint16_t)header->length[0];
|
||||
|
||||
//verify if buffer_size matches enip_data_size
|
||||
if (buffer_size - 24 < enip_data_size)
|
||||
return -1;
|
||||
|
||||
return enip_data_size;
|
||||
}
|
||||
|
||||
int parseEnipData(struct enip_header *header, struct enip_data *data)
|
||||
{
|
||||
data->interface_handle = &header->data[0];
|
||||
data->timeout = &header->data[4];
|
||||
data->item_count = &header->data[6];
|
||||
data->item1_id = &header->data[8];
|
||||
data->item1_length = &header->data[10];
|
||||
data->item1_data = &header->data[12];
|
||||
|
||||
uint16_t item_length = ((uint16_t)data->item1_length[1] << 8) | (uint16_t)data->item1_length[0];
|
||||
|
||||
data->item2_id = &header->data[12+item_length];
|
||||
data->item2_length = &header->data[14+item_length];
|
||||
data->item2_data = &header->data[16+item_length];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int registerEnipSession(struct enip_header *header)
|
||||
{
|
||||
unsigned char r[4];
|
||||
srand((unsigned)time(NULL));
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
r[i] = rand();
|
||||
|
||||
memcpy(header->session_handle, &r[0], 4);
|
||||
memcpy(&enip_session[0], &r[0], 4);
|
||||
|
||||
return ENIP_MIN_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function must parse and process the client request and write back the
|
||||
// response for it. The return value is the size of the response message in
|
||||
// bytes.
|
||||
//-----------------------------------------------------------------------------
|
||||
int processEnipMessage(unsigned char *buffer, int buffer_size)
|
||||
{
|
||||
int error_code;
|
||||
struct enip_header header;
|
||||
|
||||
error_code = parseEnipHeader(buffer, buffer_size, &header);
|
||||
if (error_code < 0)
|
||||
return respondToError(buffer, buffer_size, error_code);
|
||||
|
||||
if (header.command[0] == 0x65)
|
||||
return registerEnipSession(&header);
|
||||
|
||||
else if (header.command[0] == 0x6f)
|
||||
{
|
||||
struct enip_data data;
|
||||
error_code = parseEnipData(&header, &data);
|
||||
if (error_code < 0)
|
||||
return respondToError(buffer, buffer_size, error_code);
|
||||
|
||||
if (data.item2_id[0] == 0x91)
|
||||
{
|
||||
//PCCC type 1 - Unknown
|
||||
}
|
||||
else if (data.item2_id[0] == 0xb2)
|
||||
{
|
||||
//PCCC type 2 - Unconnected Data Item
|
||||
}
|
||||
else if (data.item1_id[0] == 0xa1 && data.item2_id[0] == 0xb1)
|
||||
{
|
||||
//PCCC type 3 - Connected Data Item
|
||||
}
|
||||
else
|
||||
{
|
||||
//Unknown type ID. Respond with error_code
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
unsigned char log_msg[1000];
|
||||
unsigned char *p = log_msg;
|
||||
p += sprintf(p, "Unknown EtherNet/IP request: ");
|
||||
for (int i = 0; i < buffer_size; i++)
|
||||
{
|
||||
p += sprintf(p, "%02x ", (unsigned char)buffer[i]);
|
||||
}
|
||||
p += sprintf(p, "\n");
|
||||
printf(log_msg);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -42,6 +42,8 @@ bool run_modbus = 0;
|
|||
int modbus_port = 502;
|
||||
bool run_dnp3 = 0;
|
||||
int dnp3_port = 20000;
|
||||
bool run_enip = 0;
|
||||
int enip_port = 44818;
|
||||
unsigned char server_command[1024];
|
||||
int command_index = 0;
|
||||
bool processing_command = 0;
|
||||
|
@ -51,13 +53,14 @@ time_t end_time;
|
|||
//Global Threads
|
||||
pthread_t modbus_thread;
|
||||
pthread_t dnp3_thread;
|
||||
pthread_t enip_thread;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Start the Modbus Thread
|
||||
//-----------------------------------------------------------------------------
|
||||
void *modbusThread(void *arg)
|
||||
{
|
||||
startServer(modbus_port);
|
||||
startServer(modbus_port, MODBUS_PROTOCOL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -68,6 +71,14 @@ void *dnp3Thread(void *arg)
|
|||
dnp3StartServer(dnp3_port);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Start the Enip Thread
|
||||
//-----------------------------------------------------------------------------
|
||||
void *enipThread(void *arg)
|
||||
{
|
||||
startServer(enip_port, ENIP_PROTOCOL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read the argument from a command function
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -216,9 +227,9 @@ void processCommand(unsigned char *buffer, int client_fd)
|
|||
else if (strncmp(buffer, "start_modbus(", 13) == 0)
|
||||
{
|
||||
processing_command = true;
|
||||
sprintf(log_msg, "Issued start_modbus() command to start on port: %d\n", readCommandArgument(buffer));
|
||||
log(log_msg);
|
||||
modbus_port = readCommandArgument(buffer);
|
||||
sprintf(log_msg, "Issued start_modbus() command to start on port: %d\n", modbus_port);
|
||||
log(log_msg);
|
||||
if (run_modbus)
|
||||
{
|
||||
sprintf(log_msg, "Modbus server already active. Restarting on port: %d\n", modbus_port);
|
||||
|
@ -251,9 +262,9 @@ void processCommand(unsigned char *buffer, int client_fd)
|
|||
else if (strncmp(buffer, "start_dnp3(", 11) == 0)
|
||||
{
|
||||
processing_command = true;
|
||||
sprintf(log_msg, "Issued start_dnp3() command to start on port: %d\n", readCommandArgument(buffer));
|
||||
log(log_msg);
|
||||
dnp3_port = readCommandArgument(buffer);
|
||||
sprintf(log_msg, "Issued start_dnp3() command to start on port: %d\n", dnp3_port);
|
||||
log(log_msg);
|
||||
if (run_dnp3)
|
||||
{
|
||||
sprintf(log_msg, "DNP3 server already active. Restarting on port: %d\n", dnp3_port);
|
||||
|
@ -283,6 +294,41 @@ void processCommand(unsigned char *buffer, int client_fd)
|
|||
}
|
||||
processing_command = false;
|
||||
}
|
||||
else if (strncmp(buffer, "start_enip(", 11) == 0)
|
||||
{
|
||||
processing_command = true;
|
||||
enip_port = readCommandArgument(buffer);
|
||||
sprintf(log_msg, "Issued start_enip() command to start on port: %d\n", enip_port);
|
||||
log(log_msg);
|
||||
if (run_enip)
|
||||
{
|
||||
sprintf(log_msg, "EtherNet/IP server already active. Restarting on port: %d\n", enip_port);
|
||||
log(log_msg);
|
||||
//Stop Enip server
|
||||
run_enip = 0;
|
||||
pthread_join(enip_thread, NULL);
|
||||
sprintf(log_msg, "EtherNet/IP server was stopped\n");
|
||||
log(log_msg);
|
||||
}
|
||||
//Start Enip server
|
||||
run_enip = 1;
|
||||
pthread_create(&enip_thread, NULL, enipThread, NULL);
|
||||
processing_command = false;
|
||||
}
|
||||
else if (strncmp(buffer, "stop_enip()", 11) == 0)
|
||||
{
|
||||
processing_command = true;
|
||||
sprintf(log_msg, "Issued stop_enip() command\n");
|
||||
log(log_msg);
|
||||
if (run_enip)
|
||||
{
|
||||
run_enip = 0;
|
||||
pthread_join(enip_thread, NULL);
|
||||
sprintf(log_msg, "EtherNet/IP server was stopped\n");
|
||||
log(log_msg);
|
||||
}
|
||||
processing_command = false;
|
||||
}
|
||||
else if (strncmp(buffer, "runtime_logs()", 14) == 0)
|
||||
{
|
||||
processing_command = true;
|
||||
|
@ -411,4 +457,4 @@ void startInteractiveServer(int port)
|
|||
closeSocket(client_fd);
|
||||
sprintf(log_msg, "Terminating interactive server thread\r\n");
|
||||
log(log_msg);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,10 @@
|
|||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MODBUS_PROTOCOL 0
|
||||
#define DNP3_PROTOCOL 1
|
||||
#define ENIP_PROTOCOL 2
|
||||
|
||||
//Internal buffers for I/O and memory. These buffers are defined in the
|
||||
//auto-generated glueVars.cpp file
|
||||
#define BUFFER_SIZE 1024
|
||||
|
@ -117,7 +121,7 @@ extern int log_index;
|
|||
void handleSpecialFunctions();
|
||||
|
||||
//server.cpp
|
||||
void startServer(int port);
|
||||
void startServer(int port, int protocol_type);
|
||||
int getSO_ERROR(int fd);
|
||||
void closeSocket(int fd);
|
||||
bool SetSocketBlockingEnabled(int fd, bool blocking);
|
||||
|
@ -126,6 +130,7 @@ bool SetSocketBlockingEnabled(int fd, bool blocking);
|
|||
void startInteractiveServer(int port);
|
||||
extern bool run_modbus;
|
||||
extern bool run_dnp3;
|
||||
extern bool run_enip;
|
||||
extern time_t start_time;
|
||||
extern time_t end_time;
|
||||
|
||||
|
@ -133,6 +138,9 @@ extern time_t end_time;
|
|||
int processModbusMessage(unsigned char *buffer, int bufferSize);
|
||||
void mapUnusedIO();
|
||||
|
||||
//enip.cpp
|
||||
int processEnipMessage(unsigned char *buffer, int buffer_size);
|
||||
|
||||
//modbus_master.cpp
|
||||
void initializeMB();
|
||||
void *querySlaveDevices(void *arg);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#define MAX_INPUT 16
|
||||
#define MAX_OUTPUT 16
|
||||
#define MAX_MODBUS 100
|
||||
#define NET_BUFFER_SIZE 10000
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -93,7 +94,7 @@ int createSocket(int port)
|
|||
socket_fd = socket(AF_INET,SOCK_STREAM,0);
|
||||
if (socket_fd<0)
|
||||
{
|
||||
sprintf(log_msg, "Modbus Server: error creating stream socket => %s\n", strerror(errno));
|
||||
sprintf(log_msg, "Server: error creating stream socket => %s\n", strerror(errno));
|
||||
log(log_msg);
|
||||
return -1;
|
||||
}
|
||||
|
@ -114,14 +115,14 @@ int createSocket(int port)
|
|||
//Bind socket
|
||||
if (bind(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
|
||||
{
|
||||
sprintf(log_msg, "Modbus Server: error binding socket => %s\n", strerror(errno));
|
||||
sprintf(log_msg, "Server: error binding socket => %s\n", strerror(errno));
|
||||
log(log_msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// we accept max 5 pending connections
|
||||
listen(socket_fd,5);
|
||||
sprintf(log_msg, "Modbus Server: Listening on port %d\n", port);
|
||||
sprintf(log_msg, "Server: Listening on port %d\n", port);
|
||||
log(log_msg);
|
||||
|
||||
return socket_fd;
|
||||
|
@ -131,18 +132,24 @@ int createSocket(int port)
|
|||
// Blocking call. Wait here for the client to connect. Returns the file
|
||||
// descriptor to communicate with the client.
|
||||
//-----------------------------------------------------------------------------
|
||||
int waitForClient(int socket_fd)
|
||||
int waitForClient(int socket_fd, int protocol_type)
|
||||
{
|
||||
unsigned char log_msg[1000];
|
||||
int client_fd;
|
||||
struct sockaddr_in client_addr;
|
||||
bool *run_server;
|
||||
socklen_t client_len;
|
||||
|
||||
sprintf(log_msg, "Modbus Server: waiting for new client...\n");
|
||||
if (protocol_type == MODBUS_PROTOCOL)
|
||||
run_server = &run_modbus;
|
||||
else if (protocol_type == ENIP_PROTOCOL)
|
||||
run_server = &run_enip;
|
||||
|
||||
sprintf(log_msg, "Server: waiting for new client...\n");
|
||||
log(log_msg);
|
||||
|
||||
client_len = sizeof(client_addr);
|
||||
while (run_modbus)
|
||||
while (*run_server)
|
||||
{
|
||||
client_fd = accept(socket_fd, (struct sockaddr *)&client_addr, &client_len); //non-blocking call
|
||||
if (client_fd > 0)
|
||||
|
@ -163,8 +170,8 @@ int waitForClient(int socket_fd)
|
|||
//-----------------------------------------------------------------------------
|
||||
int listenToClient(int client_fd, unsigned char *buffer)
|
||||
{
|
||||
bzero(buffer, 1024);
|
||||
int n = read(client_fd, buffer, 1024);
|
||||
bzero(buffer, NET_BUFFER_SIZE);
|
||||
int n = read(client_fd, buffer, NET_BUFFER_SIZE);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -173,8 +180,16 @@ int listenToClient(int client_fd, unsigned char *buffer)
|
|||
//-----------------------------------------------------------------------------
|
||||
void processMessage(unsigned char *buffer, int bufferSize, int client_fd)
|
||||
{
|
||||
int messageSize = processModbusMessage(buffer, bufferSize);
|
||||
write(client_fd, buffer, messageSize);
|
||||
if (protocol_type == MODBUS_PROTOCOL)
|
||||
{
|
||||
int messageSize = processModbusMessage(buffer, bufferSize);
|
||||
write(client_fd, buffer, messageSize);
|
||||
}
|
||||
else if (protocol_type == ENIP_PROTOCOL)
|
||||
{
|
||||
int messageSize = processEnipMessage(buffer, bufferSize);
|
||||
write(client_fd, buffer, messageSize);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -183,20 +198,28 @@ void processMessage(unsigned char *buffer, int bufferSize, int client_fd)
|
|||
void *handleConnections(void *arguments)
|
||||
{
|
||||
unsigned char log_msg[1000];
|
||||
int client_fd = *(int *)arguments;
|
||||
unsigned char buffer[1024];
|
||||
int *args = (int *)arguments;
|
||||
int client_fd = args[0];
|
||||
int protocol_type = args[1];
|
||||
unsigned char buffer[NET_BUFFER_SIZE];
|
||||
int messageSize;
|
||||
bool *run_server;
|
||||
|
||||
if (protocol_type == MODBUS_PROTOCOL)
|
||||
run_server = &run_modbus;
|
||||
else if (protocol_type == ENIP_PROTOCOL)
|
||||
run_server = &run_enip;
|
||||
|
||||
sprintf(log_msg, "Modbus Server: Thread created for client ID: %d\n", client_fd);
|
||||
sprintf(log_msg, "Server: Thread created for client ID: %d\n", client_fd);
|
||||
log(log_msg);
|
||||
|
||||
while(run_modbus)
|
||||
while(*run_server)
|
||||
{
|
||||
//unsigned char buffer[1024];
|
||||
//unsigned char buffer[NET_BUFFER_SIZE];
|
||||
//int messageSize;
|
||||
|
||||
messageSize = listenToClient(client_fd, buffer);
|
||||
if (messageSize <= 0 || messageSize > 1024)
|
||||
if (messageSize <= 0 || messageSize > NET_BUFFER_SIZE)
|
||||
{
|
||||
// something has gone wrong or the client has closed connection
|
||||
if (messageSize == 0)
|
||||
|
@ -212,7 +235,7 @@ void *handleConnections(void *arguments)
|
|||
break;
|
||||
}
|
||||
|
||||
processMessage(buffer, messageSize, client_fd);
|
||||
processMessage(buffer, messageSize, client_fd, protocol_type);
|
||||
}
|
||||
//printf("Debug: Closing client socket and calling pthread_exit in server.cpp\n");
|
||||
close(client_fd);
|
||||
|
@ -230,13 +253,21 @@ void startServer(int port)
|
|||
{
|
||||
unsigned char log_msg[1000];
|
||||
int socket_fd, client_fd;
|
||||
|
||||
socket_fd = createSocket(port);
|
||||
mapUnusedIO();
|
||||
bool *run_server;
|
||||
|
||||
while(run_modbus)
|
||||
socket_fd = createSocket(port);
|
||||
|
||||
if (protocol_type == MODBUS_PROTOCOL)
|
||||
{
|
||||
client_fd = waitForClient(socket_fd); //block until a client connects
|
||||
mapUnusedIO();
|
||||
run_server = &run_modbus;
|
||||
}
|
||||
else if (protocol_type == ENIP_PROTOCOL)
|
||||
run_server = &run_enip;
|
||||
|
||||
while(*run_server)
|
||||
{
|
||||
client_fd = waitForClient(socket_fd, protocol_type); //block until a client connects
|
||||
if (client_fd < 0)
|
||||
{
|
||||
sprintf(log_msg, "Modbus Server: Error accepting client!\n");
|
||||
|
@ -245,13 +276,14 @@ void startServer(int port)
|
|||
|
||||
else
|
||||
{
|
||||
int arguments[1];
|
||||
int arguments[2];
|
||||
pthread_t thread;
|
||||
int ret = -1;
|
||||
sprintf(log_msg, "Modbus Server: Client accepted! Creating thread for the new client ID: %d...\n", client_fd);
|
||||
log(log_msg);
|
||||
arguments[0] = client_fd;
|
||||
ret = pthread_create(&thread, NULL, handleConnections, arguments);
|
||||
arguments[1] = protocol_type;
|
||||
ret = pthread_create(&thread, NULL, handleConnections, (void*)arguments);
|
||||
if (ret==0)
|
||||
{
|
||||
pthread_detach(thread);
|
||||
|
@ -262,4 +294,4 @@ void startServer(int port)
|
|||
close(client_fd);
|
||||
sprintf(log_msg, "Terminating Modbus thread\r\n");
|
||||
log(log_msg);
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -178,6 +178,28 @@ class runtime:
|
|||
s.close()
|
||||
except:
|
||||
print("Error connecting to OpenPLC runtime")
|
||||
|
||||
def start_enip(self, port_num):
|
||||
if (self.status() == "Running"):
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect(('localhost', 43628))
|
||||
s.send('start_enip(' + str(port_num) + ')\n')
|
||||
data = s.recv(1000)
|
||||
s.close()
|
||||
except:
|
||||
print("Error connecting to OpenPLC runtime")
|
||||
|
||||
def stop_enip(self):
|
||||
if (self.status() == "Running"):
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect(('localhost', 43628))
|
||||
s.send('stop_enip()\n')
|
||||
data = s.recv(1000)
|
||||
s.close()
|
||||
except:
|
||||
print("Error connecting to OpenPLC runtime")
|
||||
|
||||
def logs(self):
|
||||
if (self.status() == "Running"):
|
||||
|
|
|
@ -884,6 +884,8 @@ settings_tail = """
|
|||
var modbus_text = document.getElementById('modbus_server_port');
|
||||
var dnp3_checkbox = document.getElementById('dnp3_server');
|
||||
var dnp3_text = document.getElementById('dnp3_server_port');
|
||||
var enip_checkbox = document.getElementById('enip_server');
|
||||
var enip_text = document.getElementById('enip_server_port');
|
||||
var auto_run_checkbox = document.getElementById('auto_run');
|
||||
var auto_run_text = document.getElementById('auto_run_text');
|
||||
|
||||
|
@ -905,6 +907,15 @@ settings_tail = """
|
|||
dnp3_text.disabled = true;
|
||||
}
|
||||
|
||||
if (enip_checkbox.checked == true)
|
||||
{
|
||||
enip_text.disabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
enip_text.disabled = true;
|
||||
}
|
||||
|
||||
if (auto_run_checkbox.checked == true)
|
||||
{
|
||||
auto_run_text.value = 'true';
|
||||
|
@ -925,6 +936,11 @@ settings_tail = """
|
|||
setupCheckboxes();
|
||||
}
|
||||
|
||||
document.getElementById('enip_server').onchange = function()
|
||||
{
|
||||
setupCheckboxes();
|
||||
}
|
||||
|
||||
document.getElementById('auto_run').onchange = function()
|
||||
{
|
||||
setupCheckboxes();
|
||||
|
@ -936,6 +952,8 @@ settings_tail = """
|
|||
var modbus_port = document.forms["uploadForm"]["modbus_server_port"].value;
|
||||
var dnp3_checkbox = document.forms["uploadForm"]["dnp3_server"].checked;
|
||||
var dnp3_port = document.forms["uploadForm"]["dnp3_server_port"].value;
|
||||
var enip_checkbox = document.forms["uploadForm"]["enip_server"].checked;
|
||||
var enip_port = document.forms["uploadForm"]["enip_server_port"].value;
|
||||
|
||||
if (modbus_checkbox && (Number(modbus_port) < 0 || Number(modbus_port) > 65535))
|
||||
{
|
||||
|
@ -947,6 +965,11 @@ settings_tail = """
|
|||
alert("Please select a port number between 0 and 65535");
|
||||
return false;
|
||||
}
|
||||
if (enip_checkbox && (Number(enip_port) < 0 || Number(enip_port) > 65535))
|
||||
{
|
||||
alert("Please select a port number between 0 and 65535");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -53,6 +53,13 @@ def configure_runtime():
|
|||
else:
|
||||
print("Disabling DNP3")
|
||||
openplc_runtime.stop_dnp3()
|
||||
elif (row[0] == "Enip_port"):
|
||||
if (row[1] != "disabled"):
|
||||
print("Enabling EtherNet/IP on port " + str(int(row[1])))
|
||||
openplc_runtime.start_enip(int(row[1]))
|
||||
else:
|
||||
print("Disabling EtherNet/IP")
|
||||
openplc_runtime.stop_enip()
|
||||
except Error as e:
|
||||
print("error connecting to the database" + str(e))
|
||||
else:
|
||||
|
@ -1684,6 +1691,8 @@ def settings():
|
|||
modbus_port = str(row[1])
|
||||
elif (row[0] == "Dnp3_port"):
|
||||
dnp3_port = str(row[1])
|
||||
elif (row[0] == "Enip_port"):
|
||||
enip_port = str(row[1])
|
||||
elif (row[0] == "Start_run_mode"):
|
||||
start_run = str(row[1])
|
||||
elif (row[0] == "Slave_polling"):
|
||||
|
@ -1728,6 +1737,28 @@ def settings():
|
|||
<label for='dnp3_server_port'><b>DNP3 Server Port</b></label>
|
||||
<input type='text' id='dnp3_server_port' name='dnp3_server_port' value='""" + dnp3_port + "'>"
|
||||
|
||||
return_str += """
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<label class="container">
|
||||
<b>Enable EtherNet/IP Server</b>"""
|
||||
|
||||
if (enip_port == 'disabled'):
|
||||
return_str += """
|
||||
<input id="enip_server" type="checkbox">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
<label for='enip_server_port'><b>EtherNet/IP Server Port</b></label>
|
||||
<input type='text' id='enip_server_port' name='enip_server_port' value='44818'>"""
|
||||
else:
|
||||
return_str += """
|
||||
<input id="enip_server" type="checkbox" checked>
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
<label for='enip_server_port'><b>EtherNet/IP Server Port</b></label>
|
||||
<input type='text' id='enip_server_port' name='enip_server_port' value='""" + enip_port + "'>"
|
||||
|
||||
return_str += """
|
||||
<br>
|
||||
<br>
|
||||
|
@ -1776,6 +1807,7 @@ def settings():
|
|||
elif (flask.request.method == 'POST'):
|
||||
modbus_port = flask.request.form.get('modbus_server_port')
|
||||
dnp3_port = flask.request.form.get('dnp3_server_port')
|
||||
enip_port = flask.request.form.get('enip_server_port')
|
||||
start_run = flask.request.form.get('auto_run_text')
|
||||
slave_polling = flask.request.form.get('slave_polling_period')
|
||||
slave_timeout = flask.request.form.get('slave_timeout')
|
||||
|
@ -1799,6 +1831,13 @@ def settings():
|
|||
cur.execute("UPDATE Settings SET Value = ? WHERE Key = 'Dnp3_port'", (str(dnp3_port),))
|
||||
conn.commit()
|
||||
|
||||
if (enip_port == None):
|
||||
cur.execute("UPDATE Settings SET Value = 'disabled' WHERE Key = 'Enip_port'")
|
||||
conn.commit()
|
||||
else:
|
||||
cur.execute("UPDATE Settings SET Value = ? WHERE Key = 'Enip_port'", (str(enip_port),))
|
||||
conn.commit()
|
||||
|
||||
if (start_run == 'true'):
|
||||
cur.execute("UPDATE Settings SET Value = 'true' WHERE Key = 'Start_run_mode'")
|
||||
conn.commit()
|
||||
|
|
Loading…
Reference in New Issue