diff options
author | Bjørn Mork <bjorn@mork.no> | 2011-09-29 10:45:44 +0200 |
---|---|---|
committer | Bjørn Mork <bjorn@mork.no> | 2011-09-29 10:45:44 +0200 |
commit | 74da6f669debb4fe8899d669fbe18b3c1d9c1eca (patch) | |
tree | 02d1dd55085f256a27439a3fb3de730aa0b8f3cc /src | |
parent | 3d569cbac033a5bd315c743df4c768cd5ac0e20f (diff) |
wwan_ctl: finally got the termios settings right by copying it from pppd
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Diffstat (limited to 'src')
-rw-r--r-- | src/wwan_ctl.c | 128 |
1 files changed, 101 insertions, 27 deletions
diff --git a/src/wwan_ctl.c b/src/wwan_ctl.c index 87bedf2..41c8ea6 100644 --- a/src/wwan_ctl.c +++ b/src/wwan_ctl.c @@ -22,6 +22,10 @@ static int wwan_mode = 1; /* Radio mode 1=auto, 5=GSM, 6=UTRAN */ static int wwan_roaming_ok = 0; /* Disallow roaming by default */ static int wwan_debug = 0; static char wwan_cfg_file[] = "/etc/default/wwan_ctl"; +static int wwan_simpin = 0; + +/* saved values */ +static struct termios restore_tios; void dbg(const char *str, ...) { @@ -53,9 +57,48 @@ char *wwan_getgpsport(void) return ""; } -char *wwan_getmgmt(void) +int wwan_getmgmt_fd(const char *device) { - return "/dev/ttyACM1"; + int fd; + struct termios tios; + + fprintf(stderr, "%s(): opening \"%s\"\n", __FUNCTION__, device); + if ((fd = open(device, O_RDWR)) < 0) + fatal("%s(): failed to open '%s': %d %m\n", __FUNCTION__, device, errno); + + /* FIXME: don't do any termios things if we use a cdc-wdm device (which is *not* a tty!) */ + + /* get current tty settings */ + if (tcgetattr(fd, &tios) < 0) + if (errno = ENOTTY) + /* don't do any termios things if we use a cdc-wdm device (which is *not* a tty!) */ + return fd; + else + fatal("%s(): tcgetattr: %m\n", __FUNCTION__); + + /* save'em so we can restor on exit */ + memcpy(&restore_tios, &tios, sizeof(restore_tios)); + + /* if this works for pppd, then it works for us */ + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CRTSCTS); + tios.c_cflag |= CS8 | CREAD | CLOCAL; + tios.c_iflag = IGNBRK | IGNPAR; + tios.c_oflag = 0; + tios.c_lflag = 0; + tios.c_cc[VMIN] = 1; + tios.c_cc[VTIME] = 0; + + + /* we don't care much, but 115k is fine */ + cfsetospeed (&tios, B115200); + cfsetispeed (&tios, B115200); + + while (tcsetattr(fd, TCSAFLUSH, &tios) < 0) + if (errno != EINTR) + fatal("%s(): tcsetattr: %m\n", __FUNCTION__); + + + return fd; } int wwan_verify_pin(void) @@ -93,37 +136,68 @@ int wwan_disconnect(void) return -1; } +int cmd(int fd, const char *cmd, char *buf, ssize_t bufsize) +{ + char *p; + ssize_t n = 0; + int ok = 0; + + if (wwan_debug > 1) + fprintf(stderr, "%s() called with fd=%d, cmd=%s, buf=%p, bufsize=%d\n", __FUNCTION__, fd, cmd, buf, bufsize); + + sprintf(buf, "%s\r\n", cmd); + write(fd, buf, strlen(buf)); + tcdrain(fd); + + while (!ok) { + p = buf + n; + n += read(fd, p, bufsize - n); + buf[n] = 0; + if (strstr(p, "OK")) + ok = 1; + else if (strstr(p, "ERROR")) + ok = -1; + } + if (wwan_debug > 1) + fprintf(stderr, "ok=%d, n=%d\n", ok, n); + return n; +} -int main (int argc, char **argv) +int main(int argc, char **argv) { int mgmt_fd; - ssize_t n, c; - char buf[512], *p; - struct termios t; + ssize_t c; + char buf[128]; + struct termios tios, restore_tios; +/* if (argc != 1) fatal("usage: %s gps|start|stop\n", argv[0]); - - if ((mgmt_fd = open(wwan_getmgmt(), O_RDWR|O_SYNC)) < 0) - fatal("failed to open '%s': %d %m\n", wwan_getmgmt(), errno); - - tcgetattr(mgmt_fd, &t); - t.c_lflag &= ~(ICANON | ECHO); - tcsetattr(mgmt_fd, TCSADRAIN, &t); - - sprintf(buf, "%s", "ATI\r\n"); - write(mgmt_fd, buf, strlen(buf)); - p = buf; - c = 0; - while (n = read(mgmt_fd, p, sizeof(buf) - c)) { - p[n] = 0; - fprintf(stderr, "%s", p); - p += n; - c += n; - } - buf[c] = 0; - - dbg("%s(): read %d bytes: %s", __FUNCTION__, c, buf); +*/ + if (argc == 2) + mgmt_fd = wwan_getmgmt_fd(argv[1]); + else + mgmt_fd = wwan_getmgmt_fd("/dev/ttyACM1"); + + c = cmd(mgmt_fd, "ATI", buf, sizeof(buf)); + fprintf(stderr, "%s", buf); + + c = cmd(mgmt_fd, "AT+CPIN?", buf, sizeof(buf)); + fprintf(stderr, "%s", buf); + + if (strstr(buf, "+CPIN: SIM PIN")) { + if (!wwan_simpin) + fatal("SIM PIN required"); + sprintf(buf, "AT+CPIN=\"%04d\"", wwan_simpin); + c = cmd(mgmt_fd, buf, buf, sizeof(buf)); + fprintf(stderr, "%s", buf); + } + + c = cmd(mgmt_fd, "AT+CGSM?", buf, sizeof(buf)); + fprintf(stderr, "%s", buf); + + c = cmd(mgmt_fd, "AT+GGSM?", buf, sizeof(buf)); + fprintf(stderr, "%s", buf); close (mgmt_fd); return 0; |