// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : test.c
// Author        : xianfeng.du
// Created On    : 2022-11-25
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <string.h>
#include <sys/time.h>

#include "typedef.h"
#include "ucp_printf.h"
#include "ucp_common.h"
#include "msg_transfer_layer.h"
#include "ucp_handshake.h"
#include "ospShell.h"
#include "stc_drv.h"
#include <unistd.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/if_ether.h>
#include "ospTask.h"

#define port     9000
#define FastCMDataLen  (512)//(44*4*16)//pionter = 20
struct sockaddr_in SrcAddr;
struct sockaddr_in DstAddr;

char pBuffer[4096] = {0}; 
char recvBuffer[4096] = {0}; 
int32_t sockfd,rawsockfd;
int32_t Len0;
int32_t Len1;

void Cpri_GmacTx_Data_Init(void)
{
	int32_t i=0;

	for(i=0;i<4096;i++)
	{
		//pBuffer[i] = (0x11223344+i);
		pBuffer[i] = 0x5a;
	}
}
//TX
int8_t Cpri_Gmac_Socket(void)
{
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd == -1) {
		perror("socket");
		return -1;
	}
	printf("socket init pass!!!!!!!!\r\n");
	
	memset(&DstAddr, 0, sizeof(DstAddr));

	DstAddr.sin_family = AF_INET;
	DstAddr.sin_port = htons(port);
	DstAddr.sin_addr.s_addr = inet_addr("192.168.30.241");
//	DstAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	return 0;

}
//RX
int8_t Cpri_Gmac_RawSocket(void)
{
	//rawsockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
	rawsockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

	//rawsockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
	//rawsockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
	if (rawsockfd < 0) {
		perror("socket");
		return -1;
	}
	printf("RAWsocket init pass!!!!!!!!\r\n");
	
	return 0;

}

int8_t Cpri_GmacTx(void)
{

	//while(1)
	for(uint32_t i = 0; i<10 ;i++)
	{
		Len0 = sendto(sockfd, pBuffer, FastCMDataLen, 0, (struct sockaddr *)&DstAddr, sizeof(struct sockaddr_in));
		printf("Start sendto:%d!!!!!!!!\r\n",Len0);
		if (Len0 != FastCMDataLen)
		{
			return (-1);
			printf("send error!!!!!!!!!!\r\n");
		}	
		usleep(1000);
		printf("send cycle:%d!!!!!!!!\r\n",i);
	}
	while(1);
	return 0;
}

void Cpri_GmacRx(void)
{
  char *ethhead,*iphead;//*p;
  void *stack_static_ptr;
  uint64_t stack_len;
  uint8_t iProtocol;
  uint16_t iPlen;
 // uint32_t iDstPort;
//  uint32_t n=0xFF;
   uint32_t cycle = 0;
  stack_static_ptr = get_static_mem(APE_PHY, &stack_len);
    if((void *)OSP_ERROR == stack_static_ptr)
    {
        printf("get_static_mem-ARM_STACK:error\n");
    }
    else
    {
        printf("get_static_mem-ARM_STACK:ok! stack_static_ptr = %lx\n",(uint64_t)stack_static_ptr);
    }
	printf("stack_static_len = %lx\n",stack_len);
	while(1)
	{
		Len1 = recvfrom(rawsockfd, recvBuffer, 1024, 0, NULL, NULL);
		//printf("recv length:%d!!!!!!!!\r\n",Len1);
		
		ethhead = recvBuffer;
	
		iphead = ethhead + 14 ;
	
		iProtocol = (*(iphead +9));
		iPlen =  ((iphead[2]<<8) | (iphead[3]));
	//	p = iphead + 20;
	//	iDstPort = ((p[2]<<8)&0xff00) | (p[3]&n);
	//	printf("recv DstPort:%d!!!!!!!!\r\n",iDstPort);
		printf("recv iProtocol:%d!!!!!!!!\r\n",iProtocol);
		printf("recv iPlen:%d!!!!!!!!\r\n",iPlen);


		//if((Len1  >= 512) && (cycle < 100))
		//if(cycle < 100)
		if(iProtocol == 17)
		{
			if(iPlen  == 540)
	 		{
	 			memcpy((char *)stack_static_ptr + 0x70000000+1024*cycle , recvBuffer,Len1);
				cycle++;
			}
		}
		
		
		printf("recv cycle:%d!!!!!!!!\r\n",cycle);
	//	printf("recv end!!!!!!!!\r\n");
	}

}

int8_t start_CpriGmacTx_task(void)
{
    OSP_TASKMSG_REG Gmac_Tx_task;

    memset(&Gmac_Tx_task, 0, sizeof(Gmac_Tx_task));
    Gmac_Tx_task.TaskId   = CpriGmacTx;
    memcpy(Gmac_Tx_task.TaskName, "CpriGmacTx", 10);
    Gmac_Tx_task.TaskPri  = RT_NOMSG_PRI(96);
    Gmac_Tx_task.Init     = NULL;
    Gmac_Tx_task.MainLoop = (OSP_FUNCPTR)Cpri_GmacTx;
    Gmac_Tx_task.Cpu      = 2;
    Gmac_Tx_task.MsgType  = OSP_OTHER_MSG;

    if (OSP_OK != osp_regtask(&Gmac_Tx_task))
    {
        UCP_PRINT_ERROR("[start_log_task]: osp_regtask error!\n");
        return OSP_ERROR;
    }
    return OSP_OK;
}

int8_t start_CpriGmacRx_task(void)
{
    OSP_TASKMSG_REG Gmac_Rx_task;

    memset(&Gmac_Rx_task, 0, sizeof(Gmac_Rx_task));
    Gmac_Rx_task.TaskId   = CpriGmacRx;
    memcpy(Gmac_Rx_task.TaskName, "CpriGmacRx", 10);
    Gmac_Rx_task.TaskPri  = RT_NOMSG_PRI(95);
    Gmac_Rx_task.Init     = NULL;
    Gmac_Rx_task.MainLoop = (OSP_FUNCPTR)Cpri_GmacRx;
    Gmac_Rx_task.Cpu      = 3;
    Gmac_Rx_task.MsgType  = OSP_OTHER_MSG;

    if (OSP_OK != osp_regtask(&Gmac_Rx_task))
    {
        UCP_PRINT_ERROR("[start_log_task]: osp_regtask error!\n");
        return OSP_ERROR;
    }
    return OSP_OK;
}

int32_t test_case(uint32_t argc, int32_t* argvp)
{
	
	UCP_PRINT_DEBUG("start running testcase 30.");
	ucp_mem_init();
	
	ucp_handshake();
	sleep(10);
	Cpri_GmacTx_Data_Init();
	Cpri_Gmac_Socket();
	Cpri_Gmac_RawSocket();

	start_CpriGmacTx_task();
	start_CpriGmacRx_task();

	UCP_PRINT_DEBUG("start cpri gmac tx.");
    return 0;
}

