summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Maki <jmaki@multitech.com>2010-09-10 10:49:55 -0500
committerJames Maki <jmaki@multitech.com>2010-09-10 10:49:55 -0500
commitf090469e2776fea6a27a7ac6612b666d20dc9a05 (patch)
tree5ddc79c8b9ca0c66333b3571453823de9766d5fb
parentd0b5cdf1351cb02dc001aab5bd44ff6c5f681abc (diff)
downloadsms-utils-sms-text-mode.tar.gz
sms-utils-sms-text-mode.tar.bz2
sms-utils-sms-text-mode.zip
sms using text modesms-text-mode
-rw-r--r--src/atcmd.c117
-rw-r--r--src/atcmd.h3
-rw-r--r--src/cmd_options.h3
-rw-r--r--src/global.h2
-rw-r--r--src/pdu.c14
-rw-r--r--src/pdu.h10
-rw-r--r--src/pdu_decode.c2
-rw-r--r--src/pdu_decode.h2
-rw-r--r--src/pdu_encode.c2
-rw-r--r--src/pdu_encode.h2
-rw-r--r--src/pdu_encoder.c4
-rw-r--r--src/sms.config.example1
-rw-r--r--src/sms_config.c9
-rw-r--r--src/sms_list.c274
-rw-r--r--src/sms_main.c15
-rw-r--r--src/sms_send.c82
16 files changed, 467 insertions, 75 deletions
diff --git a/src/atcmd.c b/src/atcmd.c
index aad15e9..8c6c3f0 100644
--- a/src/atcmd.c
+++ b/src/atcmd.c
@@ -674,6 +674,51 @@ int atcmd_plus_cmgw_write(int fd, const char *msg, size_t msg_len)
return mem_index;
}
+int atcmd_plus_cmgw_write_text(int fd, const char *addr, int addr_type,
+ const char *status, const char *msg, size_t msg_len)
+{
+ char buf[ATCMD_LINE_SIZE];
+ int tmp;
+ int mem_index;
+
+ atcmd_printf(fd, "AT+CMGW");
+ if (addr) {
+ atcmd_printf(fd, "=\"%s\"", addr);
+ if (addr_type != SMS_ADDR_UNSPEC) {
+ atcmd_printf(fd, ",%d", addr_type);
+ if (status) {
+ atcmd_printf(fd, ",\"%s\"", status);
+ }
+ }
+ }
+ atcmd_write_str(fd, ATCMD_EOL);
+
+ 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];
@@ -706,6 +751,38 @@ int atcmd_plus_cmgs_write(int fd, const char *msg, size_t msg_len)
return msg_ref;
}
+int atcmd_plus_cmgs_write_text(int fd, const char *addr, const char *msg, size_t msg_len)
+{
+ char buf[ATCMD_LINE_SIZE];
+ int tmp;
+ int msg_ref;
+
+ atcmd_writeline(fd, "AT+CMGS=\"%s\"", addr);
+ 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];
@@ -785,6 +862,10 @@ int atcmd_plus_cpms_read(int fd, struct data_store *read_store,
struct data_store *data_stores[] = {read_store, send_store, new_store};
struct data_store *store;
+ memset(read_store, 0, sizeof(*read_store));
+ memset(send_store, 0, sizeof(*send_store));
+ memset(new_store, 0, sizeof(*new_store));
+
atcmd_writeline(fd, "AT+CPMS?");
tmp = atcmd_expect_line(fd, buf, sizeof(buf), "+CPMS: ");
if (tmp <= 0) {
@@ -804,7 +885,7 @@ int atcmd_plus_cpms_read(int fd, struct data_store *read_store,
token = atcmd_value_tok(&save);
if (!token) {
- return -1;
+ break;
}
strncpy(store->name, token, STORE_NAME_LEN);
@@ -906,8 +987,15 @@ int atcmd_plus_cpms_write(int fd, const char *read_name,
char buf[ATCMD_LINE_SIZE];
int tmp;
- atcmd_writeline(fd, "AT+CPMS=\"%s\",\"%s\",\"%s\"",
- read_name, send_name, new_name);
+ atcmd_printf(fd, "AT+CPMS=\"%s\"", read_name);
+ if (send_name) {
+ atcmd_printf(fd, ",\"%s\"", send_name);
+ if (new_name) {
+ atcmd_printf(fd, ",\"%s\"", new_name);
+ }
+ }
+ atcmd_write_str(fd, ATCMD_EOL);
+
tmp = atcmd_expect_line(fd, buf, sizeof(buf), "OK");
if (tmp <= 0) {
log_debug("expected OK but it was not received");
@@ -1158,9 +1246,9 @@ static int sms_atcmd_init(int fd)
return -1;
}
- tmp = atcmd_plus_cmgf_write(fd, SMS_PDU_MODE);
+ tmp = atcmd_plus_cmgf_write(fd, Global.core.sms_mode);
if (tmp < 0) {
- return -1;
+ log_error("atcmd_plus_cmgf_write failed");
}
memset(&read_store, 0, sizeof(read_store));
@@ -1175,25 +1263,28 @@ static int sms_atcmd_init(int fd)
Global.core.msg_store_new) {
if (!msg_store_choice(&read_store, Global.core.msg_store_read)) {
- log_error("message storage location %s is not a choice",
+ log_error("read message storage location %s is not a choice",
Global.core.msg_store_read);
return -1;
}
- if (!msg_store_choice(&send_store, Global.core.msg_store_send)) {
- log_error("message storage location %s is not a choice",
+ if (*Global.core.msg_store_send && !msg_store_choice(&send_store, Global.core.msg_store_send)) {
+ log_error("send message storage location %s is not a choice",
Global.core.msg_store_send);
return -1;
}
- if (!msg_store_choice(&new_store, Global.core.msg_store_new)) {
- log_error("message storage location %s is not a choice",
+ if (*Global.core.msg_store_new && !msg_store_choice(&new_store, Global.core.msg_store_new)) {
+ log_error("new message storage location %s is not a choice",
Global.core.msg_store_new);
return -1;
}
- tmp = atcmd_plus_cpms_write(fd, Global.core.msg_store_read,
- Global.core.msg_store_send, Global.core.msg_store_new);
+ tmp = atcmd_plus_cpms_write(fd,
+ Global.core.msg_store_read,
+ *Global.core.msg_store_send ? Global.core.msg_store_send : NULL,
+ *Global.core.msg_store_new ? Global.core.msg_store_new : NULL
+ );
if (tmp < 0) {
- return -1;
+ log_error("atcmd_plus_cpms_write failed");
}
}
diff --git a/src/atcmd.h b/src/atcmd.h
index de6eeee..6461250 100644
--- a/src/atcmd.h
+++ b/src/atcmd.h
@@ -62,7 +62,10 @@ int atcmd_v_write(int fd, int mode);
int atcmd_q_write(int fd, int mode);
int atcmd_plus_cmgf_write(int fd, int mode);
int atcmd_plus_cmgw_write(int fd, const char *msg, size_t msg_len);
+int atcmd_plus_cmgw_write_text(int fd, const char *addr, int addr_type,
+ const char *status, const char *msg, size_t msg_len);
int atcmd_plus_cmgs_write(int fd, const char *msg, size_t msg_len);
+int atcmd_plus_cmgs_write_text(int fd, const char *addr, const char *msg, size_t msg_len);
int atcmd_plus_cmss_write(int fd, int index, const char *addr, int addr_type);
int atcmd_plus_cmgd_write(int fd, int index);
diff --git a/src/cmd_options.h b/src/cmd_options.h
index fef1b16..7f5eb5c 100644
--- a/src/cmd_options.h
+++ b/src/cmd_options.h
@@ -21,10 +21,11 @@ enum cmd_opt_long_only {
CMD_OPT_READ_TIMEOUT,
CMD_OPT_ALPHABET,
CMD_OPT_SMSC_ADDR,
- CMD_OPT_CMGW_FIRST,
+ CMD_OPT_SEND_MODE,
CMD_OPT_MSG_STORE_READ,
CMD_OPT_MSG_STORE_SEND,
CMD_OPT_MSG_STORE_NEW,
+ CMD_OPT_SMS_MODE,
CMD_OPT_PHONEBOOK_STORE,
CMD_OPT_SUBJECT,
};
diff --git a/src/global.h b/src/global.h
index fe8f5c2..5e2ffd8 100644
--- a/src/global.h
+++ b/src/global.h
@@ -30,6 +30,8 @@ struct global_core {
char *msg_store_new;
char *pb_store;
+ int sms_mode;
+
char *editor;
char *edit_file;
};
diff --git a/src/pdu.c b/src/pdu.c
index 2ceb7ae..9221485 100644
--- a/src/pdu.c
+++ b/src/pdu.c
@@ -162,7 +162,7 @@ int pdu_format_vp(struct pdu_info *pdu, char *str, size_t len)
}
}
-int pdu_addr_check(const char *addr_str)
+int sms_addr_check(const char *addr_str)
{
if (addr_str[0] == '+') {
addr_str++;
@@ -188,7 +188,7 @@ int pdu_addr_check(const char *addr_str)
#define NUM_ADDR "1234567890-."
#define CMD_ADDR "1234567890*#+-."
-int pdu_addr_type_infer(const char *str)
+int sms_addr_type_infer(const char *str)
{
if (*str == '+' && strlen(str + 1) == strspn(str + 1, NUM_ADDR)) {
log_debug("SMS_ADDR_GLOBAL");
@@ -205,7 +205,7 @@ int pdu_addr_type_infer(const char *str)
}
}
-static int pdu_addr_clean_copy(struct pdu_addr *addr, const char *src)
+static int sms_addr_clean_copy(struct sms_addr *addr, const char *src)
{
char *dest = addr->addr;
int count = 0;
@@ -238,15 +238,15 @@ static int pdu_addr_clean_copy(struct pdu_addr *addr, const char *src)
return count;
}
-int pdu_addr_fill(struct pdu_addr *addr, const char *addr_str, int type)
+int sms_addr_fill(struct sms_addr *addr, const char *addr_str, int type)
{
int tmp;
memset(addr, 0 , sizeof(*addr));
- addr->type = pdu_addr_type_infer(addr_str);
+ addr->type = sms_addr_type_infer(addr_str);
- tmp = pdu_addr_clean_copy(addr, addr_str);
+ tmp = sms_addr_clean_copy(addr, addr_str);
if (tmp < 0) {
return tmp;
}
@@ -300,7 +300,7 @@ done:
pdu->user_data[total] = '\0';
pdu->user_data_len = total;
- debug_buffer("message is: ", pdu->user_data, total);
+ debug_buffer("message is:", pdu->user_data, total);
return total;
}
diff --git a/src/pdu.h b/src/pdu.h
index 0305550..269b157 100644
--- a/src/pdu.h
+++ b/src/pdu.h
@@ -24,7 +24,7 @@ extern char *strptime(const char *s, const char *format, struct tm *tm);
#define PDU_VPF_RELATIVE_2DAYS 0xA8
-struct pdu_addr {
+struct sms_addr {
char addr[PDU_ADDR_SIZE];
uint8_t type;
uint8_t len;
@@ -53,8 +53,8 @@ enum {
struct pdu_info {
int msg_len;
- struct pdu_addr smsc_addr;
- struct pdu_addr addr;
+ struct sms_addr smsc_addr;
+ struct sms_addr addr;
union {
uint8_t type;
struct {
@@ -105,8 +105,8 @@ int strpad(char *str, size_t len, unsigned char c);
int pdu_format_timestamp(struct pdu_info *pdu, char *str, size_t len, const char *fmt);
int pdu_format_vp(struct pdu_info *pdu, char *str, size_t len);
-int pdu_addr_type_infer(const char *str);
-int pdu_addr_fill(struct pdu_addr *addr, const char *addr_str, int type);
+int sms_addr_type_infer(const char *str);
+int sms_addr_fill(struct sms_addr *addr, const char *addr_str, int type);
int pdu_user_data_read(int fd, struct pdu_info *pdu);
#define shiftr(a, n) ((a) >> (n))
diff --git a/src/pdu_decode.c b/src/pdu_decode.c
index 643fa15..4951ac7 100644
--- a/src/pdu_decode.c
+++ b/src/pdu_decode.c
@@ -82,7 +82,7 @@ int pdu_decode_timestamp(const char *pdu_str, struct tm *tm)
return PDU_TIMESTAMP_LEN;
}
-int pdu_decode_addr(const char *pdu_str, struct pdu_addr *addr, int smsc)
+int pdu_decode_addr(const char *pdu_str, struct sms_addr *addr, int smsc)
{
const char *begin = pdu_str;
int addr_len;
diff --git a/src/pdu_decode.h b/src/pdu_decode.h
index 004c8ad..269bf88 100644
--- a/src/pdu_decode.h
+++ b/src/pdu_decode.h
@@ -4,7 +4,7 @@
#include "pdu.h"
int pdu_decode_timestamp(const char *pdu_str, struct tm *tm);
-int pdu_decode_addr(const char *pdu_str, struct pdu_addr *addr, int smsc);
+int pdu_decode_addr(const char *pdu_str, struct sms_addr *addr, int smsc);
int pdu_decode_user_data(const char *pdu_str, struct pdu_info *pdu);
int pdu_decode(const char *pdu_str, struct pdu_info *pdu);
diff --git a/src/pdu_encode.c b/src/pdu_encode.c
index 30cb4a9..e3bee18 100644
--- a/src/pdu_encode.c
+++ b/src/pdu_encode.c
@@ -80,7 +80,7 @@ int pdu_encode_timestamp(char *pdu_str, size_t len, struct tm *tm)
return PDU_TIMESTAMP_LEN;
}
-int pdu_encode_addr(char *pdu_str, size_t len, struct pdu_addr *addr, int smsc)
+int pdu_encode_addr(char *pdu_str, size_t len, struct sms_addr *addr, int smsc)
{
char *begin = pdu_str;
int addr_len;
diff --git a/src/pdu_encode.h b/src/pdu_encode.h
index 246ea3d..c47bade 100644
--- a/src/pdu_encode.h
+++ b/src/pdu_encode.h
@@ -4,7 +4,7 @@
#include "pdu.h"
int pdu_encode_timestamp(char *pdu_str, size_t len, struct tm *tm);
-int pdu_encode_addr(char *pdu_str, size_t len, struct pdu_addr *addr, int smsc);
+int pdu_encode_addr(char *pdu_str, size_t len, struct sms_addr *addr, int smsc);
int pdu_encode_user_data(char *pdu_str, size_t len, struct pdu_info *pdu);
int pdu_encode(char *pdu_str, size_t len, struct pdu_info *pdu);
diff --git a/src/pdu_encoder.c b/src/pdu_encoder.c
index c2a046a..3df3016 100644
--- a/src/pdu_encoder.c
+++ b/src/pdu_encoder.c
@@ -148,11 +148,11 @@ int main(int argc, char *argv[])
pdu.data_coding.general.alphabet = alphabet;
if (smsc_addr) {
- pdu_addr_fill(&pdu.smsc_addr, smsc_addr, SMS_ADDR_UNSPEC);
+ sms_addr_fill(&pdu.smsc_addr, smsc_addr, SMS_ADDR_UNSPEC);
}
if (argc) {
- pdu_addr_fill(&pdu.addr, *argv, SMS_ADDR_UNSPEC);
+ sms_addr_fill(&pdu.addr, *argv, SMS_ADDR_UNSPEC);
argc++;
argv--;
}
diff --git a/src/sms.config.example b/src/sms.config.example
index 5081f17..c614d91 100644
--- a/src/sms.config.example
+++ b/src/sms.config.example
@@ -15,6 +15,7 @@ core:
msg-store-send: ME
msg-store-new: ME
pb-store: ME
+ sms-mode: pdu
editor: vi
edit-file: "${HOME}/.smsmsg"
diff --git a/src/sms_config.c b/src/sms_config.c
index 2d44e18..08bac12 100644
--- a/src/sms_config.c
+++ b/src/sms_config.c
@@ -15,6 +15,7 @@
#endif
#include "atcmd.h"
+#include "sms_utils.h"
#include "utils.h"
#include "log.h"
@@ -131,6 +132,14 @@ static int config_set_core_value(const char *key, const char *value)
} else if (!strcmp("pb-store", key)) {
free(Global.core.pb_store);
Global.core.pb_store = strdup(value);
+ } else if (!strcmp("sms-mode", key)) {
+ if (!strcmp(value, "text")) {
+ Global.core.sms_mode = SMS_TEXT_MODE;
+ } else if (!strcmp(value, "pdu")) {
+ Global.core.sms_mode = SMS_PDU_MODE;
+ } else {
+ log_warning("invalid sms-mode: %s", value);
+ }
} else if (!strcmp("editor", key)) {
free(Global.core.editor);
Global.core.editor = strdup(value);
diff --git a/src/sms_list.c b/src/sms_list.c
index 0ccec15..e6f29f1 100644
--- a/src/sms_list.c
+++ b/src/sms_list.c
@@ -42,6 +42,236 @@
#define CMGL_HEADER_START "+CMGL: "
#define CMGR_HEADER_START "+CMGR: "
+static int decode_timestamp_text_mode(const char *str, struct tm *tm)
+{
+ char *cp;
+ struct tm tm_now;
+ time_t now = time(NULL);
+
+ localtime_r(&now, &tm_now);
+
+ memset(tm, 0, sizeof(*tm));
+
+ cp = (char *) strptime(str, "%y/%m/%d,%H:%M:%S", tm);
+ if (!cp || *cp) {
+ log_error("timestamp could not be converted to tm");
+ return -1;
+ }
+
+ tm->tm_gmtoff = tm_now.tm_gmtoff;
+
+ return 0;
+}
+
+static int process_header_text_mode(struct msg_list_info *list_info, char *buf, size_t len)
+{
+ char *save = buf;
+ char *token;
+
+ struct sms_msg *msg;
+ int index;
+ int status;
+ char *name;
+ char *timestamp = NULL;
+ int msg_len;
+
+ token = atcmd_response_brk(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at start");
+ return -1;
+ }
+
+ switch (list_info->cmd_type) {
+ case CMD_TYPE_CMGL:
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at index");
+ return -1;
+ }
+ index = atoi(token);
+
+ break;
+ case CMD_TYPE_CMGR:
+ index = list_info->index;
+ break;
+ default:
+ return false;
+ }
+
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at msg-status");
+ return -1;
+ }
+ status = msg_status_name_to_value(token);
+
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at name");
+ return -1;
+ }
+ name = token;
+
+ if (list_info->cmd_type == CMD_TYPE_CMGR) {
+ timestamp = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at timestamp");
+ return -1;
+ }
+ }
+
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at lang");
+ return -1;
+ }
+
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at encode");
+ return -1;
+ }
+
+ if (list_info->cmd_type == CMD_TYPE_CMGR) {
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at prio");
+ return -1;
+ }
+ if (*save == '\"') {
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at callback");
+ return -1;
+ }
+ }
+ }
+
+ token = atcmd_value_tok(&save);
+ if (!token) {
+ log_debug("response tokenizing failed at msg-len");
+ return -1;
+ }
+ msg_len = atoi(token);
+
+ switch (status) {
+ case SMS_MSG_REC_UNREAD:
+ list_info->nr_unread++;
+ break;
+ case SMS_MSG_REC_READ:
+ list_info->nr_read++;
+ break;
+ case SMS_MSG_STO_UNSENT:
+ list_info->nr_unsent++;
+ break;
+ case SMS_MSG_STO_SENT:
+ list_info->nr_sent++;
+ break;
+ default:
+ log_warning("msg-status unknown");
+ list_info->nr_unknown++;
+ }
+
+ msg = sms_msg_alloc();
+ if (!msg) {
+ log_error("out of memory");
+ return -1;
+ }
+
+ memset(msg, 0, sizeof(*msg));
+
+ msg->index = index;
+ msg->status = status;
+ snprintf(msg->name, sizeof(msg->name), "%s", name);
+ msg->len = msg_len;
+ if (timestamp) {
+ decode_timestamp_text_mode(timestamp, &msg->pdu.timestamp);
+ }
+
+ list_add_tail(&msg->list, &list_info->msg_list);
+
+ list_info->nr_msgs++;
+
+ return 0;
+}
+
+static ssize_t readn(int fd, void *buf, size_t len)
+{
+ ssize_t cc;
+ ssize_t total;
+
+ total = 0;
+
+ while (len) {
+ cc = read(fd, buf, len);
+ if (cc <= 0) {
+ return cc;
+ }
+
+ total += cc;
+ buf = buf + cc;
+ len -= cc;
+ }
+
+ log_debug("read: \"%.*J\"", len, buf);
+
+ return total;
+}
+
+static int sms_list_text_mode(int fd, struct msg_list_info *list_info)
+{
+ char buf[ATCMD_LINE_SIZE];
+ int tmp;
+ struct sms_msg *msg;
+
+ while (1) {
+ tmp = atcmd_readline(fd, buf, sizeof(buf));
+ if (tmp <= 0) {
+ return -1;
+ }
+
+ list_info->nr_lines++;
+
+ if (!strncmp(buf, CMGL_HEADER_START, strlen(CMGL_HEADER_START)) ||
+ !strncmp(buf, CMGR_HEADER_START, strlen(CMGR_HEADER_START))) {
+ tmp = process_header_text_mode(list_info, buf, sizeof(buf));
+ if (tmp < 0) {
+ log_debug("process_header_text_mode failed");
+ return -1;
+ }
+
+ if (list_empty(&list_info->msg_list)) {
+ log_debug("empty list");
+ return -1;
+ }
+
+ msg = list_entry(list_info->msg_list.prev, typeof(*msg), list);
+ if (msg->len <= 0) {
+ continue;
+ }
+ if (msg->len >= PDU_UD_SIZE) {
+ continue;
+ }
+
+ list_info->nr_lines++;
+
+ tmp = readn(fd, msg->pdu.user_data, msg->len);
+ if (tmp <= 0) {
+ log_debug("read message failed");
+ return -1;
+ }
+
+ msg->pdu.user_data_len = msg->len;
+ } else if (!strcmp(buf, "OK")) {
+ return 0;
+ } else if (*buf) {
+ log_debug("AT response error: %s", buf);
+
+ return -1;
+ }
+ }
+}
+
static int process_header(struct msg_list_info *list_info, char *buf, size_t len)
{
char *save = buf;
@@ -221,8 +451,8 @@ static int print_list_yaml(struct msg_list_info *list_info)
enum {
LIST_STATE_BLANK,
- LIST_STATE_OPEN,
- LIST_STATE_PDU,
+ LIST_STATE_HEADER,
+ LIST_STATE_DATA,
LIST_STATE_CLOSE,
};
@@ -244,16 +474,16 @@ static int list_info_callback(char *buf, size_t len, void *data)
return -1;
}
- list_info->state = LIST_STATE_OPEN;
+ list_info->state = LIST_STATE_HEADER;
return 0;
- case LIST_STATE_OPEN:
- log_debug("state: LIST_STATE_OPEN");
+ case LIST_STATE_HEADER:
+ log_debug("state: LIST_STATE_HEADER");
if (!strncmp(buf, CMGL_HEADER_START, strlen(CMGL_HEADER_START)) ||
!strncmp(buf, CMGR_HEADER_START, strlen(CMGR_HEADER_START))) {
- list_info->state = LIST_STATE_PDU;
+ list_info->state = LIST_STATE_DATA;
return process_header(list_info, buf, len);
} else if (!strcmp(buf, "OK")) {
@@ -269,8 +499,8 @@ static int list_info_callback(char *buf, size_t len, void *data)
return 0;
}
- case LIST_STATE_PDU:
- log_debug("state: LIST_STATE_PDU");
+ case LIST_STATE_DATA:
+ log_debug("state: LIST_STATE_DATA");
if (list_empty(&list_info->msg_list)) {
log_debug("empty list");
@@ -285,7 +515,7 @@ static int list_info_callback(char *buf, size_t len, void *data)
}
}
- list_info->state = LIST_STATE_OPEN;
+ list_info->state = LIST_STATE_HEADER;
return 0;
@@ -324,7 +554,11 @@ int sms_list_get(int fd, struct msg_list_info *list_info)
switch (list_info->cmd_type) {
case CMD_TYPE_CMGL:
- atcmd_writeline(fd, "AT+CMGL=%d", list_info->status);
+ if (Global.core.sms_mode == SMS_TEXT_MODE) {
+ atcmd_writeline(fd, "AT+CMGL=\"%s\"", msg_status_value_to_name(list_info->status));
+ } else {
+ atcmd_writeline(fd, "AT+CMGL=%d", list_info->status);
+ }
break;
case CMD_TYPE_CMGR:
@@ -335,12 +569,22 @@ int sms_list_get(int fd, struct msg_list_info *list_info)
return -1;
}
- tmp = atcmd_response_foreach_line(fd, list_info_callback, list_info);
- if (tmp < 0) {
- log_error("listing failed");
- sms_list_free(list_info);
+ if (Global.core.sms_mode == SMS_TEXT_MODE) {
+ tmp = sms_list_text_mode(fd, list_info);
+ if (tmp < 0) {
+ log_error("listing failed");
+ sms_list_free(list_info);
- return tmp;
+ return tmp;
+ }
+ } else if (Global.core.sms_mode == SMS_PDU_MODE) {
+ tmp = atcmd_response_foreach_line(fd, list_info_callback, list_info);
+ if (tmp < 0) {
+ log_error("listing failed");
+ sms_list_free(list_info);
+
+ return tmp;
+ }
}
return 0;
diff --git a/src/sms_main.c b/src/sms_main.c
index 92c831f..0138487 100644
--- a/src/sms_main.c
+++ b/src/sms_main.c
@@ -59,6 +59,7 @@ static int global_init(void)
Global.core.msg_store_send = strdup("ME");
Global.core.msg_store_new = strdup("ME");
Global.core.pb_store = strdup("ME");
+ Global.core.sms_mode = SMS_PDU_MODE;
Global.core.editor = strdup("vi");
Global.core.edit_file = strdup("${HOME}/.smsmsg");
@@ -218,6 +219,7 @@ static struct option long_options[] = {
{"msg-store-send", 1, NULL, CMD_OPT_MSG_STORE_SEND},
{"msg-store-new", 1, NULL, CMD_OPT_MSG_STORE_NEW},
{"pb-store", 1, NULL, CMD_OPT_PHONEBOOK_STORE},
+ {"sms-mode", 1, NULL, CMD_OPT_SMS_MODE},
{"interactive", 0, NULL, CMD_OPT_INTERACTIVE},
{"non-interactive", 0, NULL, CMD_OPT_NON_INTERACTIVE},
{"verbose", 0, NULL, CMD_OPT_VERBOSE},
@@ -278,7 +280,7 @@ int main(int argc, char *argv[])
Global.core.baud_rate = atoi(optarg);
Global.core.baud_rate = value_to_baud(Global.core.baud_rate);
if (Global.core.baud_rate == (speed_t) -1) {
- sms_send_help(stderr);
+ usage(stderr);
exit(1);
}
break;
@@ -307,6 +309,17 @@ int main(int argc, char *argv[])
Global.core.pb_store = strdup(optarg);
break;
+ case CMD_OPT_SMS_MODE:
+ if (!strcmp(optarg, "text")) {
+ Global.core.sms_mode = SMS_TEXT_MODE;
+ } else if (!strcmp(optarg, "pdu")) {
+ Global.core.sms_mode = SMS_PDU_MODE;
+ } else {
+ usage(stderr);
+ exit(1);
+ }
+ break;
+
case CMD_OPT_VERSION:
print_version("sms");
exit(0);
diff --git a/src/sms_send.c b/src/sms_send.c
index 8ed7ebb..72b5a13 100644
--- a/src/sms_send.c
+++ b/src/sms_send.c
@@ -39,14 +39,19 @@
#include "pdu_encode.h"
#include "phonebook.h"
+enum {
+ SEND_MODE_CMGW_CMSS,
+ SEND_MODE_CMGS,
+};
+
struct send_options {
char *file;
int alphabet;
const char *smsc_addr;
- int cmgw_first;
+ int send_mode;
};
-static int auto_fill_smsc(int fd, struct pdu_addr *addr)
+static int auto_fill_smsc(int fd, struct sms_addr *addr)
{
char buf[ATCMD_LINE_SIZE];
char *save;
@@ -97,17 +102,17 @@ static int auto_fill_smsc(int fd, struct pdu_addr *addr)
return -1;
}
- return pdu_addr_fill(addr, addr_str, type);
+ return sms_addr_fill(addr, addr_str, type);
}
static int fill_addr(struct phonebook_list_info *list_info,
- struct pdu_addr *addr, const char *addr_str)
+ struct sms_addr *addr, const char *addr_str)
{
struct phonebook_entry *entry;
int type;
int tmp;
- type = pdu_addr_type_infer(addr_str);
+ type = sms_addr_type_infer(addr_str);
if (type != SMS_ADDR_TEXT) {
goto fill;
}
@@ -130,7 +135,7 @@ static int fill_addr(struct phonebook_list_info *list_info,
fill:
- tmp = pdu_addr_fill(addr, addr_str, SMS_ADDR_UNSPEC);
+ tmp = sms_addr_fill(addr, addr_str, SMS_ADDR_UNSPEC);
if (tmp < 0) {
log_debug("pdu fill failed with addr %s", addr_str);
return -1;
@@ -208,7 +213,7 @@ static int do_send(int fd, struct send_options *options, int argc, char **argv)
pdu.data_coding.general.alphabet = options->alphabet;
if (options->smsc_addr) {
- tmp = pdu_addr_fill(&pdu.smsc_addr, options->smsc_addr, SMS_ADDR_UNSPEC);
+ tmp = sms_addr_fill(&pdu.smsc_addr, options->smsc_addr, SMS_ADDR_UNSPEC);
if (tmp < 0) {
return false;
}
@@ -224,18 +229,25 @@ static int do_send(int fd, struct send_options *options, int argc, char **argv)
printf("preparing for send...\n");
}
- if (options->cmgw_first) {
- tmp = pdu_encode(buf, sizeof(buf), &pdu);
- if (tmp < 0) {
- log_error("pdu encode failed");
- return false;
+ if (options->send_mode == SEND_MODE_CMGW_CMSS) {
+ if (Global.core.sms_mode == SMS_PDU_MODE) {
+ tmp = pdu_encode(buf, sizeof(buf), &pdu);
+ if (tmp < 0) {
+ log_error("pdu encode failed");
+ return false;
+ }
}
if (Global.core.verbose) {
printf("writing message to memory\n");
}
- mem_index = atcmd_plus_cmgw_write(fd, buf, pdu.msg_len);
+ if (Global.core.sms_mode == SMS_TEXT_MODE) {
+ mem_index = atcmd_plus_cmgw_write_text(fd, NULL,
+ SMS_ADDR_UNSPEC, NULL, pdu.user_data, pdu.user_data_len);
+ } else {
+ mem_index = atcmd_plus_cmgw_write(fd, buf, pdu.msg_len);
+ }
if (mem_index < 0) {
log_error("write message to memory failed");
return false;
@@ -266,23 +278,30 @@ static int do_send(int fd, struct send_options *options, int argc, char **argv)
continue;
}
- if (options->cmgw_first) {
+ if (options->send_mode == SEND_MODE_CMGW_CMSS) {
tmp = atcmd_plus_cmss_write(fd, mem_index,
- pdu.addr.addr, SMS_ADDR_UNSPEC);
+ pdu.addr.addr, SMS_ADDR_UNSPEC);
if (tmp < 0) {
printf("sending message to %s failed\n", argv[i]);
failed++;
continue;
}
} else {
- tmp = pdu_encode(buf, sizeof(buf), &pdu);
- if (tmp < 0) {
- printf("sending message to %s failed\n", argv[i]);
- failed++;
- continue;
+ if (Global.core.sms_mode == SMS_PDU_MODE) {
+ tmp = pdu_encode(buf, sizeof(buf), &pdu);
+ if (tmp < 0) {
+ printf("sending message to %s failed\n", argv[i]);
+ failed++;
+ continue;
+ }
}
- tmp = atcmd_plus_cmgs_write(fd, buf, pdu.msg_len);
+ if (Global.core.sms_mode == SMS_TEXT_MODE) {
+ tmp = atcmd_plus_cmgs_write_text(fd, pdu.addr.addr,
+ pdu.user_data, pdu.user_data_len);
+ } else {
+ tmp = atcmd_plus_cmgs_write(fd, buf, pdu.msg_len);
+ }
if (tmp < 0) {
printf("sending message to %s failed\n", argv[i]);
failed++;
@@ -305,7 +324,7 @@ static struct option long_options[] = {
{"alphabet", 1, NULL, CMD_OPT_ALPHABET},
{"file", 1, NULL, CMD_OPT_FILE},
{"smsc-addr", 1, NULL, CMD_OPT_SMSC_ADDR},
- {"cmgw-first", 0, NULL, CMD_OPT_CMGW_FIRST},
+ {"send-mode", 1, NULL, CMD_OPT_SEND_MODE},
{NULL, 0, NULL, 0},
};
@@ -315,7 +334,7 @@ void sms_send_help(FILE *out) {
fprintf(out, " --alphabet { seven-bit | eight-bit } |\n");
fprintf(out, " -f, --file <input-file> |\n");
fprintf(out, " --smsc-addr <smsc-addr> |\n");
- fprintf(out, " --cmgw-first\n");
+ fprintf(out, " --send-mode { cmgw-cmss | cmgs } \n");
fprintf(out, " }\n");
fprintf(out, "\n");
}
@@ -330,9 +349,8 @@ int sms_send(int argc, char **argv)
struct send_options options;
options.alphabet = PDU_ALPHABET_DEFAULT;
options.file = NULL;
- options.cmgw_first = false;
+ options.send_mode = SEND_MODE_CMGS;
options.smsc_addr = NULL;
- options.cmgw_first = false;
while ((i = getopt_long(argc, argv, short_options, long_options, &option_index)) >= 0) {
switch (i) {
@@ -344,6 +362,9 @@ int sms_send(int argc, char **argv)
options.alphabet = PDU_ALPHABET_DEFAULT;
} else if (!strcmp(optarg, "eight-bit")) {
options.alphabet = PDU_ALPHABET_EIGHT;
+ } else {
+ sms_send_help(stderr);
+ return false;
}
break;
@@ -355,8 +376,15 @@ int sms_send(int argc, char **argv)
options.smsc_addr = optarg;
break;
- case CMD_OPT_CMGW_FIRST:
- options.cmgw_first = true;
+ case CMD_OPT_SEND_MODE:
+ if (!strcmp(optarg, "cmgw-cmss")) {
+ options.send_mode = SEND_MODE_CMGW_CMSS;
+ } else if (!strcmp(optarg, "cmgs")) {
+ options.send_mode = SEND_MODE_CMGS;
+ } else {
+ sms_send_help(stderr);
+ return false;
+ }
break;
default: