Software doesn't distinguish between different input ports
Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Software doesn't distinguish between different input ports
I working on a project, where a central unit (we call it System Controller ) should talk to several peripheral units on different input ports.
The system controller have 4 RS485 ports, 1 RS232, 1 USB A, 1 USB B and a switch with 2 TCP/IP ports.
The problem is that when the peripheral unit that is supposed to be connected to one of the two TCP/IP inputs isn't connected (which the system should be able to handle), the software thinks that data from the unit connected to the RS232 port is from the unit that should be connected to the TCP/IP.
No good. I very new to embedded Linux (and Linux at all), and don't really know where to start...
The input peripherals are defined as:
#define CR_DEVICE "/dev/ttyS1" // ttyS1
#define SL_PORT "/dev/ttyUSB0"
#define BO_PORT ""
It is the last one which are supposed to receive from the TCP/IP port, and of course the first one which should receive data from the RS232 port.
Without seeing your program code it is difficult to know where it is going astray nor where to provide help. We need to know how your serial ports are configured. Are you using the select function and not keeping track of your file descriptors? #define BO_PORT "" does not provide and real information on what you are using for your network protocol, port number etc.
/* open the device to be non-blocking (read will return immediatly) */
fd = open(device, O_RDWR | O_NOCTTY);
if (fd < 0)
{
perror(device);
goto Error;
}
/* install the signal handler before making the device asynchronous */
// Several code which are not used
/* Make the file descriptor asynchronous (the manual page says only
O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
//fcntl(fd, F_SETFL, FASYNC);
/* Define baud rate */
switch (config.BaudRate)
{
case 19200:
BAUD = B19200;
break;
case 9600:
default:
BAUD = B9600;
break;
case 4800:
BAUD = B4800;
break;
case 2400:
BAUD = B2400;
break;
case 1200:
BAUD = B1200;
break;
} //end of switch BaudRate
switch (config.DataBits)
{
case 8:
default:
DATABITS = CS8;
break;
} //end of switch DataBits
switch (config.StopBits)
{
case 1:
default:
STOPBITS = 0;
break;
case 2:
STOPBITS = CSTOPB;
break;
} //end of switch StopBits
switch (config.Parity)
{
case 0:
default: //none
PARITYON = 0;
PARITY = 0;
break;
} //end of switch Parity
/*
IGNPAR : ignore bytes with parity errors
ICRNL : map CR to NL (otherwise a CR input on the other computer
will not terminate input)
otherwise make device raw (no other input processing)
*/
newtio.c_iflag = IGNPAR; // | ICRNL;
/* Raw output. */
newtio.c_oflag = 0;
/*
ICANON : enable canonical input
disable all echo functionality, and don't send signals to calling program
*/
newtio.c_lflag = 0; //ICANON;
newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
int16_t CreateTCPSystemControllerSocket(uint16_t port)
{
int16_t createdSocket; // socket to create
int16_t bindResult; // Result from binding
int16_t listenResult; // Result from listening
uint8_t on, ret;
struct sockaddr_in systemControllerAddress; // Local address
/* Enable address reuse */
on = 1;
ret = setsockopt( createdSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
/* Construct local address structure */
memset(&systemControllerAddress, 0, sizeof(systemControllerAddress)); // Zero out structure
systemControllerAddress.sin_family = AF_INET; // Internet address family
systemControllerAddress.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
systemControllerAddress.sin_port = htons(port); // Local port
/* Bind to the local address */
bindResult = bind(createdSocket, (struct sockaddr *) &systemControllerAddress, sizeof(systemControllerAddress));
if (bindResult < 0) {
perror("bind() failed");
if (errno == EADDRINUSE) {
DEBUG_PRINT("Address in Use\n");
}
goto Error;
}
/* Mark the socket so it will listen for incoming connections */
listenResult = listen(createdSocket, MAXPENDING);
if (listenResult < 0) {
perror("listen() failed");
goto Error;
}
return createdSocket;
Error:
return -1;
}
int16_t AcceptTCPConnection(int16_t systemControllerSocket)
{
int32_t clientSock; /* Socket descriptor for client */
struct sockaddr_in clientAddress; /* Client address */
uint32_t clientLength; /* Length of client address data structure */
/* Set the size of the in-out parameter */
clientLength = sizeof(clientAddress);
/* Wait for a client to connect */
clientSock = accept(systemControllerSocket, (struct sockaddr *) &clientAddress, &clientLength);
if (clientSock < 0) {
perror("accept() failed");
goto Error;
}
/* clientSock is connected to a client! */
DEBUG_PRINT("Handling client %s\n", inet_ntoa(clientAddress.sin_addr));
FD_ZERO(&readfs);
FD_SET(eqStatus.Client_File_Descriptor, &readfs);
FD_SET(eqStatus.Server_File_Descriptor, &readfs);
if(eqStatus.Client_File_Descriptor > eqStatus.Server_File_Descriptor) {
nfds = eqStatus.Client_File_Descriptor + 1; // Highest fd in the set, plus 1.
}
else {
nfds = eqStatus.Server_File_Descriptor + 1; // Highest fd in the set, plus 1.
}
/* set timeout value within input loop */
Timeout.tv_usec = 0; /* milliseconds */
Timeout.tv_sec = 0; /* seconds */
res = select(nfds, &readfs, NULL, NULL, &Timeout);
if(res < 0)
{
DEBUG_PRINT("Error in select command.\n"); // select returned -1, thus an error occurred
goto Error;
}
else if (res > 0)
{
if (FD_ISSET(eqStatus.Client_File_Descriptor, &readfs)) // input from source 1 available
{
rest = read(eqStatus.Client_File_Descriptor, buf, EQUIPMENT_BUFFER_SIZE -1);
buf[rest] = 0;
dataLength = rest;
AppendBuffer(eq, buf, dataLength);
//DEBUG_SL_HEX(buf, dataLength, "A:");
if (eq == BackOffice) {
// Still in place for CashRegister handling. No switch yet.
if(dataLength == 0) {
close(eqStatus.Client_File_Descriptor);
PutEqClientFD(eqStatus.Equipment, 0);
}
else {
//DEBUG_CONTROL("CheckMessage(): DataRcvd set\n");
PutEqDataRcvd(eq, TRUE);
}
}
else if(eq == SlavePort){// || (eq == SlavePort2) || (eq == SlavePort3) || (eq == SlavePort4)) {
if (SL_IsMessageComplete(eq)) {
PutEqDataRcvd(eq, TRUE);
}
}
else if(eq == CashRegister) {
// Still in place for CashRegister handling. No switch yet.
if(CRBiStd_IsCompleteMessage(eq)) {
//DEBUG_BO_HEX(buf, dataLength, "Message received from CR: ")
PutEqDataRcvd(eq, TRUE);
}
}
}
else if(FD_ISSET(eqStatus.Server_File_Descriptor, &readfs)) /* input from source 1 available */
{
if (eq == BackOffice) {
// Still in place for CashRegister handling. No switch yet.
clientSocket = AcceptTCPConnection(eqStatus.Server_File_Descriptor);
PutEqClientFD(eqStatus.Equipment, clientSocket);
}
}
I have not examined your code in detail but is eqStatus.Client_File_Descriptor being assigned the file descriptor for the RS232 port and eqStatus.Server_File_Descriptor being assigned the file descriptor for your TCP/IP connection? I can not tell from what you posted.
Ok, thanks for the tip! Is it the "#" I should use to insert code?
In the code, there are three global structs of the typ eqStatus. The first two (RS232 and USB) have only the Client_File_Descriptor set (3 resp. 4) and the third (TCP/IP) have both Server and Client_File_Descriptor set (5 and 6).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.