LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This 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


Reply
  Search this Thread
Old 02-26-2010, 05:30 AM   #1
JJRockford
LQ Newbie
 
Registered: Feb 2010
Posts: 11

Rep: Reputation: 0
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.

Any ideas where I should start?
 
Old 02-26-2010, 07:43 AM   #2
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,749

Rep: Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928
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.
 
Old 02-26-2010, 09:26 AM   #3
JJRockford
LQ Newbie
 
Registered: Feb 2010
Posts: 11

Original Poster
Rep: Reputation: 0
Ok, here is the functions I guess is relevant:

int16_t RS232Init (const char* device, struct comDefine config)
{
int16_t fd;
struct termios newtio;

/* 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

newtio.c_cflag = BAUD | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;

/*
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 */

tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);

return fd;

Error:
return -1;
}


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

createdSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // Create socket for incoming connections
if (createdSocket < 0) {
perror("socket() failed");
goto Error;
}

/* 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));

return clientSock;

Error:
return -1;
}


int16_t InitRS232(const EquipmentList_t Eq)
{
uint8_t retValue = FALSE;
struct comDefine CRComDefaultValue;
int16_t rs232Fd;
EqStatus_t tmpCR;

retValue = GetEqStatus(Eq, &tmpCR);

// Initialize
// Default settings of RS232 communication port
// 9600 baud, 8 data bits, 1 stop bit, no parity
CRComDefaultValue.BaudRate = 9600;
CRComDefaultValue.DataBits = 8;
CRComDefaultValue.StopBits = 1;
CRComDefaultValue.Parity = 0;
rs232Fd = RS232Init(tmpCR.Device, CRComDefaultValue);
if(rs232Fd < 0)
{
DEBUG_PRINT("Error wrong file descriptor, %d\n", rs232Fd);
goto Error;
}

retValue = PutEqClientFD(tmpCR.Equipment, rs232Fd);

return retValue;

Error:
return -1;

}


int16_t InitTCPIP(const EquipmentList_t Eq)
{
uint8_t retValue = FALSE;
int16_t socketFd;
EqStatus_t tmpCR;

retValue = GetEqStatus(Eq, &tmpCR);

// Initialize
// Default settings of BO communication port
// Port: 2101
socketFd = CreateTCPSystemControllerSocket(2101);
if(socketFd < 0)
{
DEBUG_PRINT("Error wrong file descriptor, %d\n", socketFd);
goto Error;
}

retValue = PutEqServerFD(tmpCR.Equipment, socketFd);

return retValue;

Error:
return -1;

}


uint8_t CheckMessage(const EquipmentList_t eq)
{
int16_t res;
int16_t nfds;
fd_set readfs; /* file descriptor set */
struct timeval Timeout;
EqStatus_t eqStatus;
BYTE buf[EQUIPMENT_BUFFER_SIZE] = "";
int16_t rest;
uint8_t dataLength;
int16_t clientSocket;

GetEqStatus(eq, &eqStatus);

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);
}
}

}

return OK;

Error:
return -1;
}
 
Old 02-26-2010, 11:52 AM   #4
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,749

Rep: Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928
FYI using code tags will preserve text format.

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.
 
Old 03-02-2010, 07:45 AM   #5
JJRockford
LQ Newbie
 
Registered: Feb 2010
Posts: 11

Original Poster
Rep: Reputation: 0
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).
 
Old 03-02-2010, 11:13 AM   #6
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,749

Rep: Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928Reputation: 5928
Yes use the # for code tags.

It might be just me but it is difficult to follow your file descriptors with what you posted.
 
Old 03-15-2010, 02:07 AM   #7
JJRockford
LQ Newbie
 
Registered: Feb 2010
Posts: 11

Original Poster
Rep: Reputation: 0
I guess I understand to little about this even to give the right input to you other more experienced guys... Might come back to this later.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Looking For User Input / Response Software frohike111 Programming 1 09-24-2008 12:43 AM
Distinguish Terminals Eilya Programming 12 09-22-2008 02:35 AM
I lost input ports on Audigy SB agron Linux - Software 1 11-15-2005 11:05 AM
Chinese input in linux? Is there any software for this purpose TruongAn Linux - Software 2 08-11-2005 01:39 AM
Closing Ports by Uninstalling Software race Linux - Security 6 09-17-2004 09:12 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 12:15 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration