Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
混口饭吃,
rt-thread
提交
ed7f0cad
R
rt-thread
项目概览
混口饭吃,
/
rt-thread
与 Fork 源项目一致
Fork自
Mr_Pangza / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ed7f0cad
编写于
8月 28, 2018
作者:
Lawlieta
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[net][at] Add AT multiple client support
上级
6d702e57
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
352 addition
and
205 deletion
+352
-205
components/net/at/Kconfig
components/net/at/Kconfig
+19
-17
components/net/at/include/at.h
components/net/at/include/at.h
+45
-21
components/net/at/src/at_cli.c
components/net/at/src/at_cli.c
+30
-14
components/net/at/src/at_client.c
components/net/at/src/at_client.c
+256
-151
components/net/at/src/at_server.c
components/net/at/src/at_server.c
+2
-2
未找到文件。
components/net/at/Kconfig
浏览文件 @
ed7f0cad
...
...
@@ -51,22 +51,22 @@ if RT_USING_AT
if AT_USING_CLIENT
config AT_CLIENT_DEVICE
string "Client device name"
default "uart2"
config AT_CLIENT_RECV_BUFF_LEN
int "The maximum length of client data accepted"
default 512
config AT_CLIENT_NUM_MAX
int "The maximum number of supported clients"
default 1
range 1 65535
config AT_USING_SOCKET
bool "
Provide similar BSD Socket API by AT
"
bool "
Enable BSD Socket API support by AT commnads
"
select RT_USING_LIBC
default n
endif
if AT_USING_SERVER || AT_USING_CLIENT
config AT_USING_CLI
bool "Enable command-line interface
for AT commands"
bool "Enable CLI(Command-Line Interface)
for AT commands"
default y
depends on FINSH_USING_MSH
...
...
@@ -74,6 +74,8 @@ if RT_USING_AT
bool "Enable print RAW format AT command communication data"
default n
endif
endif
endmenu
components/net/at/include/at.h
浏览文件 @
ed7f0cad
...
...
@@ -20,6 +20,7 @@
* Change Logs:
* Date Author Notes
* 2018-03-30 chenyong first version
* 2018-08-17 chenyong multiple client support
*/
#ifndef __AT_H__
...
...
@@ -30,7 +31,8 @@
#ifdef __cplusplus
extern
"C"
{
#endif
#define AT_SW_VERSION "0.3.0"
#define AT_SW_VERSION "1.0.0"
#define AT_SW_VERSION_NUM 0x10000
#define DBG_ENABLE
#define DBG_SECTION_NAME "AT"
...
...
@@ -67,16 +69,13 @@ extern "C" {
#define AT_SERVER_RECV_BUFF_LEN 256
#endif
#ifndef AT_CLIENT_RECV_BUFF_LEN
#define AT_CLIENT_RECV_BUFF_LEN 512
#endif
#ifndef AT_SERVER_DEVICE
#define AT_SERVER_DEVICE "uart2"
#endif
#ifndef AT_CLIENT_DEVICE
#define AT_CLIENT_DEVICE "uart2"
/* the maximum number of supported AT clients */
#ifndef AT_CLIENT_NUM_MAX
#define AT_CLIENT_NUM_MAX 1
#endif
#define AT_CMD_EXPORT(_name_, _args_expr_, _test_, _query_, _setup_, _exec_) \
...
...
@@ -137,7 +136,6 @@ struct at_server
rt_thread_t
parser
;
void
(
*
parser_entry
)(
struct
at_server
*
server
);
};
typedef
struct
at_server
*
at_server_t
;
#endif
/* AT_USING_SERVER */
...
...
@@ -183,8 +181,10 @@ struct at_client
rt_device_t
device
;
at_status_t
status
;
char
end_sign
;
char
recv_buffer
[
AT_CLIENT_RECV_BUFF_LEN
];
char
*
recv_buffer
;
rt_size_t
recv_bufsz
;
rt_size_t
cur_recv_len
;
rt_sem_t
rx_notice
;
rt_mutex_t
lock
;
...
...
@@ -198,7 +198,6 @@ struct at_client
rt_thread_t
parser
;
};
typedef
struct
at_client
*
at_client_t
;
#endif
/* AT_USING_CLIENT */
...
...
@@ -216,20 +215,33 @@ int at_req_parse_args(const char *req_args, const char *req_expr, ...);
#endif
/* AT_USING_SERVER */
#ifdef AT_USING_CLIENT
/* AT client initialize and start */
int
at_client_init
(
void
);
/* AT client initialize and start*/
int
at_client_init
(
const
char
*
dev_name
,
rt_size_t
recv_bufsz
);
/* ========================== multiple AT client function ============================ */
/* get AT client object */
at_client_t
at_client_get
(
const
char
*
dev_name
);
at_client_t
at_client_get_first
(
void
);
/* AT client wait for connection to external devices. */
int
at_client_
wait_connect
(
rt_uint32_t
timeout
);
int
at_client_
obj_wait_connect
(
at_client_t
client
,
rt_uint32_t
timeout
);
/* AT client send commands to AT server and waiter response */
int
at_exec_cmd
(
at_response_t
resp
,
const
char
*
cmd_expr
,
...);
/* AT client send or receive data */
rt_size_t
at_client_obj_send
(
at_client_t
client
,
const
char
*
buf
,
rt_size_t
size
);
rt_size_t
at_client_obj_recv
(
at_client_t
client
,
char
*
buf
,
rt_size_t
size
);
/* AT Client send or receive data */
rt_size_t
at_client_send
(
const
char
*
buf
,
rt_size_t
size
);
rt_size_t
at_client_recv
(
char
*
buf
,
rt_size_t
size
);
/* set AT client a line end sign */
void
at_obj_set_end_sign
(
at_client_t
client
,
char
ch
);
/* AT response structure create and delete */
/* Set URC(Unsolicited Result Code) table */
void
at_obj_set_urc_table
(
at_client_t
client
,
const
struct
at_urc
*
table
,
rt_size_t
size
);
/* 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
,
...);
/* 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
);
void
at_delete_resp
(
at_response_t
resp
);
at_response_t
at_resp_set_info
(
at_response_t
resp
,
rt_size_t
buf_size
,
rt_size_t
line_num
,
rt_int32_t
timeout
);
...
...
@@ -240,8 +252,20 @@ const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword);
int
at_resp_parse_line_args
(
at_response_t
resp
,
rt_size_t
resp_line
,
const
char
*
resp_expr
,
...);
int
at_resp_parse_line_args_by_kw
(
at_response_t
resp
,
const
char
*
keyword
,
const
char
*
resp_expr
,
...);
/* Set URC(Unsolicited Result Code) table */
void
at_set_urc_table
(
const
struct
at_urc
*
table
,
rt_size_t
size
);
/* ========================== single AT client function ============================ */
/**
* NOTE: These functions can be used directly when there is only one AT client.
* If there are multiple AT Client in the program, these functions can operate on the first initialized AT client.
*/
#define at_exec_cmd(resp, ...) at_obj_exec_cmd(at_client_get_first(), resp, __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) at_client_obj_recv(at_client_get_first(), buf, size)
#define at_set_end_sign(ch) at_obj_set_end_sign(at_client_get_first(), ch)
#define at_set_urc_table(urc_table, table_sz) at_obj_set_urc_table(at_client_get_first(), urc_table, table_sz)
#endif
/* AT_USING_CLIENT */
/* ========================== User port function ============================ */
...
...
components/net/at/src/at_cli.c
浏览文件 @
ed7f0cad
...
...
@@ -76,7 +76,7 @@ void at_cli_init(void)
rt_base_t
int_lvl
;
rt_device_t
console
;
rt_sem_init
(
&
console_rx_notice
,
"
at_cli_notice
"
,
0
,
RT_IPC_FLAG_FIFO
);
rt_sem_init
(
&
console_rx_notice
,
"
cli_c
"
,
0
,
RT_IPC_FLAG_FIFO
);
/* create RX FIFO */
console_rx_fifo
=
rt_ringbuffer_create
(
AT_CLI_FIFO_SIZE
);
...
...
@@ -209,14 +209,12 @@ static rt_err_t client_getchar_rx_ind(rt_device_t dev, rt_size_t size)
return
RT_EOK
;
}
static
void
client_cli_parser
(
void
)
static
void
client_cli_parser
(
at_client_t
client
)
{
#define ESC_KEY 0x1B
#define BACKSPACE_KEY 0x08
#define DELECT_KEY 0x7F
extern
at_client_t
rt_at_get_client
(
void
);
at_client_t
client
=
rt_at_get_client
();
char
ch
;
char
cur_line
[
FINSH_CMD_SIZE
]
=
{
0
};
rt_size_t
cur_line_len
=
0
;
...
...
@@ -234,10 +232,10 @@ static void client_cli_parser(void)
rt_hw_interrupt_enable
(
int_lvl
);
}
rt_sem_init
(
&
client_rx_notice
,
"
at_cli_client_notice
"
,
0
,
RT_IPC_FLAG_FIFO
);
rt_sem_init
(
&
client_rx_notice
,
"
cli_r
"
,
0
,
RT_IPC_FLAG_FIFO
);
client_rx_fifo
=
rt_ringbuffer_create
(
AT_CLI_FIFO_SIZE
);
at_client
=
rt_thread_create
(
"at_cli
_client
"
,
at_client_entry
,
RT_NULL
,
512
,
8
,
8
);
at_client
=
rt_thread_create
(
"at_cli"
,
at_client_entry
,
RT_NULL
,
512
,
8
,
8
);
if
(
client_rx_fifo
&&
at_client
)
{
rt_kprintf
(
"======== Welcome to using RT-Thread AT command client cli ========
\n
"
);
...
...
@@ -261,7 +259,7 @@ static void client_cli_parser(void)
if
(
cur_line_len
)
{
rt_kprintf
(
"
\n
"
);
at_
exec_cmd
(
RT_NULL
,
"%.*s"
,
cur_line_len
,
cur_line
);
at_
obj_exec_cmd
(
client
,
RT_NULL
,
"%.*s"
,
cur_line_len
,
cur_line
);
}
cur_line_len
=
0
;
}
...
...
@@ -297,9 +295,10 @@ static void client_cli_parser(void)
static
void
at
(
int
argc
,
char
**
argv
)
{
if
(
argc
<
2
)
if
(
argc
!=
2
&&
argc
!=
3
)
{
rt_kprintf
(
"Please input '
at <server|client
>'
\n
"
);
rt_kprintf
(
"Please input '
<server|client [dev_name]
>'
\n
"
);
return
;
}
...
...
@@ -311,23 +310,40 @@ static void at(int argc, char **argv)
server_cli_parser
();
#else
rt_kprintf
(
"Not support AT server, please check your configure!
\n
"
);
#endif
#endif
/* AT_USING_SERVER */
}
else
if
(
!
strcmp
(
argv
[
1
],
"client"
))
{
#ifdef AT_USING_CLIENT
client_cli_parser
();
at_client_t
client
=
RT_NULL
;
if
(
argc
==
2
)
{
client_cli_parser
(
at_client_get_first
());
}
else
if
(
argc
==
3
)
{
client
=
at_client_get
(
argv
[
2
]);
if
(
client
==
RT_NULL
)
{
rt_kprintf
(
"input AT client device name(%s) error.
\n
"
,
argv
[
2
]);
}
else
{
client_cli_parser
(
client
);
}
}
#else
rt_kprintf
(
"Not support AT client, please check your configure!
\n
"
);
#endif
#endif
/* AT_USING_CLIENT */
}
else
{
rt_kprintf
(
"Please input '
at <server|client
>'
\n
"
);
rt_kprintf
(
"Please input '
<server|client [dev_name]
>'
\n
"
);
}
at_cli_deinit
();
}
MSH_CMD_EXPORT
(
at
,
RT
-
Thread
AT
component
cli
:
at
<
server
|
client
>
);
MSH_CMD_EXPORT
(
at
,
RT
-
Thread
AT
component
cli
:
at
<
server
|
client
[
dev_name
]
>
);
#endif
/* AT_USING_CLI */
components/net/at/src/at_client.c
浏览文件 @
ed7f0cad
...
...
@@ -21,6 +21,7 @@
* Date Author Notes
* 2018-03-30 chenyong first version
* 2018-04-12 chenyong add client implement
* 2018-08-17 chenyong multiple client support
*/
#include <at.h>
...
...
@@ -33,15 +34,14 @@
#define AT_RESP_END_FAIL "FAIL"
#define AT_END_CR_LF "\r\n"
static
at_client_t
at_client_local
=
RT_NULL
;
static
char
cust_end_sign
=
0
;
static
struct
at_client
at_client_table
[
AT_CLIENT_NUM_MAX
]
=
{
0
};
extern
rt_size_t
at_vprintfln
(
rt_device_t
device
,
const
char
*
format
,
va_list
args
);
extern
void
at_print_raw_cmd
(
const
char
*
type
,
const
char
*
cmd
,
rt_size_t
size
);
extern
const
char
*
at_get_last_cmd
(
rt_size_t
*
cmd_size
);
/**
* Create response
structure
.
* Create response
object
.
*
* @param buf_size the maximum response buffer size
* @param line_num the number of setting response lines
...
...
@@ -49,7 +49,7 @@ extern const char *at_get_last_cmd(rt_size_t *cmd_size);
* != 0: the response data will return when received setting lines number data
* @param timeout the maximum response time
*
* @return != RT_NULL: response
structure
* @return != RT_NULL: response
object
* = RT_NULL: no memory
*/
at_response_t
at_create_resp
(
rt_size_t
buf_size
,
rt_size_t
line_num
,
rt_int32_t
timeout
)
...
...
@@ -57,16 +57,16 @@ at_response_t at_create_resp(rt_size_t buf_size, rt_size_t line_num, rt_int32_t
at_response_t
resp
=
RT_NULL
;
resp
=
(
at_response_t
)
rt_calloc
(
1
,
sizeof
(
struct
at_response
));
if
(
!
resp
)
if
(
resp
==
RT_NULL
)
{
LOG_E
(
"AT create response
structure failed! No memory for response structure
!"
);
LOG_E
(
"AT create response
object failed! No memory for response object
!"
);
return
RT_NULL
;
}
resp
->
buf
=
(
char
*
)
rt_calloc
(
1
,
buf_size
);
if
(
!
resp
->
buf
)
if
(
resp
->
buf
==
RT_NULL
)
{
LOG_E
(
"AT create response
structure failed! No memory for response buf structure
!"
);
LOG_E
(
"AT create response
object failed! No memory for response buffer
!"
);
rt_free
(
resp
);
return
RT_NULL
;
}
...
...
@@ -80,9 +80,9 @@ at_response_t at_create_resp(rt_size_t buf_size, rt_size_t line_num, rt_int32_t
}
/**
* Delete and free response
structure
.
* Delete and free response
object
.
*
* @param resp response
structure
* @param resp response
object
*/
void
at_delete_resp
(
at_response_t
resp
)
{
...
...
@@ -99,28 +99,28 @@ void at_delete_resp(at_response_t resp)
}
/**
* Set response
structure
information
* Set response
object
information
*
* @param resp response
structure
* @param resp response
object
* @param buf_size the maximum response buffer size
* @param line_num the number of setting response lines
* = 0: the response data will auto return when received 'OK' or 'ERROR'
* != 0: the response data will return when received setting lines number data
* @param timeout the maximum response time
*
* @return != RT_NULL: response
structure
* @return != RT_NULL: response
object
* = RT_NULL: no memory
*/
at_response_t
at_resp_set_info
(
at_response_t
resp
,
rt_size_t
buf_size
,
rt_size_t
line_num
,
rt_int32_t
timeout
)
{
RT_ASSERT
(
resp
);
if
(
resp
->
buf_size
!=
buf_size
)
if
(
resp
->
buf_size
!=
buf_size
)
{
resp
->
buf_size
=
buf_size
;
resp
->
buf
=
rt_realloc
(
resp
->
buf
,
buf_size
);
if
(
!
resp
->
buf
)
resp
->
buf
=
(
char
*
)
rt_realloc
(
resp
->
buf
,
buf_size
);
if
(
!
resp
->
buf
)
{
LOG_D
(
"No memory for realloc response buffer size(%d)."
,
buf_size
);
return
RT_NULL
;
...
...
@@ -136,7 +136,7 @@ at_response_t at_resp_set_info(at_response_t resp, rt_size_t buf_size, rt_size_t
/**
* Get one line AT response buffer by line number.
*
* @param resp response
structure
* @param resp response
object
* @param resp_line line number, start from '1'
*
* @return != RT_NULL: response line buffer
...
...
@@ -174,7 +174,7 @@ const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line)
/**
* Get one line AT response buffer by keyword
*
* @param resp response
structure
* @param resp response
object
* @param keyword query keyword
*
* @return != RT_NULL: response line buffer
...
...
@@ -191,7 +191,7 @@ const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword)
for
(
line_num
=
1
;
line_num
<=
resp
->
line_counts
;
line_num
++
)
{
if
(
strstr
(
resp_buf
,
keyword
))
if
(
strstr
(
resp_buf
,
keyword
))
{
resp_line_buf
=
resp_buf
;
...
...
@@ -207,7 +207,7 @@ const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword)
/**
* Get and parse AT response buffer arguments by line number.
*
* @param resp response
structure
* @param resp response
object
* @param resp_line line number, start from '1'
* @param resp_expr response buffer expression
*
...
...
@@ -241,7 +241,7 @@ int at_resp_parse_line_args(at_response_t resp, rt_size_t resp_line, const char
/**
* Get and parse AT response buffer arguments by keyword.
*
* @param resp response
structure
* @param resp response
object
* @param keyword query keyword
* @param resp_expr response buffer expression
*
...
...
@@ -275,21 +275,22 @@ int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const
/**
* Send commands to AT server and wait response.
*
* @param resp AT response structure, using RT_NULL when you don't care response
* @param client current AT client object
* @param resp AT response object, using RT_NULL when you don't care response
* @param cmd_expr AT commands expression
*
* @return 0 : success
* -1 : response status error
* -2 : wait timeout
*/
int
at_
exec_cmd
(
at_response_t
resp
,
const
char
*
cmd_expr
,
...)
int
at_
obj_exec_cmd
(
at_client_t
client
,
at_response_t
resp
,
const
char
*
cmd_expr
,
...)
{
at_client_t
client
=
at_client_local
;
va_list
args
;
rt_size_t
cmd_size
=
0
;
rt_err_t
result
=
RT_EOK
;
const
char
*
cmd
=
RT_NULL
;
RT_ASSERT
(
client
);
RT_ASSERT
(
cmd_expr
);
rt_mutex_take
(
client
->
lock
,
RT_WAITING_FOREVER
);
...
...
@@ -301,7 +302,7 @@ int at_exec_cmd(at_response_t resp, const char *cmd_expr, ...)
at_vprintfln
(
client
->
device
,
cmd_expr
,
args
);
va_end
(
args
);
if
(
resp
)
if
(
resp
!=
RT_NULL
)
{
resp
->
line_counts
=
0
;
if
(
rt_sem_take
(
client
->
resp_notice
,
resp
->
timeout
)
!=
RT_EOK
)
...
...
@@ -332,23 +333,29 @@ __exit:
/**
* Waiting for connection to external devices.
*
* @param client current AT client object
* @param timeout millisecond for timeout
*
* @return 0 : success
* -2 : timeout
* -5 : no memory
*/
int
at_client_
wait_connect
(
rt_uint32_t
timeout
)
int
at_client_
obj_wait_connect
(
at_client_t
client
,
rt_uint32_t
timeout
)
{
rt_err_t
result
=
RT_EOK
;
at_response_t
resp
=
RT_NULL
;
at_client_t
client
=
at_client_local
;
rt_tick_t
start_time
=
0
;
if
(
client
==
RT_NULL
)
{
LOG_E
(
"Input AT Client is NULL, please create or get AT Client!"
);
return
RT_NULL
;
}
resp
=
at_create_resp
(
16
,
0
,
rt_tick_from_millisecond
(
500
));
if
(
!
resp
)
if
(
resp
==
RT_NULL
)
{
LOG_E
(
"No memory for response
structure
!"
);
LOG_E
(
"No memory for response
object
!"
);
return
-
RT_ENOMEM
;
}
...
...
@@ -389,15 +396,15 @@ int at_client_wait_connect(rt_uint32_t timeout)
/**
* Send data to AT server, send data don't have end sign(eg: \r\n).
*
* @param client current AT client object
* @param buf send data buffer
* @param size send fixed data size
*
* @return send data size
*/
rt_size_t
at_client_
send
(
const
char
*
buf
,
rt_size_t
size
)
rt_size_t
at_client_
obj_send
(
at_client_t
client
,
const
char
*
buf
,
rt_size_t
size
)
{
at_client_t
client
=
at_client_local
;
RT_ASSERT
(
client
);
RT_ASSERT
(
buf
);
#ifdef AT_PRINT_RAW_CMD
...
...
@@ -405,17 +412,16 @@ rt_size_t at_client_send(const char *buf, rt_size_t size)
#endif
return
rt_device_write
(
client
->
device
,
0
,
buf
,
size
);
}
static
char
at_client_getchar
(
void
)
static
char
at_client_getchar
(
at_client_t
client
)
{
char
ch
;
while
(
rt_device_read
(
at_client_local
->
device
,
0
,
&
ch
,
1
)
==
0
)
while
(
rt_device_read
(
client
->
device
,
0
,
&
ch
,
1
)
==
0
)
{
rt_sem_control
(
at_client_local
->
rx_notice
,
RT_IPC_CMD_RESET
,
RT_NULL
);
rt_sem_take
(
at_client_local
->
rx_notice
,
RT_WAITING_FOREVER
);
rt_sem_control
(
client
->
rx_notice
,
RT_IPC_CMD_RESET
,
RT_NULL
);
rt_sem_take
(
client
->
rx_notice
,
RT_WAITING_FOREVER
);
}
return
ch
;
...
...
@@ -424,6 +430,7 @@ static char at_client_getchar(void)
/**
* AT client receive fixed-length data.
*
* @param client current AT client object
* @param buf receive data buffer
* @param size receive fixed data size
*
...
...
@@ -431,18 +438,19 @@ static char at_client_getchar(void)
*
* @return success receive data size
*/
rt_size_t
at_client_
recv
(
char
*
buf
,
rt_size_t
size
)
rt_size_t
at_client_
obj_recv
(
at_client_t
client
,
char
*
buf
,
rt_size_t
size
)
{
rt_size_t
read_idx
=
0
;
char
ch
;
RT_ASSERT
(
client
);
RT_ASSERT
(
buf
);
while
(
1
)
{
if
(
read_idx
<
size
)
{
ch
=
at_client_getchar
();
ch
=
at_client_getchar
(
client
);
buf
[
read_idx
++
]
=
ch
;
}
...
...
@@ -457,56 +465,105 @@ rt_size_t at_client_recv(char *buf, rt_size_t size)
#endif
return
read_idx
;
}
/**
* AT client set end sign.
*
* @param client current AT client object
* @param ch the end sign, can not be used when it is '\0'
*/
void
at_obj_set_end_sign
(
at_client_t
client
,
char
ch
)
{
RT_ASSERT
(
client
);
client
->
end_sign
=
ch
;
}
/**
*
get AT client structure pointer.
*
set URC(Unsolicited Result Code) table
*
* @return AT client structure pointer
* @param client current AT client object
* @param table URC table
* @param size table size
*/
at_client_t
rt_at_get_client
(
void
)
void
at_obj_set_urc_table
(
at_client_t
client
,
const
struct
at_urc
*
urc_table
,
rt_size_t
table_sz
)
{
RT_ASSERT
(
at_client_local
);
RT_ASSERT
(
at_client_local
->
status
!=
AT_STATUS_UNINITIALIZED
);
rt_size_t
idx
;
return
at_client_local
;
for
(
idx
=
0
;
idx
<
table_sz
;
idx
++
)
{
RT_ASSERT
(
urc_table
[
idx
].
cmd_prefix
);
RT_ASSERT
(
urc_table
[
idx
].
cmd_suffix
);
}
client
->
urc_table
=
urc_table
;
client
->
urc_table_size
=
table_sz
;
}
/**
*
AT client set end sign
.
*
get AT client object by AT device name
.
*
* @param ch the end sign, can not be used when it is '\0'
* @dev_name AT client device name
*
* @return AT client object
*/
at_client_t
at_client_get
(
const
char
*
dev_name
)
{
int
idx
=
0
;
RT_ASSERT
(
dev_name
);
for
(
idx
=
0
;
idx
<
AT_CLIENT_NUM_MAX
;
idx
++
)
{
if
(
rt_strcmp
(
at_client_table
[
idx
].
device
->
parent
.
name
,
dev_name
)
==
0
)
{
return
&
at_client_table
[
idx
];
}
}
return
RT_NULL
;
}
/**
* get first AT client object in the table.
*
* @return
0: set success
* @return
AT client object
*/
int
at_set_end_sign
(
char
ch
)
at_client_t
at_client_get_first
(
void
)
{
cust_end_sign
=
ch
;
if
(
at_client_table
[
0
].
device
==
RT_NULL
)
{
return
RT_NULL
;
}
return
0
;
return
&
at_client_table
[
0
]
;
}
static
const
struct
at_urc
*
get_urc_obj
(
char
*
data
,
rt_size_t
size
)
static
const
struct
at_urc
*
get_urc_obj
(
at_client_t
client
)
{
rt_size_t
i
,
prefix_len
,
suffix_len
;
at_client_t
client
=
at_client_local
;
rt_size_t
buf_sz
;
char
*
buffer
=
RT_NULL
;
if
(
client
->
urc_table
==
RT_NULL
)
{
return
RT_NULL
;
}
buffer
=
client
->
recv_buffer
;
buf_sz
=
client
->
cur_recv_len
;
for
(
i
=
0
;
i
<
client
->
urc_table_size
;
i
++
)
{
prefix_len
=
strlen
(
client
->
urc_table
[
i
].
cmd_prefix
);
suffix_len
=
strlen
(
client
->
urc_table
[
i
].
cmd_suffix
);
if
(
size
<
prefix_len
+
suffix_len
)
if
(
buf_sz
<
prefix_len
+
suffix_len
)
{
continue
;
}
if
((
prefix_len
?
!
strncmp
(
data
,
client
->
urc_table
[
i
].
cmd_prefix
,
prefix_len
)
:
1
)
&&
(
suffix_len
?
!
strncmp
(
data
+
size
-
suffix_len
,
client
->
urc_table
[
i
].
cmd_suffix
,
suffix_len
)
:
1
))
if
((
prefix_len
?
!
strncmp
(
buffer
,
client
->
urc_table
[
i
].
cmd_prefix
,
prefix_len
)
:
1
)
&&
(
suffix_len
?
!
strncmp
(
buffer
+
buf_sz
-
suffix_len
,
client
->
urc_table
[
i
].
cmd_suffix
,
suffix_len
)
:
1
))
{
return
&
client
->
urc_table
[
i
];
}
...
...
@@ -515,23 +572,23 @@ static const struct at_urc *get_urc_obj(char *data, rt_size_t size)
return
RT_NULL
;
}
static
int
at_recv_readline
(
void
)
static
int
at_recv_readline
(
at_client_t
client
)
{
rt_size_t
read_len
=
0
;
char
ch
=
0
,
last_ch
=
0
;
rt_bool_t
is_full
=
RT_FALSE
;
at_client_t
client
=
at_client_local
;
memset
(
client
->
recv_buffer
,
0x00
,
AT_CLIENT_RECV_BUFF_LEN
);
memset
(
client
->
recv_buffer
,
0x00
,
client
->
recv_bufsz
);
client
->
cur_recv_len
=
0
;
while
(
1
)
{
ch
=
at_client_getchar
();
ch
=
at_client_getchar
(
client
);
if
(
read_len
<
AT_CLIENT_RECV_BUFF_LEN
)
if
(
read_len
<
client
->
recv_bufsz
)
{
client
->
recv_buffer
[
read_len
++
]
=
ch
;
client
->
cur_recv_len
=
read_len
;
}
else
{
...
...
@@ -539,17 +596,16 @@ static int at_recv_readline(void)
}
/* is newline or URC data */
if
((
ch
==
'\n'
&&
last_ch
==
'\r'
)
||
(
c
ust_end_sign
!=
0
&&
ch
==
cust_
end_sign
)
||
get_urc_obj
(
client
->
recv_buffer
,
read_len
))
if
((
ch
==
'\n'
&&
last_ch
==
'\r'
)
||
(
c
lient
->
end_sign
!=
0
&&
ch
==
client
->
end_sign
)
||
get_urc_obj
(
client
))
{
if
(
is_full
)
{
LOG_E
(
"read line failed. The line data length is out of buffer size(%d)!"
,
AT_CLIENT_RECV_BUFF_LEN
);
memset
(
client
->
recv_buffer
,
0x00
,
AT_CLIENT_RECV_BUFF_LEN
);
LOG_E
(
"read line failed. The line data length is out of buffer size(%d)!"
,
client
->
recv_bufsz
);
memset
(
client
->
recv_buffer
,
0x00
,
client
->
recv_bufsz
);
client
->
cur_recv_len
=
0
;
return
-
RT_EFULL
;
}
client
->
cur_recv_len
=
read_len
;
break
;
}
last_ch
=
ch
;
...
...
@@ -570,9 +626,9 @@ static void client_parser(at_client_t client)
while
(
1
)
{
if
(
at_recv_readline
()
>
0
)
if
(
at_recv_readline
(
client
)
>
0
)
{
if
((
urc
=
get_urc_obj
(
client
->
recv_buffer
,
client
->
cur_recv_len
))
!=
RT_NULL
)
if
((
urc
=
get_urc_obj
(
client
))
!=
RT_NULL
)
{
/* current receive is request, try to execute related operations */
if
(
urc
->
func
!=
RT_NULL
)
...
...
@@ -634,149 +690,198 @@ static void client_parser(at_client_t client)
static
rt_err_t
at_client_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
)
{
if
(
size
>
0
)
int
idx
=
0
;
for
(
idx
=
0
;
idx
<
AT_CLIENT_NUM_MAX
;
idx
++
)
{
rt_sem_release
(
at_client_local
->
rx_notice
);
if
(
at_client_table
[
idx
].
device
==
dev
&&
size
>
0
)
{
rt_sem_release
(
at_client_table
[
idx
].
rx_notice
);
}
}
return
RT_EOK
;
}
/**
* Set URC(Unsolicited Result Code) table
*
* @param table URC table
* @param size table size
*/
void
at_set_urc_table
(
const
struct
at_urc
*
table
,
rt_size_t
size
)
/* initialize the client object parameters */
static
int
at_client_para_init
(
at_client_t
client
)
{
rt_size_t
idx
;
for
(
idx
=
0
;
idx
<
size
;
idx
++
)
{
RT_ASSERT
(
table
[
idx
].
cmd_prefix
);
RT_ASSERT
(
table
[
idx
].
cmd_suffix
);
}
#define AT_CLIENT_LOCK_NAME "at_c"
#define AT_CLIENT_SEM_NAME "at_cs"
#define AT_CLIENT_RESP_NAME "at_cr"
#define AT_CLIENT_THREAD_NAME "at_clnt"
at_client_local
->
urc_table
=
table
;
at_client_local
->
urc_table_size
=
size
;
int
result
=
RT_EOK
;
static
int
at_client_num
=
0
;
char
name
[
RT_NAME_MAX
];
}
client
->
status
=
AT_STATUS_UNINITIALIZED
;
/**
* initialize AT client.
*
* @return 0: initialize success
* -1: initialize failed
* -5: no memory
*/
int
at_client_init
(
void
)
{
int
result
=
RT_EOK
;
rt_err_t
open_result
=
RT_EOK
;
client
->
cur_recv_len
=
0
;
client
->
recv_buffer
=
(
char
*
)
rt_calloc
(
1
,
client
->
recv_bufsz
);
if
(
client
->
recv_buffer
==
RT_NULL
)
{
LOG_E
(
"AT client initialize failed! No memory for receive buffer."
)
result
=
-
RT_ENOMEM
;
goto
__exit
;
}
if
(
at_client_local
)
rt_snprintf
(
name
,
RT_NAME_MAX
,
"%s%d"
,
AT_CLIENT_LOCK_NAME
,
at_client_num
);
client
->
lock
=
rt_mutex_create
(
name
,
RT_IPC_FLAG_FIFO
);
if
(
client
->
lock
==
RT_NULL
)
{
return
result
;
LOG_E
(
"AT client initialize failed! at_client_recv_lock create failed!"
);
result
=
-
RT_ENOMEM
;
goto
__exit
;
}
at_client_local
=
(
at_client_t
)
rt_calloc
(
1
,
sizeof
(
struct
at_client
));
if
(
!
at_client_local
)
rt_snprintf
(
name
,
RT_NAME_MAX
,
"%s%d"
,
AT_CLIENT_SEM_NAME
,
at_client_num
);
client
->
rx_notice
=
rt_sem_create
(
name
,
0
,
RT_IPC_FLAG_FIFO
);
if
(
client
->
rx_notice
==
RT_NULL
)
{
result
=
-
RT_ERROR
;
LOG_E
(
"AT client session initialize failed! No memory for at_client structure !"
)
;
LOG_E
(
"AT client initialize failed! at_client_notice semaphore create failed!"
)
;
result
=
-
RT_ENOMEM
;
goto
__exit
;
}
at_client_local
->
status
=
AT_STATUS_UNINITIALIZED
;
at_client_local
->
lock
=
rt_mutex_create
(
"at_lock"
,
RT_IPC_FLAG_FIFO
);
if
(
!
at_client_local
->
lock
)
rt_snprintf
(
name
,
RT_NAME_MAX
,
"%s%d"
,
AT_CLIENT_RESP_NAME
,
at_client_num
)
;
client
->
resp_notice
=
rt_sem_create
(
name
,
0
,
RT_IPC_FLAG_FIFO
);
if
(
client
->
resp_notice
==
RT_NULL
)
{
LOG_E
(
"AT client
session initialize failed! at_client_recv_lock
create failed!"
);
LOG_E
(
"AT client
initialize failed! at_client_resp semaphore
create failed!"
);
result
=
-
RT_ENOMEM
;
goto
__exit
;
}
at_client_local
->
cur_recv_len
=
0
;
client
->
urc_table
=
RT_NULL
;
client
->
urc_table_size
=
0
;
at_client_local
->
rx_notice
=
rt_sem_create
(
"at_client_notice"
,
0
,
RT_IPC_FLAG_FIFO
);
if
(
!
at_client_local
->
rx_notice
)
rt_snprintf
(
name
,
RT_NAME_MAX
,
"%s%d"
,
AT_CLIENT_THREAD_NAME
,
at_client_num
);
client
->
parser
=
rt_thread_create
(
name
,
(
void
(
*
)(
void
*
parameter
))
client_parser
,
client
,
1024
+
512
,
RT_THREAD_PRIORITY_MAX
/
3
-
1
,
5
);
if
(
client
->
parser
==
RT_NULL
)
{
LOG_E
(
"AT client session initialize failed! at_client_notice semaphore create failed!"
);
result
=
-
RT_ENOMEM
;
goto
__exit
;
}
at_client_local
->
resp_notice
=
rt_sem_create
(
"at_client_resp"
,
0
,
RT_IPC_FLAG_FIFO
);
if
(
!
at_client_local
->
resp_notice
)
__exit:
if
(
result
!=
RT_EOK
)
{
if
(
client
->
lock
)
{
rt_mutex_delete
(
client
->
lock
);
}
if
(
client
->
rx_notice
)
{
LOG_E
(
"AT client session initialize failed! at_client_resp semaphore create failed!"
);
result
=
-
RT_ENOMEM
;
rt_sem_delete
(
client
->
rx_notice
);
}
if
(
client
->
resp_notice
)
{
rt_sem_delete
(
client
->
resp_notice
);
}
if
(
client
->
device
)
{
rt_device_close
(
client
->
device
);
}
if
(
client
->
recv_buffer
)
{
rt_free
(
client
->
recv_buffer
);
}
rt_memset
(
client
,
0x00
,
sizeof
(
struct
at_client
));
}
else
{
at_client_num
++
;
}
return
result
;
}
/**
* AT client initialize.
*
* @param dev_name AT client device name
* @param recv_bufsz the maximum number of receive buffer length
*
* @return 0 : initialize success
* -1 : initialize failed
* -5 : no memory
*/
int
at_client_init
(
const
char
*
dev_name
,
rt_size_t
recv_bufsz
)
{
int
idx
=
0
;
int
result
=
RT_EOK
;
rt_err_t
open_result
=
RT_EOK
;
at_client_t
client
=
RT_NULL
;
RT_ASSERT
(
dev_name
);
RT_ASSERT
(
recv_bufsz
>
0
);
for
(
idx
=
0
;
idx
<
AT_CLIENT_NUM_MAX
&&
at_client_table
[
idx
].
device
;
idx
++
);
if
(
idx
>=
AT_CLIENT_NUM_MAX
)
{
LOG_E
(
"AT client initialize filed! Check the maximum number(%d) of AT client."
,
AT_CLIENT_NUM_MAX
);
result
=
-
RT_EFULL
;
goto
__exit
;
}
/* Find and open command device */
at_client_local
->
device
=
rt_device_find
(
AT_CLIENT_DEVICE
);
if
(
at_client_local
->
device
)
client
=
&
at_client_table
[
idx
];
client
->
recv_bufsz
=
recv_bufsz
;
/* find and open command device */
client
->
device
=
rt_device_find
(
dev_name
);
if
(
client
->
device
)
{
RT_ASSERT
(
at_client_local
->
device
->
type
==
RT_Device_Class_Char
);
RT_ASSERT
(
client
->
device
->
type
==
RT_Device_Class_Char
);
/* using DMA mode first */
open_result
=
rt_device_open
(
at_client_local
->
device
,
RT_DEVICE_OFLAG_RDWR
|
RT_DEVICE_FLAG_DMA_RX
);
open_result
=
rt_device_open
(
client
->
device
,
RT_DEVICE_OFLAG_RDWR
|
RT_DEVICE_FLAG_DMA_RX
);
/* using interrupt mode when DMA mode not supported */
if
(
open_result
==
-
RT_EIO
)
{
open_result
=
rt_device_open
(
at_client_local
->
device
,
RT_DEVICE_OFLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
);
open_result
=
rt_device_open
(
client
->
device
,
RT_DEVICE_OFLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
);
}
RT_ASSERT
(
open_result
==
RT_EOK
);
rt_device_set_rx_indicate
(
at_client_local
->
device
,
at_client_rx_ind
);
rt_device_set_rx_indicate
(
client
->
device
,
at_client_rx_ind
);
}
else
{
LOG_E
(
"AT client
device initialize failed! Not find the device : %s."
,
AT_CLIENT_DEVICE
);
LOG_E
(
"AT client
initialize failed! Not find the device(%s)."
,
dev_name
);
result
=
-
RT_ERROR
;
goto
__exit
;
}
at_client_local
->
urc_table
=
RT_NULL
;
at_client_local
->
urc_table_size
=
0
;
at_client_local
->
parser
=
rt_thread_create
(
"at_client"
,
(
void
(
*
)(
void
*
parameter
))
client_parser
,
at_client_local
,
1024
+
512
,
RT_THREAD_PRIORITY_MAX
/
3
-
1
,
5
);
if
(
at_client_local
->
parser
==
RT_NULL
)
result
=
at_client_para_init
(
client
);
if
(
result
!=
RT_EOK
)
{
result
=
-
RT_ENOMEM
;
goto
__exit
;
}
__exit:
if
(
!
result
)
if
(
result
==
RT_EOK
)
{
at_client_local
->
status
=
AT_STATUS_INITIALIZED
;
client
->
status
=
AT_STATUS_INITIALIZED
;
rt_thread_startup
(
at_client_local
->
parser
);
rt_thread_startup
(
client
->
parser
);
LOG_I
(
"
RT-Thread AT client (V%s) initialize success."
,
AT_SW_VERSION
);
LOG_I
(
"
AT client(V%s) on device %s initialize success."
,
AT_SW_VERSION
,
dev_name
);
}
else
{
if
(
at_client_local
)
{
rt_free
(
at_client_local
);
}
LOG_E
(
"RT-Thread AT client (V%s) initialize failed(%d)."
,
AT_SW_VERSION
,
result
);
LOG_E
(
"AT client(V%s) on device %s initialize failed(%d)."
,
AT_SW_VERSION
,
dev_name
,
result
);
}
return
result
;
}
#ifdef FINSH_USING_MSH
#include <finsh.h>
MSH_CMD_EXPORT
(
at_client_init
,
initialize
AT
client
);
#endif
components/net/at/src/at_server.c
浏览文件 @
ed7f0cad
...
...
@@ -485,7 +485,7 @@ int at_server_init(void)
memset
(
at_server_local
->
recv_buffer
,
0x00
,
AT_SERVER_RECV_BUFF_LEN
);
at_server_local
->
cur_recv_len
=
0
;
at_server_local
->
rx_notice
=
rt_sem_create
(
"at_s
erver_notice
"
,
0
,
RT_IPC_FLAG_FIFO
);
at_server_local
->
rx_notice
=
rt_sem_create
(
"at_s
vr
"
,
0
,
RT_IPC_FLAG_FIFO
);
if
(
!
at_server_local
->
rx_notice
)
{
LOG_E
(
"AT server session initialize failed! at_rx_notice semaphore create failed!"
);
...
...
@@ -521,7 +521,7 @@ int at_server_init(void)
memcpy
(
at_server_local
->
end_mark
,
AT_CMD_END_MARK
,
sizeof
(
AT_CMD_END_MARK
));
at_server_local
->
parser_entry
=
server_parser
;
at_server_local
->
parser
=
rt_thread_create
(
"at_s
erve
r"
,
at_server_local
->
parser
=
rt_thread_create
(
"at_s
v
r"
,
(
void
(
*
)(
void
*
parameter
))
server_parser
,
at_server_local
,
2
*
1024
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录