1/*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <string.h>
8
9#include "client.h"
10
11int udp_socket;
12
13int udp_socket_handle_async_received(tx_msg_t *msg)
14{
15    virtqueue_ring_object_t handle;
16    if (msg->done_len == -1 || msg->done_len == 0) {
17        msg->total_len = UDP_READ_SIZE;
18        msg->done_len = 0;
19        virtqueue_init_ring_object(&handle);
20        if (!virtqueue_add_available_buf(&rx_virtqueue, &handle, ENCODE_DMA_ADDRESS(msg), BUF_SIZE, VQ_RW)) {
21            ZF_LOGF("udp_handle_received: Error while enqueuing available buffer, queue full");
22        }
23
24    } else {
25        msg->total_len = msg->done_len;
26        msg->done_len = 0;
27        /* copy the packet over */
28
29        virtqueue_init_ring_object(&handle);
30        if (!virtqueue_add_available_buf(&tx_virtqueue, &handle, ENCODE_DMA_ADDRESS(msg), sizeof(*msg), VQ_RW)) {
31            ZF_LOGF("udp_handle_received: Error while enqueuing available buffer, queue full");
32        }
33
34    }
35    return 0;
36
37}
38
39
40int udp_socket_handle_async_sent(tx_msg_t *msg)
41{
42    virtqueue_ring_object_t handle;
43    msg->total_len = UDP_READ_SIZE;
44    msg->done_len = 0;
45    virtqueue_init_ring_object(&handle);
46    if (!virtqueue_add_available_buf(&rx_virtqueue, &handle, ENCODE_DMA_ADDRESS(msg), BUF_SIZE, VQ_RW)) {
47        ZF_LOGF("udp_handle_sent: Error while enqueuing available buffer, queue full");
48    }
49    return 0;
50
51}
52
53static int setup_udp_echo_socket(ps_io_ops_t *io_ops)
54{
55    udp_socket = echo_control_open(true);
56    if (udp_socket == -1) {
57        ZF_LOGF("Failed to open a socket for listening!");
58    }
59    int ret = echo_control_set_async(udp_socket, true);
60    if (ret) {
61        ZF_LOGF("Failed to set a socket to async: %d!", ret);
62    }
63
64    ret = echo_control_bind(udp_socket, PICOSERVER_ANY_ADDR_IPV4, UDP_ECHO_PORT);
65    if (ret) {
66        ZF_LOGF("Failed to bind a socket for listening: %d!", ret);
67    }
68
69    for (int i = 0; i < NUM_UDP_BUFS - 1; i++) {
70        tx_msg_t *buf = ps_dma_alloc(&io_ops->dma_manager, BUF_SIZE, 4, 1, PS_MEM_NORMAL);
71        ZF_LOGF_IF(buf == NULL, "Failed to alloc");
72        memset(buf, 0, BUF_SIZE);
73        buf->total_len = UDP_READ_SIZE;
74        buf->socket_fd = udp_socket;
75        buf->client_cookie = (void *)UDP_SOCKETS_ASYNC_ID;
76
77        virtqueue_ring_object_t handle;
78
79        virtqueue_init_ring_object(&handle);
80
81        if (!virtqueue_add_available_buf(&rx_virtqueue, &handle, ENCODE_DMA_ADDRESS(buf), sizeof(*buf), VQ_RW)) {
82            ZF_LOGF("Error while enqueuing available buffer, queue full");
83        }
84    }
85
86    return 0;
87}
88
89CAMKES_POST_INIT_MODULE_DEFINE(setup_udp, setup_udp_echo_socket);
90