summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author1078249029 <[email protected]>2025-03-06 21:56:07 +0800
committerRbb666 <[email protected]>2025-03-17 16:42:35 +0800
commit76b1f6b80eb0e6992d84c876fb912ac3fa13021f (patch)
tree51761c7081a9458ba73f882183ccb94adb01855d
parentb1d6a930e5fdcec84f714ae1b4fd074f99285d2b (diff)
[components][at] Add formatting message function for at client
It will be useful for quiting transmission mode of some chips like esp8266. Signed-off-by: 1078249029 <[email protected]>
-rw-r--r--components/net/at/include/at.h6
-rw-r--r--components/net/at/src/at_client.c104
-rw-r--r--components/net/at/src/at_utils.c37
3 files changed, 137 insertions, 10 deletions
diff --git a/components/net/at/include/at.h b/components/net/at/include/at.h
index bfd4550d2a..6af944168a 100644
--- a/components/net/at/include/at.h
+++ b/components/net/at/include/at.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2025, RT-Thread Development Team
+ * Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -222,6 +222,7 @@ int at_obj_set_urc_table(at_client_t client, const struct at_urc * table, rt_siz
/* AT client send commands to AT server and waiter response */
int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr, ...);
+int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char* format, const char *cmd_expr, ...);
/* AT response object create and delete */
at_response_t at_create_resp(rt_size_t buf_size, rt_size_t line_num, rt_int32_t timeout);
@@ -242,6 +243,7 @@ int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const
*/
#define at_exec_cmd(resp, ...) at_obj_exec_cmd(at_client_get_first(), resp, __VA_ARGS__)
+#define at_exec_cmd_format(resp, format, ...) at_obj_exec_cmd_format(at_client_get_first(), resp, format, __VA_ARGS__)
#define at_client_wait_connect(timeout) at_client_obj_wait_connect(at_client_get_first(), timeout)
#define at_client_send(buf, size) at_client_obj_send(at_client_get_first(), buf, size)
#define at_client_recv(buf, size, timeout) at_client_obj_recv(at_client_get_first(), buf, size, timeout)
@@ -264,4 +266,4 @@ void at_port_factory_reset(void);
}
#endif
-#endif /* __AT_H__ */
+#endif /* __AT_H__ */ \ No newline at end of file
diff --git a/components/net/at/src/at_client.c b/components/net/at/src/at_client.c
index 81879d8402..900f2b1b96 100644
--- a/components/net/at/src/at_client.c
+++ b/components/net/at/src/at_client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2025, RT-Thread Development Team
+ * Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -20,13 +20,15 @@
#define LOG_TAG "at.clnt"
#include <at_log.h>
-
#ifdef AT_USING_CLIENT
#define AT_RESP_END_OK "OK"
#define AT_RESP_END_ERROR "ERROR"
#define AT_RESP_END_FAIL "FAIL"
#define AT_END_CR_LF "\r\n"
+#define AT_END_CR "\r"
+#define AT_END_LF "\n"
+#define AT_END_RAW ""
static struct at_client at_client_table[AT_CLIENT_NUM_MAX] = { 0 };
@@ -35,6 +37,9 @@ extern rt_size_t at_utils_send(rt_device_t dev,
const void *buffer,
rt_size_t size);
extern rt_size_t at_vprintfln(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args);
+extern rt_size_t at_vprintf(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args);
+extern rt_size_t at_vprintfcr(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args);
+extern rt_size_t at_vprintflf(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args);
extern void at_print_raw_cmd(const char *type, const char *cmd, rt_size_t size);
/**
@@ -343,6 +348,97 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
}
/**
+ * Send commands through custom formatting to AT server and wait response.
+ *
+ * @param client current AT client object
+ * @param resp AT response object, using RT_NULL when you don't care response
+ * @param format formatting macro, it can be one of these values: AT_END_CR_LF, AT_END_RAW, AT_END_CR, AT_END_LF.
+ * Behavior of AT_END_CR_LF is same as at_obj_exec_cmd, and it will add \r\n symnbol behind message.
+ * AT_END_RAW means frame work won't modify anything of message. AT_END_CR will add \r for Carriage
+ * Return. AT_END_LF means add \\n for Line Feed.
+ * @param cmd_expr AT commands expression
+ *
+ * @return 0 : success
+ * -1 : response status error
+ * -2 : wait timeout
+ * -7 : enter AT CLI mode
+ */
+int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char* format, const char *cmd_expr, ...)
+{
+ va_list args;
+ rt_err_t result = RT_EOK;
+
+ RT_ASSERT(cmd_expr);
+
+ if (client == RT_NULL)
+ {
+ LOG_E("input AT Client object is NULL, please create or get AT Client object!");
+ return -RT_ERROR;
+ }
+
+ /* check AT CLI mode */
+ if (client->status == AT_STATUS_CLI && resp)
+ {
+ return -RT_EBUSY;
+ }
+
+ rt_mutex_take(client->lock, RT_WAITING_FOREVER);
+
+ client->resp_status = AT_RESP_OK;
+
+ if (resp != RT_NULL)
+ {
+ resp->buf_len = 0;
+ resp->line_counts = 0;
+ }
+
+ client->resp = resp;
+ rt_sem_control(client->resp_notice, RT_IPC_CMD_RESET, RT_NULL);
+
+ va_start(args, cmd_expr);
+
+ if (strcmp(format, AT_END_CR_LF) == 0)
+ {
+ client->last_cmd_len = at_vprintfln(client->device, client->send_buf, client->send_bufsz, cmd_expr, args);
+ }
+ else if (strcmp(format, AT_END_RAW) == 0)
+ {
+ client->last_cmd_len = at_vprintf(client->device, client->send_buf, client->send_bufsz, cmd_expr, args);
+ }
+ else if (strcmp(format, AT_END_CR) == 0)
+ {
+ client->last_cmd_len = at_vprintfcr(client->device, client->send_buf, client->send_bufsz, cmd_expr, args);
+ }
+ else if (strcmp(format, AT_END_LF) == 0)
+ {
+ client->last_cmd_len = at_vprintflf(client->device, client->send_buf, client->send_bufsz, cmd_expr, args);
+ }
+
+ va_end(args);
+
+ if (resp != RT_NULL)
+ {
+ if (rt_sem_take(client->resp_notice, resp->timeout) != RT_EOK)
+ {
+ LOG_W("execute command (%.*s) timeout (%d ticks)!", client->last_cmd_len, client->send_buf, resp->timeout);
+ client->resp_status = AT_RESP_TIMEOUT;
+ result = -RT_ETIMEOUT;
+ }
+ else if (client->resp_status != AT_RESP_OK)
+ {
+ LOG_E("execute command (%.*s) failed!", client->last_cmd_len, client->send_buf);
+ result = -RT_ERROR;
+ }
+ }
+
+ client->resp = RT_NULL;
+
+ rt_mutex_release(client->lock);
+
+ return result;
+}
+
+/**
* Waiting for connection to external devices.
*
* @param client current AT client object
@@ -775,7 +871,7 @@ static void client_parser(at_client_t client)
}
else
{
-// log_d("unrecognized line: %.*s", client->recv_line_len, client->recv_line_buf);
+/* log_d("unrecognized line: %.*s", client->recv_line_len, client->recv_line_buf);*/
}
}
}
@@ -997,4 +1093,4 @@ __exit:
return result;
}
-#endif /* AT_USING_CLIENT */
+#endif /* AT_USING_CLIENT */ \ No newline at end of file
diff --git a/components/net/at/src/at_utils.c b/components/net/at/src/at_utils.c
index bee6817bb0..a5cbf7c8fd 100644
--- a/components/net/at/src/at_utils.c
+++ b/components/net/at/src/at_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -56,7 +56,6 @@ void at_print_raw_cmd(const char *name, const char *buf, rt_size_t size)
rt_kprintf("\n");
}
}
-
rt_weak rt_size_t at_utils_send(rt_device_t dev,
rt_off_t pos,
const void *buffer,
@@ -64,7 +63,6 @@ rt_weak rt_size_t at_utils_send(rt_device_t dev,
{
return rt_device_write(dev, pos, buffer, size);
}
-
rt_size_t at_vprintf(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args)
{
rt_size_t len = vsnprintf(send_buf, buf_size, format, args);
@@ -79,7 +77,6 @@ rt_size_t at_vprintf(rt_device_t device, char *send_buf, rt_size_t buf_size, con
return at_utils_send(device, 0, send_buf, len);
}
-
rt_size_t at_vprintfln(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args)
{
rt_size_t len = vsnprintf(send_buf, buf_size - 2, format, args);
@@ -97,3 +94,35 @@ rt_size_t at_vprintfln(rt_device_t device, char *send_buf, rt_size_t buf_size, c
return at_utils_send(device, 0, send_buf, len);
}
+rt_size_t at_vprintfcr(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args)
+{
+ rt_size_t len = vsnprintf(send_buf, buf_size - 1, format, args);
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ send_buf[len++] = '\r';
+
+#ifdef AT_PRINT_RAW_CMD
+ at_print_raw_cmd("sendline", send_buf, len);
+#endif
+
+ return at_utils_send(device, 0, send_buf, len);
+}
+rt_size_t at_vprintflf(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args)
+{
+ rt_size_t len = vsnprintf(send_buf, buf_size - 1, format, args);
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ send_buf[len++] = '\n';
+
+#ifdef AT_PRINT_RAW_CMD
+ at_print_raw_cmd("sendline", send_buf, len);
+#endif
+
+ return at_utils_send(device, 0, send_buf, len);
+} \ No newline at end of file