From 223246228c5224a91147a98dc394ea60efab81ef Mon Sep 17 00:00:00 2001 From: James Maki Date: Wed, 28 Apr 2010 09:57:12 -0500 Subject: optional at command init --- README | 92 +++++++++++++++++++++++++++++++++++++++++++++++++- src/atcmd.c | 74 ++++++++++++++++++++++++++++++++++------ src/atcmd.h | 2 ++ src/global.h | 2 ++ src/pdu_encode.c | 2 +- src/sms.config.example | 1 + src/sms_config.c | 2 ++ src/sms_delete.c | 10 +----- src/sms_list.c | 10 +----- src/sms_main.c | 24 +++++++++++-- src/sms_send.c | 10 +----- 11 files changed, 187 insertions(+), 42 deletions(-) diff --git a/README b/README index a31a6cb..f5e88a0 100644 --- a/README +++ b/README @@ -1,3 +1,93 @@ -SMS command line utilities for Linux +Description: + +SMS command line utilities for Linux. + +Introduction: Command line utility to send, list, read, delete SMS messages from your mobile device. + +Motivation: + +Send text messages from the command line using vi. + +Setup: + +Copy src/sms.config.example to your home directory and edit it to fit. + + cp src/sms.config.example ${HOME}/.smsconfig + vi ${HOME}/.smsconfig + ... + +Options found in your local .smsconfig override the compile time defaults. Command +line options override options in .smsconfig. + + +Sending messages: + +By default or when interactive mode is enabled and an editor is configured, sending +an SMS will pop you into your editor to create the message. The length of the +message will be truncated without warning to the maximum message length in the +selected alphabet. Seven-bit mode can contain up to 160 characters. Eight-bit mode +can contain up to 140 bytes. + +To send an SMS to 1234567890 issue the command: + +sms send 1234567890 + +If all goes well there should be no errors or warning messages +printed to stderr and the program should exit with 0. + +The validity period is not configurable and will be set to 2 days out from +the time of send. + +If the address specified contains any non-digit and non-command characters, the +selected phonebook will be searched for a match. In interactive mode a substring +search is performed and the user is prompted with any matches found. In +non-interactive mode an exact match must be found. + +Listing messages: + +You can read the messages stored in the selected storage areas by issuing the +command: + +sms list all + +If you only wanted to list unread messages then issue the command: + +sms list unread + +The output is in YAML which is both readable and easily parsed. Other output formats +such as XML could be added as well. + +Reading a messages: + +To read the message at index 1 issue the command: + +sms read 1 + +After the read command completes the message at index 1 will be +marked as read. + + +Deleting messages: + +You can delete a message by its status {unread, read, sent, unsent}, by index, or +all messages. + +To delete a message at index 1 issue the command: + +sms delete index 1 + +To delete all messages issue the command: + +sms delete all + +To delete only read messages issue: + +sms delete read + + +Future: + +Add TCP client/server mode support. + diff --git a/src/atcmd.c b/src/atcmd.c index 10470c1..55d2ebc 100644 --- a/src/atcmd.c +++ b/src/atcmd.c @@ -566,6 +566,21 @@ int atcmd_e_write(int fd, int mode) return 0; } +int atcmd_v_write(int fd, int mode) +{ + char buf[ATCMD_LINE_SIZE]; + int tmp; + + atcmd_writeline(fd, "ATV%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]; @@ -1045,30 +1060,39 @@ int atcmd_plus_cpbr_test(int fd, struct phonebook_store *store) int atcmd_init(int fd, int read_timeout) { - char buf[ATCMD_LINE_SIZE]; int tmp; - tmp = tty_set_read_timeout(fd, read_timeout); + tmp = atcmd_v_write(fd, 1); 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; } + return 0; +} + +static int sms_atcmd_init(int fd) +{ + int tmp; + struct msg_store read_store; struct msg_store send_store; struct msg_store new_store; + tmp = atcmd_init(fd, Global.core.read_timeout); + if (tmp < 0) { + return -1; + } + + tmp = atcmd_plus_cmgf_write(fd, SMS_PDU_MODE); + if (tmp < 0) { + return -1; + } + memset(&read_store, 0, sizeof(read_store)); memset(&send_store, 0, sizeof(send_store)); memset(&new_store, 0, sizeof(new_store)); @@ -1079,9 +1103,39 @@ int atcmd_init(int fd, int read_timeout) &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, + tmp = atcmd_plus_cpms_write(fd, Global.core.msg_store_read, Global.core.msg_store_send, Global.core.msg_store_new); + if (tmp < 0) { + return -1; + } } return 0; } + +int sms_device_open(void) +{ + int fd; + int tmp; + + fd = tty_open(Global.core.device, Global.core.baud_rate); + if (fd < 0) { + return -1; + } + + tmp = tty_set_read_timeout(fd, Global.core.read_timeout); + if (tmp < 0) { + close(fd); + return tmp; + } + + if (Global.core.sms_init) { + tmp = sms_atcmd_init(fd); + if (tmp < 0) { + close(fd); + return tmp; + } + } + + return fd; +} diff --git a/src/atcmd.h b/src/atcmd.h index 692a711..8fbd240 100644 --- a/src/atcmd.h +++ b/src/atcmd.h @@ -58,6 +58,7 @@ typedef int (*atcmd_response_callback_t)(char *buf, size_t len, void *prv); int atcmd_response_foreach_line(int fd, atcmd_response_callback_t call, void *prv); int atcmd_e_write(int fd, int mode); +int atcmd_v_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_cmgs_write(int fd, const char *msg, size_t msg_len); @@ -107,6 +108,7 @@ int atcmd_plus_cpbs_write(int fd, const char *name); int atcmd_plus_cpbr_test(int fd, struct phonebook_store *store); int atcmd_init(int fd, int read_timeout); +int sms_device_open(void); #if __ATCMD_C const char *abort_dfl[] = { diff --git a/src/global.h b/src/global.h index ccfb6b4..4a73d9e 100644 --- a/src/global.h +++ b/src/global.h @@ -20,6 +20,7 @@ struct global_user { struct global_core { speed_t baud_rate; int read_timeout; + int sms_init; char *device; int verbose; int interactive; @@ -61,6 +62,7 @@ struct global_config Global = { .core = { .verbose = false, .interactive = true, + .sms_init = true, .baud_rate = B115200, .read_timeout = 5000, .device = DEFAULT_DEVICE, diff --git a/src/pdu_encode.c b/src/pdu_encode.c index 704bc5b..30cb4a9 100644 --- a/src/pdu_encode.c +++ b/src/pdu_encode.c @@ -72,8 +72,8 @@ int pdu_encode_timestamp(char *pdu_str, size_t len, struct tm *tm) snprintf(pdu_str + GMT_OFFSET_IDX, 2, "%X", off_upper & 0xF); snprintf(pdu_str + GMT_OFFSET_IDX + 1, 2, "%X", off_lower & 0xF); - nibble_swap(pdu_str, PDU_TIMESTAMP_LEN); strpad(pdu_str, PDU_TIMESTAMP_LEN, 'F'); + nibble_swap(pdu_str, PDU_TIMESTAMP_LEN); log_debug("%s", pdu_str); diff --git a/src/sms.config.example b/src/sms.config.example index 96ee1b0..9f6c903 100644 --- a/src/sms.config.example +++ b/src/sms.config.example @@ -5,6 +5,7 @@ user: core: verbose: false interactive: true + sms-init: true baud-rate: 115200 read-timeout: 5000 device: /dev/ttyS1 diff --git a/src/sms_config.c b/src/sms_config.c index 79271a3..0fa4173 100644 --- a/src/sms_config.c +++ b/src/sms_config.c @@ -109,6 +109,8 @@ static int config_set_core_value(const char *key, const char *value) Global.core.verbose = boolean_value(value); } else if (!strcmp("interactive", key)) { Global.core.interactive = boolean_value(value); + } else if (!strcmp("sms-init", key)) { + Global.core.sms_init = boolean_value(value); } else if (!strcmp("baud-rate", key)) { Global.core.baud_rate = atoi(value); Global.core.baud_rate = value_to_baud(Global.core.baud_rate); diff --git a/src/sms_delete.c b/src/sms_delete.c index bcef866..aee01dd 100644 --- a/src/sms_delete.c +++ b/src/sms_delete.c @@ -90,12 +90,6 @@ static int do_delete(int fd, int argc, char **argv) printf("preparing for delete...\n"); } - tmp = atcmd_plus_cmgf_write(fd, SMS_PDU_MODE); - if (tmp < 0) { - log_error("atcmd_plus_cmgf_write failed"); - return false; - } - tmp = sms_list_get(fd, &list_info); if (tmp < 0) { log_error("failed to get msg list"); @@ -166,12 +160,10 @@ int sms_delete(int argc, char **argv) argc -= optind; argv += optind; - fd = tty_open(Global.core.device, Global.core.baud_rate); + fd = sms_device_open(); if (fd < 0) { - fprintf(stderr, "failed to open tty device %s\n", Global.core.device); return false; } - atcmd_init(fd, Global.core.read_timeout); ret = do_delete(fd, argc, argv); diff --git a/src/sms_list.c b/src/sms_list.c index 0f9a9e6..4e815fc 100644 --- a/src/sms_list.c +++ b/src/sms_list.c @@ -322,12 +322,6 @@ int sms_list_get(int fd, struct msg_list_info *list_info) list_info->nr_unknown = 0; list_info->nr_msgs = 0; - tmp = atcmd_plus_cmgf_write(fd, SMS_PDU_MODE); - if (tmp < 0) { - log_error("setting pdu mode failed"); - return -1; - } - switch (list_info->cmd_type) { case CMD_TYPE_CMGL: atcmd_writeline(fd, "AT+CMGL=%d", list_info->status); @@ -487,12 +481,10 @@ int sms_list(int argc, char **argv) argc -= optind; argv += optind; - fd = tty_open(Global.core.device, Global.core.baud_rate); + fd = sms_device_open(); if (fd < 0) { - fprintf(stderr, "failed to open tty device %s\n", Global.core.device); return false; } - atcmd_init(fd, Global.core.read_timeout); ret = do_list(fd, cmd_type, argc, argv); diff --git a/src/sms_main.c b/src/sms_main.c index 5dda451..f319019 100644 --- a/src/sms_main.c +++ b/src/sms_main.c @@ -52,12 +52,10 @@ static int pb_list(int argc, char **argv) int fd; int ret; - fd = tty_open(Global.core.device, Global.core.baud_rate); + fd = sms_device_open(); if (fd < 0) { - fprintf(stderr, "failed to open tty device %s\n", Global.core.device); return false; } - atcmd_init(fd, Global.core.read_timeout); ret = print_phonebook_list(fd, Global.core.pb_store); @@ -66,6 +64,22 @@ static int pb_list(int argc, char **argv) return ret; } +static int sms_init(int argc, char **argv) +{ + int fd; + + Global.core.sms_init = true; + + fd = sms_device_open(); + if (fd < 0) { + return false; + } + + tty_close(fd); + + return true; +} + static struct sms_cmd top_cmds[] = { { .object = "send", @@ -93,6 +107,10 @@ static struct sms_cmd top_cmds[] = { .object = "pb-list", .call = pb_list, }, + { + .object = "sms-init", + .call = sms_init, + }, { .object = NULL, .call = NULL, diff --git a/src/sms_send.c b/src/sms_send.c index 3cae12e..7099c06 100644 --- a/src/sms_send.c +++ b/src/sms_send.c @@ -224,12 +224,6 @@ static int do_send(int fd, struct send_options *options, int argc, char **argv) printf("preparing for send...\n"); } - tmp = atcmd_plus_cmgf_write(fd, SMS_PDU_MODE); - if (tmp < 0) { - log_error("setting pdu mode failed"); - return false; - } - if (options->cmgw_first) { tmp = pdu_encode(buf, sizeof(buf), &pdu); if (tmp < 0) { @@ -377,12 +371,10 @@ int sms_send(int argc, char **argv) argc -= optind; argv += optind; - fd = tty_open(Global.core.device, Global.core.baud_rate); + fd = sms_device_open(); if (fd < 0) { - fprintf(stderr, "failed to open tty device %s\n", Global.core.device); return false; } - atcmd_init(fd, Global.core.read_timeout); ret = do_send(fd, &options, argc, argv); -- cgit v1.2.3