Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
红岛
rt-thread
提交
cca2f40a
R
rt-thread
项目概览
红岛
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cca2f40a
编写于
6月 02, 2022
作者:
L
liuxianliang
提交者:
guo
7月 04, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[add] implement about "AT server".
上级
b2bc0dcd
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
325 addition
and
2 deletion
+325
-2
components/net/at/Kconfig
components/net/at/Kconfig
+8
-0
components/net/at/at_socket/at_socket.c
components/net/at/at_socket/at_socket.c
+277
-2
components/net/at/at_socket/at_socket.h
components/net/at/at_socket/at_socket.h
+32
-0
components/net/sal/impl/af_inet_at.c
components/net/sal/impl/af_inet_at.c
+8
-0
未找到文件。
components/net/at/Kconfig
浏览文件 @
cca2f40a
...
...
@@ -60,6 +60,14 @@ if RT_USING_AT
select SAL_USING_AT
default n
if AT_USING_SOCKET
config AT_USING_SOCKET_SERVER
bool "Enable BSD Socket API support about AT server"
default n
endif
endif
if AT_USING_SERVER || AT_USING_CLIENT
...
...
components/net/at/at_socket/at_socket.c
浏览文件 @
cca2f40a
...
...
@@ -6,9 +6,13 @@
* Change Logs:
* Date Author Notes
* 2018-06-06 chenyong first version
* 2022-06-02 xianxistu add implement about "AT server"
*/
#include <at.h>
#ifdef AT_USING_SOCKET_SERVER
#include <stdio.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
...
...
@@ -48,6 +52,9 @@ typedef enum {
AT_EVENT_ERROR
,
}
at_event_t
;
#ifdef AT_USING_SOCKET_SERVER
static
void
at_connect_notice_cb
(
struct
at_socket
*
sock
,
at_socket_evt_t
event
,
const
char
*
buff
,
size_t
bfsz
);
#endif
/* the global of sockets list */
static
rt_slist_t
_socket_list
=
RT_SLIST_OBJECT_INIT
(
_socket_list
);
...
...
@@ -78,6 +85,34 @@ struct at_socket *at_get_socket(int socket)
return
RT_NULL
;
}
#ifdef AT_USING_SOCKET_SERVER
struct
at_socket
*
at_get_base_socket
(
int
base_socket
)
{
rt_base_t
level
;
rt_slist_t
*
node
=
RT_NULL
;
struct
at_socket
*
at_sock
=
RT_NULL
;
level
=
rt_hw_interrupt_disable
();
rt_slist_for_each
(
node
,
&
_socket_list
)
{
at_sock
=
rt_slist_entry
(
node
,
struct
at_socket
,
list
);
if
(
base_socket
==
(
int
)
at_sock
->
user_data
&&
at_sock
->
state
!=
AT_SOCKET_LISTEN
)
{
if
(
at_sock
&&
at_sock
->
magic
==
AT_SOCKET_MAGIC
)
{
rt_hw_interrupt_enable
(
level
);
return
at_sock
;
}
}
}
rt_hw_interrupt_enable
(
level
);
return
RT_NULL
;
}
#endif
/* get a block to the AT socket receive list*/
static
rt_err_t
at_recvpkt_put
(
rt_slist_t
*
rlist
,
const
char
*
ptr
,
size_t
length
)
{
...
...
@@ -457,6 +492,9 @@ int at_socket(int domain, int type, int protocol)
/* set AT socket receive data callback function */
sock
->
ops
->
at_set_event_cb
(
AT_SOCKET_EVT_RECV
,
at_recv_notice_cb
);
sock
->
ops
->
at_set_event_cb
(
AT_SOCKET_EVT_CLOSED
,
at_closed_notice_cb
);
#ifdef AT_USING_SOCKET_SERVER
sock
->
ops
->
at_set_event_cb
(
AT_SOCKET_EVT_CONNECTED
,
at_connect_notice_cb
);
#endif
return
sock
->
socket
;
}
...
...
@@ -587,6 +625,26 @@ static int socketaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t
return
0
;
}
#ifdef AT_USING_SOCKET_SERVER
/* set socketaddr structure information by IP address and port */
static
int
ipaddr_port_to_socketaddr
(
struct
sockaddr
*
sockaddr
,
ip_addr_t
*
addr
,
uint16_t
*
port
)
{
struct
sockaddr_in
*
sin
=
(
struct
sockaddr_in
*
)
(
void
*
)
sockaddr
;
#if NETDEV_IPV4 && NETDEV_IPV6
sin
->
sin_addr
.
s_addr
=
addr
->
u_addr
.
ip4
.
addr
;
#elif NETDEV_IPV4
sin
->
sin_addr
.
s_addr
=
addr
->
addr
;
#elif NETDEV_IPV6
#error "not support IPV6."
#endif
/* NETDEV_IPV4 && NETDEV_IPV6 */
sin
->
sin_port
=
(
uint16_t
)
HTONS_PORT
(
*
port
);
return
0
;
}
#endif
int
at_bind
(
int
socket
,
const
struct
sockaddr
*
name
,
socklen_t
namelen
)
{
struct
at_socket
*
sock
=
RT_NULL
;
...
...
@@ -608,7 +666,7 @@ int at_bind(int socket, const struct sockaddr *name, socklen_t namelen)
socketaddr_to_ipaddr_port
(
name
,
&
input_ipaddr
,
&
port
);
/* input ip address is different from device ip address */
if
(
ip_addr_cmp
(
&
input_ipaddr
,
&
local_ipaddr
)
=
=
0
)
if
(
ip_addr_cmp
(
&
input_ipaddr
,
&
local_ipaddr
)
!
=
0
)
{
struct
at_socket
*
new_sock
=
RT_NULL
;
struct
at_device
*
new_device
=
RT_NULL
;
...
...
@@ -637,6 +695,11 @@ int at_bind(int socket, const struct sockaddr *name, socklen_t namelen)
new_sock
->
state
=
AT_SOCKET_OPEN
;
}
#ifdef AT_USING_SOCKET_SERVER
/* store 'port' into at_socket */
sock
->
listen
.
port
=
port
;
#endif
return
0
;
}
...
...
@@ -651,6 +714,103 @@ static int ipaddr_to_ipstr(const struct sockaddr *sockaddr, char *ipstr)
return
0
;
}
#ifdef AT_USING_SOCKET_SERVER
static
int
(
*
store_at_socket_temporary
)(
struct
at_device
*
device
,
enum
at_socket_type
type
);
static
void
at_connect_notice_cb
(
struct
at_socket
*
sock
,
at_socket_evt_t
event
,
const
char
*
buff
,
size_t
bfsz
)
{
RT_ASSERT
(
buff
);
RT_ASSERT
(
sock
==
RT_NULL
);
RT_ASSERT
(
event
==
AT_SOCKET_EVT_CONNECTED
);
extern
struct
netdev
*
netdev_default
;
struct
netdev
*
netdev
=
RT_NULL
;
struct
at_device
*
device
=
RT_NULL
;
struct
at_socket
*
new_sock
=
RT_NULL
;
rt_base_t
level
;
rt_slist_t
*
node
=
RT_NULL
;
struct
at_socket
*
at_sock
=
RT_NULL
;
char
*
socket_info
=
RT_NULL
;
int
base_socket
=
0
;
if
(
netdev_default
&&
netdev_is_up
(
netdev_default
)
&&
netdev_family_get
(
netdev_default
)
==
AF_AT
)
{
netdev
=
netdev_default
;
}
else
{
/* get network interface device by protocol family AF_AT */
netdev
=
netdev_get_by_family
(
AF_AT
);
if
(
netdev
==
RT_NULL
)
{
return
;
}
}
device
=
at_device_get_by_name
(
AT_DEVICE_NAMETYPE_NETDEV
,
netdev
->
name
);
if
(
device
==
RT_NULL
)
{
return
;
}
/* avoid use bottom driver to alloc "socket" */
store_at_socket_temporary
=
device
->
class
->
socket_ops
->
at_socket
;
device
->
class
->
socket_ops
->
at_socket
=
RT_NULL
;
new_sock
=
alloc_socket_by_device
(
device
,
AT_SOCKET_TCP
);
if
(
new_sock
==
RT_NULL
)
{
return
;
}
new_sock
->
type
=
AT_SOCKET_TCP
;
new_sock
->
state
=
AT_SOCKET_CONNECT
;
/* set AT socket receive data callback function */
new_sock
->
ops
->
at_set_event_cb
(
AT_SOCKET_EVT_RECV
,
at_recv_notice_cb
);
new_sock
->
ops
->
at_set_event_cb
(
AT_SOCKET_EVT_CLOSED
,
at_closed_notice_cb
);
new_sock
->
ops
->
at_set_event_cb
(
AT_SOCKET_EVT_CONNECTED
,
at_connect_notice_cb
);
device
->
class
->
socket_ops
->
at_socket
=
store_at_socket_temporary
;
/* put incoming "socket" to the listen socket receiver packet list */
sscanf
(
buff
,
"SOCKET:%d"
,
&
base_socket
);
LOG_D
(
"ACCEPT BASE SOCKET: %d"
,
base_socket
);
new_sock
->
user_data
=
(
void
*
)
base_socket
;
socket_info
=
rt_malloc
(
AT_SOCKET_INFO_LEN
);
rt_memset
(
socket_info
,
0
,
AT_SOCKET_INFO_LEN
);
rt_sprintf
(
socket_info
,
"SOCKET:%d"
,
new_sock
->
socket
);
/* find out the listen socket */
level
=
rt_hw_interrupt_disable
();
rt_slist_for_each
(
node
,
&
_socket_list
)
{
at_sock
=
rt_slist_entry
(
node
,
struct
at_socket
,
list
);
if
(
at_sock
&&
at_sock
->
magic
==
AT_SOCKET_MAGIC
&&
at_sock
->
listen
.
is_listen
==
RT_TRUE
)
{
break
;
}
at_sock
=
RT_NULL
;
}
rt_hw_interrupt_enable
(
level
);
if
(
at_sock
==
RT_NULL
)
{
return
;
}
/* wakeup the "accept" function */
rt_mutex_take
(
at_sock
->
recv_lock
,
RT_WAITING_FOREVER
);
if
(
at_recvpkt_put
(
&
(
at_sock
->
recvpkt_list
),
socket_info
,
AT_SOCKET_INFO_LEN
)
!=
RT_EOK
)
{
rt_free
((
void
*
)
buff
);
rt_mutex_release
(
at_sock
->
recv_lock
);
return
;
}
rt_mutex_release
(
at_sock
->
recv_lock
);
rt_sem_release
(
at_sock
->
recv_notice
);
at_do_event_changes
(
at_sock
,
AT_EVENT_RECV
,
RT_TRUE
);
}
#endif
static
void
at_recv_notice_cb
(
struct
at_socket
*
sock
,
at_socket_evt_t
event
,
const
char
*
buff
,
size_t
bfsz
)
{
RT_ASSERT
(
buff
);
...
...
@@ -695,6 +855,49 @@ static void at_closed_notice_cb(struct at_socket *sock, at_socket_evt_t event, c
rt_sem_release
(
sock
->
recv_notice
);
}
#ifdef AT_USING_SOCKET_SERVER
int
at_listen
(
int
socket
,
int
backlog
)
{
struct
at_socket
*
sock
=
RT_NULL
;
int
result
=
0
;
sock
=
at_get_socket
(
socket
);
if
(
sock
==
RT_NULL
)
{
result
=
-
1
;
goto
__exit
;
}
if
(
sock
->
state
!=
AT_SOCKET_OPEN
)
{
LOG_E
(
"Socket(%d) connect state is %d."
,
sock
->
socket
,
sock
->
state
);
result
=
-
1
;
goto
__exit
;
}
if
(
sock
->
ops
->
at_listen
(
sock
,
backlog
)
<
0
)
{
result
=
-
1
;
goto
__exit
;
}
sock
->
listen
.
is_listen
=
RT_TRUE
;
sock
->
state
=
AT_SOCKET_LISTEN
;
__exit:
if
(
result
<
0
)
{
if
(
sock
!=
RT_NULL
)
{
at_do_event_changes
(
sock
,
AT_EVENT_ERROR
,
RT_TRUE
);
}
}
return
result
;
}
#endif
int
at_connect
(
int
socket
,
const
struct
sockaddr
*
name
,
socklen_t
namelen
)
{
struct
at_socket
*
sock
=
RT_NULL
;
...
...
@@ -747,6 +950,71 @@ __exit:
return
result
;
}
#ifdef AT_USING_SOCKET_SERVER
int
at_accept
(
int
socket
,
struct
sockaddr
*
name
,
socklen_t
*
namelen
)
{
struct
at_socket
*
sock
=
RT_NULL
;
struct
at_socket
*
new_sock
=
RT_NULL
;
char
receive_buff
[
AT_SOCKET_INFO_LEN
];
ip_addr_t
remote_addr
;
uint16_t
remote_port
=
0
;
int
new_socket
=
-
1
;
int
result
=
0
;
sock
=
at_get_socket
(
socket
);
if
(
sock
==
RT_NULL
)
{
result
=
-
1
;
goto
__exit
;
}
if
(
sock
->
state
!=
AT_SOCKET_LISTEN
)
{
LOG_E
(
"Socket(%d) connect state is %d."
,
sock
->
socket
,
sock
->
state
);
result
=
-
1
;
goto
__exit
;
}
/* wait the receive semaphore, waiting for info */
if
(
rt_sem_take
(
sock
->
recv_notice
,
RT_WAITING_FOREVER
)
<
0
)
{
errno
=
EAGAIN
;
result
=
-
1
;
goto
__exit
;
}
else
{
/* get receive buffer to receiver ring buffer */
rt_mutex_take
(
sock
->
recv_lock
,
RT_WAITING_FOREVER
);
at_recvpkt_get
(
&
(
sock
->
recvpkt_list
),
(
char
*
)
&
receive_buff
,
AT_SOCKET_INFO_LEN
);
rt_mutex_release
(
sock
->
recv_lock
);
}
sscanf
(
&
receive_buff
[
0
],
"SOCKET:%d"
,
&
new_socket
);
new_sock
=
at_get_socket
(
new_socket
);
if
(
sock
==
RT_NULL
)
{
result
=
-
1
;
goto
__exit
;
}
new_sock
->
state
=
AT_SOCKET_CONNECT
;
ip4_addr_set_any
(
&
remote_addr
);
ipaddr_port_to_socketaddr
(
name
,
&
remote_addr
,
&
remote_port
);
LOG_D
(
"Accept: [socket :%d, base_socket:%d]"
,
new_socket
,
(
int
)
new_sock
->
user_data
);
__exit:
if
(
result
<
0
)
{
if
(
sock
!=
RT_NULL
)
{
at_do_event_changes
(
sock
,
AT_EVENT_ERROR
,
RT_TRUE
);
}
}
return
new_sock
->
socket
;
}
#endif
int
at_recvfrom
(
int
socket
,
void
*
mem
,
size_t
len
,
int
flags
,
struct
sockaddr
*
from
,
socklen_t
*
fromlen
)
{
struct
at_socket
*
sock
=
RT_NULL
;
...
...
@@ -843,7 +1111,14 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f
{
break
;
}
else
{
/* we have no data to receive but are woken up,
which means the socket have been closed. */
errno
=
EIO
;
result
=
-
1
;
goto
__exit
;
}
}
}
...
...
components/net/at/at_socket/at_socket.h
浏览文件 @
cca2f40a
...
...
@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2018-06-06 chenYong first version
* 2022-06-02 xianxistu add implement about "AT server"
*/
#ifndef __AT_SOCKET_H__
...
...
@@ -32,6 +33,10 @@ extern "C" {
/* sal socket magic word */
#define AT_SOCKET_MAGIC 0xA100
#ifdef AT_USING_SOCKET_SERVER
#define AT_SOCKET_INFO_LEN (sizeof("SOCKET:") + 4)
#endif
/* Current state of the AT socket. */
enum
at_socket_state
{
...
...
@@ -53,6 +58,9 @@ typedef enum
{
AT_SOCKET_EVT_RECV
,
AT_SOCKET_EVT_CLOSED
,
#ifdef AT_USING_SOCKET_SERVER
AT_SOCKET_EVT_CONNECTED
,
#endif
}
at_socket_evt_t
;
struct
at_socket
;
...
...
@@ -72,6 +80,9 @@ struct at_socket_ops
int
(
*
at_domain_resolve
)(
const
char
*
name
,
char
ip
[
16
]);
void
(
*
at_set_event_cb
)(
at_socket_evt_t
event
,
at_evt_cb_t
cb
);
int
(
*
at_socket
)(
struct
at_device
*
device
,
enum
at_socket_type
type
);
#ifdef AT_USING_SOCKET_SERVER
int
(
*
at_listen
)(
struct
at_socket
*
socket
,
int
backlog
);
#endif
};
/* AT receive package list structure */
...
...
@@ -84,12 +95,24 @@ struct at_recv_pkt
};
typedef
struct
at_recv_pkt
*
at_recv_pkt_t
;
#ifdef AT_USING_SOCKET_SERVER
struct
at_listen_state
{
uint16_t
is_listen
;
uint16_t
port
;
};
#endif
struct
at_socket
{
/* AT socket magic word */
uint32_t
magic
;
int
socket
;
#ifdef AT_USING_SOCKET_SERVER
struct
at_listen_state
listen
;
#endif
/* device releated information for the socket */
void
*
device
;
/* type of the AT socket (TCP, UDP or RAW) */
...
...
@@ -129,7 +152,13 @@ int at_socket(int domain, int type, int protocol);
int
at_closesocket
(
int
socket
);
int
at_shutdown
(
int
socket
,
int
how
);
int
at_bind
(
int
socket
,
const
struct
sockaddr
*
name
,
socklen_t
namelen
);
#ifdef AT_USING_SOCKET_SERVER
int
at_listen
(
int
socket
,
int
backlog
);
#endif
int
at_connect
(
int
socket
,
const
struct
sockaddr
*
name
,
socklen_t
namelen
);
#ifdef AT_USING_SOCKET_SERVER
int
at_accept
(
int
socket
,
struct
sockaddr
*
name
,
socklen_t
*
namelen
);
#endif
int
at_sendto
(
int
socket
,
const
void
*
data
,
size_t
size
,
int
flags
,
const
struct
sockaddr
*
to
,
socklen_t
tolen
);
int
at_send
(
int
socket
,
const
void
*
data
,
size_t
size
,
int
flags
);
int
at_recvfrom
(
int
socket
,
void
*
mem
,
size_t
len
,
int
flags
,
struct
sockaddr
*
from
,
socklen_t
*
fromlen
);
...
...
@@ -141,6 +170,9 @@ int at_getaddrinfo(const char *nodename, const char *servname, const struct addr
void
at_freeaddrinfo
(
struct
addrinfo
*
ai
);
struct
at_socket
*
at_get_socket
(
int
socket
);
#ifdef AT_USING_SOCKET_SERVER
struct
at_socket
*
at_get_base_socket
(
int
base_socket
);
#endif
#ifndef RT_USING_SAL
...
...
components/net/sal/impl/af_inet_at.c
浏览文件 @
cca2f40a
...
...
@@ -69,9 +69,17 @@ static const struct sal_socket_ops at_socket_ops =
at_socket
,
at_closesocket
,
at_bind
,
#ifdef AT_USING_SOCKET_SERVER
at_listen
,
#else
NULL
,
#endif
at_connect
,
#ifdef AT_USING_SOCKET_SERVER
at_accept
,
#else
NULL
,
#endif
at_sendto
,
at_recvfrom
,
at_getsockopt
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录