tom_modem: add greedy read feature and dynamic at_message mem alloc
This commit is contained in:
parent
c76c791574
commit
20022805ab
@ -3,7 +3,7 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:= tom_modem
|
||||
PKG_RELEASE:=1
|
||||
PKG_VERSION:=1.0.1
|
||||
PKG_VERSION:=1.0.2
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
@ -112,6 +112,9 @@ int parse_user_input(int argc, char *argv[], PROFILE_T *profile)
|
||||
}
|
||||
profile->sms_index = atoi(argv[opt++]);
|
||||
break;
|
||||
case GREEDY_READ:
|
||||
profile->greedy_read = 1;
|
||||
break;
|
||||
default:
|
||||
err_msg("Invalid option: %s", argv[opt]);
|
||||
break;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define DEBUG_S 'D'
|
||||
#define SMS_PDU_S 'p'
|
||||
#define SMS_INDEX_S 'i'
|
||||
#define GREEDY_READ_S 'g'
|
||||
|
||||
#define AT_CMD_L "at_cmd"
|
||||
#define TTY_DEV_L "tty_dev"
|
||||
@ -30,6 +31,7 @@
|
||||
#define DEBUG_L "debug"
|
||||
#define SMS_PDU_L "sms_pdu"
|
||||
#define SMS_INDEX_L "sms_index"
|
||||
#define GREEDY_READ_L "greedy_read"
|
||||
|
||||
//operations
|
||||
#define AT_OP_S 'a'
|
||||
@ -85,6 +87,7 @@ typedef struct _PROFILE {
|
||||
int debug;
|
||||
char *sms_pdu;
|
||||
int sms_index;
|
||||
int greedy_read;
|
||||
} PROFILE_T;
|
||||
|
||||
|
||||
@ -141,7 +144,8 @@ enum OPTIONS {
|
||||
OPERATION,
|
||||
DEBUG,
|
||||
SMS_PDU,
|
||||
SMS_INDEX
|
||||
SMS_INDEX,
|
||||
GREEDY_READ
|
||||
};
|
||||
|
||||
enum OPERATIONS {
|
||||
|
@ -3,7 +3,7 @@
|
||||
int at(PROFILE_T *profile,FDS_T *fds)
|
||||
{
|
||||
int w_ret,r_ret;
|
||||
char output[COMMON_BUF_SIZE] = {0};
|
||||
AT_MESSAGE_T message = {0};
|
||||
if (profile->at_cmd == NULL)
|
||||
{
|
||||
err_msg("AT command is empty");
|
||||
@ -15,23 +15,26 @@ int at(PROFILE_T *profile,FDS_T *fds)
|
||||
return w_ret;
|
||||
}
|
||||
|
||||
r_ret = tty_read(fds->fdi, output, COMMON_BUF_SIZE,profile->timeout);
|
||||
r_ret = tty_read(fds->fdi, &message, profile);
|
||||
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);
|
||||
if (message.message)
|
||||
{
|
||||
user_msg("%s", message.message);
|
||||
free(message.message);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int binary_at(PROFILE_T *profile,FDS_T *fds)
|
||||
{
|
||||
int w_ret,r_ret,hex_convert_ret;
|
||||
int binary_at_cmd_len;
|
||||
char *binary_at_cmd;
|
||||
char output[COMMON_BUF_SIZE] = {0};
|
||||
AT_MESSAGE_T message = {0};
|
||||
if (profile->at_cmd == NULL)
|
||||
{
|
||||
err_msg("AT command is empty");
|
||||
@ -52,18 +55,23 @@ int binary_at(PROFILE_T *profile,FDS_T *fds)
|
||||
}
|
||||
|
||||
w_ret = tty_write_raw(fds->fdo, binary_at_cmd);
|
||||
free(binary_at_cmd);
|
||||
if (w_ret)
|
||||
{
|
||||
return w_ret;
|
||||
}
|
||||
r_ret = tty_read_keyword(fds->fdi, output, COMMON_BUF_SIZE, "OK",profile->timeout);
|
||||
r_ret = tty_read_keyword(fds->fdi, &message, "OK", profile);
|
||||
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);
|
||||
if (message.message)
|
||||
{
|
||||
user_msg("%s", message.message);
|
||||
free(message.message);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -83,7 +91,7 @@ int sms_delete(PROFILE_T *profile,FDS_T *fds)
|
||||
{
|
||||
return w_ret;
|
||||
}
|
||||
r_ret = tty_read_keyword(fds->fdi, NULL, COMMON_BUF_SIZE, "OK",profile->timeout);
|
||||
r_ret = tty_read_keyword(fds->fdi, NULL, "OK", profile);
|
||||
if (r_ret)
|
||||
{
|
||||
dbg_msg("Error deleting SMS, error code: %d", r_ret);
|
||||
@ -97,38 +105,46 @@ 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};
|
||||
AT_MESSAGE_T message = {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);
|
||||
|
||||
r_ret = tty_read_keyword(fds->fdi, NULL, "OK", profile);
|
||||
if (r_ret)
|
||||
{
|
||||
dbg_msg("Error setting PDU format , error code: %d", 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);
|
||||
|
||||
r_ret = tty_read_keyword(fds->fdi, &message, "OK", profile);
|
||||
if (r_ret)
|
||||
{
|
||||
dbg_msg("Error reading SMS , error code: %d", 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");
|
||||
if (message.message)
|
||||
{
|
||||
char *line = strtok(message.message, "\n");
|
||||
int sms_count = 0;
|
||||
|
||||
while (line != NULL)
|
||||
{
|
||||
if (strncmp(line, "+CMGL:", 6) == 0)
|
||||
@ -149,85 +165,95 @@ int sms_read(PROFILE_T *profile,FDS_T *fds)
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_msg("Error decoding sms in line: %s", line);
|
||||
dbg_msg("Error decoding SMS in line: %s", line);
|
||||
destroy_sms(sms);
|
||||
}
|
||||
}
|
||||
line = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
display_sms_in_json(sms_list, sms_count);
|
||||
free(message.message);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int sms_send(PROFILE_T *profile, FDS_T *fds) {
|
||||
int w_ret, r_ret;
|
||||
AT_MESSAGE_T message = {0};
|
||||
|
||||
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;
|
||||
char *send_sms_cmd = (char *)malloc(32);
|
||||
char *write_pdu_cmd = (char *)malloc(256);
|
||||
|
||||
w_ret = tty_write(fds->fdo, SET_PDU_FORMAT);
|
||||
if (w_ret)
|
||||
{
|
||||
if (w_ret) {
|
||||
free(send_sms_cmd);
|
||||
free(write_pdu_cmd);
|
||||
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)
|
||||
|
||||
r_ret = tty_read_keyword(fds->fdi, NULL, "OK", profile);
|
||||
if (r_ret) {
|
||||
dbg_msg("Error setting PDU format, error code: %d", r_ret);
|
||||
free(send_sms_cmd);
|
||||
free(write_pdu_cmd);
|
||||
if (message.message) free(message.message);
|
||||
return r_ret;
|
||||
}
|
||||
dbg_msg("Set PDU format success");
|
||||
send_sms_cmd = (char *)malloc(32);
|
||||
write_pdu_cmd = (char *)malloc(256);
|
||||
if (message.message) free(message.message);
|
||||
|
||||
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("Send SMS command: %s", send_sms_cmd);
|
||||
dbg_msg("Write PDU command: %s", write_pdu_cmd);
|
||||
|
||||
w_ret = tty_write(fds->fdo, send_sms_cmd);
|
||||
if (w_ret)
|
||||
{
|
||||
if (w_ret) {
|
||||
free(send_sms_cmd);
|
||||
free(write_pdu_cmd);
|
||||
return w_ret;
|
||||
}
|
||||
r_ret = tty_read_keyword(fds->fdi, NULL, COMMON_BUF_SIZE, ">",profile->timeout);
|
||||
if (r_ret)
|
||||
{
|
||||
|
||||
r_ret = tty_read_keyword(fds->fdi, NULL, ">", profile);
|
||||
if (r_ret) {
|
||||
dbg_msg("Error sending SMS STEP 1, error code: %d", r_ret);
|
||||
if (r_ret == COMM_ERROR)
|
||||
return COMM_ERROR;
|
||||
free(send_sms_cmd);
|
||||
free(write_pdu_cmd);
|
||||
if (message.message) free(message.message);
|
||||
return r_ret;
|
||||
}
|
||||
if (message.message) free(message.message);
|
||||
|
||||
usleep(10000);
|
||||
w_ret = tty_write(fds->fdo, write_pdu_cmd);
|
||||
if (w_ret)
|
||||
{
|
||||
if (w_ret) {
|
||||
free(send_sms_cmd);
|
||||
free(write_pdu_cmd);
|
||||
return w_ret;
|
||||
}
|
||||
r_ret = tty_read_keyword(fds->fdi, NULL, COMMON_BUF_SIZE, "+CMGS:",profile->timeout);
|
||||
if (r_ret)
|
||||
{
|
||||
|
||||
r_ret = tty_read_keyword(fds->fdi, &message, "+CMGS:", profile);
|
||||
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);
|
||||
if (message.message) free(message.message);
|
||||
return r_ret;
|
||||
}
|
||||
if (message.message) free(message.message);
|
||||
|
||||
free(send_sms_cmd);
|
||||
free(write_pdu_cmd);
|
||||
|
||||
|
||||
return 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include "utils.h"
|
||||
int str_to_hex(char *str, char *hex);
|
||||
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_read(FILE *fdi, AT_MESSAGE_T *message, PROFILE_T *profile);
|
||||
int tty_read_keyword(FILE *fdi, AT_MESSAGE_T *message, char *key_word, PROFILE_T *profile);
|
||||
int tty_write_raw(FILE *fdo, char *input);
|
||||
int tty_write(FILE *fdo, char *input);
|
||||
#endif
|
||||
|
@ -128,76 +128,84 @@ int tty_open_device(PROFILE_T *profile,FDS_T *fds)
|
||||
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(FILE *fdi, AT_MESSAGE_T *message, PROFILE_T *profile) {
|
||||
return tty_read_keyword(fdi, message, NULL, profile);
|
||||
}
|
||||
|
||||
int tty_read_keyword(FILE *fdi, char *output, int len, char *key_word, int soft_timeout)
|
||||
{
|
||||
int tty_read_keyword(FILE *fdi, AT_MESSAGE_T *message, char *key_word, PROFILE_T *profile) {
|
||||
char tmp[LINE_BUF] = {0};
|
||||
int msg_len = 0;
|
||||
char *dynamic_buffer = NULL;
|
||||
int buffer_size = 0;
|
||||
int read_flag = 0;
|
||||
time_t start_time = time(NULL);
|
||||
int exitcode = TIMEOUT_WAITING_NEWLINE;
|
||||
while (difftime(time(NULL), start_time) < soft_timeout)
|
||||
{
|
||||
|
||||
while (difftime(time(NULL), start_time) < profile->timeout) {
|
||||
memset(tmp, 0, LINE_BUF);
|
||||
if (fgets(tmp, LINE_BUF, fdi))
|
||||
{
|
||||
if (fgets(tmp, LINE_BUF, fdi)) {
|
||||
read_flag = 1;
|
||||
dbg_msg("%s", tmp);
|
||||
if (msg_len + strlen(tmp) >= len)
|
||||
{
|
||||
err_msg("Error: output buffer is too small");
|
||||
if (profile->greedy_read && strlen(tmp) > 0) {
|
||||
start_time = time(NULL);
|
||||
}
|
||||
if (message != NULL) {
|
||||
int tmp_len = strlen(tmp);
|
||||
char *new_buffer = realloc(dynamic_buffer, buffer_size + tmp_len + 1);
|
||||
if (!new_buffer) {
|
||||
free(dynamic_buffer);
|
||||
err_msg("Error: memory allocation failed");
|
||||
exitcode = BUFFER_OVERFLOW;
|
||||
break;
|
||||
}
|
||||
if (output != NULL)
|
||||
msg_len += snprintf(output + msg_len, len - msg_len, "%s", tmp);
|
||||
dynamic_buffer = new_buffer;
|
||||
memcpy(dynamic_buffer + buffer_size, tmp, tmp_len);
|
||||
buffer_size += tmp_len;
|
||||
dynamic_buffer[buffer_size] = '\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 ||
|
||||
(key_word != NULL && strncmp(tmp, key_word, strlen(key_word)) == 0))
|
||||
{
|
||||
if (key_word != NULL && strncmp(tmp, key_word, strlen(key_word)) == 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)
|
||||
{
|
||||
} else if (key_word == NULL) {
|
||||
exitcode = SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
exitcode = KEYWORD_NOT_MATCH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef EARLY_RETURN
|
||||
else
|
||||
{
|
||||
if (read_flag > 500){
|
||||
else {
|
||||
if (read_flag > 500) {
|
||||
dbg_msg("early return");
|
||||
exitcode = TIMEOUT_WAITING_NEWLINE;
|
||||
break;
|
||||
}
|
||||
if (read_flag){
|
||||
if (read_flag) {
|
||||
read_flag++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
usleep(5000);
|
||||
}
|
||||
if (read_flag == 0)
|
||||
{
|
||||
|
||||
if (read_flag == 0) {
|
||||
exitcode = COMM_ERROR;
|
||||
}
|
||||
|
||||
if (message != NULL) {
|
||||
message->message = dynamic_buffer;
|
||||
message->len = buffer_size;
|
||||
} else {
|
||||
free(dynamic_buffer);
|
||||
}
|
||||
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
|
@ -204,6 +204,8 @@ int match_option(char *option_name)
|
||||
return SMS_PDU;
|
||||
case SMS_INDEX_S:
|
||||
return SMS_INDEX;
|
||||
case GREEDY_READ_S:
|
||||
return GREEDY_READ;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -259,6 +261,10 @@ int match_option(char *option_name)
|
||||
{
|
||||
return SMS_INDEX;
|
||||
}
|
||||
else if (strcmp(long_option, GREEDY_READ_L) == 0)
|
||||
{
|
||||
return GREEDY_READ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
@ -389,11 +395,12 @@ int usage(char* name)
|
||||
err_msg(" -d, --tty_dev <TTY device> TTY device **REQUIRED**");
|
||||
err_msg(" -b, --baud_rate <baud rate> Baud rate Default: 115200 Supported: 4800,9600,19200,38400,57600,115200");
|
||||
err_msg(" -B, --data_bits <data bits> Data bits Default: 8 Supported: 5,6,7,8");
|
||||
err_msg(" -t, --timeout <timeout> Timeout Default: 3");
|
||||
err_msg(" -t, --timeout <timeout> Default: 3 Timeout in seconds, if output is more than timeout, it will be ignored unless -g option is set");
|
||||
err_msg(" -o, --operation <operation> Operation(at[a:defualt],binary_at[b], sms_read[r], sms_send[s], sms_delete[d])");
|
||||
err_msg(" -D, --debug Debug mode Default: off");
|
||||
err_msg(" -p, --sms_pdu <sms pdu> SMS PDU");
|
||||
err_msg(" -i, --sms_index <sms index> SMS index");
|
||||
err_msg(" -g, --greedy_read Default: off, Greedy read mode, if set, each round it get new data from tty device, it will reset the timeout");
|
||||
#ifdef USE_SEMAPHORE
|
||||
err_msg(" -C, --cleanup Semaphore cleanup");
|
||||
#endif
|
||||
@ -440,6 +447,7 @@ void dump_profile()
|
||||
dbg_msg("Debug: %d", s_profile.debug);
|
||||
dbg_msg("SMS PDU: %s", s_profile.sms_pdu);
|
||||
dbg_msg("SMS index: %d", s_profile.sms_index);
|
||||
dbg_msg("Greedy read: %d", s_profile.greedy_read);
|
||||
}
|
||||
int display_sms_in_json(SMS_T **sms,int num)
|
||||
{
|
||||
|
@ -75,9 +75,9 @@ int match_operation(char *operation_name);
|
||||
int decode_pdu(SMS_T *sms);
|
||||
|
||||
|
||||
int tty_read_keyword(FILE *fdi, char *output, int len, char *key_word, int soft_timeout);
|
||||
int tty_read(FILE *fdi, AT_MESSAGE_T *message, PROFILE_T *profile);
|
||||
|
||||
int tty_read(FILE *fdi, char *output, int len, int soft_timeout);
|
||||
int tty_read_keyword(FILE *fdi, AT_MESSAGE_T *message, char *key_word, PROFILE_T *profile);
|
||||
|
||||
int dump_sms(SMS_T *sms);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user