1 /**
2  * Copyright (c) 2018 Linaro
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #define LOG_LEVEL CONFIG_WIFI_LOG_LEVEL
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 <zephyr/net/net_pkt.h>
18 #include <zephyr/net/net_if.h>
19 
20 #include "eswifi.h"
21 
22 
eswifi_off_bind(struct net_context * context,const struct sockaddr * addr,socklen_t addrlen)23 static int eswifi_off_bind(struct net_context *context,
24 			   const struct sockaddr *addr,
25 			   socklen_t addrlen)
26 {
27 	struct eswifi_off_socket *socket = context->offload_context;
28 	struct eswifi_dev *eswifi = eswifi_by_iface_idx(context->iface);
29 	int err;
30 
31 	LOG_DBG("");
32 	eswifi_lock(eswifi);
33 	err = __eswifi_bind(eswifi, socket, addr, addrlen);
34 	eswifi_unlock(eswifi);
35 
36 	return err;
37 }
38 
eswifi_off_listen(struct net_context * context,int backlog)39 static int eswifi_off_listen(struct net_context *context, int backlog)
40 {
41 	struct eswifi_off_socket *socket = context->offload_context;
42 	struct eswifi_dev *eswifi = eswifi_by_iface_idx(context->iface);
43 	int err;
44 
45 	LOG_DBG("Listening backlog=%d", backlog);
46 
47 	eswifi_lock(eswifi);
48 
49 	__select_socket(eswifi, socket->index);
50 
51 	/* Set backlog */
52 	snprintk(eswifi->buf, sizeof(eswifi->buf), "P8=%d\r", backlog);
53 	err = eswifi_at_cmd(eswifi, eswifi->buf);
54 	if (err < 0) {
55 		LOG_ERR("Unable to start set listen backlog");
56 		err = -EIO;
57 	}
58 
59 	socket->is_server = true;
60 
61 	eswifi_unlock(eswifi);
62 
63 	return err;
64 }
65 
eswifi_off_connect_work(struct k_work * work)66 static void eswifi_off_connect_work(struct k_work *work)
67 {
68 	struct eswifi_off_socket *socket;
69 	net_context_connect_cb_t cb;
70 	struct net_context *context;
71 	struct eswifi_dev *eswifi;
72 	void *user_data;
73 	int err;
74 
75 	socket = CONTAINER_OF(work, struct eswifi_off_socket, connect_work);
76 	eswifi = eswifi_socket_to_dev(socket);
77 
78 	eswifi_lock(eswifi);
79 
80 	cb = socket->conn_cb;
81 	context = socket->context;
82 	user_data = socket->conn_data;
83 
84 	err = __eswifi_off_start_client(eswifi, socket);
85 	if (!err) {
86 		socket->state = ESWIFI_SOCKET_STATE_CONNECTED;
87 		net_context_set_state(socket->context, NET_CONTEXT_CONNECTED);
88 	} else {
89 		socket->state = ESWIFI_SOCKET_STATE_NONE;
90 	}
91 
92 	eswifi_unlock(eswifi);
93 
94 	if (cb) {
95 		cb(context, err, user_data);
96 	}
97 }
98 
eswifi_off_connect(struct net_context * context,const struct sockaddr * addr,socklen_t addrlen,net_context_connect_cb_t cb,int32_t timeout,void * user_data)99 static int eswifi_off_connect(struct net_context *context,
100 			      const struct sockaddr *addr,
101 			      socklen_t addrlen,
102 			      net_context_connect_cb_t cb,
103 			      int32_t timeout,
104 			      void *user_data)
105 {
106 	struct eswifi_off_socket *socket = context->offload_context;
107 	struct eswifi_dev *eswifi = eswifi_by_iface_idx(context->iface);
108 	int err;
109 
110 	LOG_DBG("timeout=%d", timeout);
111 
112 	if (addr->sa_family != AF_INET) {
113 		LOG_ERR("Only AF_INET is supported!");
114 		return -EPFNOSUPPORT;
115 	}
116 
117 	eswifi_lock(eswifi);
118 
119 	if (socket->state != ESWIFI_SOCKET_STATE_NONE) {
120 		eswifi_unlock(eswifi);
121 		return -EBUSY;
122 	}
123 
124 	socket->peer_addr = *addr;
125 	socket->conn_data = user_data;
126 	socket->conn_cb = cb;
127 	socket->state = ESWIFI_SOCKET_STATE_CONNECTING;
128 
129 	if (timeout == 0) {
130 		/* async */
131 		k_work_submit_to_queue(&eswifi->work_q, &socket->connect_work);
132 		eswifi_unlock(eswifi);
133 		return 0;
134 	}
135 
136 	err = __eswifi_off_start_client(eswifi, socket);
137 	if (!err) {
138 		socket->state = ESWIFI_SOCKET_STATE_CONNECTED;
139 	} else {
140 		socket->state = ESWIFI_SOCKET_STATE_NONE;
141 	}
142 
143 	eswifi_unlock(eswifi);
144 
145 	if (cb) {
146 		cb(context, err, user_data);
147 	}
148 
149 	return err;
150 }
151 
eswifi_off_accept(struct net_context * context,net_tcp_accept_cb_t cb,int32_t timeout,void * user_data)152 static int eswifi_off_accept(struct net_context *context,
153 			     net_tcp_accept_cb_t cb, int32_t timeout,
154 			     void *user_data)
155 {
156 	struct eswifi_off_socket *socket = context->offload_context;
157 	struct eswifi_dev *eswifi = eswifi_by_iface_idx(context->iface);
158 	int ret;
159 
160 	eswifi_lock(eswifi);
161 
162 	ret = __eswifi_accept(eswifi, socket);
163 	if (ret < 0) {
164 		eswifi_unlock(eswifi);
165 		return ret;
166 	}
167 
168 	socket->accept_cb = cb;
169 	socket->accept_data = user_data;
170 	k_sem_reset(&socket->accept_sem);
171 
172 	eswifi_unlock(eswifi);
173 
174 	if (timeout == 0) {
175 		return 0;
176 	}
177 
178 	return k_sem_take(&socket->accept_sem, K_MSEC(timeout));
179 }
180 
__eswifi_off_send_pkt(struct eswifi_dev * eswifi,struct eswifi_off_socket * socket)181 static int __eswifi_off_send_pkt(struct eswifi_dev *eswifi,
182 				 struct eswifi_off_socket *socket)
183 {
184 	struct net_pkt *pkt = socket->tx_pkt;
185 	unsigned int bytes;
186 	int err, offset;
187 
188 	LOG_DBG("");
189 
190 	if (!pkt) {
191 		return -EINVAL;
192 	}
193 
194 	bytes = net_pkt_get_len(pkt);
195 
196 	__select_socket(eswifi, socket->index);
197 
198 	/* header */
199 	snprintk(eswifi->buf, sizeof(eswifi->buf), "S3=%u\r", bytes);
200 	offset = strlen(eswifi->buf);
201 
202 	/* copy payload */
203 	if (net_pkt_read(pkt, &eswifi->buf[offset], bytes)) {
204 		return -ENOBUFS;
205 	}
206 
207 	offset += bytes;
208 
209 	err = eswifi_request(eswifi, eswifi->buf, offset + 1,
210 			     eswifi->buf, sizeof(eswifi->buf));
211 	if (err < 0) {
212 		LOG_ERR("Unable to send data");
213 		return -EIO;
214 	}
215 
216 	net_pkt_unref(pkt);
217 
218 	return 0;
219 }
220 
eswifi_off_send_work(struct k_work * work)221 static void eswifi_off_send_work(struct k_work *work)
222 {
223 	struct eswifi_off_socket *socket;
224 	net_context_send_cb_t cb;
225 	struct net_context *context;
226 	struct eswifi_dev *eswifi;
227 	void *user_data;
228 	int err;
229 
230 	socket = CONTAINER_OF(work, struct eswifi_off_socket, send_work);
231 	eswifi = eswifi_socket_to_dev(socket);
232 
233 	eswifi_lock(eswifi);
234 
235 	user_data = socket->send_data;
236 	cb = socket->send_cb;
237 	context = socket->context;
238 
239 	err = __eswifi_off_send_pkt(eswifi, socket);
240 	socket->tx_pkt = NULL;
241 
242 	eswifi_unlock(eswifi);
243 
244 	if (cb) {
245 		cb(context, err, user_data);
246 	}
247 }
248 
eswifi_off_send(struct net_pkt * pkt,net_context_send_cb_t cb,int32_t timeout,void * user_data)249 static int eswifi_off_send(struct net_pkt *pkt,
250 			   net_context_send_cb_t cb,
251 			   int32_t timeout,
252 			   void *user_data)
253 {
254 	struct eswifi_off_socket *socket = pkt->context->offload_context;
255 	struct eswifi_dev *eswifi = eswifi_by_iface_idx(socket->context->iface);
256 	int err;
257 
258 	LOG_DBG("timeout=%d", timeout);
259 
260 	eswifi_lock(eswifi);
261 
262 	if (socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
263 		eswifi_unlock(eswifi);
264 		return -ENOTCONN;
265 	}
266 
267 	if (socket->tx_pkt) {
268 		eswifi_unlock(eswifi);
269 		return -EBUSY;
270 	}
271 	socket->tx_pkt = pkt;
272 
273 	if (timeout == 0) {
274 		socket->send_data = user_data;
275 		socket->send_cb = cb;
276 
277 		k_work_submit_to_queue(&eswifi->work_q, &socket->send_work);
278 
279 		eswifi_unlock(eswifi);
280 
281 		return 0;
282 	}
283 
284 	err = __eswifi_off_send_pkt(eswifi, socket);
285 	socket->tx_pkt = NULL;
286 
287 	eswifi_unlock(eswifi);
288 
289 	if (cb) {
290 		cb(socket->context, err, user_data);
291 	}
292 
293 	return err;
294 }
295 
eswifi_off_sendto(struct net_pkt * pkt,const struct sockaddr * dst_addr,socklen_t addrlen,net_context_send_cb_t cb,int32_t timeout,void * user_data)296 static int eswifi_off_sendto(struct net_pkt *pkt,
297 			     const struct sockaddr *dst_addr,
298 			     socklen_t addrlen,
299 			     net_context_send_cb_t cb,
300 			     int32_t timeout,
301 			     void *user_data)
302 {
303 	struct eswifi_off_socket *socket = pkt->context->offload_context;
304 	struct eswifi_dev *eswifi = eswifi_by_iface_idx(socket->context->iface);
305 	int err;
306 
307 	LOG_DBG("timeout=%d", timeout);
308 
309 	eswifi_lock(eswifi);
310 
311 	if (socket->tx_pkt) {
312 		eswifi_unlock(eswifi);
313 		return -EBUSY;
314 	}
315 
316 	socket->tx_pkt = pkt;
317 
318 	if (socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
319 		socket->peer_addr = *dst_addr;
320 		err = __eswifi_off_start_client(eswifi, socket);
321 		if (err < 0) {
322 			eswifi_unlock(eswifi);
323 			return err;
324 		}
325 
326 		socket->state = ESWIFI_SOCKET_STATE_CONNECTED;
327 	}
328 
329 	if (timeout == 0) {
330 		socket->send_data = user_data;
331 		socket->send_cb = cb;
332 
333 		k_work_submit_to_queue(&eswifi->work_q, &socket->send_work);
334 
335 		eswifi_unlock(eswifi);
336 
337 		return 0;
338 	}
339 
340 	err = __eswifi_off_send_pkt(eswifi, socket);
341 	socket->tx_pkt = NULL;
342 
343 	eswifi_unlock(eswifi);
344 
345 	if (cb) {
346 		cb(socket->context, err, user_data);
347 	}
348 
349 	return err;
350 }
351 
eswifi_off_recv(struct net_context * context,net_context_recv_cb_t cb,int32_t timeout,void * user_data)352 static int eswifi_off_recv(struct net_context *context,
353 			   net_context_recv_cb_t cb,
354 			   int32_t timeout,
355 			   void *user_data)
356 {
357 	struct eswifi_off_socket *socket = context->offload_context;
358 	struct eswifi_dev *eswifi = eswifi_by_iface_idx(context->iface);
359 	int err;
360 
361 
362 	LOG_DBG("");
363 
364 	eswifi_lock(eswifi);
365 	socket->recv_cb = cb;
366 	socket->recv_data = user_data;
367 	k_sem_reset(&socket->read_sem);
368 	eswifi_unlock(eswifi);
369 
370 	if (timeout == 0) {
371 		return 0;
372 	}
373 
374 	err = k_sem_take(&socket->read_sem, K_MSEC(timeout));
375 
376 	/* Unregister callback */
377 	eswifi_lock(eswifi);
378 	socket->recv_cb = NULL;
379 	eswifi_unlock(eswifi);
380 
381 	return err;
382 }
383 
eswifi_off_put(struct net_context * context)384 static int eswifi_off_put(struct net_context *context)
385 {
386 	struct eswifi_off_socket *socket = context->offload_context;
387 	struct eswifi_dev *eswifi = eswifi_by_iface_idx(context->iface);
388 	int ret;
389 
390 	LOG_DBG("");
391 
392 	eswifi_lock(eswifi);
393 
394 	ret = __eswifi_socket_free(eswifi, socket);
395 	if (ret) {
396 		goto done;
397 	}
398 
399 	if (--socket->usage <= 0) {
400 		socket->context = NULL;
401 	}
402 done:
403 	eswifi_unlock(eswifi);
404 	return ret;
405 }
406 
eswifi_off_get(sa_family_t family,enum net_sock_type type,enum net_ip_protocol ip_proto,struct net_context ** context)407 static int eswifi_off_get(sa_family_t family,
408 			  enum net_sock_type type,
409 			  enum net_ip_protocol ip_proto,
410 			  struct net_context **context)
411 {
412 	struct eswifi_dev *eswifi = eswifi_by_iface_idx((*context)->iface);
413 	struct eswifi_off_socket *socket = NULL;
414 	int idx;
415 
416 	LOG_DBG("");
417 
418 	eswifi_lock(eswifi);
419 
420 	idx = __eswifi_socket_new(eswifi, family, type, ip_proto, *context);
421 	if (idx < 0) {
422 		goto unlock;
423 	}
424 
425 	socket = &eswifi->socket[idx];
426 	(*context)->offload_context = socket;
427 
428 	LOG_DBG("Socket index %d", socket->index);
429 
430 	k_work_init(&socket->connect_work, eswifi_off_connect_work);
431 	k_work_init(&socket->send_work, eswifi_off_send_work);
432 	k_sem_init(&socket->read_sem, 1, 1);
433 	k_sem_init(&socket->accept_sem, 1, 1);
434 
435 	k_work_reschedule_for_queue(&eswifi->work_q, &socket->read_work,
436 				    K_MSEC(500));
437 
438 unlock:
439 	eswifi_unlock(eswifi);
440 	return idx;
441 }
442 
eswifi_offload_async_msg(struct eswifi_dev * eswifi,char * msg,size_t len)443 void eswifi_offload_async_msg(struct eswifi_dev *eswifi, char *msg, size_t len)
444 {
445 	static const char msg_tcp_accept[] = "[TCP SVR] Accepted ";
446 
447 	if (!strncmp(msg, msg_tcp_accept, sizeof(msg_tcp_accept) - 1)) {
448 		struct eswifi_off_socket *socket = NULL;
449 		struct in_addr *sin_addr;
450 		uint8_t ip[4];
451 		uint16_t port = 0;
452 		char *str;
453 		int i = 0;
454 
455 		/* extract client ip/port e.g. 192.168.1.1:8080 */
456 		/* TODO: use net_ipaddr_parse */
457 		str = msg + sizeof(msg_tcp_accept) - 1;
458 		while (*str) {
459 			if (i < 4) {
460 				ip[i++] = atoi(str);
461 			} else if (i < 5) {
462 				port = atoi(str);
463 				break;
464 			}
465 
466 			while (*str && (*str != '.') && (*str != ':')) {
467 				str++;
468 			}
469 
470 			str++;
471 		}
472 
473 		for (i = 0; i < ESWIFI_OFFLOAD_MAX_SOCKETS; i++) {
474 			struct eswifi_off_socket *s = &eswifi->socket[i];
475 			if (s->context && s->port == port &&
476 			    s->state == ESWIFI_SOCKET_STATE_ACCEPTING) {
477 				socket = s;
478 				break;
479 			}
480 		}
481 
482 		if (!socket) {
483 			LOG_ERR("No listening socket");
484 			return;
485 		}
486 
487 		struct sockaddr_in *peer = net_sin(&socket->peer_addr);
488 
489 		sin_addr = &peer->sin_addr;
490 		memcpy(&sin_addr->s4_addr, ip, 4);
491 		peer->sin_port = htons(port);
492 		peer->sin_family = AF_INET;
493 		socket->state = ESWIFI_SOCKET_STATE_CONNECTED;
494 		socket->usage++;
495 
496 		/* Save information about remote. */
497 		socket->context->flags |= NET_CONTEXT_REMOTE_ADDR_SET;
498 		memcpy(&socket->context->remote, &socket->peer_addr,
499 		       sizeof(struct sockaddr));
500 
501 		LOG_DBG("%u.%u.%u.%u connected to port %u",
502 			ip[0], ip[1], ip[2], ip[3], port);
503 
504 		if (socket->accept_cb) {
505 			socket->accept_cb(socket->context,
506 					  &socket->peer_addr,
507 					  sizeof(struct sockaddr_in), 0,
508 					  socket->accept_data);
509 		}
510 
511 		k_sem_give(&socket->accept_sem);
512 		k_yield();
513 	}
514 }
515 
516 static struct net_offload eswifi_offload = {
517 	.get	       = eswifi_off_get,
518 	.bind	       = eswifi_off_bind,
519 	.listen	       = eswifi_off_listen,
520 	.connect       = eswifi_off_connect,
521 	.accept	       = eswifi_off_accept,
522 	.send	       = eswifi_off_send,
523 	.sendto	       = eswifi_off_sendto,
524 	.recv	       = eswifi_off_recv,
525 	.put	       = eswifi_off_put,
526 };
527 
eswifi_off_enable_dhcp(struct eswifi_dev * eswifi)528 static int eswifi_off_enable_dhcp(struct eswifi_dev *eswifi)
529 {
530 	char cmd[] = "C4=1\r";
531 	int err;
532 
533 	LOG_DBG("");
534 
535 	eswifi_lock(eswifi);
536 
537 	err = eswifi_at_cmd(eswifi, cmd);
538 
539 	eswifi_unlock(eswifi);
540 
541 	return 0;
542 }
543 
eswifi_off_disable_bypass(struct eswifi_dev * eswifi)544 static int eswifi_off_disable_bypass(struct eswifi_dev *eswifi)
545 {
546 	char cmd[] = "PR=0\r";
547 	int err;
548 
549 	LOG_DBG("");
550 
551 	eswifi_lock(eswifi);
552 
553 	err = eswifi_at_cmd(eswifi, cmd);
554 
555 	eswifi_unlock(eswifi);
556 
557 	return err;
558 }
559 
eswifi_offload_init(struct eswifi_dev * eswifi)560 int eswifi_offload_init(struct eswifi_dev *eswifi)
561 {
562 	eswifi->iface->if_dev->offload = &eswifi_offload;
563 	int err;
564 
565 	err = eswifi_off_enable_dhcp(eswifi);
566 	if (err < 0) {
567 		LOG_ERR("Unable to configure dhcp");
568 		return err;
569 	}
570 
571 	err = eswifi_off_disable_bypass(eswifi);
572 	if (err < 0) {
573 		LOG_ERR("Unable to disable bypass mode");
574 		return err;
575 	}
576 
577 	return 0;
578 }
579