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