diff --git a/application/tom_modem/Makefile b/application/tom_modem/Makefile index 31b0a72..c65cd84 100644 --- a/application/tom_modem/Makefile +++ b/application/tom_modem/Makefile @@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:= tom_modem -PKG_RELEASE:=beta-1 -PKG_VERSION:=0.9.1 +PKG_RELEASE:=beta-2 +PKG_VERSION:=0.9.2 include $(INCLUDE_DIR)/package.mk @@ -13,6 +13,12 @@ define Package/$(PKG_NAME) TITLE:=Fujr Modem Communite Tool endef +define Package/$(PKG_NAME)/config + config PACKAGE_$(PKG_NAME)_EARLY_RETURN + bool "Early return" + default y +endef + define Package/$(PKG_NAME)/description Modem Communite Tool for 5G modem (By Fujr) endef @@ -23,6 +29,9 @@ define Build/Prepare endef define Build/Compile + ifdef CONFIG_PACKAGE_$(PKG_NAME)_EARLY_RETURN + TARGET_CFLAGS+=-DEARLY_RETURN + else $(MAKE) -C $(PKG_BUILD_DIR) \ $(TARGET_CONFIGURE_OPTS) CFLAGS="$(TARGET_CFLAGS)" endef diff --git a/application/tom_modem/src/Makefile b/application/tom_modem/src/Makefile index 85f4a61..35bb93e 100644 --- a/application/tom_modem/src/Makefile +++ b/application/tom_modem/src/Makefile @@ -1,8 +1,8 @@ TARGET = tom_modem -CFLAGS = -Wall -Ipdu_lib +CFLAGS ?= -Wall -Iextlib -SRCS = main.c utils.c pdu_lib/pdu.c pdu_lib/ucs2_to_utf8.c +SRCS = main.c utils.c extlib/pdu.c extlib/ucs2_to_utf8.c OBJS = $(SRCS:.c=.o) @@ -19,6 +19,8 @@ clean: .PHONY:clean clean: rm -rf *.o *.*~ *~ *.swap $(all) + rm -rf $(TARGET) + rm -rf extlib/*.o depend: $(CC) $(CFLAGS) -MM $(SRCS) > .depend diff --git a/application/tom_modem/src/pdu_lib/pdu.c b/application/tom_modem/src/extlib/pdu.c similarity index 100% rename from application/tom_modem/src/pdu_lib/pdu.c rename to application/tom_modem/src/extlib/pdu.c diff --git a/application/tom_modem/src/pdu_lib/pdu.h b/application/tom_modem/src/extlib/pdu.h similarity index 100% rename from application/tom_modem/src/pdu_lib/pdu.h rename to application/tom_modem/src/extlib/pdu.h diff --git a/application/tom_modem/src/pdu_lib/pdu_decoder.c b/application/tom_modem/src/extlib/pdu_decoder.c similarity index 100% rename from application/tom_modem/src/pdu_lib/pdu_decoder.c rename to application/tom_modem/src/extlib/pdu_decoder.c diff --git a/application/tom_modem/src/pdu_lib/ucs2_to_utf8.c b/application/tom_modem/src/extlib/ucs2_to_utf8.c similarity index 100% rename from application/tom_modem/src/pdu_lib/ucs2_to_utf8.c rename to application/tom_modem/src/extlib/ucs2_to_utf8.c diff --git a/application/tom_modem/src/main.c b/application/tom_modem/src/main.c index bf3775a..e659fd6 100644 --- a/application/tom_modem/src/main.c +++ b/application/tom_modem/src/main.c @@ -1,27 +1,8 @@ -#include "modem_types.h" + #include "main.h" -#include "utils.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -FILE *fdi; // file descriptor for input -FILE *fdo; // file descriptor for output -int tty_fd; // file descriptor for tty device +FDS_T s_fds; PROFILE_T s_profile; // global profile -char *self_name; // program name -void _timeout(int signo) -{ - err_msg("Exit with Signal %d", signo); - kill(getpid(), SIGINT); -} int parse_user_input(int argc, char *argv[], PROFILE_T *profile) { @@ -34,8 +15,8 @@ int parse_user_input(int argc, char *argv[], PROFILE_T *profile) option = match_option(argv[opt]); if (option == -1) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } opt++; switch (option) @@ -43,72 +24,72 @@ int parse_user_input(int argc, char *argv[], PROFILE_T *profile) case AT_CMD: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->at_cmd = argv[opt++]; break; case TTY_DEV: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->tty_dev = argv[opt++]; break; case BAUD_RATE: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->baud_rate = atoi(argv[opt++]); break; case DATA_BITS: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->data_bits = atoi(argv[opt++]); break; case PARITY: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->parity = argv[opt++]; break; case STOP_BITS: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->stop_bits = atoi(argv[opt++]); break; case FLOW_CONTROL: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->flow_control = argv[opt++]; break; case TIMEOUT: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->timeout = atoi(argv[opt++]); break; case OPERATION: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->op = match_operation(argv[opt++]); break; @@ -118,16 +99,16 @@ int parse_user_input(int argc, char *argv[], PROFILE_T *profile) case SMS_PDU: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->sms_pdu = argv[opt++]; break; case SMS_INDEX: if (!has_more_argv()) { - usage(); - return -1; + usage(argv[0]); + return INVALID_PARAM; } profile->sms_index = atoi(argv[opt++]); break; @@ -153,53 +134,57 @@ int parse_user_input(int argc, char *argv[], PROFILE_T *profile) { profile->op = AT_OP; } - + return SUCCESS; } - -int run_op(PROFILE_T *profile) +int run_op(PROFILE_T *profile,FDS_T *fds) { switch (profile->op) { case AT_OP: - at(profile); - break; + return at(profile,fds); case SMS_READ_OP: - sms_read(profile); - break; + return sms_read(profile,fds); case SMS_SEND_OP: - sms_send(profile); - break; + return sms_send(profile,fds); case SMS_DELETE_OP: - sms_delete(profile); - break; + return sms_delete(profile,fds); default: err_msg("Invalid operation"); - break; } + return UNKNOWN_ERROR; +} +static void clean_up() +{ + if (tcsetattr(s_fds.tty_fd, TCSANOW, &s_fds.old_termios) != 0) + { + err_msg("Error restoring old tty attributes"); + return; + } + dbg_msg("Clean up success"); + tcflush(s_fds.tty_fd, TCIOFLUSH); + if (s_fds.tty_fd >= 0) + close(s_fds.tty_fd); } int main(int argc, char *argv[]) { - int ret; - // init - self_name = argv[0]; PROFILE_T *profile = &s_profile; + FDS_T *fds = &s_fds; parse_user_input(argc, argv, profile); dump_profile(); - signal(SIGALRM, _timeout); - // try open tty devices - if (open_tty_device(profile)) + if (tty_open_device(profile,fds)) { err_msg("Failed to open tty device"); - return -1; + return COMM_ERROR; } - if (run_op(profile)) + atexit(clean_up); + if (run_op(profile,fds)) { err_msg("Failed to run operation %d", profile->op); - return -1; + kill(getpid(), SIGINT); } dbg_msg("Exit"); - return 0; + return SUCCESS; } diff --git a/application/tom_modem/src/main.h b/application/tom_modem/src/main.h index 6a95996..77b1c6e 100644 --- a/application/tom_modem/src/main.h +++ b/application/tom_modem/src/main.h @@ -1,7 +1,5 @@ #ifndef _MAIN_H_ #define _MAIN_H_ -#include "modem_types.h" -#include "main.h" #include #include #include @@ -11,23 +9,24 @@ #include #include #include +#include "operations.h" +#include "ttydevice.h" +#include "modem_types.h" +#include "utils.h" #define DEFAULT_TIMEOUT 3 // -extern FILE *fdi; // file descriptor for input -extern FILE *fdo; // file descriptor for output -extern int tty_fd; // file descriptor for tty device + extern PROFILE_T s_profile; // global profile -extern char *self_name; // program name -extern struct termios oldtio; // old tty setting -extern int at(PROFILE_T *profile); -extern int sms_read(PROFILE_T *profile); +extern int at(PROFILE_T *profile,FDS_T *fds); -extern int sms_send(PROFILE_T *profile); +extern int sms_read(PROFILE_T *profile,FDS_T *fds); -extern int sms_delete(PROFILE_T *profile); +extern int sms_send(PROFILE_T *profile,FDS_T *fds); + +extern int sms_delete(PROFILE_T *profile,FDS_T *fds); extern void dump_profile(); @@ -35,8 +34,8 @@ extern int match_option(char *option_name); extern int match_operation(char *operation_name); -extern int open_tty_device(PROFILE_T *profile); +extern int open_tty_device(PROFILE_T *profile,FDS_T *fds); -extern int usage(); +extern int usage(char* name); #endif diff --git a/application/tom_modem/src/modem_types.h b/application/tom_modem/src/modem_types.h index 6c19849..670d028 100644 --- a/application/tom_modem/src/modem_types.h +++ b/application/tom_modem/src/modem_types.h @@ -1,7 +1,9 @@ #ifndef _MODEM_TYPES_H_ #define _MODEM_TYPES_H_ - +#include +#include +#include //options #define AT_CMD_S 'c' #define TTY_DEV_S 'd' @@ -80,12 +82,20 @@ typedef struct _PROFILE { int sms_index; } PROFILE_T; + +typedef struct _FDS { + int tty_fd; + struct termios old_termios; + FILE *fdi; + FILE *fdo; +} FDS_T; + typedef struct _SMS { int sms_index; int sms_lenght; int ref_number; int segment_number; - int timestamp; + time_t timestamp; int total_segments; int type; char *sender; @@ -93,6 +103,15 @@ typedef struct _SMS { char *sms_pdu; } SMS_T; +enum ERROR_CODES { + COMM_ERROR = -1, + SUCCESS = 0, + KEYWORD_NOT_MATCH, + TIMEOUT_WAITING_NEWLINE, + INVALID_PARAM, + UNKNOWN_ERROR, +}; + enum SMS_CHARSET { SMS_CHARSET_7BIT, SMS_CHARSET_UCS2 @@ -121,5 +140,5 @@ enum OPERATIONS { SMS_DELETE_OP }; - +char *self_name; // program name #endif diff --git a/application/tom_modem/src/operations.c b/application/tom_modem/src/operations.c new file mode 100644 index 0000000..fcf795f --- /dev/null +++ b/application/tom_modem/src/operations.c @@ -0,0 +1,191 @@ +#include "operations.h" + +int at(PROFILE_T *profile,FDS_T *fds) +{ + int w_ret,r_ret; + char output[COMMON_BUF_SIZE] = {0}; + if (profile->at_cmd == NULL) + { + err_msg("AT command is empty"); + return INVALID_PARAM; + } + w_ret = tty_write(fds->fdo, profile->at_cmd); + if (w_ret) + { + return w_ret; + } + + r_ret = tty_read(fds->fdi, output, COMMON_BUF_SIZE,profile->timeout); + if (r_ret) + { + dbg_msg("Error sending AT command, error code: %d", r_ret); + if (r_ret == COMM_ERROR) + return r_ret; + } + user_msg("%s", output); + return SUCCESS; +} +int sms_delete(PROFILE_T *profile,FDS_T *fds) +{ + int w_ret,r_ret; + if (profile->sms_index < 0) + { + err_msg("SMS index is empty"); + return INVALID_PARAM; + } + char *delete_sms_cmd; + delete_sms_cmd = (char *)malloc(32); + snprintf(delete_sms_cmd, 32, DELETE_SMS, profile->sms_index); + w_ret = tty_write(fds->fdo, delete_sms_cmd); + if (w_ret) + { + return w_ret; + } + r_ret = tty_read_keyword(fds->fdi, NULL, COMMON_BUF_SIZE, "OK",profile->timeout); + if (r_ret) + { + dbg_msg("Error deleting SMS, error code: %d", r_ret); + if (r_ret == COMM_ERROR) + return COMM_ERROR; + } + return SUCCESS; +} +int sms_read(PROFILE_T *profile,FDS_T *fds) +{ + SMS_T *sms_list[SMS_LIST_SIZE]; + SMS_T *sms; + int w_ret,r_ret; + char sms_pdu[SMS_BUF_SIZE] = {0}; + w_ret = tty_write(fds->fdo, SET_PDU_FORMAT); + if (w_ret) + { + return w_ret; + } + r_ret = tty_read_keyword(fds->fdi, NULL, COMMON_BUF_SIZE, "OK",profile->timeout); + if (r_ret) + { + dbg_msg("Error setting PDU format , error code: %d", r_ret); + if (r_ret == COMM_ERROR) + return r_ret; + } + dbg_msg("Set PDU format success"); + w_ret = tty_write(fds->fdo, READ_ALL_SMS); + if (w_ret) + { + return w_ret; + } + r_ret = tty_read_keyword(fds->fdi, sms_pdu, SMS_BUF_SIZE, "OK",profile->timeout); + if (r_ret) + { + dbg_msg("Error reading SMS , error code: %d", r_ret); + if (r_ret == COMM_ERROR) + return r_ret; + } + + + + //遍历 sms_pdu 的每一行 + char *line = strtok(sms_pdu, "\n"); + int sms_count = 0; + while (line != NULL) + { + if (strncmp(line, "+CMGL:", 6) == 0) + { + sms = (SMS_T *)malloc(sizeof(SMS_T)); + memset(sms, 0, sizeof(SMS_T)); + char *pdu = strtok(NULL, "\n"); + sms->sms_pdu = (char *)malloc(strlen(pdu)); + sms->sender = (char *)malloc(PHONE_NUMBER_SIZE); + sms->sms_text = (char *)malloc(SMS_TEXT_SIZE); + sms->sms_index = get_sms_index(line); + memcpy(sms->sms_pdu, pdu, strlen(pdu)); + int sms_len = decode_pdu(sms); + if (sms_len > 0) + { + sms_list[sms_count] = sms; + sms_count++; + } + else + { + dbg_msg("Error decoding sms"); + destroy_sms(sms); + } + } + line = strtok(NULL, "\n"); + } + + + display_sms_in_json(sms_list,sms_count); + // for (int i = 1; i <= sms_count; i++) + // { + // dump_sms(sms_list[i]); + // destroy_sms(sms_list[i]); + // } + dbg_msg("Read SMS success"); + dbg_msg("%s", sms_pdu); + return SUCCESS; +} +int sms_send(PROFILE_T *profile,FDS_T *fds) +{ + int w_ret,r_ret; + if (profile->sms_pdu == NULL) + { + err_msg("SMS PDU is empty"); + return INVALID_PARAM; + } + + int pdu_len = strlen(profile->sms_pdu); + int pdu_expected_len = (pdu_len) / 2 - 1; + char *send_sms_cmd; + char *write_pdu_cmd; + w_ret = tty_write(fds->fdo, SET_PDU_FORMAT); + if (w_ret) + { + return w_ret; + } + r_ret = tty_read_keyword(fds->fdi, NULL, COMMON_BUF_SIZE, "OK",profile->timeout); + if (r_ret) + { + dbg_msg("Error setting PDU format , error code: %d", r_ret); + if (r_ret == COMM_ERROR) + return r_ret; + } + dbg_msg("Set PDU format success"); + send_sms_cmd = (char *)malloc(32); + write_pdu_cmd = (char *)malloc(256); + snprintf(send_sms_cmd, 32, SEND_SMS, pdu_expected_len); + dbg_msg("Send SMS command: %s", send_sms_cmd); + snprintf(write_pdu_cmd, 256, "%s%c", profile->sms_pdu, 0x1A); + dbg_msg("Write PDU command: %s", write_pdu_cmd); + w_ret = tty_write(fds->fdo, send_sms_cmd); + if (w_ret) + { + return w_ret; + } + r_ret = tty_read_keyword(fds->fdi, NULL, COMMON_BUF_SIZE, ">",profile->timeout); + if (r_ret) + { + dbg_msg("Error sending SMS STEP 1, error code: %d", r_ret); + if (r_ret == COMM_ERROR) + return COMM_ERROR; + } + usleep(10000); + w_ret = tty_write(fds->fdo, write_pdu_cmd); + if (w_ret) + { + return w_ret; + } + r_ret = tty_read_keyword(fds->fdi, NULL, COMMON_BUF_SIZE, "+CMGS:",profile->timeout); + if (r_ret) + { + dbg_msg("Error sending SMS STEP 2, error code: %d", r_ret); + if (r_ret == COMM_ERROR) + return COMM_ERROR; + } + + free(send_sms_cmd); + free(write_pdu_cmd); + + + return 0; +} diff --git a/application/tom_modem/src/operations.h b/application/tom_modem/src/operations.h new file mode 100644 index 0000000..75531b0 --- /dev/null +++ b/application/tom_modem/src/operations.h @@ -0,0 +1,10 @@ +#ifndef OPERATION_H +#define OPERATION_H +#include "modem_types.h" +#include "ttydevice.h" +#include "utils.h" +int tty_open_device(PROFILE_T *profile, FDS_T *fds); +int tty_read(FILE *fdi, char *output, int len, int soft_timeout); +int tty_read_keyword(FILE *fdi, char *output, int len, char *key_word, int soft_timeout); +int tty_write(FILE *fdo, char *input); +#endif diff --git a/application/tom_modem/src/pdu_lib/Makefile b/application/tom_modem/src/pdu_lib/Makefile deleted file mode 100644 index 4985007..0000000 --- a/application/tom_modem/src/pdu_lib/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -ALL: pdu_decoder - -#CROSS_COMPILE=mips-openwrt-linux- - -#CC = $(CROSS_COMPILE)gcc - -#CFLAGS = -O2 - -pdu.o: - $(CC) $(CFLAGS) -c pdu.c -pdu_decoder.o: - $(CC) $(CFLAGS) -c pdu_decoder.c -ucs2_to_utf8: - $(CC) $(CFLAGS) -c ucs2_to_utf8.c -pdu_decoder: pdu.o pdu_decoder.o ucs2_to_utf8 - $(CC) $(CFLAGS) ucs2_to_utf8.o pdu.o pdu_decoder.o -o pdu_decoder -clean: - rm -f *.o pdu_decoder -test: clean ALL - echo "0891683108501405F8240BA10156686616F60008414090912385235C6D4191CF6C4752A860015BC67801FF1A00350030003900360036FF0C4EB2FF0C8BB05F9762BD59566BCF592990FD8981676554E6FF0C611F89C9597D76848BDD63A883507ED960A87684670B53CBFF019884795D60A84E2D5956FF01"|./pdu_decoder - echo "0891683108501405F8640BA10156686616F6000841400100957423830608048A3002026B21767B5F556D4191CF6C475373900100356D4191CF5E01FF0853EF63620035004D6D4191CFFF09FF0C731B623394FE63A5FF1A0068007400740070003A002F002F007300680061006B0065002E00730064002E006300680069006E0061006D006F00620069006C0065002E0063006F006D30025C714E1C79FB52A8"|./pdu_decoder diff --git a/application/tom_modem/src/ttydevice.c b/application/tom_modem/src/ttydevice.c new file mode 100644 index 0000000..3569985 --- /dev/null +++ b/application/tom_modem/src/ttydevice.c @@ -0,0 +1,210 @@ +#include "ttydevice.h" +static int tty_set_device(PROFILE_T *profile, FDS_T *fds) +{ + int baud_rate, data_bits; + struct termios tty; + baud_rate = profile->baud_rate; + data_bits = profile->data_bits; + if (tcgetattr(fds->tty_fd, &tty) != 0) + { + err_msg("Error getting tty attributes"); + return COMM_ERROR; + } + memmove(&fds->old_termios, &tty, sizeof(struct termios)); + cfmakeraw(&tty); + tty.c_cflag |= CLOCAL; // 忽略调制解调器控制线,允许本地连接 + tty.c_cflag |= CREAD; // 使能接收 + + // clear flow control ,stop bits parity + tty.c_cflag &= ~CRTSCTS; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~PARENB; + tty.c_oflag &= ~OPOST; + tty.c_cc[VMIN] = 0; + tty.c_cc[VTIME] = 1; + + // set data bits 5,6,7,8 + tty.c_cflag &= ~CSIZE; // 清除数据位设置 + switch (data_bits) + { + case 5: + tty.c_cflag |= CS5; + break; + case 6: + tty.c_cflag |= CS6; + break; + case 7: + tty.c_cflag |= CS7; + break; + case 8: + tty.c_cflag |= CS8; + break; + default: + tty.c_cflag |= CS8; + break; + } + + // set baud rate + switch (baud_rate) + { + case 4800: + cfsetspeed(&tty, B4800); + break; + case 9600: + cfsetspeed(&tty, B9600); + break; + case 19200: + cfsetspeed(&tty, B19200); + break; + case 38400: + cfsetspeed(&tty, B38400); + break; + case 57600: + cfsetspeed(&tty, B57600); + break; + case 115200: + cfsetspeed(&tty, B115200); + break; + + default: + cfsetspeed(&tty, B115200); + break; + } + if (tcsetattr(fds->tty_fd, TCSANOW, &tty) != 0) + { + err_msg("Error setting tty attributes"); + return COMM_ERROR; + } + return SUCCESS; +} +int tty_open_device(PROFILE_T *profile,FDS_T *fds) +{ + fds->tty_fd = open(profile->tty_dev, O_RDWR | O_NOCTTY); + if (fds->tty_fd < 0) + { + err_msg("Error opening tty device: %s", profile->tty_dev); + return COMM_ERROR; + } + + if (tty_set_device(profile,fds) != 0) + { + err_msg("Error setting tty device"); + return COMM_ERROR; + } + tcflush(fds->tty_fd, TCIOFLUSH); + if (fds->tty_fd >= 0) + close(fds->tty_fd); + else + return COMM_ERROR; + fds->tty_fd = open(profile->tty_dev, O_RDWR | O_NOCTTY | O_NONBLOCK); + fds->fdi = fdopen(fds->tty_fd, "r"); + fds->fdo = fdopen(fds->tty_fd, "w"); + if (fds->fdi == NULL || fds->fdo == NULL) + { + err_msg("Error opening file descriptor"); + return COMM_ERROR; + } + + if (setvbuf(fds->fdo , NULL, _IOFBF, 0)) + { + err_msg("Error setting buffer for fdi"); + return COMM_ERROR; + } + + if (setvbuf(fds->fdi , NULL, _IOLBF, 0)) + { + err_msg("Error setting buffer for fdi"); + return COMM_ERROR; + } + return SUCCESS; +} + +int tty_read(FILE *fdi, char *output, int len, int soft_timeout) +{ + return tty_read_keyword(fdi, output, len, NULL, soft_timeout); +} + +int tty_read_keyword(FILE *fdi, char *output, int len, char *key_word, int soft_timeout) +{ + char tmp[LINE_BUF] = {0}; + int msg_len = 0; + int read_flag = 0; + time_t start_time = time(NULL); + int exitcode = TIMEOUT_WAITING_NEWLINE; + while (difftime(time(NULL), start_time) < soft_timeout) + { + if (fgets(tmp, LINE_BUF, fdi)) + { + read_flag = 1; + dbg_msg("%s", tmp); + if (output != NULL) + msg_len += snprintf(output + msg_len, len - msg_len, "%s", tmp); + + if (strncmp(tmp, "OK", 2) == 0 || + strncmp(tmp, "ERROR", 5) == 0 || + strncmp(tmp, "+CMS ERROR:", 11) == 0 || + strncmp(tmp, "+CME ERROR:", 11) == 0 || + strncmp(tmp, "NO CARRIER", 10) == 0 || + (key_word != NULL && strncmp(tmp, key_word, strlen(key_word)) == 0)) + { + if (key_word != NULL && strncmp(tmp, key_word, strlen(key_word)) == 0) + { + dbg_msg("keyword found"); + exitcode = SUCCESS; + } + else if (key_word == NULL) + { + exitcode = SUCCESS; + } + else + { + exitcode = KEYWORD_NOT_MATCH; + } + break; + } + } +#ifdef EARLY_RETURN + else + { + if (read_flag > 500){ + dbg_msg("early return"); + exitcode = TIMEOUT_WAITING_NEWLINE; + break; + } + if (read_flag){ + read_flag++; + } + } +#endif + usleep(1000); + } + if (read_flag == 0) + { + exitcode = COMM_ERROR; + } + return exitcode; +} + +int tty_write(FILE *fdo, char *input) +{ + int cmd_len, ret; + char *cmd_line; + cmd_len = strlen(input) + 3; + cmd_line = (char *)malloc(cmd_len); + if (cmd_line == NULL) + { + err_msg("Error allocating memory"); + return COMM_ERROR; + } + snprintf(cmd_line, cmd_len, "%s\r\n", input); + ret = fputs(cmd_line, fdo); + free(cmd_line); + fflush(fdo); + usleep(100); + if (ret < 0) + { + err_msg("Error writing to tty %d" , ret); + return COMM_ERROR; + } + return SUCCESS; +} diff --git a/application/tom_modem/src/ttydevice.h b/application/tom_modem/src/ttydevice.h new file mode 100644 index 0000000..14b086c --- /dev/null +++ b/application/tom_modem/src/ttydevice.h @@ -0,0 +1,6 @@ +#ifndef TTYDEVICE_H +#define TTYDEVICE_H +#include "modem_types.h" +#include "utils.h" +int tty_open_device(PROFILE_T *profile,FDS_T *fds); +#endif diff --git a/application/tom_modem/src/utils.c b/application/tom_modem/src/utils.c index d33daa7..36a1a49 100644 --- a/application/tom_modem/src/utils.c +++ b/application/tom_modem/src/utils.c @@ -1,7 +1,133 @@ #include "utils.h" -#include "pdu_lib/pdu.h" -struct termios oldtio; +static int char_to_hex(char c) +{ + // convert char to hex + int is_digit, is_lower, is_upper; + is_digit = c - '0'; + is_lower = c - 'a' + 10; + is_upper = c - 'A' + 10; + if (is_digit >= 0 && is_digit <= 9) + { + return is_digit; + } + else if (is_lower >= 10 && is_lower <= 15) + { + return is_lower; + } + else if (is_upper >= 10 && is_upper <= 15) + { + return is_upper; + } + else + { + return -1; + } +} +int decode_pdu(SMS_T *sms) +{ + char sms_text[SMS_TEXT_SIZE] = {0}; + int tp_dcs; + int skip_bytes; + int pdu_str_len; + unsigned char hex_pdu[SMS_PDU_HEX_SIZE] = {0}; + pdu_str_len = strlen(sms->sms_pdu); + for (int i = 0; i < pdu_str_len; i += 2) + { + hex_pdu[i / 2] = char_to_hex(sms->sms_pdu[i]) << 4; + hex_pdu[i / 2] |= char_to_hex(sms->sms_pdu[i + 1]); + } + int sms_len = pdu_decode(hex_pdu, pdu_str_len/2, + &sms->timestamp, + sms->sender, PHONE_NUMBER_SIZE, + sms_text, SMS_TEXT_SIZE, + &tp_dcs, + &sms->ref_number, + &sms->total_segments, + &sms->segment_number, + &skip_bytes); + if (sms_len <= 0) + { + err_msg("Error decoding pdu"); + return sms_len; + } + sms->sms_lenght = sms_len; + + switch ((tp_dcs / 4) % 4) + { + case 0: + { + // GSM 7 bit + sms->type = SMS_CHARSET_7BIT; + int i; + i = skip_bytes; + if (skip_bytes > 0) + i = (skip_bytes * 8 + 6) / 7; + for (; i < strlen(sms_text); i++) + { + sprintf(sms->sms_text + i, "%c", sms_text[i]); + } + i++; + sprintf(sms->sms_text + i, "%c", '\0'); + break; + } + case 2: + { + // UCS2 + sms->type = SMS_CHARSET_UCS2; + int offset = 0; + for (int i = skip_bytes; i < SMS_TEXT_SIZE; i += 2) + { + int ucs2_char = 0x000000FF & sms_text[i + 1]; + ucs2_char |= (0x0000FF00 & (sms_text[i] << 8)); + unsigned char utf8_char[5]; + int len = ucs2_to_utf8(ucs2_char, utf8_char); + int j; + for (j = 0; j < len; j++) + { + sprintf(sms->sms_text + offset, "%c", utf8_char[j]); + if (utf8_char[j] != '\0') + { + offset++; + } + + } + } + offset++; + sprintf(sms->sms_text + offset, "%c", '\0'); + break; + } + default: + break; + } + return sms_len; +} +int destroy_sms(SMS_T *sms) +{ + if (sms->sms_pdu != NULL) + { + free(sms->sms_pdu); + } + if (sms->sender != NULL) + { + free(sms->sender); + } + if (sms->sms_text != NULL) + { + free(sms->sms_text); + } + free(sms); + return SUCCESS; +} +int dump_sms(SMS_T *sms) +{ + dbg_msg("SMS Index: %d", sms->sms_index); + dbg_msg("SMS Text: %s", sms->sms_text); + dbg_msg("SMS Sender: %s", sms->sender); + dbg_msg("SMS Timestamp: %ld", sms->timestamp); + dbg_msg("SMS Segment: %d/%d", sms->segment_number, sms->total_segments); + return SUCCESS; +} int match_option(char *option_name) { char short_option; @@ -100,7 +226,6 @@ int match_option(char *option_name) // if start with '--' then it is a long option return -1; } - int match_operation(char *operation_name) { @@ -120,7 +245,7 @@ int match_operation(char *operation_name) case SMS_DELETE_OP_S: return SMS_DELETE_OP; default: - return -1; + return INVALID_PARAM; break; } } @@ -144,174 +269,12 @@ int match_operation(char *operation_name) } else { - return -1; + return INVALID_PARAM; } } + return SUCCESS; } - -int open_tty_device(PROFILE_T *profile) -{ - tty_fd = open(profile->tty_dev, O_RDWR | O_NOCTTY); - if (tty_fd < 0) - { - err_msg("Error opening tty device: %s", profile->tty_dev); - return -1; - } - - if (set_tty_device(profile) != 0) - { - err_msg("Error setting tty device"); - return -1; - } - tcflush(tty_fd, TCIOFLUSH); - atexit(clean_up); - if (tty_fd >= 0) - close(tty_fd); - tty_fd = open(profile->tty_dev, O_RDWR | O_NOCTTY); - fdi = fdopen(tty_fd, "r"); - fdo = fdopen(tty_fd, "w"); - if (fdi == NULL || fdo == NULL) - { - err_msg("Error opening file descriptor"); - return -1; - } - - if (setvbuf(fdo, NULL, _IOFBF, 0)) - { - err_msg("Error setting buffer for fdi"); - return -1; - } - - if (setvbuf(fdi, NULL, _IOLBF, 0)) - { - err_msg("Error setting buffer for fdi"); - return -1; - } - - return 0; -} - -static int set_tty_device(PROFILE_T *profile) -{ - int baud_rate, data_bits, stop_bits; - char *flow_control; - struct termios tty; - baud_rate = profile->baud_rate; - data_bits = profile->data_bits; - stop_bits = profile->stop_bits; - flow_control = profile->flow_control; - if (tcgetattr(tty_fd, &tty) != 0) - { - err_msg("Error getting tty attributes"); - return -1; - } - memmove(&oldtio, &tty, sizeof(struct termios)); - cfmakeraw(&tty); - tty.c_cflag |= CLOCAL; // 忽略调制解调器控制线,允许本地连接 - tty.c_cflag |= CREAD; // 使能接收 - - // clear flow control ,stop bits parity - tty.c_cflag &= ~CRTSCTS; - tty.c_cflag &= ~CSTOPB; - tty.c_cflag &= ~PARENB; - tty.c_oflag &= ~OPOST; - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - - // set data bits 5,6,7,8 - tty.c_cflag &= ~CSIZE; // 清除数据位设置 - switch (data_bits) - { - case 5: - tty.c_cflag |= CS5; - break; - case 6: - tty.c_cflag |= CS6; - break; - case 7: - tty.c_cflag |= CS7; - break; - case 8: - tty.c_cflag |= CS8; - break; - default: - tty.c_cflag |= CS8; - break; - } - - // set baud rate - switch (baud_rate) - { - case 4800: - cfsetspeed(&tty, B4800); - break; - case 9600: - cfsetspeed(&tty, B9600); - break; - case 19200: - cfsetspeed(&tty, B19200); - break; - case 38400: - cfsetspeed(&tty, B38400); - break; - case 57600: - cfsetspeed(&tty, B57600); - break; - case 115200: - cfsetspeed(&tty, B115200); - break; - - default: - cfsetspeed(&tty, B115200); - break; - } - if (tcsetattr(tty_fd, TCSANOW, &tty) != 0) - { - err_msg("Error setting tty attributes"); - return -1; - } - return 0; -} - -int char_to_hex(char c) -{ - // convert char to hex - int is_digit, is_lower, is_upper; - is_digit = c - '0'; - is_lower = c - 'a' + 10; - is_upper = c - 'A' + 10; - if (is_digit >= 0 && is_digit <= 9) - { - return is_digit; - } - else if (is_lower >= 10 && is_lower <= 15) - { - return is_lower; - } - else if (is_upper >= 10 && is_upper <= 15) - { - return is_upper; - } - else - { - return -1; - } -} - -static void clean_up() -{ - if (tcsetattr(tty_fd, TCSANOW, &oldtio) != 0) - { - err_msg("Error restoring old tty attributes"); - return; - } - dbg_msg("Clean up success"); - tcflush(tty_fd, TCIOFLUSH); - // if (tty_fd >= 0) - // close(tty_fd); -} - -static void escape_json(char *input, char *output) +void escape_json(char *input, char *output) { char *p = input; char *q = output; @@ -365,10 +328,9 @@ static void escape_json(char *input, char *output) } *q = '\0'; } - -int usage() +int usage(char* name) { - err_msg("Usage: %s [options]", self_name); + err_msg("Usage: %s [options]", name); err_msg("Options:"); err_msg(" -c, --at_cmd AT command"); err_msg(" -d, --tty_dev TTY device **REQUIRED**"); @@ -380,12 +342,11 @@ int usage() err_msg(" -p, --sms_pdu SMS PDU"); err_msg(" -i, --sms_index SMS index"); err_msg("Example:"); - err_msg(" %s -c ATI -d /dev/ttyUSB2 -b 115200 -B 8 -o at #advance at mode set bautrate and data bit", self_name); - err_msg(" %s -c ATI -d /dev/ttyUSB2 # normal at mode", self_name); - err_msg(" %s -d /dev/mhi_DUN -o r # read sms", self_name); + err_msg(" %s -c ATI -d /dev/ttyUSB2 -b 115200 -B 8 -o at #advance at mode set bautrate and data bit", name); + err_msg(" %s -c ATI -d /dev/ttyUSB2 # normal at mode", name); + err_msg(" %s -d /dev/mhi_DUN -o r # read sms", name); exit(-1); } - void dump_profile() { dbg_msg("AT command: %s", s_profile.at_cmd); @@ -401,332 +362,6 @@ void dump_profile() dbg_msg("SMS PDU: %s", s_profile.sms_pdu); dbg_msg("SMS index: %d", s_profile.sms_index); } - -int tty_read(FILE *fdi, char *output, int len, int timeout) -{ - return tty_read_keyword(fdi, output, len, timeout, NULL); -} - -int tty_read_keyword(FILE *fdi, char *output, int len, int timeout, char *key_word) -{ - int ret, fd; - fd_set rfds; - struct timeval tv; - char tmp[LINE_BUF] = {0}; - int msg_len = 0; - int key_word_len = 0; - fd = fileno(fdi); - tv.tv_sec = 0; - tv.tv_usec = timeout; - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - if (key_word != NULL) - { - key_word_len = strlen(key_word); - } - while (1) - { - ret = select(fd + 1, &rfds, NULL, NULL, &tv); - if (ret == -1) - { - if (errno == EINTR) - { - err_msg("Interrupted by signal"); - return -1; - } - err_msg("Error in select"); - return -1; - } - else - { - fgets(tmp, LINE_BUF, fdi); - if (output != NULL) - msg_len += snprintf(output + msg_len, len - msg_len, "%s", tmp); - dbg_msg("%s", tmp); - } - if (key_word != NULL){ - if (strncmp(tmp, key_word, key_word_len) == 0) - { - dbg_msg("Received end sign: %s", tmp); - return 0; - } - } - if (strncmp(tmp, "OK", 2) == 0 || - strncmp(tmp, "ERROR", 5) == 0 || - strncmp(tmp, "+CMS ERROR:", 11) == 0 || - strncmp(tmp, "+CME ERROR:", 11) == 0 || - strncmp(tmp, "NO CARRIER", 10) == 0){ - dbg_msg("Received end sign: %s", tmp); - if (key_word == NULL){ - return 0; - } - break; - } - } - - return -1; -} - -int tty_write(FILE *fdo, char *input) -{ - int cmd_len, ret; - char *cmd_line; - cmd_len = strlen(input) + 3; - cmd_line = (char *)malloc(cmd_len); - if (cmd_line == NULL) - { - err_msg("Error allocating memory"); - return -1; - } - snprintf(cmd_line, cmd_len, "%s\r\n", input); - ret = fputs(cmd_line, fdo); - free(cmd_line); - fflush(fdo); - usleep(100); - if (ret < 0) - { - err_msg("Error writing to tty %d" , ret); - return -1; - } - return 0; -} - -int at(PROFILE_T *profile) -{ - char output[COMMON_BUF_SIZE] = {0}; - if (profile->at_cmd == NULL) - { - err_msg("AT command is empty"); - return -1; - } - alarm(profile->timeout); - - if (tty_write(fdo, profile->at_cmd)) - { - err_msg("Error writing to tty"); - return -1; - } - - if (tty_read(fdi, output, COMMON_BUF_SIZE, 100)) - { - err_msg("Error reading from tty"); - return -1; - } - user_msg("%s", output); - return 0; -} - -int sms_read(PROFILE_T *profile) -{ - SMS_T *sms_list[SMS_LIST_SIZE]; - SMS_T *sms; - char sms_pdu[SMS_BUF_SIZE] = {0}; - tty_write(fdo, SET_PDU_FORMAT); - alarm(profile->timeout); - if (tty_read_keyword(fdi, NULL, COMMON_BUF_SIZE, 100, "OK")) - { - err_msg("Error setting PDU format"); - return -1; - } - dbg_msg("Set PDU format success"); - tty_write(fdo, READ_ALL_SMS); - alarm(profile->timeout); - if (tty_read_keyword(fdi, sms_pdu, SMS_BUF_SIZE, 100, "OK")) - { - err_msg("Error reading SMS"); - return -1; - } - alarm(0); - - - //遍历 sms_pdu 的每一行 - char *line = strtok(sms_pdu, "\n"); - int sms_count = 0; - while (line != NULL) - { - - if (strncmp(line, "+CMGL:", 6) == 0) - { - //解析 line +CMGL: 2,1,,102 获取短信索引 - sms = (SMS_T *)malloc(sizeof(SMS_T)); - memset(sms, 0, sizeof(SMS_T)); - char *pdu = strtok(NULL, "\n"); - sms->sms_pdu = (char *)malloc(strlen(pdu)); - sms->sender = (char *)malloc(PHONE_NUMBER_SIZE); - sms->sms_text = (char *)malloc(SMS_TEXT_SIZE); - sms->sms_index = get_sms_index(line); - memcpy(sms->sms_pdu, pdu, strlen(pdu)); - int sms_len = decode(sms); - if (sms_len > 0) - { - sms_list[sms_count] = sms; - sms_count++; - } - else - { - destroy_sms(sms); - } - } - line = strtok(NULL, "\n"); - } - - // for (int i = 1; i <= sms_count; i++) - // { - // dump_sms(sms_list[i]); - // //destroy_sms(sms_list[i]); - // } - display_sms_in_json(sms_list,sms_count); - dbg_msg("Read SMS success"); - dbg_msg("%s", sms_pdu); - return 0; -} - -int sms_send(PROFILE_T *profile) -{ - if (profile->sms_pdu == NULL) - { - err_msg("SMS PDU is empty"); - return -1; - } - - int pdu_len = strlen(profile->sms_pdu); - int pdu_expected_len = (pdu_len) / 2 - 1; - char *send_sms_cmd; - char *write_pdu_cmd; - tty_write(fdo, SET_PDU_FORMAT); - alarm(profile->timeout); - if (tty_read_keyword(fdi, NULL, COMMON_BUF_SIZE, 100, "OK")) - { - err_msg("Error setting PDU format"); - return -1; - } - dbg_msg("Set PDU format success"); - send_sms_cmd = (char *)malloc(32); - write_pdu_cmd = (char *)malloc(256); - snprintf(send_sms_cmd, 32, SEND_SMS, pdu_expected_len); - dbg_msg("Send SMS command: %s", send_sms_cmd); - snprintf(write_pdu_cmd, 256, "%s%c", profile->sms_pdu, 0x1A); - dbg_msg("Write PDU command: %s", write_pdu_cmd); - free(send_sms_cmd); - free(write_pdu_cmd); - alarm(0); - tty_write(fdo, send_sms_cmd); - usleep(10000); - tty_write(fdo, write_pdu_cmd); - alarm(profile->timeout); - if (tty_read_keyword(fdi, NULL, COMMON_BUF_SIZE, 100, "+CMGS:")) - { - err_msg("Error sending SMS STEP 2"); - return -1; - } - - - - - return 0; -} - -int sms_delete(PROFILE_T *profile) -{ - if (profile->sms_index < 0) - { - err_msg("SMS index is empty"); - return -1; - } - char *delete_sms_cmd; - delete_sms_cmd = (char *)malloc(32); - snprintf(delete_sms_cmd, 32, DELETE_SMS, profile->sms_index); - tty_write(fdo, delete_sms_cmd); - alarm(profile->timeout); - if (tty_read_keyword(fdi, NULL, COMMON_BUF_SIZE, 100, "OK")) - { - err_msg("Error deleting SMS"); - return -1; - } - return 0; -} - -int decode(SMS_T *sms) -{ - char sms_text[SMS_TEXT_SIZE] = {0}; - int tp_dcs; - int skip_bytes; - int pdu_str_len; - time_t sms_time; - unsigned char hex_pdu[SMS_PDU_HEX_SIZE] = {0}; - pdu_str_len = strlen(sms->sms_pdu); - for (int i = 0; i < pdu_str_len; i += 2) - { - hex_pdu[i / 2] = char_to_hex(sms->sms_pdu[i]) << 4; - hex_pdu[i / 2] |= char_to_hex(sms->sms_pdu[i + 1]); - } - int sms_len = pdu_decode(hex_pdu, pdu_str_len/2, - &sms->timestamp, - sms->sender, PHONE_NUMBER_SIZE, - sms_text, SMS_TEXT_SIZE, - &tp_dcs, - &sms->ref_number, - &sms->total_segments, - &sms->segment_number, - &skip_bytes); - if (sms_len <= 0) - { - err_msg("Error decoding pdu"); - return sms_len; - } - sms->sms_lenght = sms_len; - - switch ((tp_dcs / 4) % 4) - { - case 0: - { - // GSM 7 bit - sms->type = SMS_CHARSET_7BIT; - int i; - i = skip_bytes; - if (skip_bytes > 0) - i = (skip_bytes * 8 + 6) / 7; - for (; i < strlen(sms_text); i++) - { - sprintf(sms->sms_text + i, "%c", sms_text[i]); - } - i++; - sprintf(sms->sms_text + i, "%c", '\0'); - break; - } - case 2: - { - // UCS2 - sms->type = SMS_CHARSET_UCS2; - int offset = 0; - for (int i = skip_bytes; i < SMS_TEXT_SIZE; i += 2) - { - int ucs2_char = 0x000000FF & sms_text[i + 1]; - ucs2_char |= (0x0000FF00 & (sms_text[i] << 8)); - unsigned char utf8_char[5]; - int len = ucs2_to_utf8(ucs2_char, utf8_char); - int j; - for (j = 0; j < len; j++) - { - sprintf(sms->sms_text + offset, "%c", utf8_char[j]); - if (utf8_char[j] != '\0') - { - offset++; - } - - } - } - offset++; - sprintf(sms->sms_text + offset, "%c", '\0'); - break; - } - default: - break; - } - return sms_len; -} - int display_sms_in_json(SMS_T **sms,int num) { @@ -738,10 +373,10 @@ int display_sms_in_json(SMS_T **sms,int num) char escaped_text[SMS_TEXT_SIZE]; escape_json(sms[i]->sms_text, escaped_text); if (sms[i]->ref_number) - offset += sprintf(msg_json + offset, "{\"index\":%d,\"sender\":\"%s\",\"timestamp\":%d,\"content\":\"%s\",\"reference\":%d,\"total\":%d,\"part\":%d},", + offset += sprintf(msg_json + offset, "{\"index\":%d,\"sender\":\"%s\",\"timestamp\":%ld,\"content\":\"%s\",\"reference\":%d,\"total\":%d,\"part\":%d},", sms[i]->sms_index, sms[i]->sender, sms[i]->timestamp, escaped_text, sms[i]->ref_number, sms[i]->total_segments, sms[i]->segment_number); else - offset += sprintf(msg_json + offset, "{\"index\":%d,\"sender\":\"%s\",\"timestamp\":%d,\"content\":\"%s\"},", + offset += sprintf(msg_json + offset, "{\"index\":%d,\"sender\":\"%s\",\"timestamp\":%ld,\"content\":\"%s\"},", sms[i]->sms_index, sms[i]->sender, sms[i]->timestamp, escaped_text); } @@ -752,35 +387,7 @@ int display_sms_in_json(SMS_T **sms,int num) } offset += sprintf(msg_json + offset, "]}"); user_msg("%s\n", msg_json); - return 0; + return SUCCESS; } - -int dump_sms(SMS_T *sms) -{ - dbg_msg("SMS Index: %d", sms->sms_index); - dbg_msg("SMS Text: %s", sms->sms_text); - dbg_msg("SMS Sender: %s", sms->sender); - dbg_msg("SMS Timestamp: %d", sms->timestamp); - dbg_msg("SMS Segment: %d/%d", sms->segment_number, sms->total_segments); - return 0; -} - -int destroy_sms(SMS_T *sms) -{ - if (sms->sms_pdu != NULL) - { - free(sms->sms_pdu); - } - if (sms->sender != NULL) - { - free(sms->sender); - } - if (sms->sms_text != NULL) - { - free(sms->sms_text); - } - free(sms); - return 0; -} diff --git a/application/tom_modem/src/utils.h b/application/tom_modem/src/utils.h index 8758c1b..f71fdff 100644 --- a/application/tom_modem/src/utils.h +++ b/application/tom_modem/src/utils.h @@ -1,17 +1,20 @@ #ifndef _UTILS_H #define _UTILS_H #include +#include +#include +#include #include +#include +#include +#include +#include #include "modem_types.h" -#include "main.h" +#include "extlib/pdu.h" +#include "time.h" extern PROFILE_T s_profile; -extern FILE *fdi; // file descriptor for input -extern FILE *fdo; // file descriptor for output -extern int tty_fd; // file descriptor for tty device -extern struct termios oldtio; // old tty setting - - +extern FDS_T s_fds; #define dbg_msg(fmt, args...) do { \ if (s_profile.debug) { \ @@ -51,9 +54,17 @@ int match_option(char *option_name); int match_operation(char *operation_name); -int open_tty_device(PROFILE_T *profile); -static int set_tty_device(PROFILE_T *profile); +int decode_pdu(SMS_T *sms); -static void clean_up(); + +int tty_read_keyword(FILE *fdi, char *output, int len, char *key_word, int soft_timeout); + +int tty_read(FILE *fdi, char *output, int len, int soft_timeout); + +int dump_sms(SMS_T *sms); + +int destroy_sms(SMS_T *sms); + +int display_sms_in_json(SMS_T **sms,int num); #endif diff --git a/docs/tom_modem.cn.md b/docs/tom_modem.cn.md index d873ce8..38da17a 100644 --- a/docs/tom_modem.cn.md +++ b/docs/tom_modem.cn.md @@ -1,5 +1,19 @@ # 工具介绍 +## 更新介绍 + +### 0.9.2 + +#### 特性变更 + +- 在AT通信中,优化了响应处理逻辑:在接收到初始响应后的特定时间内如果没有进一步的响应,则认为通信已结束。这种机制特别适用于那些可能无法正确返回终止符号的命令。(需要注意的是,当ATE功能启用时,命令回显会立即被读取,这可能导致对于执行时间较长的命令提前返回结果。) +- 在操作执行时,若是模组通讯异常(无返回、护法读写等),会在run_ops函数中返回-1,然后直接发送kill -9 命令(避免close时大量的花销),正常返回则返回0,若是与模组通讯无关的故障(如解析异常)应当返回>0的错误代码 + +#### 优化 + +- 更新了超时处理机制,不再依赖alarm信号,而是通过设置阻塞的读写操作,并结合vmin和vtime参数实现超时控制。 +- 实现了组件间的一定程度解耦,提高了系统的灵活性和可维护性。 + ## 概述 这个工具是一个 AT 命令行界面,用于与调制解调器进行通信。它支持多种操作,包括发送和读取短信、设置波特率和数据位等。