1 /*
2  * Copyright (c) 2019 Linumiz
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "eswifi_log.h"
8 LOG_MODULE_DECLARE(LOG_MODULE_NAME);
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <errno.h>
16 
17 #include "eswifi.h"
18 #include <zephyr/net/net_pkt.h>
19 
eswifi_socket_type_from_zephyr(int proto,enum eswifi_transport_type * type)20 int eswifi_socket_type_from_zephyr(int proto, enum eswifi_transport_type *type)
21 {
22 	if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS) &&
23 	    proto >= IPPROTO_TLS_1_0 && proto <= IPPROTO_TLS_1_2) {
24 		*type = ESWIFI_TRANSPORT_TCP_SSL;
25 	} else if (proto == IPPROTO_TCP) {
26 		*type = ESWIFI_TRANSPORT_TCP;
27 	} else if (proto == IPPROTO_UDP) {
28 		*type = ESWIFI_TRANSPORT_UDP;
29 	} else {
30 		return -EPFNOSUPPORT;
31 	}
32 
33 	return 0;
34 }
35 
__stop_socket(struct eswifi_dev * eswifi,struct eswifi_off_socket * socket)36 static int __stop_socket(struct eswifi_dev *eswifi,
37 			 struct eswifi_off_socket *socket)
38 {
39 	char cmd_srv[] = "P5=0\r";
40 	char cmd_cli[] = "P6=0\r";
41 
42 	LOG_DBG("Stopping socket %d", socket->index);
43 	if (socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
44 		return 0;
45 	}
46 
47 	socket->state = ESWIFI_SOCKET_STATE_NONE;
48 	return eswifi_at_cmd(eswifi, socket->is_server ? cmd_srv : cmd_cli);
49 }
50 
__read_data(struct eswifi_dev * eswifi,size_t len,char ** data)51 static int __read_data(struct eswifi_dev *eswifi, size_t len, char **data)
52 {
53 	char cmd[] = "R0\r";
54 	char size[] = "R1=9999\r";
55 	char timeout[] = "R2=30000\r";
56 	int ret;
57 
58 	/* Set max read size */
59 	snprintk(size, sizeof(size), "R1=%u\r", len);
60 	ret = eswifi_at_cmd(eswifi, size);
61 	if (ret < 0) {
62 		LOG_ERR("Unable to set read size");
63 		return -EIO;
64 	}
65 
66 	/* Set timeout */
67 	snprintk(timeout, sizeof(timeout), "R2=%u\r", 30); /* 30 ms */
68 	ret = eswifi_at_cmd(eswifi, timeout);
69 	if (ret < 0) {
70 		LOG_ERR("Unable to set timeout");
71 		return -EIO;
72 	}
73 
74 	return eswifi_at_cmd_rsp(eswifi, cmd, data);
75 }
76 
__eswifi_bind(struct eswifi_dev * eswifi,struct eswifi_off_socket * socket,const struct sockaddr * addr,socklen_t addrlen)77 int __eswifi_bind(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket,
78 		      const struct sockaddr *addr, socklen_t addrlen)
79 {
80 	int err;
81 
82 	if (addr->sa_family != AF_INET) {
83 		LOG_ERR("Only AF_INET is supported!");
84 		return -EPFNOSUPPORT;
85 	}
86 
87 	__select_socket(eswifi, socket->index);
88 	socket->port = sys_be16_to_cpu(net_sin(addr)->sin_port);
89 
90 	/* Set Local Port */
91 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P2=%d\r", socket->port);
92 	err = eswifi_at_cmd(eswifi, eswifi->buf);
93 	if (err < 0) {
94 		LOG_ERR("Unable to set local port");
95 		return -EIO;
96 	}
97 
98 	if (socket->type == ESWIFI_TRANSPORT_UDP) {
99 		/* No listen or accept, so start UDP server now */
100 		snprintk(eswifi->buf, sizeof(eswifi->buf), "P5=1\r");
101 		err = eswifi_at_cmd(eswifi, eswifi->buf);
102 		if (err < 0) {
103 			LOG_ERR("Unable to start UDP server");
104 			return -EIO;
105 		}
106 	}
107 
108 	return 0;
109 }
110 
eswifi_off_read_work(struct k_work * work)111 static void eswifi_off_read_work(struct k_work *work)
112 {
113 	struct eswifi_off_socket *socket;
114 	struct eswifi_dev *eswifi;
115 	struct net_pkt *pkt = NULL;
116 	int next_timeout_ms = 100;
117 	int err, len;
118 	char *data;
119 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
120 
121 	LOG_DBG("");
122 
123 	socket = CONTAINER_OF(dwork, struct eswifi_off_socket, read_work);
124 	eswifi = eswifi_socket_to_dev(socket);
125 
126 	eswifi_lock(eswifi);
127 
128 	if ((socket->type == ESWIFI_TRANSPORT_TCP ||
129 	     socket->type == ESWIFI_TRANSPORT_TCP_SSL) &&
130 	     socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
131 		goto done;
132 	}
133 
134 	__select_socket(eswifi, socket->index);
135 
136 	/* Verify if we can allocate a rx packet before reading data to prevent leaks */
137 	pkt = net_pkt_rx_alloc_with_buffer(eswifi->iface, 1460,
138 					   AF_UNSPEC, 0, K_NO_WAIT);
139 	if (!pkt) {
140 		LOG_ERR("Cannot allocate rx packet");
141 		goto done;
142 	}
143 
144 	len = __read_data(eswifi, 1460, &data); /* 1460 is max size */
145 	if (len < 0) {
146 		__stop_socket(eswifi, socket);
147 
148 		if (socket->recv_cb) {
149 			/* send EOF (null pkt) */
150 			net_pkt_unref(pkt);
151 			pkt = NULL;
152 			goto do_recv_cb;
153 		}
154 	}
155 
156 	if (!len || !socket->recv_cb) {
157 		net_pkt_unref(pkt);
158 		goto done;
159 	}
160 
161 	LOG_DBG("payload sz = %d", len);
162 
163 	if (net_pkt_write(pkt, data, len) < 0) {
164 		LOG_WRN("Incomplete buffer copy");
165 	}
166 
167 	/* Resize the packet */
168 	net_pkt_trim_buffer(pkt);
169 
170 	net_pkt_cursor_init(pkt);
171 
172 do_recv_cb:
173 	socket->recv_cb(socket->context, pkt,
174 			NULL, NULL, 0, socket->recv_data);
175 
176 	if (!socket->context) {
177 		/* something destroyed the socket in the recv path */
178 		eswifi_unlock(eswifi);
179 		return;
180 	}
181 
182 	k_sem_give(&socket->read_sem);
183 	next_timeout_ms = 0;
184 
185 done:
186 	err = k_work_reschedule_for_queue(&eswifi->work_q, &socket->read_work,
187 					  K_MSEC(next_timeout_ms));
188 	if (err < 0) {
189 		LOG_ERR("Rescheduling socket read error");
190 	}
191 
192 	eswifi_unlock(eswifi);
193 }
194 
__eswifi_off_start_client(struct eswifi_dev * eswifi,struct eswifi_off_socket * socket)195 int __eswifi_off_start_client(struct eswifi_dev *eswifi,
196 			      struct eswifi_off_socket *socket)
197 {
198 	struct sockaddr *addr = &socket->peer_addr;
199 	struct in_addr *sin_addr = &net_sin(addr)->sin_addr;
200 	int err;
201 
202 	LOG_DBG("");
203 
204 	__select_socket(eswifi, socket->index);
205 
206 	/* Stop any running client */
207 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P6=0\r");
208 	err = eswifi_at_cmd(eswifi, eswifi->buf);
209 	if (err < 0) {
210 		LOG_ERR("Unable to stop running client");
211 		return -EIO;
212 	}
213 
214 	/* Stop any running server */
215 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P5=0\r");
216 	err = eswifi_at_cmd(eswifi, eswifi->buf);
217 	if (err < 0) {
218 		LOG_ERR("Unable to stop running client");
219 		return -EIO;
220 	}
221 
222 	/* Clear local port */
223 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P2=0\r");
224 	err = eswifi_at_cmd(eswifi, eswifi->buf);
225 	if (err < 0) {
226 		LOG_ERR("Unable to stop running client");
227 		return -EIO;
228 	}
229 
230 	/* Set Remote IP */
231 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P3=%u.%u.%u.%u\r",
232 		 sin_addr->s4_addr[0], sin_addr->s4_addr[1],
233 		 sin_addr->s4_addr[2], sin_addr->s4_addr[3]);
234 
235 	err = eswifi_at_cmd(eswifi, eswifi->buf);
236 	if (err < 0) {
237 		LOG_ERR("Unable to set remote ip");
238 		return -EIO;
239 	}
240 
241 	/* Set Remote Port */
242 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P4=%d\r",
243 		(uint16_t)sys_be16_to_cpu(net_sin(addr)->sin_port));
244 	err = eswifi_at_cmd(eswifi, eswifi->buf);
245 	if (err < 0) {
246 		LOG_ERR("Unable to set remote port");
247 		return -EIO;
248 	}
249 
250 	/* Start TCP/UDP client */
251 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P6=1\r");
252 	err = eswifi_at_cmd(eswifi, eswifi->buf);
253 	if (err < 0) {
254 		LOG_ERR("Unable to start TCP/UDP client");
255 		return -EIO;
256 	}
257 
258 #if !defined(CONFIG_NET_SOCKETS_OFFLOAD)
259 	net_context_set_state(socket->context, NET_CONTEXT_CONNECTED);
260 #endif
261 
262 	return 0;
263 }
264 
__eswifi_listen(struct eswifi_dev * eswifi,struct eswifi_off_socket * socket,int backlog)265 int __eswifi_listen(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket, int backlog)
266 {
267 	int err;
268 
269 	__select_socket(eswifi, socket->index);
270 
271 	/* Set backlog */
272 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P8=%d\r", backlog);
273 	err = eswifi_at_cmd(eswifi, eswifi->buf);
274 	if (err < 0) {
275 		LOG_ERR("Unable to start set listen backlog");
276 		err = -EIO;
277 	}
278 
279 	socket->is_server = true;
280 
281 	return 0;
282 }
283 
__eswifi_accept(struct eswifi_dev * eswifi,struct eswifi_off_socket * socket)284 int __eswifi_accept(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket)
285 {
286 	char cmd[] = "P5=1\r";
287 
288 	if (socket->state != ESWIFI_SOCKET_STATE_NONE) {
289 		/* we can only handle one connection at a time */
290 		return -EBUSY;
291 	}
292 
293 	__select_socket(eswifi, socket->index);
294 
295 	/* Start TCP Server */
296 	if (eswifi_at_cmd(eswifi, cmd) < 0) {
297 		LOG_ERR("Unable to start TCP server");
298 		return -EIO;
299 	}
300 
301 	LOG_DBG("TCP Server started");
302 	socket->state = ESWIFI_SOCKET_STATE_ACCEPTING;
303 
304 	return 0;
305 }
306 
__eswifi_socket_free(struct eswifi_dev * eswifi,struct eswifi_off_socket * socket)307 int __eswifi_socket_free(struct eswifi_dev *eswifi,
308 			 struct eswifi_off_socket *socket)
309 {
310 	__select_socket(eswifi, socket->index);
311 	k_work_cancel_delayable(&socket->read_work);
312 
313 	__select_socket(eswifi, socket->index);
314 	__stop_socket(eswifi, socket);
315 
316 	return 0;
317 }
318 
__eswifi_socket_new(struct eswifi_dev * eswifi,int family,int type,int proto,void * context)319 int __eswifi_socket_new(struct eswifi_dev *eswifi, int family, int type,
320 			int proto, void *context)
321 {
322 	struct eswifi_off_socket *socket = NULL;
323 	int err, i;
324 
325 	LOG_DBG("");
326 
327 	if (family != AF_INET) {
328 		LOG_ERR("Only AF_INET is supported!");
329 		return -EPFNOSUPPORT;
330 	}
331 
332 	/* pickup available socket */
333 	for (i = 0; i < ESWIFI_OFFLOAD_MAX_SOCKETS; i++) {
334 		if (!eswifi->socket[i].context) {
335 			socket = &eswifi->socket[i];
336 			socket->index = i;
337 			socket->context = context;
338 			break;
339 		}
340 	}
341 
342 	if (!socket) {
343 		LOG_ERR("No socket resource available");
344 		return -ENOMEM;
345 	}
346 
347 	err = eswifi_socket_type_from_zephyr(proto, &socket->type);
348 	if (err) {
349 		LOG_ERR("Only TCP & UDP is supported");
350 		return err;
351 	}
352 
353 	err = __select_socket(eswifi, socket->index);
354 	if (err < 0) {
355 		LOG_ERR("Unable to select socket %u", socket->index);
356 		return -EIO;
357 	}
358 
359 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P1=%d\r", socket->type);
360 	err = eswifi_at_cmd(eswifi, eswifi->buf);
361 	if (err < 0) {
362 		LOG_ERR("Unable to set transport protocol");
363 		return -EIO;
364 	}
365 
366 	k_work_init_delayable(&socket->read_work, eswifi_off_read_work);
367 	socket->usage = 1;
368 	LOG_DBG("Socket index %d", socket->index);
369 
370 	return socket->index;
371 }
372