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