diff options
author | James Maki <jmaki@multitech.com> | 2010-04-23 11:58:20 -0500 |
---|---|---|
committer | James Maki <jmaki@multitech.com> | 2010-04-23 11:58:20 -0500 |
commit | 14fb44b17123b27e562379f51b75ee889982688d (patch) | |
tree | 3c2344f5c42396ab839638ee12f7c2f66a2656cb /src/atcmd.c | |
download | sms-utils-14fb44b17123b27e562379f51b75ee889982688d.tar.gz sms-utils-14fb44b17123b27e562379f51b75ee889982688d.tar.bz2 sms-utils-14fb44b17123b27e562379f51b75ee889982688d.zip |
initial commit
Diffstat (limited to 'src/atcmd.c')
-rw-r--r-- | src/atcmd.c | 1087 |
1 files changed, 1087 insertions, 0 deletions
diff --git a/src/atcmd.c b/src/atcmd.c new file mode 100644 index 0000000..10470c1 --- /dev/null +++ b/src/atcmd.c @@ -0,0 +1,1087 @@ +/* + * AT Command Utilities (and terminal stuff for now) + * + * Copyright (C) 2010 by Multi-Tech Systems + * + * Author: James Maki <jmaki@multitech.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define _GNU_SOURCE + +#define __ATCMD_C 1 + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <getopt.h> +#include <errno.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <string.h> + +#include "global.h" +#include "log.h" +#include "utils.h" +#include "atcmd.h" +#include "sms_utils.h" + +static const struct baud_map __baud_map[] = { + {B300, 300}, + {B600, 600}, + {B1200, 1200}, + {B1800, 1800}, + {B2400, 2400}, + {B4800, 4800}, + {B9600, 9600}, + {B19200, 19200}, + {B38400, 38400}, + {B57600, 57600}, + {B115200, 115200}, + {B230400, 230400}, + {B460800, 460800}, + {B921600, 921600}, +}; + +speed_t value_to_baud(speed_t value) +{ + int n = ARRAY_SIZE(__baud_map); + int i; + + for (i = 0; i < n; ++i) { + if (__baud_map[i].value == value) { + return __baud_map[i].baud; + } + } + + log_warning("baud rate not valid: %lu", (unsigned long) value); + + return (speed_t) -1; +} + +int rts_get(int fd) +{ + int err; + int status; + + err = ioctl(fd, TIOCMGET, &status); + if (err < 0) { + return -1; + } + return status & TIOCM_RTS ? 1 : 0; +} + +int dtr_get(int fd) +{ + int err; + int status; + + err = ioctl(fd, TIOCMGET, &status); + if (err < 0) { + return -1; + } + return status & TIOCM_DTR ? 1 : 0; +} + +int cts_get(int fd) +{ + int err; + int status; + + err = ioctl(fd, TIOCMGET, &status); + if (err < 0) { + return -1; + } + return status & TIOCM_CTS ? 1 : 0; +} + +int dsr_get(int fd) +{ + int err; + int status; + + err = ioctl(fd, TIOCMGET, &status); + if (err < 0) { + return -1; + } + return status & TIOCM_DSR ? 1 : 0; +} + +int cd_get(int fd) +{ + int err; + int status; + + err = ioctl(fd, TIOCMGET, &status); + if (err < 0) { + return -1; + } + return status & TIOCM_CD ? 1 : 0; +} + +int ri_get(int fd) +{ + int err; + int status; + + err = ioctl(fd, TIOCMGET, &status); + if (err < 0) { + return -1; + } + return status & TIOCM_RI ? 1 : 0; +} + +int line_signal_set(int fd, int signal, int value) +{ + int err; + int status; + + err = ioctl(fd, TIOCMGET, &status); + if (err < 0) { + return -1; + } + + if (value) { + status &= ~signal; + } else { + status |= signal; + } + + err = ioctl(fd, TIOCMSET, &status); + if (err < 0) { + return -1; + } + + return status; +} + +int rts_set(int fd, int value) +{ + return line_signal_set(fd, TIOCM_RTS, value); +} + +int dtr_set(int fd, int value) +{ + return line_signal_set(fd, TIOCM_DTR, value); +} + +int tty_configure(int fd, speed_t baud_rate) +{ + int err; + struct termios params; + + err = tcgetattr(fd, ¶ms); + if (err < 0) { + log_error("tcgetattr failed: %m"); + return -1; + } + + cfmakeraw(¶ms); + cfsetspeed(¶ms, baud_rate); + + err = tcsetattr(fd, TCSANOW, ¶ms); + if (err < 0) { + log_error("tcsetattr failed: %m"); + return -1; + } + + return 0; +} + +int tty_open(const char *dev, speed_t baud_rate) +{ + int fd; + + fd = open(dev, O_RDWR | O_NOCTTY); + if (fd < 0) { + log_error("failed to open %s: %m", dev); + return fd; + } + + if (!isatty(fd)) { + log_error("%s is not a tty device", dev); + close(fd); + return -1; + } + + tty_configure(fd, baud_rate); + tcflush(fd, TCIOFLUSH); + + log_debug("rts: %d", rts_get(fd)); + log_debug("dtr: %d", dtr_get(fd)); + log_debug("cts: %d", cts_get(fd)); + log_debug("dsr: %d", dsr_get(fd)); + log_debug("cd: %d", cd_get(fd)); + log_debug("ri: %d", ri_get(fd)); + + return fd; +} + +int tty_set_read_timeout(int fd, int timeout) +{ + int err; + struct termios params; + + err = tcgetattr(fd, ¶ms); + if (err < 0) { + log_error("tcgetattr failed: %m"); + return -1; + } + + if (timeout < 0) { + params.c_cc[VTIME] = 0; + params.c_cc[VMIN] = 0; + } else if (timeout == 0) { + params.c_cc[VTIME] = 0; + params.c_cc[VMIN] = 1; + } else { + params.c_cc[VTIME] = (timeout + 50) / 100; + params.c_cc[VMIN] = 0; + } + + err = tcsetattr(fd, TCSANOW, ¶ms); + if (err < 0) { + log_error("tcsetattr failed: %m"); + return -1; + } + + return 0; +} + +int tty_close(int fd) +{ + tcflush(fd, TCIOFLUSH); + return close(fd); +} + +int atcmd_read(int fd, char *buf, size_t len) +{ + int err; + + err = read(fd, buf, len); + if (!err) { + log_notice("read timeout"); + } else if (err < 0) { + log_error("read failed: %m"); + } + + return err; +} + +int atcmd_read_until(int fd, char *buf, size_t len, const char *stop) +{ + int err; + char c; + ssize_t total = 0; + size_t stop_len = strlen(stop); + + if (!stop_len) { + BUG("specify a stop string"); + } + + while (1) { + err = atcmd_read(fd, &c, 1); + if (err <= 0) { + buf[total] = '\0'; + return err; + } + + if (total < len - 1) { + buf[total++] = c; + } + + if (stop_len <= total && c == stop[stop_len - 1] && + !memcmp(buf + (total - stop_len), stop, stop_len)) { + buf[total] = '\0'; + break; + } + + if (total >= len - 1) { + buf[total] = '\0'; + log_notice("buffer exceeded before finding stop sequence"); + log_notice("buffer so far: %s", buf); + return -1; + } + } + + debug_buffer("read:", buf, strlen(buf)); + + return total; +} + +int atcmd_readline(int fd, char *buf, size_t len) +{ + int tmp; + + tmp = atcmd_read_until(fd, buf, len, ATCMD_RESPONSE_EOL); + if (tmp <= 0) { + log_debug("atcmd_read_until failed with %d", tmp); + return tmp; + } + + buf = strpbrk(buf, ATCMD_RESPONSE_EOL); + if (buf) { + *buf = '\0'; + } + + return tmp; +} + +int atcmd_expect_line(int fd, char *buf, size_t len, const char *expect) +{ + int tmp; + + while (1) { + tmp = atcmd_readline(fd, buf, len); + if (tmp <= 0) { + *buf = '\0'; + log_debug("atcmd_readline failed"); + return tmp; + } + + if (strstr(buf, expect)) { + return tmp; + } else if (!strcmp(buf, "OK")) { + log_error("expected %s but got %s", expect, buf); + return -1; + } else if (!strcmp(buf, "ERROR")) { + log_error("expected %s but got %s", expect, buf); + return -1; + } else if (!strncmp(buf, "+CMS ERROR: ", sizeof("+CMS ERROR: ") - 1)) { + log_error("expected %s but got %s", expect, buf); + return -1; + } + } + + return -1; +} + +int atcmd_write(int fd, const char *buf, size_t len) +{ + int err; + + debug_buffer("writing:", buf, len); + + err = full_write(fd, buf, len); + if (err < 0) { + log_error("full_write failed: %m"); + } + return err; +} + +int atcmd_write_str(int fd, const char *buf) +{ + return atcmd_write(fd, buf, strlen(buf)); +} + +int atcmd_vprintf(int fd, char *fmt, va_list ap) +{ + char *buf; + int err; + + err = vasprintf(&buf, fmt, ap); + if (err < 0) { + log_error("out of memory"); + return err; + } + + err = atcmd_write_str(fd, buf); + if (err < 0) { + log_debug("atcmd_write failed"); + } + free(buf); + + return err; +} + +int atcmd_printf(int fd, char *fmt, ...) +{ + va_list ap; + int err; + + va_start(ap, fmt); + err = atcmd_vprintf(fd, fmt, ap); + if (err < 0) { + log_debug("atcmd_write failed"); + } + va_end(ap); + + return err; +} + +int atcmd_writeline(int fd, char *fmt, ...) +{ + va_list ap; + int err; + int total = 0; + + va_start(ap, fmt); + err = atcmd_vprintf(fd, fmt, ap); + va_end(ap); + if (err < 0) { + log_debug("atcmd_vprintf failed"); + return err; + } + total += err; + + err = atcmd_write_str(fd, ATCMD_EOL); + if (err < 0) { + log_debug("atcmd_write_str failed"); + return err; + } + total += err; + + return total; +} + +/** + * atcmd_value_tok - Tokenize an AT compound value. + * @str: The compound value to tokenize. + * + * Return: A pointer to the next token is returned and @str is updated for the next + * call. Returns NULL on error or when there are no more tokens. + * + */ +char *atcmd_value_tok(char **str) +{ + char *next; + char *begin; + + begin = *str; + if (!begin || !*begin) { + return NULL; + } + + begin += strspn(begin, " \t"); + + if (*begin == '\"') { + next = ++begin; + + next = strchr(next, '\"'); + if (!next) { + log_notice("unterminated string"); + return NULL; + } + *next++ = '\0'; + + next = strchr(next, ','); + if (next) { + *next++ = '\0'; + } + } else if (*begin == '(') { + next = ++begin; + + next = strchr(next, ')'); + if (!next) { + log_notice("unterminated group"); + return NULL; + } + *next++ = '\0'; + + next = strchr(next, ','); + if (next) { + *next++ = '\0'; + } + } else { + next = begin; + + next = strchr(next, ','); + if (next) { + *next++ = '\0'; + } + + strrstrip(begin); + } + + *str = next; + + return begin; +} + +/** + * atcmd_response_brk - Break an AT command response info line in half. + * @str: The response info line to break in half + * + * expected format: "<key>: <value>". <value> can be the empty string. + * + * Return: A pointer to <key> is returned. @str is set to <value>. + * + */ +char *atcmd_response_brk(char **str) +{ + char *next; + char *begin; + + begin = *str; + if (!begin || !*begin) { + return NULL; + } + + begin += strspn(begin, " \t"); + + next = begin; + + next = strstr(next, ": "); + if (!next) { + log_notice("separator \": \" not found"); + return NULL; + } + *next++ = '\0'; + next += strspn(next, " \t"); + + *str = next; + + return begin; +} + +int atcmd_e_write(int fd, int mode) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + + atcmd_writeline(fd, "ATE%d", mode); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_plus_cmgf_write(int fd, int mode) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + + atcmd_writeline(fd, "AT+CMGF=%d", mode); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_plus_cmgw_write(int fd, const char *msg, size_t msg_len) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + int mem_index; + + atcmd_writeline(fd, "AT+CMGW=%d", msg_len); + tmp = atcmd_read_until(fd, buf, sizeof(buf), "> "); + if (tmp <= 0) { + log_debug("expected > start sequence but it was not received"); + return -1; + } + + tmp = atcmd_write(fd, msg, strlen(msg)); + tmp = atcmd_write_str(fd, CONTROL_Z_STR); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CMGW: "); + if (tmp <= 0) { + log_debug("expected +CMGW: but it was not received"); + return -1; + } + + mem_index = atoi(buf + strlen("+CMGW: ")); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return mem_index; +} + +int atcmd_plus_cmgs_write(int fd, const char *msg, size_t msg_len) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + int msg_ref; + + atcmd_writeline(fd, "AT+CMGS=%d", msg_len); + tmp = atcmd_read_until(fd, buf, sizeof(buf), "> "); + if (tmp <= 0) { + log_debug("expected > start sequence but it was not received"); + return -1; + } + + tmp = atcmd_write(fd, msg, strlen(msg)); + tmp = atcmd_write_str(fd, CONTROL_Z_STR); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CMGS: "); + if (tmp <= 0) { + log_debug("expected +CMGS: but it was not received"); + return -1; + } + msg_ref = atoi(buf + strlen("+CMGS: ")); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return msg_ref; +} + +int atcmd_plus_cmss_write(int fd, int index, const char *addr, int addr_type) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + int msg_ref; + + atcmd_printf(fd, "AT+CMSS=%d", index); + if (addr) { + atcmd_printf(fd, ",\"%s\"", addr); + if (addr_type != SMS_ADDR_UNSPEC) { + atcmd_printf(fd, ",%d", addr_type); + } + } + atcmd_write_str(fd, ATCMD_EOL); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CMSS: "); + if (tmp <= 0) { + log_debug("expected +CMSS: but it was not received"); + return -1; + } + + msg_ref = atoi(buf + strlen("+CMSS: ")); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return msg_ref; +} + +int atcmd_plus_cmgd_write(int fd, int index) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + + atcmd_writeline(fd, "AT+CMGD=%d", index); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_response_foreach_line(int fd, atcmd_response_callback_t call, void *prv) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + + while (1) { + tmp = atcmd_readline(fd, buf, sizeof(buf)); + if (tmp <= 0) { + return -1; + } + + tmp = call(buf, strlen(buf), prv); + if (tmp) { + return tmp; + } + } + + return -1; +} + +int atcmd_plus_cpms_read(int fd, struct data_store *read_store, + struct data_store *send_store, struct data_store *new_store) +{ + char buf[ATCMD_LINE_SIZE]; + char *save; + char *token; + int tmp; + int i; + + struct data_store *data_stores[] = {read_store, send_store, new_store}; + struct data_store *store; + + atcmd_writeline(fd, "AT+CPMS?"); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CPMS: "); + if (tmp <= 0) { + log_debug("expected +CPMS: but it was not received"); + return -1; + } + + save = buf; + token = atcmd_response_brk(&save); + if (!token) { + log_debug("atcmd_response_brk failed"); + return -1; + } + + for (i = 0; i < ARRAY_SIZE(data_stores); i++) { + store = data_stores[i]; + + token = atcmd_value_tok(&save); + if (!token) { + return -1; + } + strncpy(store->name, token, STORE_NAME_LEN); + + token = atcmd_value_tok(&save); + if (!token) { + return -1; + } + store->used = atoi(token); + + token = atcmd_value_tok(&save); + if (!token) { + return -1; + } + store->max = atoi(token); + + log_debug("name[%d]: %s", i, store->name); + log_debug("used[%d]: %d", i, store->used); + log_debug("max[%d]: %d", i, store->max); + } + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_plus_cpms_test(int fd, struct store_locations *read_loc, + struct store_locations *send_loc, struct store_locations *new_loc) +{ + char buf[ATCMD_LINE_SIZE]; + char *save; + char *token; + char *choices; + int tmp; + int i, j; + + struct store_locations *locations[] = {read_loc, send_loc, new_loc}; + struct store_locations *loc; + + atcmd_writeline(fd, "AT+CPMS=?"); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CPMS: "); + if (tmp <= 0) { + log_debug("expected +CPMS: but it was not received"); + return -1; + } + + save = buf; + token = atcmd_response_brk(&save); + if (!token) { + log_debug("atcmd_response_brk failed"); + return -1; + } + + for (i = 0; i < ARRAY_SIZE(locations); i++) { + loc = locations[i]; + + token = atcmd_value_tok(&save); + if (!token) { + break; + } + + choices = token; + for (j = 0; j < STORE_LOCATIONS_MAX; j++) { + token = atcmd_value_tok(&choices); + if (!token) { + break; + } + + strncpy(loc->names[j], token, STORE_NAME_LEN); + + log_debug("loc[%d] choice[%d]: %s", i, j, token); + + loc->nr_locations++; + } + } + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_plus_cpms_write(int fd, const char *read_name, + const char *send_name, const char *new_name) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + + atcmd_writeline(fd, "AT+CPMS=\"%s\",\"%s\",\"%s\"", + read_name, send_name, new_name); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_plus_cpbs_read(int fd, struct data_store *store) +{ + char buf[ATCMD_LINE_SIZE]; + char *save; + char *token; + int tmp; + + atcmd_writeline(fd, "AT+CPBS?"); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CPBS: "); + if (tmp <= 0) { + log_debug("expected +CPBS: but it was not received"); + return -1; + } + + save = buf; + token = atcmd_response_brk(&save); + if (!token) { + log_debug("atcmd_response_brk failed"); + return -1; + } + + token = atcmd_value_tok(&save); + if (!token) { + log_debug("atcmd_value_tok name"); + return -1; + } + strncpy(store->name, token, STORE_NAME_LEN); + + token = atcmd_value_tok(&save); + if (!token) { + log_debug("atcmd_value_tok used"); + return -1; + } + store->used = atoi(token); + + token = atcmd_value_tok(&save); + if (!token) { + log_debug("atcmd_value_tok max"); + return -1; + } + store->max = atoi(token); + + log_debug("name: %s", store->name); + log_debug("used: %d", store->used); + log_debug("max: %d", store->max); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_plus_cpbs_test(int fd, struct store_locations *loc) +{ + char buf[ATCMD_LINE_SIZE]; + char *save; + char *token; + char *choices; + int tmp; + int i; + + atcmd_writeline(fd, "AT+CPBS=?"); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CPBS: "); + if (tmp <= 0) { + log_debug("expected +CPBS: but it was not received"); + return -1; + } + + save = buf; + token = atcmd_response_brk(&save); + if (!token) { + log_debug("atcmd_response_brk failed"); + return -1; + } + + token = atcmd_value_tok(&save); + if (!token) { + log_debug("atcmd_value_tok group"); + return -1; + } + + choices = token; + for (i = 0; i < STORE_LOCATIONS_MAX; i++) { + token = atcmd_value_tok(&choices); + if (!token) { + break; + } + + strncpy(loc->names[i], token, STORE_NAME_LEN); + + log_debug("choice[%d]: %s", i, token); + + loc->nr_locations++; + } + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_plus_cpbs_write(int fd, const char *name) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + + atcmd_writeline(fd, "AT+CPBS=\"%s\"", name); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_plus_cpbr_test(int fd, struct phonebook_store *store) +{ + char buf[ATCMD_LINE_SIZE]; + char *save; + char *range; + char *token; + int tmp; + + atcmd_writeline(fd, "AT+CPBR=?"); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CPBR: "); + if (tmp <= 0) { + log_debug("expected +CPBR: but it was not received"); + return -1; + } + + save = buf; + token = atcmd_response_brk(&save); + if (!token) { + log_debug("atcmd_response_brk failed"); + return -1; + } + + token = atcmd_value_tok(&save); + if (!token) { + log_debug("atcmd_value_tok start"); + return -1; + } + + range = token; + token = atcmd_value_tok(&range); + if (!token) { + log_debug("atcmd_value_tok range"); + return -1; + } + + range = strchr(token, '-'); + if (!range) { + log_debug("break range"); + return -1; + } + store->index_min = atoi(token); + store->index_max = atoi(range + 1); + + token = atcmd_value_tok(&save); + if (!token) { + log_debug("atcmd_value_tok addr_max"); + return -1; + } + store->addr_max = atoi(token); + + token = atcmd_value_tok(&save); + if (!token) { + log_debug("atcmd_value_tok name_max"); + return -1; + } + store->name_max = atoi(token); + + log_debug("index_min: %d", store->index_min); + log_debug("index_max: %d", store->index_max); + log_debug("addr_max: %d", store->addr_max); + log_debug("name_max: %d", store->name_max); + + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + return 0; +} + +int atcmd_init(int fd, int read_timeout) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + + tmp = tty_set_read_timeout(fd, read_timeout); + if (tmp < 0) { + return tmp; + } + + atcmd_writeline(fd, "ATV1"); + tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK"); + if (tmp <= 0) { + log_debug("expected OK but it was not received"); + return -1; + } + + tmp = atcmd_e_write(fd, 0); + if (tmp < 0) { + return tmp; + } + + struct msg_store read_store; + struct msg_store send_store; + struct msg_store new_store; + + memset(&read_store, 0, sizeof(read_store)); + memset(&send_store, 0, sizeof(send_store)); + memset(&new_store, 0, sizeof(new_store)); + + atcmd_plus_cpms_test(fd, &read_store.choices, + &send_store.choices, &new_store.choices); + atcmd_plus_cpms_read(fd, &read_store.selected, + &send_store.selected, &new_store.selected); + if (Global.core.msg_store_read && Global.core.msg_store_send && + Global.core.msg_store_new) { + atcmd_plus_cpms_write(fd, Global.core.msg_store_read, + Global.core.msg_store_send, Global.core.msg_store_new); + } + + return 0; +} |