/*
 * recvraw.c
 *
 *  Created on: 2015-6-15
 *      Author: hjj
 */


#include <netmain.h>
#include <_stack.h>
#include <cslr_emac.h>
#define EMAC_REGS                 ((CSL_EmacRegs *)0x02C80000u)
#define     pac_COUNT    100000

void recvraw()
{
	SOCKET      sraw;
	INT32       val,retVal, count = 0, bytes;
	struct   	sockaddr_in sin1;
    struct   	timeval timeout;
    char*    	pBuf;
    HANDLE   	hBuffer;
	Uint32      rawchannel_num;
	ETHHDR*     ptr_eth_header;

	printf ("Raw Eth Rx Task has been started\n");

    /* Allocate the file environment for this task */
    fdOpenSession( TaskSelf() );

    /* Demonstrating use of SO_PRIORITY to configure
     * custom properties for all packets travelling
     * using this socket.
     *
     * Here, in this example we will use it for
     * configuring a distinct EMAC channel number for each
     * of the raw ethernet sockets.
     *
     * For example, Channel Assignment:
     *      Chan 0 - IP
     *      Chan 3 - Raw
     */
    rawchannel_num = 3;

    /* Create the main UDP listen socket */
    sraw = socket(AF_RAWETH, SOCK_RAW, IPPROTO_IP);
    if( sraw == INVALID_SOCKET )
        return;

    val=1;
    retVal = setsockopt(sraw,IPPROTO_IP,IP_HDRINCL,&val,sizeof(val));
	if(retVal)
		printf("error in setsockopt1 \n");


    /* Configure the transmit device */
    val = 1;
    retVal = setsockopt(sraw, SOL_SOCKET, SO_IFDEVICE, &val, sizeof(val));
	if(retVal)
		printf("error in setsockopt2 \n");

    /* Configure the EMAC channel number as the priority tag for packets */
    val = rawchannel_num;
    retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
	if(retVal)
		printf("error in setsockopt3 \n");

    /* Configure the Receive buffer size */
    val = 1000;
    retVal = setsockopt(sraw, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));
	if(retVal)
		printf("error in setsockopt4 \n");

    bzero( &sin1, sizeof(struct sockaddr_in) );
    sin1.sin_family = AF_INET;
    sin1.sin_len    = sizeof( sin1 );
    sin1.sin_port   = htons(217);


    if (0 != bind(sraw,(PSA) &sin1,sizeof(sin1)))
    {
    	printf("bind failed!\n");
    }

    timeout.tv_sec  = 15;
    timeout.tv_usec = 0;
    setsockopt( sraw, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof( timeout ) );
    setsockopt( sraw, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof( timeout ) );

    //ÉèÖÃÍø¿¨Îª»ìÔÓÄ£Ê½
    CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXPASSCRC, INCLUDE);
    CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXQOSEN, ENABLE);
    CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXNOCHAIN, ENABLE);
    CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCMFEN, ENABLE);
    CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCSFEN, ENABLE);
    CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCEFEN, ENABLE);
    CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCAFEN, ENABLE);


    while (count < pac_COUNT)
    {
		bytes = (int)recvnc( sraw, (void **)&pBuf, 0, &hBuffer );

        if (bytes < 0)
        {
			/* Receive failed: Close the session & kill the task */
			printf("Receive failed after packets Error:%d\n",fdError());
		    fdCloseSession( TaskSelf() );
		    TaskExit();
        }
		else
		{
    		ptr_eth_header = (ETHHDR*)pBuf;

		    printf("Received RAW ETH packet, len: %d \n", PBM_getValidLen((PBM_Handle)hBuffer));
			printf("Dst MAC Address = %02x-%02x-%02x-%02x-%02x-%02x Src MAC Address = %02x-%02x-%02x-%02x-%02x-%02x Eth Type = %d Data = %s \n",
           			ptr_eth_header->DstMac[0],ptr_eth_header->DstMac[1],ptr_eth_header->DstMac[2],
           			ptr_eth_header->DstMac[3],ptr_eth_header->DstMac[4],ptr_eth_header->DstMac[5],
           			ptr_eth_header->SrcMac[0],ptr_eth_header->SrcMac[1],ptr_eth_header->SrcMac[2],
           			ptr_eth_header->SrcMac[3],ptr_eth_header->SrcMac[4],ptr_eth_header->SrcMac[5],
           			ntohs(ptr_eth_header->Type), (pBuf + ETHHDR_SIZE));
		}


		count++;

		/* Clean out the buffer */
		recvncfree( hBuffer );
    }

	/* Close the session & kill the task */
    fdCloseSession( TaskSelf() );
    TaskExit();

    return;
}
