G. Lippolis
G. Lippolis

Reputation: 28

read() and select() from 3g modem

I'm developing a monitor for the 3g modem embedded in my router. It is interfaced as /dev/ttyUSB device in the linux system.

I need to use a nonblocking read and I'm going to use select(). This is the code:

    df = open(MODEMDEVICE, O_RDWR|O_EXCL);
if (df <0) {perror(MODEMDEVICE); exit(-1); }

tv.tv_sec = 5;
tv.tv_usec = 0;

FD_ZERO(&rfds);
FD_SET(df, &rfds);

while (1) {
    retval = select(df+1, &rfds, NULL, NULL, &tv);
    if (retval == -1)
        perror("select()");
    else if (retval) {
        rdnum=read(df, rdbuf, MSGBUFFSIZE-1);
        rdbuf[rdnum]='\0';
        if (rdnum == 1)
            printf("data available(%i-%i): 0x%02x\n",retval , rdnum, rdbuf[0]);
        else
            printf("data available(%i-%i):%s\n",retval , rdnum, rdbuf);
        usleep(200000);
    } else
        printf("No data within five seconds.\n");

}

But the output is this one:

data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-17):+PSBEARER: 24, 8

data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-17):+PSBEARER: 24, 3

data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-17):+PSBEARER: 24, 8

data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-17):+PSBEARER: 24, 3

It seems that every time the select() is called it returns immediatly and when the read() is called a 0x0a (line feed) is returned also if no real data are available.

By converse using picomm I get:

+PSBEARER: 24, 8

+PSBEARER: 24, 3

+PSBEARER: 24, 8

+PSBEARER: 24, 3

It doesn't show the line feed and there is a bigger lag after the "+PSBEARER: 24, 3" code.

Where I'm wrong? Thanks.

Upvotes: 0

Views: 255

Answers (1)

Marc Balmer
Marc Balmer

Reputation: 1830

You serial device is in "cooked" mode, set it to raw using tcgetattr()/cfmakeraw()/tcsetattr(), e.g. with code like this:

 fd = open(dev, O_RDWR);
 if (fd > 0 && isatty(fd)) {
      if (tcgetattr(fd, &tty) < 0)
           fprintf(stderr, "Can't get tty attributes\n");
      else {
           cfmakeraw(&tty); /* set to "raw" mode */
           if (tcsetattr(fd, TCSADRAIN, &tty) < 0)
                fprintf(stderr, "Can't set tty attributes\n");
      }
 }

Upvotes: 1

Related Questions