/*
    Copyright 2000 (c) by Marc Wegmueller,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
	
    File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Net/Modules/UDP/NetUDPTest.c,v $
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2922 $
    Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $  by: $Author: baderma $
 
*/


#include "Topsy.h"
#include "IODevice.h"
#include "Syscall.h"
#include "Support.h"
#include "NetByteorder.h"
#include "NetDevice.h"
#include "NetError.h"
#include "NetConfigMngr.h"
#include "NetARP.h"
#include "NetDebug.h"
#include "Socket.h"
#include "NetSocket.h"
#include "TMTimerNG.h"
#include "TMTime.h"
#include "NetAutoConfiguration.h"
#include "NetMemoryManager.h"


u8						gatesOfHell[4];		// Gateway address


void NetUDPTest(ThreadId arg)
{
  int					i,
  myDevice,
  defaultDevice,
  moreDevToConfig,
  configuredDefaultDevice;

  ThreadId				mySock;

  char                                    *stringsend;

  long			                len;


  NetAttr					*mySockAttr;

  defaultDevice = 0;
  myDevice = defaultDevice;
  configuredDefaultDevice = FALSE;
  moreDevToConfig = TRUE;


  printf("NetUDPTest: started arg=%x\n", arg);

  if ( (mySock = socketXXX (AF_INET, SOCK_DGRAM, 0) ) == 0 )
  {
    netdbgPrintf (NETDEBUG_CONFIG, "BootP: failed to get a socket\n");
    tmExit();
  }

  vmAlloc ((Address*) &(mySockAttr), sizeof(NetAttr) * 14);	// should be big enough

  // make sure that the default devices has been configured before
  // trying to configure other devices via the default devoce

  netdbgPrintf(NETDEBUG_AUTOCONFIG,  "NetAutoConfiguration: STATE_UDP_TEST starting\n");
  // Set to address
  mySockAttr[0].key = NETATTR_IP6_DESTINATIONADDRESS_0;
  mySockAttr[1].key = NETATTR_IP6_DESTINATIONADDRESS_1;
  mySockAttr[2].key = NETATTR_IP6_DESTINATIONADDRESS_2;
  mySockAttr[3].key = NETATTR_IP6_DESTINATIONADDRESS_3;
  mySockAttr[4].key = NETATTR_IP6_DESTINATIONADDRESS_4;
  mySockAttr[5].key = NETATTR_IP6_DESTINATIONADDRESS_5;
  mySockAttr[6].key = NETATTR_IP6_DESTINATIONADDRESS_6;
  mySockAttr[7].key = NETATTR_IP6_DESTINATIONADDRESS_7;

  netdbgPrintf(NETDEBUG_AUTOCONFIG,  "NetAutoConfiguration: STATE_UDP_TEST 2\n");
  mySockAttr[0].data = 0xfe80;
  mySockAttr[1].data = 0x0;
  mySockAttr[2].data = 0x0;
  mySockAttr[3].data = 0x0;
  mySockAttr[4].data = 0xfcfd;
  mySockAttr[5].data = 0x00ff;
  mySockAttr[6].data = 0xfe00;
  mySockAttr[7].data = 0x0;

  /*for (i = 0; i < 8; i++) {
       mySockAttr[i].data = 255;
}
  */
  // Set server port
  mySockAttr[8].key =   NETATTR_UDP_REMOTE;
  mySockAttr[8].data =  7;
  // Set client port
  mySockAttr[9].key =   NETATTR_UDP_LOCAL;
  mySockAttr[9].data =  7;
  // Set OSI_2 type
  mySockAttr[10].key =  NETATTR_OSI_2_TYPE;
  mySockAttr[10].data = NETATTR_TYPE_ETHERNET;
  // Set OSI_3 type
  mySockAttr[11].key =  NETATTR_OSI_3_TYPE;
  mySockAttr[11].data = NETATTR_TYPE_IPv6;
  // Set BROADCAST
  mySockAttr[12].key =  NETATTR_BROADCAST;
  mySockAttr[12].data = 1;
  // Set Interface XXX this is a hack or probably not
  mySockAttr[13].key = NETATTR_IF_TO;
  mySockAttr[13].data = defaultDevice;

  netdbgPrintf(NETDEBUG_AUTOCONFIG,  "NetAutoConfiguration: STATE_UDP_TEST 10\n");

  if (connectXXX(mySock,mySockAttr, 14) )
  {
    printf ("Autoconfiguration: failed to connect!\n");
    vmFree (mySockAttr);
    tmExit();
  }

  netdbgPrintf(NETDEBUG_AUTOCONFIG,  "NetAutoConfiguration: STATE_UDP_TEST 20\n");

  stringsend  = "UDP-Packet over IPv6";
  len = 20;

  if (ioWrite (mySock, (char*) stringsend, &len) != IO_WRITEOK )
  {
    printf ("NetAutoConfiguration: failed to write to socket!\n");
  }


  netdbgPrintf(NETDEBUG_AUTOCONFIG,  "NetAutoConfiguration: STATE_UDP_TEST 20\n");


  /*
    myRequest.op			= NETBOOTP_OPCODE_REQUEST;
    myRequest.htype			= NETBOOTP_HTYPE_ENET;
    myRequest.hlen			= NETBOOTP_HLEN_ENET;
    myRequest.hops			= 0;			// needs to be zero
    myRequest.xid			= htonl(sId);
    myRequest.secs			= htons(secs(k_now()));
    myRequest.flags			= 0;			// ignored in BootP
    
    netdbgPrintf(NETDEBUG_AUTOCONFIG,  "NetAutoConfiguration: STATE_UDP_TEST 30\n");
    
    for (i = 0; i < 4; i++) {
    myRequest.ciaddr[i]		= 0;		// needs to be zero
    myRequest.yiaddr[i]		= 0;		// needs to be zero
    myRequest.siaddr[i]		= 0;		// needs to be zero
    myRequest.giaddr[i]		= gatesOfHell[i];
    }
    for (i = 0; i < 6; i++) {
    (myRequest.chaddr)[i]	= myHWAddress[i];
    }
    (myRequest.sname)[0]	= 0;			// just to be sure
    (myRequest.file)[0]		= 0;			// dito :)
    
    len = sizeof(NetAutoConfigurationHdr);
    if (ioWrite (mySock, (char*) &myRequest, &len) != IO_WRITEOK || len != sizeof(NetAutoConfigurationHdr)) {
    printf ("NetAutoConfiguration: failed to write to socket!\n");
    }
    
  */
  ioClose (mySock);
  vmFree (mySockAttr);
  printf("UDP over IPv6 completed!\n");

  tmExit();		// do not remove this unless you know what you are doing

}
