1
1
/*
2
- * Copyright (c) 2006-2025, RT-Thread Development Team
2
+ * Copyright (c) 2006-2025 RT-Thread Development Team
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*
20
20
21
21
#define LOG_TAG "at.clnt"
22
22
#include <at_log.h>
23
-
24
23
#ifdef AT_USING_CLIENT
25
24
26
25
#define AT_RESP_END_OK "OK"
27
26
#define AT_RESP_END_ERROR "ERROR"
28
27
#define AT_RESP_END_FAIL "FAIL"
29
28
#define AT_END_CR_LF "\r\n"
29
+ #define AT_END_CR "\r"
30
+ #define AT_END_LF "\n"
31
+ #define AT_END_RAW ""
30
32
31
33
static struct at_client at_client_table [AT_CLIENT_NUM_MAX ] = { 0 };
32
34
@@ -35,6 +37,9 @@ extern rt_size_t at_utils_send(rt_device_t dev,
35
37
const void * buffer ,
36
38
rt_size_t size );
37
39
extern 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 );
38
43
extern void at_print_raw_cmd (const char * type , const char * cmd , rt_size_t size );
39
44
40
45
/**
@@ -342,6 +347,97 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
342
347
return result ;
343
348
}
344
349
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
+
345
441
/**
346
442
* Waiting for connection to external devices.
347
443
*
@@ -775,7 +871,7 @@ static void client_parser(at_client_t client)
775
871
}
776
872
else
777
873
{
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);*/
779
875
}
780
876
}
781
877
}
@@ -997,4 +1093,4 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu
997
1093
998
1094
return result ;
999
1095
}
1000
- #endif /* AT_USING_CLIENT */
1096
+ #endif /* AT_USING_CLIENT */
0 commit comments