11/*
2- * Copyright (c) 2006-2025, RT-Thread Development Team
2+ * Copyright (c) 2006-2025 RT-Thread Development Team
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
2020
2121#define LOG_TAG "at.clnt"
2222#include <at_log.h>
23-
2423#ifdef AT_USING_CLIENT
2524
2625#define AT_RESP_END_OK "OK"
2726#define AT_RESP_END_ERROR "ERROR"
2827#define AT_RESP_END_FAIL "FAIL"
2928#define AT_END_CR_LF "\r\n"
29+ #define AT_END_CR "\r"
30+ #define AT_END_LF "\n"
31+ #define AT_END_RAW ""
3032
3133static struct at_client at_client_table [AT_CLIENT_NUM_MAX ] = { 0 };
3234
@@ -35,6 +37,9 @@ extern rt_size_t at_utils_send(rt_device_t dev,
3537 const void * buffer ,
3638 rt_size_t size );
3739extern rt_size_t at_vprintfln (rt_device_t device , char * send_buf , rt_size_t buf_size , const char * format , va_list args );
40+ extern rt_size_t at_vprintf (rt_device_t device , char * send_buf , rt_size_t buf_size , const char * format , va_list args );
41+ extern rt_size_t at_vprintfcr (rt_device_t device , char * send_buf , rt_size_t buf_size , const char * format , va_list args );
42+ extern rt_size_t at_vprintflf (rt_device_t device , char * send_buf , rt_size_t buf_size , const char * format , va_list args );
3843extern void at_print_raw_cmd (const char * type , const char * cmd , rt_size_t size );
3944
4045/**
@@ -342,6 +347,97 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
342347 return result ;
343348}
344349
350+ /**
351+ * Send commands through custom formatting to AT server and wait response.
352+ *
353+ * @param client current AT client object
354+ * @param resp AT response object, using RT_NULL when you don't care response
355+ * @param format formatting macro, it can be one of these values: AT_END_CR_LF, AT_END_RAW, AT_END_CR, AT_END_LF.
356+ * Behavior of AT_END_CR_LF is same as at_obj_exec_cmd, and it will add \r\n symnbol behind message.
357+ * AT_END_RAW means frame work won't modify anything of message. AT_END_CR will add \r for Carriage
358+ * Return. AT_END_LF means add \\n for Line Feed.
359+ * @param cmd_expr AT commands expression
360+ *
361+ * @return 0 : success
362+ * -1 : response status error
363+ * -2 : wait timeout
364+ * -7 : enter AT CLI mode
365+ */
366+ int at_obj_exec_cmd_format (at_client_t client , at_response_t resp , const char * format , const char * cmd_expr , ...)
367+ {
368+ va_list args ;
369+ rt_err_t result = RT_EOK ;
370+
371+ RT_ASSERT (cmd_expr );
372+
373+ if (client == RT_NULL )
374+ {
375+ LOG_E ("input AT Client object is NULL, please create or get AT Client object!" );
376+ return - RT_ERROR ;
377+ }
378+
379+ /* check AT CLI mode */
380+ if (client -> status == AT_STATUS_CLI && resp )
381+ {
382+ return - RT_EBUSY ;
383+ }
384+
385+ rt_mutex_take (client -> lock , RT_WAITING_FOREVER );
386+
387+ client -> resp_status = AT_RESP_OK ;
388+
389+ if (resp != RT_NULL )
390+ {
391+ resp -> buf_len = 0 ;
392+ resp -> line_counts = 0 ;
393+ }
394+
395+ client -> resp = resp ;
396+ rt_sem_control (client -> resp_notice , RT_IPC_CMD_RESET , RT_NULL );
397+
398+ va_start (args , cmd_expr );
399+
400+ if (strcmp (format , AT_END_CR_LF ) == 0 )
401+ {
402+ client -> last_cmd_len = at_vprintfln (client -> device , client -> send_buf , client -> send_bufsz , cmd_expr , args );
403+ }
404+ else if (strcmp (format , AT_END_RAW ) == 0 )
405+ {
406+ client -> last_cmd_len = at_vprintf (client -> device , client -> send_buf , client -> send_bufsz , cmd_expr , args );
407+ }
408+ else if (strcmp (format , AT_END_CR ) == 0 )
409+ {
410+ client -> last_cmd_len = at_vprintfcr (client -> device , client -> send_buf , client -> send_bufsz , cmd_expr , args );
411+ }
412+ else if (strcmp (format , AT_END_LF ) == 0 )
413+ {
414+ client -> last_cmd_len = at_vprintflf (client -> device , client -> send_buf , client -> send_bufsz , cmd_expr , args );
415+ }
416+
417+ va_end (args );
418+
419+ if (resp != RT_NULL )
420+ {
421+ if (rt_sem_take (client -> resp_notice , resp -> timeout ) != RT_EOK )
422+ {
423+ LOG_W ("execute command (%.*s) timeout (%d ticks)!" , client -> last_cmd_len , client -> send_buf , resp -> timeout );
424+ client -> resp_status = AT_RESP_TIMEOUT ;
425+ result = - RT_ETIMEOUT ;
426+ }
427+ else if (client -> resp_status != AT_RESP_OK )
428+ {
429+ LOG_E ("execute command (%.*s) failed!" , client -> last_cmd_len , client -> send_buf );
430+ result = - RT_ERROR ;
431+ }
432+ }
433+
434+ client -> resp = RT_NULL ;
435+
436+ rt_mutex_release (client -> lock );
437+
438+ return result ;
439+ }
440+
345441/**
346442 * Waiting for connection to external devices.
347443 *
@@ -775,7 +871,7 @@ static void client_parser(at_client_t client)
775871 }
776872 else
777873 {
778- // log_d("unrecognized line: %.*s", client->recv_line_len, client->recv_line_buf);
874+ /* log_d("unrecognized line: %.*s", client->recv_line_len, client->recv_line_buf);*/
779875 }
780876 }
781877 }
@@ -997,4 +1093,4 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu
9971093
9981094 return result ;
9991095}
1000- #endif /* AT_USING_CLIENT */
1096+ #endif /* AT_USING_CLIENT */
0 commit comments