/*
 * net_test.c
 *
 * created: 2023-01-16
 *  author: 
 */

/*
 * RTEMS Task for udp_server_task, Auto Generated by Wizard.
 * Created: 2023-01-16 21:19:34
 */

#include "udp_tcp_test.h"

#if UDP_TSET

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <rtems.h>
#include <rtems/error.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <bsp.h>

//-----------------------------------------------------------------------------

static char local_IP[]  = "192.168.1.123";
//static char remote_IP[] = "192.168.1.111";

#define UDP_LOCAL_PORT      9062    // 本地端口
#define UDP_REMOTE_PORT     9063    // 远程端口

//-----------------------------------------------------------------------------

static rtems_id udp_server_task_taskid;

static char udp_msg[100];

//-----------------------------------------------------------------------------

static rtems_task udp_server_task_task(rtems_task_argument arg)
{
    /*
     * Add udp_server_task initialize code here.
     */
	struct sockaddr_in local_addr;
	int svr_fd;
	int err;

	svr_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (svr_fd < 0)
    {
		printf("failed to create sock_fd!\n");
		return;
	}

	memset(&local_addr, 0, sizeof(local_addr));
	local_addr.sin_family = AF_INET;
	local_addr.sin_addr.s_addr = inet_addr(local_IP);   // 192.168.1.123:9062 // htonl(INADDR_ANY); //
	local_addr.sin_port = htons(UDP_LOCAL_PORT);

	err = bind(svr_fd, (struct sockaddr *)&local_addr, sizeof(local_addr));
	if (err < 0)
    {
        close(svr_fd);
		printf("udp server bind() error.\r\n");
		return;
	}

    for ( ; ; )
    {
        /*
         * Add udp_server_task task code here.
         */

        struct sockaddr from;
        socklen_t fromlen = sizeof(struct sockaddr);

		err = recvfrom(svr_fd, (unsigned char *)udp_msg, sizeof(udp_msg), 0, &from, &fromlen);

        if (err <= 0)       // 返回接收到的字节数
        {
            rtems_task_wake_after(10); // delay_ms(10);
            continue;
        }

		printf("receive msg: %s\r\n", udp_msg);

		/*
         * Reply, 远程 IP:PORT
         */
		sendto(svr_fd, (unsigned char *)udp_msg, sizeof(udp_msg), 0, &from, fromlen);

        memset(udp_msg, 0, sizeof(udp_msg));

        /* abandon cpu time to run other task */
        rtems_task_wake_after(10);                      // task sleep 10 ms
        //rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); // task sleep until cpu idle
        //rtems_task_wake_when(When);                   // task sleep to time When
    }

    close(svr_fd);
    // return;
}

int udp_server_task_create(void)
{
    rtems_status_code rc;

    /* create the task */
    rc = rtems_task_create(rtems_build_name('U', 'D', 'P', 's'),
                           100,  // TODO PRIORITY
                           (8*1024),    // TODO Stack Size
                           RTEMS_DEFAULT_MODES,
                           RTEMS_DEFAULT_ATTRIBUTES,
                           &udp_server_task_taskid);

    if (RTEMS_SUCCESSFUL == rc)
    {
        /* start the task */
        rc = rtems_task_start(udp_server_task_taskid, udp_server_task_task, 0);
        if (RTEMS_SUCCESSFUL != rc)
        {
            /* start fail, clear the task */
            rtems_task_delete(udp_server_task_taskid);
        }
        printf("start task udp_server_task %s\r\n", rtems_status_text(rc));
    }
    else
        printf("create task udp_server_task %s\r\n", rtems_status_text(rc));

    return rc;
}

#endif


