Linux To Sco

Unfrtunately one of my customers is unable to migrate in the forseeable future to LINUX so a smaller library has to be ported from LINUX to SCO.

This library contains code for handling the serial ports and thus is used to to fill in information in the temrios structure. All of the trivia in handling the serial prots are collected in one c module. However, even though the code compiles fine on both platforms (on linux I am using gcc of course, i do not know what environment is used on the SCO platform) the behaviours is quite different.

I try to set the serial port to 12007e1, something which works quite well on the the linux machine but do not work properly on the SCO box. The code used is the following:
/** Sets/changes the parameters for the serial port.
*

  • \note Use the defines specified for
  •      the POSIX termios structure.
    

*

  • \param rs
  •      The port object
    
  • \param baudRate
  •      The speed of the port.
    
  • \param length
  •      The word length.
    
  • \param flow
  •      Enable flowcontrol \(rts/cts, xon/xoff\).
    
  • \param parity
  •      Enable parity checking.
    
  • \param strip
  •      Strip the eight bit.
    
  • \return Normally an int with the value 1.
    */
    int rsportChangesetting (RSPORT_T rs,
    int baudRate,
    int length,
    int flow,
    int parity,
    int strip,
    RSPORT_MODE_E m)
    {
    int p;
    RSPORT_INT_T *r;

/* Sanity check */
r = (RSPORT_INT_T *)rs;
if (r == NULL) return 0;

/* Implementation */
LOG_ENTER ("rsportChangesetting");

p = tcgetattr (r->fd, &r->oldtio);
if (p < 0)
{
//perror ("rsportInit");
//LOG_FATAL ("Couln't get attributes!");
abort ();
}

#ifdef FREE_BSD
cfsetspeed (&r->newtio, baudRate);
r->newtio.c_cflag = flow|length|CREAD|parity;
r->newtio.c_iflag = IGNBRK|strip;
r->newtio.c_oflag = 0;
r->newtio.c_lflag = 0;
r->newtio.c_cc[VTIME] = 0; /* Inter character timer used /
r->newtio.c_cc[VMIN] = 1; /
Block read until 1 char is received! /
#else
cfmakeraw (&r->newtio);
r->newtio.c_cflag = r->newtio.c_cflag | /*CRTSCTS
/flow | CREAD;
r->newtio.c_lflag = 0;
r->newtio.c_oflag = 0;
r->newtio.c_cc[VINTR] = 0;
r->newtio.c_cc[VQUIT] = 0;
r->newtio.c_cc[VERASE] = 0;
r->newtio.c_cc[VKILL] = 0;
r->newtio.c_cc[VEOF] = 0;
r->newtio.c_cc[VTIME] = 0;
r->newtio.c_cc[VMIN] = 1;
r->newtio.c_cc[VSWTC] = 0;
r->newtio.c_cc[VSTART] = 0;
r->newtio.c_cc[VSTOP] = 0;
r->newtio.c_cc[VSUSP] = 0;
r->newtio.c_cc[VEOL] = 0;
r->newtio.c_cc[VREPRINT] = 0;
r->newtio.c_cc[VDISCARD] = 0;
r->newtio.c_cc[VWERASE] = 0;
r->newtio.c_cc[VLNEXT] = 0;
r->newtio.c_cc[VEOL2] = 0;
//printf ("CFLAG01: %08x\n", r->newtio.c_cflag);
cfsetospeed (&r->newtio, baudRate);
cfsetispeed (&r->newtio, baudRate);
//printf ("CFLAG02: %08x\n", r->newtio.c_cflag);
r->newtio.c_cflag = (r->newtio.c_cflag & ~CSIZE) | length;
//printf ("CFLAG03: %08x\n", r->newtio.c_cflag);
r->newtio.c_cflag = r->newtio.c_cflag & ~CSTOPB;
//printf ("CFLAG04: %08x\n", r->newtio.c_cflag);
r->newtio.c_cflag = r->newtio.c_cflag & ~PARENB;
//printf ("CFLAG05: %08x\n", r->newtio.c_cflag);
r->newtio.c_cflag = r->newtio.c_cflag & ~PARODD;
//printf ("CFLAG06: %08x\n", r->newtio.c_cflag);
if (parity == 1) r->newtio.c_cflag = r->newtio.c_cflag | PARENB;
//printf ("CFLAG07: %08x\n", r->newtio.c_cflag);
if (parity == 2) r->newtio.c_cflag = r->newtio.c_cflag | PARODD;
//printf ("CFLAG08: %08x\n", r->newtio.c_cflag);
if (m == RSPORT_LOCAL_E) r->newtio.c_cflag = r->newtio.c_cflag | CLOCAL;
else r->newtio.c_cflag = r->newtio.c_cflag & ~CLOCAL;
//printf ("CFLAG09: %08x\n", r->newtio.c_cflag);
#endif
/*
printf ("Debug printouts\n");
printf ("(r->newtio.c_cflag & ~CSIZE) | length\n");
printf ("(%08x & ~%08x) | %08x ==> %08x\n",
r->newtio.c_cflag,
~CSIZE,
length,
((r->newtio.c_cflag & ~CSIZE) | length));
printf ("\n");
printf ("c_cflag = %08x\n", r->newtio.c_cflag);
if (r->newtio.c_cflag&length) printf ("Length set to: %d\n", length);
else printf ("Failed to set length(l=%08x:m=%08x)...\n", length, CSIZE);
if (r->newtio.c_cflag&PARENB) printf ("PARENB set\n");
else printf ("Failed to set parity even (%08x)...\n", PARENB);
if (r->newtio.c_cflag&PARODD) printf ("PARODD set\n");
else printf ("Failed to set parity odd (%08x)...\n", PARODD);
if (r->newtio.c_cflag&CLOCAL) printf ("CLOCAL set\n");
else printf ("Failed to set CLOCAL (%08x)...\n", CLOCAL);
*/
p = tcflush (r->fd, TCIOFLUSH);
if (p < 0)
{
LOG_FATAL ("Failed in flushing the device!");
perror ("rsportChangesetting (1)");
abort ();
}

p = tcsetattr (r->fd, TCSANOW, &r->newtio);
if (p < 0)
{
LOG_FATAL ("Failed in setting the attribute (2)!");
perror ("rsportChangesetting (2)");
abort ();
}

p = tcflush (r->fd, TCIOFLUSH);
if (p < 0)
{
LOG_FATAL ("Failed in flushing (2)");
perror ("rsportChangesetting (3)");
abort ();
}

/* * * */
LOG_LEAVE ("rsportChangesetting");
return 1;
}

with calling arguments like:
if (rsportChangesetting (r, // Port object
B1200, // Speed
CS7, // Length
/*CRTSCTS*/0, // Flow
1, // Parity, Even
0, // No strip
RSPORT_LOCAL_E // Not really used...
) != 1)

Any takings on the problem? Personally I would say, junk the SCO box, but currently, this is not an option allthough we are working on it...

regards

After som investigation the above issue has been solved (when I finally actually could lay my hands on an SCO unix box).

Case closed.