1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2015-02-17     Bernard      First version
9  * 2016-05-07     Bernard      Rename dfs_lwip to dfs_net
10  * 2018-03-09     Bernard      Fix the last data issue in poll.
11  * 2018-05-24     ChenYong     Add socket abstraction layer
12  */
13 
14 #include <rtthread.h>
15 
16 #include <dfs.h>
17 #include <dfs_net.h>
18 
19 #include <sys/socket.h>
20 
dfs_net_getsocket(int fd)21 int dfs_net_getsocket(int fd)
22 {
23     int socket;
24     struct dfs_file *file;
25 
26     file = fd_get(fd);
27     if (file == NULL) return -1;
28 
29     if (file->vnode->type != FT_SOCKET) socket = -1;
30     else socket = (int)(size_t)file->vnode->data;
31 
32     return socket;
33 }
34 
dfs_net_ioctl(struct dfs_file * file,int cmd,void * args)35 static int dfs_net_ioctl(struct dfs_file* file, int cmd, void* args)
36 {
37     int ret;
38     int socket = (int)(size_t)file->vnode->data;
39 
40     ret = sal_ioctlsocket(socket, cmd, args);
41     if (ret < 0)
42     {
43         ret = rt_get_errno();
44         return (ret > 0) ? (-ret) : ret;
45     }
46     return ret;
47 }
48 
49 #ifdef RT_USING_DFS_V2
dfs_net_read(struct dfs_file * file,void * buf,size_t count,off_t * pos)50 static ssize_t dfs_net_read(struct dfs_file* file, void *buf, size_t count, off_t *pos)
51 #else
52 static ssize_t dfs_net_read(struct dfs_file* file, void *buf, size_t count)
53 #endif
54 {
55     int ret;
56     int socket = (int)(size_t)file->vnode->data;
57 
58     ret = sal_recvfrom(socket, buf, count, 0, NULL, NULL);
59     if (ret < 0)
60     {
61         ret = rt_get_errno();
62         return (ret > 0) ? (-ret) : ret;
63     }
64 
65     return ret;
66 }
67 
68 #ifdef RT_USING_DFS_V2
dfs_net_write(struct dfs_file * file,const void * buf,size_t count,off_t * pos)69 static ssize_t dfs_net_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
70 #else
71 static ssize_t dfs_net_write(struct dfs_file *file, const void *buf, size_t count)
72 #endif
73 {
74     int ret;
75     int socket = (int)(size_t)file->vnode->data;
76 
77     ret = sal_sendto(socket, buf, count, 0, NULL, 0);
78     if (ret < 0)
79     {
80         ret = rt_get_errno();
81         return (ret > 0) ? (-ret) : ret;
82     }
83 
84     return ret;
85 }
86 
dfs_net_close(struct dfs_file * file)87 static int dfs_net_close(struct dfs_file* file)
88 {
89     int socket;
90     int ret = 0;
91 
92     if (file->vnode->ref_count == 1)
93     {
94         socket = (int)(size_t)file->vnode->data;
95         ret = sal_closesocket(socket);
96     }
97     return ret;
98 }
99 
dfs_net_poll(struct dfs_file * file,struct rt_pollreq * req)100 static int dfs_net_poll(struct dfs_file *file, struct rt_pollreq *req)
101 {
102     extern int sal_poll(struct dfs_file *file, struct rt_pollreq *req);
103 
104     return sal_poll(file, req);
105 }
106 
107 const struct dfs_file_ops _net_fops =
108 {
109     .close = dfs_net_close,
110     .ioctl = dfs_net_ioctl,
111     .read  = dfs_net_read,
112     .write = dfs_net_write,
113     .poll  = dfs_net_poll,
114 };
115 
dfs_net_get_fops(void)116 const struct dfs_file_ops *dfs_net_get_fops(void)
117 {
118     return &_net_fops;
119 }
120