mirror of
https://gitee.com/moluo-tech/AT-Command
synced 2025-06-17 07:57:52 +00:00
1.Optimized the processing logic when multi-line command execution fails.
2. Resolve URC message containing ':' character causing parsing failure.
This commit is contained in:
parent
8866cdf7f9
commit
a1cf6f2672
@ -1,6 +1,6 @@
|
||||
<!-- navbar.md -->
|
||||
|
||||
* [介绍](readme#简介)
|
||||
* [介绍](README#简介)
|
||||
* [快速上手](quickStart#基础应用)
|
||||
* [高级教程](Expert#高级教程)
|
||||
* [平台移植](Porting#平台移植)
|
@ -8,11 +8,16 @@
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-01-02 roger.luo Initial version
|
||||
* 2021-01-20 roger.luo Add debugging interface, and at the same time solve
|
||||
* the problem of uninitialized linked list leading to
|
||||
* segment fault.
|
||||
* 2021-03-03 roger.luo Fix the problem of frequent print receive timeout caused by not clearing the URC counter.
|
||||
* 2021-01-20 roger.luo Add debugging interface, and at the same time
|
||||
* solve the problem of uninitialized linked list
|
||||
* leading to segment fault.
|
||||
* 2021-03-03 roger.luo Fix the problem of frequent print receive timeout
|
||||
* caused by not clearing the URC counter.
|
||||
* 2022-10-01 roger.luo Redesign the entire AT framework and release V2.0.
|
||||
* 2023-01-09 roger.luo Optimized the processing logic when multi-line
|
||||
* command execution fails.
|
||||
* 2023-01-10 roger.luo Resolve URC message containing ':' character
|
||||
* causing parsing failure.
|
||||
******************************************************************************/
|
||||
#ifndef _AT_CHAT_H_
|
||||
#define _AT_CHAT_H_
|
||||
@ -243,7 +248,7 @@ bool at_exec_cmd(at_obj_t *at, const at_attr_t *attr, const char *cmd, ...);
|
||||
|
||||
bool at_exec_vcmd(at_obj_t *at, const at_attr_t *attr, const char *cmd, va_list va);
|
||||
|
||||
bool at_send_singlline(at_obj_t *at, at_callback_t cb, int timeout, int retry, const char *singlline);
|
||||
bool at_send_singlline(at_obj_t *at, const at_attr_t *attr, const char *singlline);
|
||||
|
||||
bool at_send_multiline(at_obj_t *at, const at_attr_t *attr, const char **multiline);
|
||||
|
||||
|
@ -8,11 +8,16 @@
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-01-02 roger.luo Initial version
|
||||
* 2021-01-20 roger.luo Add debugging interface, and at the same time solve
|
||||
* the problem of uninitialized linked list leading to
|
||||
* segment fault.
|
||||
* 2021-03-03 roger.luo Fix the problem of frequent print receive timeout caused by not clearing the URC counter.
|
||||
* 2021-01-20 roger.luo Add debugging interface, and at the same time
|
||||
* solve the problem of uninitialized linked list
|
||||
* leading to segment fault.
|
||||
* 2021-03-03 roger.luo Fix the problem of frequent print receive timeout
|
||||
* caused by not clearing the URC counter.
|
||||
* 2022-10-01 roger.luo Redesign the entire AT framework and release V2.0.
|
||||
* 2023-01-09 roger.luo Optimized the processing logic when multi-line
|
||||
* command execution fails.
|
||||
* 2023-01-10 roger.luo Resolve URC message containing ':' character
|
||||
* causing parsing failure.
|
||||
******************************************************************************/
|
||||
#include "at_chat.h"
|
||||
#include "at_port.h"
|
||||
@ -155,13 +160,7 @@ static inline at_info_t *obj_map(at_obj_t *at)
|
||||
{
|
||||
return (at_info_t *)at;
|
||||
}
|
||||
/**
|
||||
* @brief void * -> work_item_t *
|
||||
*/
|
||||
static inline work_item_t *work_item_map(void *work_obj)
|
||||
{
|
||||
return (work_item_t *)work_obj;
|
||||
}
|
||||
|
||||
|
||||
static inline const at_adapter_t *__get_adapter(at_info_t *ai)
|
||||
{
|
||||
@ -196,7 +195,7 @@ static void send_cmdline(at_info_t *at, const char *cmd)
|
||||
len = strlen(cmd);
|
||||
__get_adapter(at)->write(cmd, len);
|
||||
__get_adapter(at)->write("\r\n", 2);
|
||||
AT_DEBUG(at,"=>:\r\n%s\r\n", cmd);
|
||||
AT_DEBUG(at,"->\r\n%s\r\n", cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -268,10 +267,10 @@ static void at_next_wait(struct at_env *env, unsigned int ms)
|
||||
|
||||
static void update_work_state(work_item_t *wi, at_work_state state, at_resp_code code)
|
||||
{
|
||||
at_context_t *ctx = wi->attr.ctx;
|
||||
wi->state = state;
|
||||
wi->code = code;
|
||||
#if AT_WORK_CONTEXT_EN
|
||||
at_context_t *ctx = wi->attr.ctx;
|
||||
if (ctx != NULL) {
|
||||
ctx->code = (at_resp_code)wi->code;
|
||||
ctx->work_state = (at_work_state)wi->state;
|
||||
@ -294,8 +293,7 @@ static void at_finish(struct at_env *env, at_resp_code code)
|
||||
static void do_at_callback(at_info_t *ai, work_item_t *wi, at_resp_code code)
|
||||
{
|
||||
at_response_t r;
|
||||
at_context_t *ctx;
|
||||
AT_DEBUG(ai, "<=:\r\n%s\r\n", ai->recvbuf);
|
||||
AT_DEBUG(ai, "<-\r\n%s\r\n", ai->recvbuf);
|
||||
//Exception notification
|
||||
if ((code == AT_RESP_ERROR || code == AT_RESP_TIMEOUT) && __get_adapter(ai)->error != NULL) {
|
||||
__get_adapter(ai)->error(&r);
|
||||
@ -305,7 +303,7 @@ static void do_at_callback(at_info_t *ai, work_item_t *wi, at_resp_code code)
|
||||
ai->err_occur = 0;
|
||||
}
|
||||
#if AT_WORK_CONTEXT_EN
|
||||
ctx = wi->attr.ctx;
|
||||
at_context_t *ctx = wi->attr.ctx;
|
||||
if (ctx != NULL ) {
|
||||
if (ctx->respbuf != NULL/* && ctx->bufsize */) {
|
||||
ctx->resplen = ai->recv_cnt >= ctx->bufsize ? ctx->bufsize - 1 : ai->recv_cnt;
|
||||
@ -412,10 +410,12 @@ static work_item_t *create_work_item(at_info_t *ai, int type, const at_attr_t *a
|
||||
it->attr = *attr;
|
||||
it->type = type;
|
||||
it->state = AT_WORK_STAT_READY;
|
||||
#if AT_WORK_CONTEXT_EN
|
||||
if (attr->ctx) {
|
||||
attr->ctx->code = AT_RESP_OK;
|
||||
attr->ctx->work_state = AT_WORK_STAT_READY;
|
||||
}
|
||||
#endif
|
||||
return it;
|
||||
}
|
||||
|
||||
@ -518,7 +518,7 @@ static int do_cmd_handler(at_info_t *ai)
|
||||
do_at_callback(ai, wi, AT_RESP_ERROR);
|
||||
return true;
|
||||
}
|
||||
AT_DEBUG(ai, "<=\r\n%s\r\n", ai->recvbuf);
|
||||
AT_DEBUG(ai, "<-\r\n%s\r\n", ai->recvbuf);
|
||||
env->state = AT_STAT_RETRY; //If the command responds incorrectly, it will wait for a while and try again.
|
||||
env->reset_timer(env);
|
||||
}
|
||||
@ -558,7 +558,7 @@ static int send_multiline_handler(at_info_t *ai)
|
||||
{
|
||||
case AT_STAT_SEND:
|
||||
if (cmds[env->i] == NULL) { /* All commands are sent.*/
|
||||
do_at_callback(ai, wi, AT_RESP_OK);
|
||||
do_at_callback(ai, wi, env->params ? AT_RESP_OK : AT_RESP_ERROR);
|
||||
return true;
|
||||
}
|
||||
send_cmdline(ai, cmds[env->i]);
|
||||
@ -572,23 +572,27 @@ static int send_multiline_handler(at_info_t *ai)
|
||||
env->state = 0;
|
||||
env->i++;
|
||||
env->j = 0;
|
||||
AT_DEBUG(ai, "<-\r\n%s\r\n", ai->recvbuf);
|
||||
env->params = (void *)true; /*Mark execution status*/
|
||||
AT_DEBUG(ai, "<-\r\n%s\r\n", ai->recvbuf);
|
||||
} else if (find_substr(env, AT_DEF_RESP_ERR)) {
|
||||
AT_DEBUG(ai, "<-\r\n%s\r\n", ai->recvbuf);
|
||||
if (env->j++ >= attr->retry) {
|
||||
do_at_callback(ai, wi, AT_RESP_ERROR);
|
||||
return true;
|
||||
env->j++;
|
||||
AT_DEBUG(ai, "CMD:'%s' failed to executed, retry:%d\r\n", cmds[env->i], env->j);
|
||||
if (env->j >= attr->retry) {
|
||||
env->state = 0;
|
||||
env->j = 0;
|
||||
env->i++;
|
||||
} else {
|
||||
env->state = AT_STAT_RETRY; //After the command responds incorrect, try again after a period of time.
|
||||
env->reset_timer(env);
|
||||
}
|
||||
AT_DEBUG(ai, "<=\r\n%s\r\n", ai->recvbuf);
|
||||
env->state = AT_STAT_RETRY; //After the command responds incorrect, try again after a period of time.
|
||||
env->reset_timer(env);
|
||||
} else if (env->is_timeout(env, AT_DEF_TIMEOUT)) {
|
||||
do_at_callback(ai, wi, AT_RESP_TIMEOUT);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case AT_STAT_RETRY:
|
||||
if (env->is_timeout(env, 200))
|
||||
if (env->is_timeout(env, 100))
|
||||
env->state = AT_STAT_SEND;/*Go back to the send state and resend.*/
|
||||
break;
|
||||
default:
|
||||
@ -663,11 +667,13 @@ static void urc_handler_entry(at_info_t *ai, urc_recv_status status, char *urc,
|
||||
{
|
||||
int remain;
|
||||
at_urc_info_t ctx = {status, urc, size};
|
||||
if (ai->cursor == NULL && ai->urc_target == 0)
|
||||
AT_DEBUG(ai, "<=\r\n%s ...\r\n", urc);
|
||||
/* Send URC event notification. */
|
||||
remain = ai->urc_item ? ai->urc_item->handler(&ctx) : 0;
|
||||
if (remain == 0) {
|
||||
if (remain == 0 && (ai->urc_item || ai->cursor == NULL)) {
|
||||
if (ai->urc_target > 0)
|
||||
AT_DEBUG(ai, "<=\r\n%.5s..\r\n", urc);
|
||||
else
|
||||
AT_DEBUG(ai, "<=\r\n%s\r\n", urc);
|
||||
urc_reset(ai);
|
||||
} else {
|
||||
AT_DEBUG(ai,"URC receives %d bytes remaining.\r\n", remain);
|
||||
@ -723,13 +729,16 @@ static void urc_recv_process(at_info_t *ai, char *buf, unsigned int size)
|
||||
continue;
|
||||
urc_buf[ai->urc_cnt] = '\0';
|
||||
if (ai->urc_item == NULL) { //Find the corresponding URC handler
|
||||
if (ai->urc_cnt < 3 ||
|
||||
(ai->urc_item = find_urc_item(ai, urc_buf, ai->urc_cnt)) == NULL) {
|
||||
urc_reset(ai);
|
||||
}
|
||||
ai->urc_item = find_urc_item(ai, urc_buf, ai->urc_cnt);
|
||||
if (ai->urc_item == NULL && ch == '\n') {
|
||||
if (ai->urc_cnt > 2 && ai->cursor == NULL) //Unrecognized URC message
|
||||
AT_DEBUG(ai, "%s\r\n", urc_buf);
|
||||
urc_reset(ai);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ai->urc_item != NULL && ch == ai->urc_item->endmark)
|
||||
urc_handler_entry(ai, URC_RECV_OK, urc_buf, ai->urc_cnt);
|
||||
urc_handler_entry(ai, URC_RECV_OK, urc_buf, ai->urc_cnt);
|
||||
}
|
||||
|
||||
}
|
||||
@ -985,13 +994,9 @@ bool at_send_data(at_obj_t *at, const at_attr_t *attr, const void *databuf, unsi
|
||||
* @retval Indicates whether the asynchronous work was enqueued successfully.
|
||||
* @note Only the address is saved, so the 'singlline' can not be a local variable which will be destroyed.
|
||||
*/
|
||||
bool at_send_singlline(at_obj_t *at, at_callback_t cb, int timeout, int retry, const char *singlline)
|
||||
bool at_send_singlline(at_obj_t *at, const at_attr_t *attr, const char *singlline)
|
||||
{
|
||||
at_attr_t attr = at_def_attr;
|
||||
attr.cb = cb;
|
||||
attr.timeout = timeout;
|
||||
attr.retry = retry;
|
||||
return add_work_item(obj_map(at), WORK_TYPE_SINGLLINE, &attr, singlline, 0) != NULL;
|
||||
return add_work_item(obj_map(at), WORK_TYPE_SINGLLINE, attr, singlline, 0) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1107,6 +1112,14 @@ static void at_core_free(void *ptr)
|
||||
|
||||
#if AT_WORK_CONTEXT_EN
|
||||
|
||||
/**
|
||||
* @brief void * -> work_item_t *
|
||||
*/
|
||||
static inline work_item_t *work_item_map(void *work_obj)
|
||||
{
|
||||
return (work_item_t *)work_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Indicates whether the AT work is valid.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user