Jump to content

A demo game


yorel

Recommended Posts

Well, i have to realise a connexion between a PC and a DS. I though to do a little game but i have some difficulties...

 

Sypherce told me to go at http://akkit.org/dswifi/udp_test.c but :

- what is types.h ? --> stupid question

( is-it possible to send me that file jeleroy@ulb.ac.be ? )

- it is ok for all WIFI PCI card or only ones with RT2500/RT2560 chipset.

 

Jérémy.

Edited by yorel
Link to comment
Share on other sites

Space for the DS program.

 

There is a lot of errors but i'm using a old PC ( 350Mhz - win 98 )... only word pad seems to work correctly...

 

// Conversation between a pc and a DS 
// Version 0.0001 16/03 15h08.

#include <PA9.h>  // PAlib include

#include "C:\Projects\HelloWorld\source\wifi_shared.h" 
#include "C:\Projects\HelloWorld\source\wifi_arm7.h"

//Template c ( ARM 7 surement )
//#include "C:\Documents and Settings\jleroy\Bureau\jl\librairie\wifi_lib_test\arm9\source\template.c"
#include "nds.h"
#include <nds/arm9/console.h> //basic print funcionality
#include <stdio.h>
#include <Stdlib.h>
#include <string.h>
#include <stdarg.h>

//#include "C:\Documents and Settings\jleroy\Bureau\jl\librairie\wifi_lib\arm9\include\dswifi9.h"
//#include "C:\Documents and Settings\jleroy\Bureau\jl\librairie\wifi_lib\arm9\include\sys\socket.h"
//#include "C:\Documents and Settings\jleroy\Bureau\jl\librairie\wifi_lib\arm9\include\netinet\in.h"

//#include "C:\Documents and Settings\jleroy\Bureau\jl\librairie\wifi_lib_test\arm9\data\ascii.bin"

//Ajout provenant du fichier template
#define  VRAM1  ((u16 *) 0x06000000)
#define  VRAM2  ((u16 *) 0x06200000)
#define  VCOUNT  (*((u16 volatile *) 0x04000006))
//#define PAL_BG1	((volatile u16 *)0x05000000) // inutile
//#define PAL_BG1	((volatile u16 *)0x05000400) // changer % à sgstair ici PAL_BG2
#define RGB(r,g,b) ((r) | ((g)<<5) | ((b)<<10))

Wifi_AccessPoint global_connectAP;
unsigned char global_wepkeys[4][32];
int global_wepkeyid, global_wepmode;
int global_dhcp; // 0=none, 1=get IP, 2=get DNS
unsigned long global_ipaddr, global_snmask, global_gateway, global_dns1,global_dns2;

void ScrollUpTop() {
int i;
for(i=0;i<23*32;i++)
 VRAM1[0x07C00+i]=VRAM1[0x07C00+i+32];
for(i=0;i<32;i++) {
 VRAM1[0x07C00+23*32+i]=' ';
}
}
void printtop(const char * str) {
int x;
ScrollUpTop();
x=0;
while(*str) {
 if(x==32) {x=0; ScrollUpTop();}
 VRAM1[0x07C00+23*32+x++]=*str;
 str++;
}
}
void sgIP_dbgprint(char * txt,...) {
char buffer[256];
va_list args;
va_start(args,txt);
vsprintf(buffer,txt,args);
printtop(buffer);  
}
void printbtm(int x, int y, const char * str) {
while(*str) {
 if(x==32) {x=0; y++;}
 if(y==24) return;
 VRAM2[0x07C00+y*32+x++]=*str;
 str++;
}
}
void printbtmn(int x, int y, const char * str, int n) {
while(*str && 0<=--n) {
 if(x==32) {x=0; y++;}
 if(y==24) return;
 VRAM2[0x07C00+y*32+x++]=*str;
 str++;
}
}

void * sgIP_malloc(int size) { return malloc(size); }
void sgIP_free(void * ptr) { free(ptr); }
//Cette fonction provient de Dsreg.h
#define  IME  	(*((u16 volatile *) 0x04000208)) //Elle était mise en commentaires.
//Ces fonctions proviennent de wifi_arm9.c ( autres en dessous )
int sgIP_DisableInterrupts() {
int a;
a=IME;
IME=0;
return a;
}
void sgIP_RestoreInterrupts(int old_ime) {
IME=old_ime;
}



//Ajout provenant du fichier in.h
#define INADDR_ANY  	0x00000000
#define INADDR_BROADCAST	0xFFFFFFFF
#define INADDR_NONE  	0xFFFFFFFF

struct in_addr {
unsigned long s_addr;
};

struct sockaddr_in {
unsigned short  sin_family;
unsigned short  sin_port;
struct in_addr  sin_addr;
unsigned char  sin_zero[8];
};

//Fonctions provenant de socket.h
#define PF_UNSPEC  0
#define PF_INET  	2
#define PF_INET6  10

#define AF_UNSPEC  PF_UNSPEC
#define AF_INET  	PF_INET
#define AF_INET6  PF_INET6

#define SOCK_STREAM  1
#define SOCK_DGRAM  2

#define FIONBIO  	1

//#ifndef ntohs
#define ntohs(num) htons(num)
#define ntohl(num) htonl(num)
//#endif

//Fonctions provenant de sgIP_socket.h
#define SGIP_SOCKET_FLAG_ACTIVE    0x8000
#define SGIP_SOCKET_FLAG_NONBLOCKING  0x4000
#define SGIP_SOCKET_FLAG_TYPEMASK  	0x0001
#define SGIP_SOCKET_FLAG_TYPE_TCP  	0x0001
#define SGIP_SOCKET_FLAG_TYPE_UDP  	0x0000


typedef struct SGIP_SOCKET_DATA {
unsigned int flags;
void * conn_ptr;
} sgIP_socket_data;

//Fonctions provenant de sgIP_Config.h
#define SGIP_SOCKET_MAXSOCKETS    	32
// SGIP_TCPRECEIVEBUFFERLENGTH: The size (in bytes) of the receive FIFO in a TCP connection
#define SGIP_TCP_RECEIVEBUFFERLENGTH  	8192
// SGIP_TCPTRANSMITBUFFERLENGTH: The size (in bytes) of the transmit FIFO in a TCP connection
#define SGIP_TCP_TRANSMITBUFFERLENGTH  	8192
// SGIP_TCPOOBBUFFERLENGTH: The size (in bytes) of the receive OOB data FIFO in a TCP connection
#define SGIP_TCP_OOBBUFFERLENGTH    256
// SGIP_MEMBLOCK_DATASIZE: This is the maximum data size contained in a single sgIP_memblock.
//  for best performance ensure this value is larger than any packet that is expected to be
//  received, however, in a memory-tight situation, much smaller values can be used.
#define SGIP_MEMBLOCK_DATASIZE  1600
// SGIP_MEMBLOCK_BASENUM: The starting number of memblocks that will be allocated. This is 
//  also the total number of memblocks that will be allocated if sgIP is not configured to use
//  dynamic memory allocation.
#define SGIP_MEMBLOCK_BASENUM  12
// SGIP_MAXHWHEADER: The maximum allocated size for hardware headers.
#define SGIP_MAXHWHEADER	16
// SGIP_TCP_TTL: Time-to-live value given to outgoing packets, in the absence of a reason to
//  manually override this value.
#define SGIP_IP_TTL        128
// SGIP_HUB_MAXHWINTERFACES: The maximum number of hardware interfaces the sgIP hub will 
//  connect to. A hardware interface being some port (ethernet, wifi, etc) that will relay
//  packets to the outside world.
#define SGIP_HUB_MAXHWINTERFACES    1
// SGIP_MAXHWADDRLEN: The maximum usable hardware address length.  Ethernet is 6 bytes.
#define SGIP_MAXHWADDRLEN	8
// SGIP_ARP_MAXENTRIES: The maximum number of cached ARP entries - this is defined staticly
//  because it's somewhat impractical to dynamicly allocate memory for such a small structure
//  (at least on most smaller systems)
#define SGIP_ARP_MAXENTRIES      32

#define SGIP_INTR_PROTECT() \
int tIME; \
tIME=sgIP_DisableInterrupts();
#define SGIP_INTR_REPROTECT() \
tIME=sgIP_DisableInterrupts();
#define SGIP_INTR_UNPROTECT() \
sgIP_RestoreInterrupts(tIME);
//#else // !SGIP_INTERRUPT_THREADING_MO

// SGIP_DEBUG: Enable debug logging.
//  requires external function "void sgIP_dbgprint(char *,...);"
#define SGIP_DEBUG

#ifdef SGIP_DEBUG
#define SGIP_DEBUG_MESSAGE(param) sgIP_dbgprint param
#define SGIP_DEBUG_ERROR(param) sgIP_dbgprint param; while(1);
#else
#define SGIP_DEBUG_MESSAGE(param) 
#define SGIP_DEBUG_ERROR(param)
#endif

//Fonctions provenant de sgIP_socket.c
sgIP_socket_data socketlist[SGIP_SOCKET_MAXSOCKETS];
//Ces fonctions appartiennent à SgIP_memblock.h
typedef struct SGIP_MEMBLOCK {
int totallength;
int thislength;
struct SGIP_MEMBLOCK * next;
char * datastart;
char reserved[SGIP_MEMBLOCK_DATASIZE-16]; // assume the other 4 values are 16 bytes total in length.
} sgIP_memblock;

#define SGIP_MEMBLOCK_INTERNALSIZE (SGIP_MEMBLOCK_DATASIZE-16)
#define SGIP_MEMBLOCK_FIRSTINTERNALSIZE (SGIP_MEMBLOCK_DATASIZE-16-SGIP_MAXHWHEADER)
//Ces fonctions appartiennent à sgIP_memblock.c
#include <stdlib.h>
#ifndef SGIP_USEDYNAMICMEMORY
sgIP_memblock memblock_pool[SGIP_MEMBLOCK_BASENUM];
#else
sgIP_memblock * memblock_pool;
#endif

sgIP_memblock * memblock_poolfree; //
int numused, numfree; //
void * pool_link; //
sgIP_memblock * sgIP_memblock_getunused() { //
//int i;
sgIP_memblock * mb;
SGIP_INTR_PROTECT();
if(memblock_poolfree) { // we still have free memblocks!
 mb=memblock_poolfree;
 memblock_poolfree=mb->next;
 numfree--;
 numused++;
} else { // oh noes, we have no more free memblocks.
 mb = 0; // eventually alloc new blocks, but for now just stop.
}

SGIP_INTR_UNPROTECT();
return mb;
}

void sgIP_memblock_Init() {
int i;
#ifdef SGIP_USEDYNAMICMEMORY
pool_link = sgIP_malloc(sizeof(sgIP_memblock)*SGIP_MEMBLOCK_BASENUM+4);
((long *)pool_link)[0]=0;
memblock_pool = (sgIP_memblock *) (((char *)pool_link)+4);
#endif
numused=numfree=0;
memblock_poolfree=0;
for(i=0;i<SGIP_MEMBLOCK_BASENUM;i++) {
 memblock_pool[i].totallength=0;
 memblock_pool[i].next=memblock_poolfree;
 memblock_poolfree=memblock_pool+i;
 numfree++;
}
}
void sgIP_memblock_free(sgIP_memblock * mb) { //
sgIP_memblock * f;

SGIP_INTR_PROTECT();
while(mb) {
 mb->totallength=0;
 mb->thislength=0;
 f=mb;
 mb = mb->next;

 numfree++; // reinstate memblock into the pool!
 numused--;
 f->next=memblock_poolfree;
 memblock_poolfree=f;
}
//	SGIP_DEBUG_MESSAGE(("memblock_free: %i free, %i used",numfree,numused));

SGIP_INTR_UNPROTECT();

}
sgIP_memblock * sgIP_memblock_allocHW(int headersize, int packetsize) { //
sgIP_memblock * mb, * tmb, *t;
int totlen;
mb = sgIP_memblock_getunused();
if(!mb) return 0;
mb->totallength=headersize+packetsize;
mb->datastart=mb->reserved+SGIP_MAXHWHEADER-headersize;
mb->next=0;
mb->thislength=headersize+SGIP_MEMBLOCK_FIRSTINTERNALSIZE;
if(mb->thislength>=mb->totallength) {
 mb->thislength = mb->totallength;
//  SGIP_DEBUG_MESSAGE(("memblock_alloc: %i free, %i used",numfree,numused));
 return mb;
} else { // need more blocks
 totlen=mb->thislength;
 tmb=mb;
 while(totlen<mb->totallength) {
 	t=sgIP_memblock_getunused();
 	if(!t) { // we're skrewed.
   sgIP_memblock_free(mb);
   return 0;
 	}
 	tmb->next=t;
 	t->totallength=mb->totallength;
 	t->datastart=mb->reserved; // no header on blocks after the first.
 	t->next=0;
 	t->thislength=SGIP_MEMBLOCK_INTERNALSIZE;
 	if(t->thislength+totlen>=mb->totallength) {
   t->thislength=mb->totallength-totlen;
//    SGIP_DEBUG_MESSAGE(("memblock_alloc: %i free, %i used",numfree,numused));
   return mb;
 	} else { // need YET more blocks.
   totlen+=t->thislength;
   tmb=t;
 	} // the cycle contiues.
 }
 sgIP_memblock_free(mb); // should never get here.
}
return 0;
}
sgIP_memblock * sgIP_memblock_alloc(int packetsize) {//
return sgIP_memblock_allocHW(0,packetsize);
}

// positive to expose, negative to hide.
void sgIP_memblock_exposeheader(sgIP_memblock * mb, int change) {//
if(mb) {
 mb->thislength+=change;
 mb->totallength+=change;
 mb->datastart-=change;
 while(mb->next) {
 	mb->next->totallength=mb->totallength;
 	mb=mb->next;
 }
}
}
int sgIP_memblock_IPChecksum(sgIP_memblock * mb, int startbyte, int chksum_length) {
int chksum_temp,offset;
// check checksum
chksum_temp=0;
offset=0;
while(mb && startbyte>mb->thislength) { startbyte-=mb->thislength; mb=mb->next; }
if(!mb) return 0;
while(chksum_length) {
 while(startbyte+offset+1<mb->thislength && chksum_length>1) {
 	chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset] + (((unsigned char *)mb->datastart)[startbyte+offset+1]<<8);
 	offset+=2;
 	chksum_length-=2;
 }
 chksum_temp += chksum_temp>>16;
 chksum_temp &= 0xFFFF;
 if(startbyte+offset<mb->thislength && chksum_length>0) {
 	chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset];
 	if(chksum_length==1) break;
 	chksum_length--;
 	offset=0;
 	startbyte=0;
 	mb=mb->next;
 	if(!mb) break;
 	if(mb->thislength==0) break;
 	chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset]<<8;
 	if(chksum_length==1) break;
 	offset++;
 	chksum_length--;
 }
}
chksum_temp += chksum_temp>>16;
chksum_temp &= 0xFFFF;
return chksum_temp;
}
//Fonctions provenant de sgIP_Hub.h
// SGIP_HUB_MAXHWINTERFACES: The maximum number of hardware interfaces the sgIP hub will 
//  connect to. A hardware interface being some port (ethernet, wifi, etc) that will relay
//  packets to the outside world.
#define SGIP_HUB_MAXHWINTERFACES    1

#define SGIP_LITTLEENDIAN //( Ces lignes proviennent de sgIP_Config.h
#ifdef SGIP_LITTLEENDIAN
unsigned short htons(unsigned short num) {
return ((num<<8)&0xFF00) | (num>>8);
}
unsigned long htonl(unsigned long num) {
return (num<<24) | ((num&0xFF00)<<8) | ((num&0xFF0000)>>8) | (num>>24);
}
#else
unsigned short htons(unsigned short num) {
return num;
}
unsigned long htonl(unsigned long num) {
return num;
}
#endif

#define SGIP_FLAG_PROTOCOL_IN_USE    0x0001
#define SGIP_FLAG_PROTOCOL_ENABLED    0x8000

#define SGIP_FLAG_HWINTERFACE_IN_USE  	0x0001
#define SGIP_FLAG_HWINTERFACE_CONNECTED  	0x0002
#define SGIP_FLAG_HWINTERFACE_USEDHCP  	0x0004
#define SGIP_FLAG_HWINTERFACE_CHANGENETWORK  0x0008
#define SGIP_FLAG_HWINTERFACE_ENABLED  	0x8000
// structure sgIP_Hub_Protocol: Used to record the interface between the sgIP Hub and a protocol handler
typedef struct SGIP_HUB_PROTOCOL {
unsigned short flags;
unsigned short protocol;
int (*ReceivePacket)(sgIP_memblock *);

} sgIP_Hub_Protocol;

typedef struct SGIP_HUB_HWINTERFACE {
unsigned short flags;
unsigned short hwaddrlen;
int MTU;
int (*TransmitFunction)(struct SGIP_HUB_HWINTERFACE *, sgIP_memblock *);
void * userdata;
unsigned long ipaddr, gateway, snmask, dns[3];
unsigned char hwaddr[SGIP_MAXHWADDRLEN];
} sgIP_Hub_HWInterface;

typedef struct SGIP_HEADER_ETHERNET {
unsigned char dest_mac[6];
unsigned char src_mac[6];
unsigned short protocol; 
} sgIP_Header_Ethernet;

sgIP_Hub_HWInterface HWInterfaces[SGIP_HUB_MAXHWINTERFACES];
int sgIP_Hub_SendRawPacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet); //définition après
//Fonctions provenant de sgIP_ARP.h
#define SGIP_ARP_FLAG_ACTIVE  0x0001
#define SGIP_ARP_FLAG_HAVEHWADDR	0x0002
typedef struct SGIP_ARP_RECORD {
unsigned short flags, retrycount;
unsigned long idletime;
sgIP_Hub_HWInterface * linked_interface;
sgIP_memblock * queued_packet;
int linked_protocol;
unsigned long protocol_address;
char hw_address[SGIP_MAXHWADDRLEN];
} sgIP_ARP_Record;


typedef struct SGIP_HEADER_ARP {
unsigned short hwspace;  // ethernet=1;
unsigned short protocol;
unsigned char hw_addr_len;
unsigned char protocol_addr_len;
unsigned short opcode;  // request=1, reply=2
unsigned char addresses[8+12]; // sender HW, sender Protocol, dest HW, dest Protocol
} sgIP_Header_ARP;

sgIP_ARP_Record ArpRecords[SGIP_ARP_MAXENTRIES];
#define SGIP_HEADER_ARP_BASESIZE	8
//Fonctions provenant de sgIP_ARP.c
int sgIP_FindArpSlot(sgIP_Hub_HWInterface * hw, unsigned long destip) {
int i;
for(i=0;i<SGIP_ARP_MAXENTRIES;i++) {
 if(ArpRecords[i].flags&SGIP_ARP_FLAG_ACTIVE) {
 	if(ArpRecords[i].linked_interface==hw && ArpRecords[i].protocol_address==destip) return i;
 }
}
return -1;
}
int sgIP_GetArpSlot() {
int i,m,midle;
m=0;
midle=0;
for(i=0;i<SGIP_ARP_MAXENTRIES;i++) {
 if(ArpRecords[i].flags&SGIP_ARP_FLAG_ACTIVE) {
 	if(ArpRecords[i].idletime>=midle) {
   midle=ArpRecords[i].idletime; m=i;
 	}
 } else {
 	return i;
 }
}
// this slot *was* in use, so let's fix that situation.
if(ArpRecords[m].queued_packet) sgIP_memblock_free(ArpRecords[m].queued_packet);
ArpRecords[m].flags=0;
ArpRecords[m].retrycount=0;
ArpRecords[m].idletime=0;
ArpRecords[m].queued_packet=0;
return m;
}

int sgIP_is_broadcast_address(sgIP_Hub_HWInterface * hw, unsigned long ipaddr) {
if((hw->snmask | ipaddr) == 0xFFFFFFFF) return 1;
return 0;
}

int sgIP_ARP_SendARPRequest(sgIP_Hub_HWInterface * hw, int protocol, unsigned long protocol_addr) {
int i;
  if(!hw) return 0;
sgIP_memblock * mb = sgIP_memblock_alloc(SGIP_HEADER_ARP_BASESIZE+2*4 + 2*hw->hwaddrlen);
if(!mb) return 0;

// Construct ARP packet
sgIP_Header_ARP * arp = (sgIP_Header_ARP *) mb->datastart;
arp->hwspace=htons(1); // 1=ethernet
arp->protocol=(protocol);
arp->opcode=htons(1); // 1=request
arp->hw_addr_len=hw->hwaddrlen;
arp->protocol_addr_len= 4;
for(i=0;i<hw->hwaddrlen;i++) arp->addresses[i]=hw->hwaddr[i];
for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen]=(hw->ipaddr>>(i*8))&255;
for(i=0;i<hw->hwaddrlen;i++) arp->addresses[i+4+hw->hwaddrlen]=0;
for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen*2+4]=(protocol_addr>>(i*8))&255;

// construct ethernet header
sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header
sgIP_Header_Ethernet * ether = (sgIP_Header_Ethernet *) mb->datastart;
for(i=0;i<6;i++) {
 ether->src_mac[i] = hw->hwaddr[i];
 ether->dest_mac[i]= 0xFF; // broadcast packet
}
ether->protocol=htons(0x0806); // ARP protocol

// Send ethernet packet
return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done.
}
int sgIP_ARP_SendProtocolFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb, unsigned short protocol, unsigned long destaddr) {
int i,j;
int m;
sgIP_Header_Ethernet * ether;
  if(!hw || !mb) return 0;
sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header

if(sgIP_is_broadcast_address(hw,destaddr)) {
 // construct ethernet header
 ether = (sgIP_Header_Ethernet *) mb->datastart;
 for(j=0;j<6;j++) {
 	ether->src_mac[j] = hw->hwaddr[j];
 	ether->dest_mac[j]= 0xFF; // broadcast destination
 }
 ether->protocol=protocol;
 return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done.
}

i=sgIP_FindArpSlot(hw,destaddr);
if(i!=-1) {
 if(ArpRecords[i].flags & SGIP_ARP_FLAG_HAVEHWADDR) { // we have the adddress
 	ArpRecords[i].idletime=0;
 	// construct ethernet header
 	ether = (sgIP_Header_Ethernet *) mb->datastart;
 	for(j=0;j<6;j++) {
   ether->src_mac[j] = hw->hwaddr[j];
   ether->dest_mac[j]= ArpRecords[i].hw_address[j];
 	}
 	ether->protocol=protocol;
 	return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done.
 } else { // we don't have the address, but are looking for it.
 	if(ArpRecords[i].queued_packet) { // if there is already a queued packet, reject the new one.
   sgIP_memblock_free(mb);
   return 0; // couldn't send.
 	} else {  
   sgIP_memblock_exposeheader(mb,-14); // re-hide ethernet header.
   ArpRecords[i].queued_packet=mb; // queue packet.
   ArpRecords[i].linked_protocol=protocol; // queue packet.
   return 0;
 	}
 }
}
m=sgIP_GetArpSlot(); // gets and cleans out an arp slot for us
 // build new record
ArpRecords[m].flags=SGIP_ARP_FLAG_ACTIVE;
ArpRecords[m].idletime=0;
ArpRecords[m].retrycount=0;
ArpRecords[m].linked_interface=hw;
ArpRecords[m].protocol_address=destaddr;
sgIP_memblock_exposeheader(mb,-14); // re-hide ethernet header.
ArpRecords[m].queued_packet=mb;
ArpRecords[m].linked_protocol=protocol;
sgIP_ARP_SendARPRequest(hw,protocol,destaddr);
return 0; // queued, but not sent yet.
}
//Fonctions provenant de sgIP_Hub.c
int sgIP_Hub_SendProtocolPacket(int protocol, sgIP_memblock * packet, unsigned long dest_address, unsigned long src_address) {
if(!packet) return 0;
sgIP_Hub_HWInterface * hw;
int i;
hw=0;
// figure out what hardware interface is in use.
for(i=0;i<SGIP_HUB_MAXHWINTERFACES;i++) if(HWInterfaces[i].ipaddr==src_address) {hw=HWInterfaces+i; break;}
if(!hw) {
 sgIP_memblock_free(packet);
 return 0;
}
// resolve protocol address to hardware address & send packet
if((src_address & hw->snmask) == (dest_address & hw->snmask)) { // on same network, send directly.
 return sgIP_ARP_SendProtocolFrame(hw,packet,protocol,dest_address);
} else { // eek, on different network. Send to gateway
 return sgIP_ARP_SendProtocolFrame(hw,packet,protocol,hw->gateway);
}
}
// send packet on a hardware interface. 
int sgIP_Hub_SendRawPacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet) {
if(!hw || !packet) return 0;
if(hw->flags&SGIP_FLAG_HWINTERFACE_ENABLED) {
 return hw->TransmitFunction(hw,packet);
}
sgIP_memblock_free(packet);
return 0;
}
unsigned long sgIP_Hub_GetCompatibleIP(unsigned long destIP) {
int n;
for(n=0;n<SGIP_HUB_MAXHWINTERFACES;n++) {
 if((HWInterfaces[n].flags&SGIP_FLAG_HWINTERFACE_IN_USE)) {
 	if((HWInterfaces[n].ipaddr & HWInterfaces[n].snmask) == (destIP & HWInterfaces[n].snmask)) return HWInterfaces[n].ipaddr;
 }
}
for(n=0;n<SGIP_HUB_MAXHWINTERFACES;n++) {
 if((HWInterfaces[n].flags&SGIP_FLAG_HWINTERFACE_IN_USE)) {
 	return HWInterfaces[n].ipaddr;
 }
}
return 0;
}
//Toutes ces fonctions appartiennent à sg_IP.h
typedef struct SGIP_HEADER_IP {
unsigned char version_ihl; // version = top 4 bits == 4, IHL = header length in 32bit increments = bottom 4 bits
unsigned char type_of_service; // [3bit prescidence][ D ][ T ][ R ][ 0 0 ] - D=low delya, T=high thoroughput, R= high reliability
unsigned short tot_length; // total length of packet including header
unsigned short identification; // value assigned by sender to aid in packet reassembly
unsigned short fragment_offset; // top 3 bits are flags [0][DF][MF] (Don't Fragment / More Fragments Exist) - offset is in 8-byte chunks.
unsigned char TTL; // time to live, measured in hops
unsigned char protocol; // protocols: ICMP=1, TCP=6, UDP=17
unsigned short header_checksum; // checksum:
unsigned long src_address; // src address is 32bit IP address
unsigned long dest_address; // dest address is 32bit IP address
unsigned char options[4]; // optional options come here.
} sgIP_Header_IP;
//Toutes ces fonctions appartiennent à sgIP_IP.c
int idnum_count;
int sgIP_IP_RequiredHeaderSize() {
return 5*4; // we'll not include zeroed options.
}
int sgIP_IP_SendViaIP(sgIP_memblock * mb, int protocol, unsigned long srcip, unsigned long destip) {
sgIP_Header_IP * iphdr;
unsigned short * chksum_calc;
int chksum_temp,i;
sgIP_memblock_exposeheader(mb,20);
iphdr=(sgIP_Header_IP *)mb->datastart;
chksum_calc=(unsigned short *)mb->datastart;
iphdr->dest_address=destip;
iphdr->fragment_offset=0;
iphdr->header_checksum=0;
iphdr->identification=idnum_count++;
iphdr->protocol=protocol;
iphdr->src_address=srcip;
iphdr->tot_length=htons(mb->totallength);
iphdr->TTL=SGIP_IP_TTL;
iphdr->type_of_service=0;
iphdr->version_ihl=0x45;
chksum_temp=0;
for(i=0;i<10;i++) chksum_temp+=chksum_calc[i];
chksum_temp += chksum_temp>>16;
chksum_temp &= 0xFFFF;
chksum_temp = ~chksum_temp;
if(chksum_temp==0) chksum_temp=0xFFFF;
iphdr->header_checksum=chksum_temp;
sgIP_Hub_SendProtocolPacket(htons(0x0800),mb,destip,srcip);
return 0;}
unsigned long sgIP_IP_GetLocalBindAddr(unsigned long srcip, unsigned long destip) {
if(srcip) return srcip;
return sgIP_Hub_GetCompatibleIP(destip);
}

//Cette fonction provient de SgIP_TCP.h
// sgIP_Record_TCP - a TCP record, to store data for an active TCP connection.
typedef struct SGIP_RECORD_TCP {
struct SGIP_RECORD_TCP * next; // operate as a linked list
// TCP state information
int tcpstate;
unsigned long sequence;
unsigned long ack;
unsigned long rxwindow;
unsigned long txwindow;
unsigned long srcip;
unsigned long destip;
unsigned short srcport,destport;
void * listendata;
int maxlisten;

// TCP buffer information:
int buf_rx_in, buf_rx_out;
int buf_tx_in, buf_tx_out;
int buf_oob_in, buf_oob_out;
unsigned char buf_rx[SGIP_TCP_RECEIVEBUFFERLENGTH];
unsigned char buf_tx[SGIP_TCP_TRANSMITBUFFERLENGTH];
unsigned char buf_oob[SGIP_TCP_OOBBUFFERLENGTH];
} sgIP_Record_TCP;

//Cette fonction provient de SgIP_UDP.h
enum SGIP_UDP_STATE {
SGIP_UDP_STATE_UNBOUND, // newly allocated
SGIP_UDP_STATE_BOUND,	// got a source address/port
SGIP_UDP_STATE_UNUSED,	// no longer in use.
};
typedef struct SGIP_HEADER_UDP {
unsigned short srcport,destport;
unsigned short length,checksum;
} sgIP_Header_UDP;
typedef struct SGIP_RECORD_UDP {
struct SGIP_RECORD_UDP * next;

int state;
unsigned long srcip;
unsigned long destip;
unsigned short srcport,destport;

sgIP_memblock * incoming_queue;
sgIP_memblock * incoming_queue_end;

} sgIP_Record_UDP;

sgIP_Record_UDP * udprecords;
sgIP_Record_UDP * sgIP_UDP_AllocRecord() {
SGIP_INTR_PROTECT();
sgIP_Record_UDP * rec;
rec = (sgIP_Record_UDP *)sgIP_malloc(sizeof(sgIP_Record_UDP));
if(rec) {
 rec->destip=0;
 rec->destport=0;
 rec->incoming_queue=0;
 rec->incoming_queue_end=0;
 rec->srcip=0;
 rec->srcport=0;
 rec->state=0;
 rec->next=udprecords;
 udprecords=rec;
}
SGIP_INTR_UNPROTECT();
return rec;
}
void sgIP_sockets_Init() {
int i;
for(i=0;i<SGIP_SOCKET_MAXSOCKETS;i++) {
 socketlist[i].conn_ptr=0;
 socketlist[i].flags = 0;
}
}


int socket(int domain, int type, int protocol) {
int s;
if(domain!=AF_INET) return -1;
if(protocol!=0) return -1;
if(type!=SOCK_DGRAM && type!=SOCK_STREAM) return -1;
SGIP_INTR_PROTECT();
for(s=0;s<SGIP_SOCKET_MAXSOCKETS;s++) if(!(socketlist[s].flags&SGIP_SOCKET_FLAG_ACTIVE)) break;
if(type==SOCK_STREAM) {
 //socketlist[s].flags=SGIP_SOCKET_FLAG_ACTIVE | SGIP_SOCKET_FLAG_TYPE_TCP;
 //socketlist[s].conn_ptr=sgIP_TCP_AllocRecord();
} else if(type==SOCK_DGRAM) {
 socketlist[s].flags=SGIP_SOCKET_FLAG_ACTIVE | SGIP_SOCKET_FLAG_TYPE_UDP;
 socketlist[s].conn_ptr=sgIP_UDP_AllocRecord();  
} else {
 SGIP_INTR_UNPROTECT();
 return -1;
}
#ifdef SGIP_SOCKET_DEFAULT_NONBLOCK
socketlist[s].flags|=SGIP_SOCKET_FLAG_NONBLOCKING;
#endif
SGIP_INTR_UNPROTECT();
return s+1;
}
void sgIP_UDP_FreeRecord(sgIP_Record_UDP * rec) {
if(!rec) return;
SGIP_INTR_PROTECT();
sgIP_Record_UDP * t;
// incoming queue is all clumped together as a single memblock, so, time to free it all in one call :)
if(rec->incoming_queue) sgIP_memblock_free(rec->incoming_queue); // woohoo!
rec->state=0;
if(udprecords==rec) {
 udprecords=rec->next;
} else {
 t=udprecords;
 while(t) {
 	if(t->next==rec) {
   t->next=rec->next;
   break;
 	}
 	t=t->next;
 }
}
sgIP_free(rec);

SGIP_INTR_UNPROTECT();
}
int close(int socket) {
if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
SGIP_INTR_PROTECT();
socket--;
if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
;//sgIP_TCP_FreeRecord((sgIP_Record_TCP *)socketlist[socket].conn_ptr);
} else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
 sgIP_UDP_FreeRecord((sgIP_Record_UDP *)socketlist[socket].conn_ptr);
}
socketlist[socket].conn_ptr=0;
socketlist[socket].flags=0;
SGIP_INTR_UNPROTECT();
return 0;
}

int sgIP_UDP_Bind(sgIP_Record_UDP * rec, int srcport, unsigned long srcip) {
if(!rec) return 0;
SGIP_INTR_PROTECT();
if(rec->state!=SGIP_UDP_STATE_UNUSED) {
 rec->srcip=srcip;
 rec->srcport=srcport;
 if(rec->state==SGIP_UDP_STATE_UNBOUND) rec->state=SGIP_UDP_STATE_BOUND;
}
SGIP_INTR_UNPROTECT();
return 0;
}
int bind(int socket,const struct sockaddr * addr, int addr_len) {
if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
SGIP_INTR_PROTECT();
int retval=-1;
socket--;
if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
} else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
 retval=sgIP_UDP_Bind((sgIP_Record_UDP *)socketlist[socket].conn_ptr,((struct sockaddr_in *)addr)->sin_port,((struct sockaddr_in *)addr)->sin_addr.s_addr);
}
SGIP_INTR_UNPROTECT();
return 0;
}

int sgIP_UDP_CalcChecksum(sgIP_memblock * mb, unsigned long srcip, unsigned long destip, int totallength) {
int checksum;//i;
if(!mb) return 0;
if(mb->totallength&1) mb->datastart[mb->totallength]=0;
checksum=sgIP_memblock_IPChecksum(mb,0,mb->totallength);
// add in checksum of "faux header"
checksum+=(destip&0xFFFF);
checksum+=(destip>>16);
checksum+=(srcip&0xFFFF);
checksum+=(srcip>>16);
checksum+=htons(totallength);
checksum+=(17)<<8;
checksum+=(checksum>>16);
checksum&=0xFFFF;

return checksum;
}
int sgIP_UDP_SendPacket(sgIP_Record_UDP * rec, char * data, int datalen, unsigned long destip, int destport) {
if(!rec || !data) return 0;
if(rec->state!=SGIP_UDP_STATE_BOUND) return 0;
int packetsize=sgIP_IP_RequiredHeaderSize()+8+datalen;
sgIP_memblock * mb = sgIP_memblock_alloc(packetsize);
if(!mb) return 0;
sgIP_memblock_exposeheader(mb,-sgIP_IP_RequiredHeaderSize()); // hide IP header space for later

SGIP_INTR_PROTECT();
unsigned long srcip = sgIP_IP_GetLocalBindAddr(rec->srcip,destip);
sgIP_Header_UDP * udp = (sgIP_Header_UDP *) mb->datastart;
udp->srcport=rec->srcport;
udp->destport=destport;
udp->length=htons(datalen+8);
udp->checksum=0;
int i;
for(i=0;i<datalen;i++) {
 mb->datastart[i+8]=data[i];
}
udp->checksum=~sgIP_UDP_CalcChecksum(mb,srcip,destip,mb->totallength);
if(udp->checksum==0) udp->checksum=0xFFFF;
sgIP_IP_SendViaIP(mb,17,srcip,destip);

SGIP_INTR_UNPROTECT();
return datalen;
}

int sgIP_UDP_SendTo(sgIP_Record_UDP * rec, char * buf, int buflength, int flags, unsigned long dest_ip, int dest_port) {
return sgIP_UDP_SendPacket(rec,buf,buflength,dest_ip,dest_port);
}
int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len) {
if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
if(!addr) return -1;
SGIP_INTR_PROTECT();
int retval=-1;
socket--;
if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
} else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
 retval=sgIP_UDP_SendTo((sgIP_Record_UDP *)socketlist[socket].conn_ptr,
       (char *)data,sendlength,flags,
       ((struct sockaddr_in *)addr)->sin_addr.s_addr,
       ((struct sockaddr_in *)addr)->sin_port);
}
SGIP_INTR_UNPROTECT();
return retval;
}
int sgIP_UDP_RecvFrom(sgIP_Record_UDP * rec, char * destbuf, int buflength, int flags, unsigned long * sender_ip, unsigned short * sender_port) {
if(!rec || !destbuf || !sender_ip || !sender_port || buflength==0) return -1;
SGIP_INTR_PROTECT();
if(rec->incoming_queue==0) { 
 SGIP_INTR_UNPROTECT();
 return -1;
}
int packetlen=rec->incoming_queue->totallength-12;
if(packetlen>buflength) {
 SGIP_INTR_UNPROTECT();
 return -1;
}
sgIP_memblock * mb;
*sender_ip=*((unsigned long *)rec->incoming_queue->datastart);
*sender_port=((unsigned short *)rec->incoming_queue->datastart)[2];
int totlen,first, buf_start,i;
totlen=rec->incoming_queue->totallength;
first=12;
buf_start=0;

while(totlen>0 && rec->incoming_queue) {
 totlen-=rec->incoming_queue->thislength;
 for(i=first;i<rec->incoming_queue->thislength;i++) {
 	destbuf[buf_start+i-first]=rec->incoming_queue->datastart[i];
 }
 buf_start+=rec->incoming_queue->thislength-first;
 first=0;
 mb=rec->incoming_queue;
 rec->incoming_queue=rec->incoming_queue->next;
 mb->next=0;
 sgIP_memblock_free(mb);
}
if(!(rec->incoming_queue)) rec->incoming_queue_end=0;

SGIP_INTR_UNPROTECT();
return buf_start;
}
int recvfrom(int socket, void * data, int recvlength, int flags, struct sockaddr * addr, int * addr_len) {
if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
if(!addr) return -1;
SGIP_INTR_PROTECT();
int retval=-1;
socket--;
if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
} else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
 retval=sgIP_UDP_RecvFrom((sgIP_Record_UDP *)socketlist[socket].conn_ptr,data,recvlength,flags,&(((struct sockaddr_in *)addr)->sin_addr.s_addr),&(((struct sockaddr_in *)addr)->sin_port));
 *addr_len = sizeof(struct sockaddr_in);
}
SGIP_INTR_UNPROTECT();
return retval;;
}

int ioctl(int socket, long cmd, void * arg) {
if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
socket--;
int retval;
retval=0;
SGIP_INTR_PROTECT();
switch(cmd) {
case FIONBIO:
 if(!arg){
 	retval=-1;
 } else {
 	socketlist[socket].flags &= ~SGIP_SOCKET_FLAG_NONBLOCKING;
 	if(*((unsigned long *)arg)) socketlist[socket].flags |= SGIP_SOCKET_FLAG_NONBLOCKING;
 }
 break;

}
SGIP_INTR_UNPROTECT();
return retval;
}

//Ces fonctions proviennent de wifi_arm9.c
sgIP_Hub_HWInterface * wifi_hw;
u32 Wifi_GetIP() {
if(wifi_hw) return wifi_hw->ipaddr;
return 0;
}
void Wifi_DisableWifi() {
WifiData->reqMode=WIFIMODE_DISABLED;
WifiData->reqReqFlags &= ~WFLAG_REQ_APCONNECT;
}
int Wifi_DisconnectAP() {
WifiData->reqMode=WIFIMODE_NORMAL;
WifiData->reqReqFlags &= ~WFLAG_REQ_APCONNECT;
return 0;}

//Ces fonctions appartiennt à SgIP_UDP.h
void sgIP_UDP_Init() {
udprecords=0;
}


int sgIP_UDP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip) {
if(!mb) return 0;
int chk = sgIP_UDP_CalcChecksum(mb,srcip,destip,mb->totallength);
if(chk!=0xFFFF) {
 SGIP_DEBUG_MESSAGE(("UDP receive checksum incorrect"));
 sgIP_memblock_free(mb);
 return 0; // checksum error
}
sgIP_Header_UDP * udp;
udp=(sgIP_Header_UDP *)mb->datastart;
sgIP_Record_UDP * rec; //, *t;
sgIP_memblock *tmb;
SGIP_INTR_PROTECT();
rec=udprecords;

while(rec) {
 if((rec->srcip==destip || rec->srcip==0) && rec->srcport==udp->destport && rec->state!=SGIP_UDP_STATE_UNUSED) break; // a match!
 rec=rec->next;
}
if(!rec) { // no matching records
 sgIP_memblock_free(mb);
 SGIP_INTR_UNPROTECT();
 return 0;
}
// we have a record and a packet for it; add some data to the record and stuff it into the record queue.
sgIP_memblock_exposeheader(mb,4);
*((unsigned long *)mb->datastart)=srcip; // keep srcip around.
if(rec->incoming_queue==0) {
 rec->incoming_queue=mb;
} else {
 rec->incoming_queue_end->next=mb;
}

tmb=mb;
while(tmb->next) tmb=tmb->next;
rec->incoming_queue_end=tmb;
// ok, data added to queue - yay!
// that means... we're done.

SGIP_INTR_UNPROTECT();
return 0;
}

//MAIN
int main(void)	{

// comments : PAlib Inits
PA_Init();
PA_InitVBL();

// comments : Text Init
PA_InitText(1,  // Top screen...
   2);	// Use background number 2

PA_OutputSimpleText(1,1,1,"-------------------------");
PA_OutputSimpleText(1,1,2,"LITTLE GAME vers. 0.00001");
PA_OutputSimpleText(1,1,3,"-------------------------");


// comments : Wifi's Initialisation
Wifi_Init(0);//u32 Wifi_pass=  //???
Wifi_Start(); //??? REchercher TxQueue et TxRaw

//Configuration du réseau
global_connectAP.ssid_len=7;
strcpy(global_connectAP.ssid,"linksys");
global_connectAP.rssi=0;
global_connectAP.channel=1;
global_connectAP.flags=0;
global_wepkeyid=0;
global_wepmode=0;
global_dhcp=0;
global_ipaddr=0xBD01A8C0; //192.168.1.189 à l'envers
global_snmask=0x00FFFFFF; //255.255.255.0 à l'envers
global_gateway=0x0101A8C0; //192.168.1.1 à l'envers
global_dns1=0x0101A8C0; //192.168.1.1 à l'envers
global_dns2=0;	

//Wifi_SetStaticIP(global_ipaddr,global_gateway,global_snmask,global_dns1,global_dns2);  //Do_ConnectAP();
//Wifi_ConnectAP(&global_connectAP,global_wepmode,global_wepkeyid,global_wepkeys[0]);

//Wifi_EnableWifi(); //Do_ConfigureWifi()
//wifi_ScanMode();

char rcvdbuf[4096];
char sendbuf[4096];

// //Do_Play_UDPTest()
int sock;
int portnum;
int rcvd=0,i=1,j,lastmsglen=0;
unsigned long destip,srcip;
struct sockaddr_in sain, sain_;
//char * tmp;
char buf[64];
char Obstacle_lutxt[64];

portnum=8888;

sock=socket(AF_INET,SOCK_DGRAM,0); // Recherche socket
sain.sin_family=AF_INET;
sain.sin_port=htons(portnum);
sain.sin_addr.s_addr=INADDR_ANY;
bind(sock,(struct sockaddr *) &sain,sizeof(sain)); // Recherche bind
//rcvd=0;
//i=1;
ioctl(sock,FIONBIO,&i);

destip=Wifi_GetIP(); //rechercher cette fonction
//lastmsglen=0;

PA_OutputSimpleText(1,1,5,"Wifi initialisé."); // Top screen, tile x = 1, y = 1...


 PA_OutputSimpleText(1,1,6,"Appuyer sur A pour lancer le jeu.");
while(!Pad.Newpress.A)
 {PA_WaitForVBL();}

//PA_OutputSimpleText(1,1,7,"Feu !");

while(!Pad.Newpress.B)
{

PA_OutputSimpleText(1,1,13,"                              ");
PA_OutputSimpleText(1,1,14,"                              ");
PA_OutputSimpleText(1,1,15,"                              ");

PA_OutputSimpleText(1,1,6,"Appuyer sur X.                        ");
while(!Pad.Newpress.X)
 {PA_WaitForVBL();}

// Envoyer un paquet pour signaler à l'ordinateur qu'il peut envoyer un premier paquet
strcpy(sendbuf,"Vas-y tu peux envoyer l'obstacle !");
sain.sin_family=AF_INET;
sain.sin_port=htons(portnum);
sain.sin_addr.s_addr=destip;
sendto(sock,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&sain,sizeof(sain));

// Recevoir un paquet de données indiquant le prochain obstacle
PA_OutputSimpleText(1,1,6,"Appuyer sur A pour recevoir un obstacle.");
while(!Pad.Newpress.A)
 {PA_WaitForVBL();}
// process incoming data...
i=sizeof(sain_);
if((j=recvfrom(sock,rcvdbuf,4095,0,(struct sockaddr *)&sain_,&i))!=-1)
 { lastmsglen=j; rcvd++; }
// display info
sprintf(buf,"%i Received",rcvd);
printbtm(29-strlen(buf),15,buf);
if(rcvd) 
 {
 srcip=sain_.sin_addr.s_addr;
 strcpy(buf,"Affichage de l'IP dz l'expéditeur.");
 //sprintf(buf,"From:%i.%i.%i.%i:%i",(srcip)&255,(srcip>>8)&255,(srcip>>16)&255,(srcip>>24)&255,ntohs(sain_.sin_port));
 printbtm(1,7,buf);
 sprintf(buf,"Msg Len: %i",lastmsglen);
 printbtm(1,8,buf);
 rcvdbuf[lastmsglen]=0;
 // have rows 9-14 to display msg- 5 lines
 for(i=0;i<11;i++) {
 	if(i*30<lastmsglen) printbtmn(1,9+i,rcvdbuf+i*30,30);
 }
}	

//Traitement de l'information
int Obstacle_lu=rcvdbuf-"111111";
PA_OutputSimpleText(1,1,11,"Message traduit :");
sprintf(Obstacle_lutxt,"%i",Obstacle_lu);
printbtm(1,12,Obstacle_lutxt);

//PA_OutputSimpleText(1,1,6,"Appuyer sur Y                           ");
//while(!Pad.Newpress.Y)
//	{PA_WaitForVBL();}
 
// Selon le contenu du paquet, on affiche différentes phrases
switch(Obstacle_lu)
{
   case 111111: //1B207 ou 11011001000000111
       PA_OutputSimpleText(1,1,13,"Il faut aller tout droit. (X)");
       break;

   case 222222: //3640E ou 110110010000001110
       PA_OutputSimpleText(1,1,13,"Il faut tourner à droite. (A)");
       break;

   case 333333: //51615 ou 1010001011000010101
       PA_OutputSimpleText(1,1,13,"Il faut tourner à gauche. (Y)");
       break;

   default: //execute no matter what.
       PA_OutputSimpleText(1,1,13,"None is true - appuyez sur X !");
       break;
}

PA_OutputSimpleText(1,1,6,"                               ");
PA_OutputSimpleText(1,1,7,"                               ");
PA_OutputSimpleText(1,1,8,"                               ");
PA_OutputSimpleText(1,1,9,"                               ");

PA_OutputSimpleText(1,1,6,"Appuies sur la direction que tu veux suivre (X)");

while((!Pad.Newpress.X) )//(!Pad.Newpress.Y)) //!Pad.Newpress.A|!Pad.Newpress.B|!Pad.Newpress.X|!Pad.Newpress.Y)
 {PA_WaitForVBL();}
 
PA_OutputSimpleText(1,1,6,"                               ");
PA_OutputSimpleText(1,1,7,"                               ");
PA_OutputSimpleText(1,1,8,"                               ");
PA_OutputSimpleText(1,1,9,"                               ");
PA_OutputSimpleText(1,1,10,"                              ");
PA_OutputSimpleText(1,1,11,"                              ");
PA_OutputSimpleText(1,1,12,"                              ");
PA_OutputSimpleText(1,1,13,"                              ");

if(Pad.Newpress.X) //(Obstacle_lu==111111 && !Pad.Newpress.X)|(Obstacle_lu==222222 && !Pad.Newpress.A)|(Obstacle_lu==333333 && !Pad.Newpress.Y)) 
 {
 PA_OutputSimpleText(1,1,14,"Coooool");
 //Envoi de la direction suivie
 strcpy(sendbuf,"La direction est bien suivie.");
 sain.sin_family=AF_INET;
 sain.sin_port=htons(portnum);
 sain.sin_addr.s_addr=destip;
 sendto(sock,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&sain,sizeof(sain));
 }
else
 {
 PA_OutputSimpleText(1,1,14,"GAME OVER");
 //Envoi d'un message de fin
 strcpy(sendbuf,"The game is over!");
    sain.sin_family=AF_INET;
 sain.sin_port=htons(portnum);
 sain.sin_addr.s_addr=destip;
 sendto(sock,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&sain,sizeof(sain));
 break;
 //break;
 }

PA_OutputSimpleText(1,1,15,"Passage à l'obstacle suivant ?");

PA_OutputSimpleText(1,1,6,"Appuyer sur Y                           ");
while(!Pad.Newpress.Y)
 {PA_WaitForVBL();}
 
//while(1)  {  // Inifinite loop
 //PA_WaitForVBL();
//}

}

PA_OutputSimpleText(1,1,20,"Arrêt!");
PA_OutputSimpleText(1,1,21,"Redémarrez le jeu !");

Wifi_DisconnectAP();
Wifi_DisableWifi();
Wifi_Shutdown();// stop wifi.
return 0;
}

 

Edit my message to see all the code...

Edited by yorel
Link to comment
Share on other sites

Wifi_arm7.c

 

// DS Wifi interface code
// Copyright © 2005 Stephen Stair - sgstair@akkit.org - [url=http://www.akkit.org]http://www.akkit.org[/url]
// wifi_arm7.c - arm7 wifi interface code
/****************************************************************************** 
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright © 2005 Stephen Stair

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/


#include <NDS.h>

//Toutes ces fonctions proviennent de spinlock.h
__asm (
".GLOBL SLasm_Acquire, SLasm_Release   \n"
"SLasm_Acquire:    	\n"
"   ldr r2,[r0]    	\n"
"   cmp r2,#0    	\n"
"   movne r0,#1                 \n"
"   bxne lr                  \n"
"   mov	r2,r1    	\n"
"   swp r2,r2,[r0]    \n"
"   cmp r2,#0    	\n"
"   cmpne r2,r1                 \n"
"   moveq r0,#0                 \n"
"   bxeq lr                  \n"
"   swp r2,r2,[r0]    \n"
"   mov r0,#1                   \n"
"   bx lr                  \n"
"\n\n"
"SLasm_Release:    	\n"
"   ldr r2,[r0]    	\n"
"   cmp r2,r1                 \n"
"   movne r0,#2                 \n"
"   bxne lr                  \n"
"   mov r2,#0    	\n"
"   swp r2,r2,[r0]    \n"
"   cmp r2,r1    	\n"
"   moveq r0,#0                 \n"
"   movne r0,#2                 \n"
"   bx lr                  \n"   
);

// Tous ces ficchiers proviennent de wifi_shared.h
#define Spinlock_Acquire(structtolock) SLasm_Acquire(&((structtolock).spinlock),SPINLOCK_VALUE)
#define Spinlock_Release(structtolock) SLasm_Release(&((structtolock).spinlock),SPINLOCK_VALUE)
#define Spinlock_Check(structtolock) (((structtolock).spinlock)!=SPINLOCK_NOBODY)

extern u32 SLasm_Acquire(volatile u32 * lockaddr, u32 lockvalue);
extern u32 SLasm_Release(volatile u32 * lockaddr, u32 lockvalue);

// Tous ces ficchiers proviennent de dsreg.h
//////////////////////////////////////////////////////////////////////////
// General registers

// general memory range defines
#define  PAL  	((u16 *) 0x05000000)
#define  VRAM1  ((u16 *) 0x06000000)
#define  VRAM2  ((u16 *) 0x06200000)

//#define  OAM  	((u16 *) 0x07000000)
#define  CART  ((u16 *) 0x08000000)

// video registers
#define  DISPCNT  (*((u32 volatile *) 0x04000000))
#define  DISPSTAT	(*((u16 volatile *) 0x04000004))
#define  VCOUNT  (*((u16 volatile *) 0x04000006))
#define  BG0CNT  (*((u16 volatile *) 0x04000008))
#define  BG1CNT  (*((u16 volatile *) 0x0400000A))
#define  BG2CNT  (*((u16 volatile *) 0x0400000C))
#define  BG3CNT  (*((u16 volatile *) 0x0400000E))
#define  BG0HOFS  (*((u16 volatile *) 0x04000010))
#define  BG0VOFS  (*((u16 volatile *) 0x04000012))
#define  BG1HOFS  (*((u16 volatile *) 0x04000014))
#define  BG1VOFS  (*((u16 volatile *) 0x04000016))
#define  BG2HOFS  (*((u16 volatile *) 0x04000018))
#define  BG2VOFS  (*((u16 volatile *) 0x0400001A))
#define  BG3HOFS  (*((u16 volatile *) 0x0400001C))
#define  BG3VOFS  (*((u16 volatile *) 0x0400001E))
#define  BG2PA  (*((u16 volatile *) 0x04000020))
#define  BG2PB  (*((u16 volatile *) 0x04000022))
#define  BG2PC  (*((u16 volatile *) 0x04000024))
#define  BG2PD  (*((u16 volatile *) 0x04000026))
#define  BG2X  (*((u32 volatile *) 0x04000028))
#define  BG2Y  (*((u32 volatile *) 0x0400002C))
#define  BG3PA  (*((u16 volatile *) 0x04000030))
#define  BG3PB  (*((u16 volatile *) 0x04000032))
#define  BG3PC  (*((u16 volatile *) 0x04000034))
#define  BG3PD  (*((u16 volatile *) 0x04000036))
#define  BG3X  (*((u32 volatile *) 0x04000038))
#define  BG3Y  (*((u32 volatile *) 0x0400003C))
#define  WIN0H  (*((u16 volatile *) 0x04000040))
#define  WIN1H  (*((u16 volatile *) 0x04000042))
#define  WIN0V  (*((u16 volatile *) 0x04000044))
#define  WIN1V  (*((u16 volatile *) 0x04000046))
#define  WININ  (*((u16 volatile *) 0x04000048))
#define  WINOUT  (*((u16 volatile *) 0x0400004A))
#define  MOSAIC  (*((u16 volatile *) 0x0400004C))
#define  BLDCNT  (*((u16 volatile *) 0x04000050))
#define  BLDALPHA	(*((u16 volatile *) 0x04000052))
#define  BLDY  (*((u16 volatile *) 0x04000054))

#define  DISPCNT2	(*((u32 volatile *) 0x04001000))
#define  DISPSTAT2	(*((u16 volatile *) 0x04001004))
#define  VCOUNT2  (*((u16 volatile *) 0x04001006))
#define  BG0CNT2  (*((u16 volatile *) 0x04001008))
#define  BG1CNT2  (*((u16 volatile *) 0x0400100A))
#define  BG2CNT2  (*((u16 volatile *) 0x0400100C))
#define  BG3CNT2  (*((u16 volatile *) 0x0400100E))
#define  BG0HOFS2	(*((u16 volatile *) 0x04001010))
#define  BG0VOFS2	(*((u16 volatile *) 0x04001012))
#define  BG1HOFS2	(*((u16 volatile *) 0x04001014))
#define  BG1VOFS2	(*((u16 volatile *) 0x04001016))
#define  BG2HOFS2	(*((u16 volatile *) 0x04001018))
#define  BG2VOFS2	(*((u16 volatile *) 0x0400101A))
#define  BG3HOFS2	(*((u16 volatile *) 0x0400101C))
#define  BG3VOFS2	(*((u16 volatile *) 0x0400101E))
#define  BG2PA2  (*((u16 volatile *) 0x04001020))
#define  BG2PB2  (*((u16 volatile *) 0x04001022))
#define  BG2PC2  (*((u16 volatile *) 0x04001024))
#define  BG2PD2  (*((u16 volatile *) 0x04001026))
#define  BG2X2  (*((u32 volatile *) 0x04001028))
#define  BG2Y2  (*((u32 volatile *) 0x0400102C))
#define  BG3PA2  (*((u16 volatile *) 0x04001030))
#define  BG3PB2  (*((u16 volatile *) 0x04001032))
#define  BG3PC2  (*((u16 volatile *) 0x04001034))
#define  BG3PD2  (*((u16 volatile *) 0x04001036))
#define  BG3X2  (*((u32 volatile *) 0x04001038))
#define  BG3Y2  (*((u32 volatile *) 0x0400103C))
#define  WIN0H2  (*((u16 volatile *) 0x04001040))
#define  WIN1H2  (*((u16 volatile *) 0x04001042))
#define  WIN0V2  (*((u16 volatile *) 0x04001044))
#define  WIN1V2  (*((u16 volatile *) 0x04001046))
#define  WININ2  (*((u16 volatile *) 0x04001048))
#define  WINOUT2  (*((u16 volatile *) 0x0400104A))
#define  MOSAIC2  (*((u16 volatile *) 0x0400104C))
#define  BLDCNT2  (*((u16 volatile *) 0x04001050))
#define  BLDALPHA2	(*((u16 volatile *) 0x04001052))
#define  BLDY2  (*((u16 volatile *) 0x04001054))

// video memory defines
#define  PAL_BG1  ((u16 *) 0x05000000)
#define  PAL_FG1  ((u16 *) 0x05000200)
#define  PAL_BG2  ((u16 *) 0x05000400)
#define  PAL_FG2  ((u16 *) 0x05000600)

// other video defines
#define  VRAMBANKCNT	(((u16 volatile *) 0x04000240))

#define  RGB(r,g,B)	( (®&31) | (((g)&31)<<5) | (((B)&31)<<10) )
#define  VRAM_SETBANK(bank, set)	\
if((bank)&1) { VRAMBANKCNT[(bank)>>1] = (VRAMBANKCNT[(bank)>>1]&0x00ff) | (((set)&0xff)<<8); } else \
 { VRAMBANKCNT[(bank)>>1] = (VRAMBANKCNT[(bank)>>1]&0xff00) | ((set)&0xff); }

// joypad input 
#define  KEYINPUT	(*((u16 volatile *) 0x04000130))
#define  KEYCNT  (*((u16 volatile *) 0x04000132))

// System registers
#define  WAITCNT  (*((u16 volatile *) 0x04000204))
#define  IME  	(*((u16 volatile *) 0x04000208)) // Mise en commentaires auparavant
//#define  IE  	(*((u32 volatile *) 0x04000210))
#define  IF  	(*((u32 volatile *) 0x04000214)) // Mise en commentaires auparavant
#define  HALTCNT  (*((u16 volatile *) 0x04000300))

//////////////////////////////////////////////////////////////////////////
// ARM7 specific registers
//#ifdef ARM7
#define  POWERCNT7	(*((u16 volatile *) 0x04000304))

#define  SPI_CR  (*((u16 volatile *) 0x040001C0))
#define  SPI_DATA	(*((u16 volatile *) 0x040001C2))

//#endif

//////////////////////////////////////////////////////////////////////////
// ARM9 specific registers
#ifdef ARM9
#define  POWERCNT	(*((u16 volatile *) 0x04000308))

#endif
// End of file!
//#endif


// on spinlock contention, the side unsuccessfully attempting the lock reverts the lock.
// if the unlocking side sees the lock incorrectly set, the unlocking side will delay until it has reverted to the correct value, then continue unlocking.
// there should be a delay of at least about ~10-20 cycles between a lock and unlock, to prevent contention.
#define SPINLOCK_NOBODY  	0x0000	
#define SPINLOCK_ARM7  	0x0001
#define SPINLOCK_ARM9  	0x0002

#define SPINLOCK_OK  0x0000
#define SPINLOCK_INUSE	0x0001
#define SPINLOCK_ERROR	0x0002

#ifdef ARM7
#define SPINLOCK_VALUE SPINLOCK_ARM7
#endif
#ifdef ARM9
#define SPINLOCK_VALUE SPINLOCK_ARM9
#endif


#define Spinlock_Acquire(structtolock) SLasm_Acquire(&((structtolock).spinlock),SPINLOCK_VALUE)
#define Spinlock_Release(structtolock) SLasm_Release(&((structtolock).spinlock),SPINLOCK_VALUE)
#define Spinlock_Check(structtolock) (((structtolock).spinlock)!=SPINLOCK_NOBODY)

#ifdef __cplusplus
extern "C" {
#endif

extern u32 SLasm_Acquire(volatile u32 * lockaddr, u32 lockvalue);
extern u32 SLasm_Release(volatile u32 * lockaddr, u32 lockvalue);

#ifdef __cplusplus
};
#endif

// If for whatever reason you want to ditch SGIP and use your own stack, comment out the following line.
#define WIFI_USE_TCP_SGIP	1

#define WIFI_RXBUFFER_SIZE	(1024*12)
#define WIFI_TXBUFFER_SIZE	(1024*24)
#define WIFI_MAX_AP  	32
#define WIFI_MAX_ASSOC_RETRY	30
#define WIFI_PS_POLL_CONST  2

#define WFLAG_PACKET_DATA  0x0001
#define WFLAG_PACKET_MGT  0x0002
#define WFLAG_PACKET_BEACON  0x0004
#define WFLAG_PACKET_CTRL  0x0008

#define WFLAG_PACKET_ALL  0xFFFF

#define WFLAG_ARM7_ACTIVE  0x0001
#define WFLAG_ARM7_RUNNING  0x0002

#define WFLAG_ARM9_ACTIVE  0x0001
#define WFLAG_ARM9_USELED  0x0002
#define WFLAG_ARM9_ARM7READY	0x0004
#define WFLAG_ARM9_NETUP  0x0008

#define WFLAG_IP_GOTDHCP  0x0001

// request - request flags
#define WFLAG_REQ_APCONNECT  	0x0001
#define WFLAG_REQ_APCOPYVALUES  0x0002
#define WFLAG_REQ_APADHOC  	0x0008

// request - informational flags
#define WFLAG_REQ_APCONNECTED  0x8000

#define WFLAG_APDATA_ADHOC  	0x0001
#define WFLAG_APDATA_WEP  	0x0002
#define WFLAG_APDATA_WPA  	0x0004
#define WFLAG_APDATA_COMPATIBLE  0x0008
#define WFLAG_APDATA_EXTCOMPATIBLE	0x0010
#define WFLAG_APDATA_SHORTPREAMBLE	0x0020
#define WFLAG_APDATA_ACTIVE  	0x8000


enum WIFI_RETURN {
WIFI_RETURN_OK =    0, // Everything went ok
WIFI_RETURN_LOCKFAILED  =  1, // the spinlock attempt failed (it wasn't retried cause that could lock both cpus- retry again after a delay.
WIFI_RETURN_ERROR =    2, // There was an error in attempting to complete the requested task.
WIFI_RETURN_PARAMERROR =  3, // There was an error in the parameters passed to the function.
};

enum WIFI_STATS {
// software stats
WSTAT_RXQUEUEDPACKETS, // number of packets queued into the rx fifo
WSTAT_TXQUEUEDPACKETS, // number of packets queued into the tx fifo
WSTAT_RXQUEUEDBYTES, // number of bytes queued into the rx fifo
WSTAT_TXQUEUEDBYTES, // number of bytes queued into the tx fifo
WSTAT_RXQUEUEDLOST, // number of packets lost due to space limitations in queuing
WSTAT_TXQUEUEDREJECTED, // number of packets rejected due to space limitations in queuing
WSTAT_RXPACKETS,
WSTAT_RXBYTES,
WSTAT_RXDATABYTES,
WSTAT_TXPACKETS,
WSTAT_TXBYTES,
WSTAT_TXDATABYTES,
  WSTAT_ARM7_UPDATES,
  WSTAT_DEBUG,
// harware stats (function mostly unknown.)
WSTAT_HW_1B0,WSTAT_HW_1B1,WSTAT_HW_1B2,WSTAT_HW_1B3,WSTAT_HW_1B4,WSTAT_HW_1
B5,WSTAT_HW_1B6,WSTAT_HW_1B7,	
WSTAT_HW_1B8,WSTAT_HW_1B9,WSTAT_HW_1BA,WSTAT_HW_1BB,WSTAT_HW_1BC,WSTAT_HW_1
BD,WSTAT_HW_1BE,WSTAT_HW_1BF,	
WSTAT_HW_1C0,WSTAT_HW_1C1,WSTAT_HW_1C4,WSTAT_HW_1C5,
WSTAT_HW_1D0,WSTAT_HW_1D1,WSTAT_HW_1D2,WSTAT_HW_1D3,WSTAT_HW_1D4,WSTAT_HW_1
D5,WSTAT_HW_1D6,WSTAT_HW_1D7,	
WSTAT_HW_1D8,WSTAT_HW_1D9,WSTAT_HW_1DA,WSTAT_HW_1DB,WSTAT_HW_1DC,WSTAT_HW_1
DD,WSTAT_HW_1DE,WSTAT_HW_1DF,	

NUM_WIFI_STATS
};


enum WIFI_MODE {
WIFIMODE_DISABLED,
WIFIMODE_NORMAL,
WIFIMODE_SCAN,
WIFIMODE_ASSOCIATE,
WIFIMODE_ASSOCIATED,
WIFIMODE_DISASSOCIATE,
WIFIMODE_CANNOTASSOCIATE,
WIFIMODE_PROMISCUOUS,
};
enum WIFI_AUTHLEVEL {
WIFI_AUTHLEVEL_DISCONNECTED,
WIFI_AUTHLEVEL_AUTHENTICATED,
WIFI_AUTHLEVEL_ASSOCIATED,
WIFI_AUTHLEVEL_DEASSOCIATED,
};

enum WIFI_IPTYPE {
WIFI_IPTYPE_DHCP,
WIFI_IPTYPE_STATIC,

};
enum WEPMODES {
WEPMODE_NONE = 0,
WEPMODE_40BIT = 1,
WEPMODE_128BIT = 3
};

enum WIFI_ASSOCSTATUS {
ASSOCSTATUS_DISCONNECTED, // not *trying* to connect
ASSOCSTATUS_AUTHENTICATING, // connecting...
ASSOCSTATUS_ASSOCIATING, // connecting...
ASSOCSTATUS_ASSOCIATED,	// Connected!
ASSOCSTATUS_CANNOTCONNECT, // error in connecting...
};
typedef struct WIFI_TXHEADER {
u16 enable_flags;
u16 unknown;
u16 countup;
u16 beaconfreq;
u16 tx_rate;
u16 tx_length;
} Wifi_TxHeader;

typedef struct WIFI_RXHEADER {
u16 a;
u16 b;
u16 c;
u16 d;
u16 byteLength;
u16 rssi_;
} Wifi_RxHeader;

typedef struct WIFI_ACCESSPOINT {
char ssid[33]; // 0-32byte data, zero
char ssid_len;
u8 bssid[6];
u8 macaddr[6];
u16 maxrate; // max rate is measured in steps of 1/2Mbit - 5.5Mbit will be represented as 11, or 0x0B
u32 timectr;
u16 rssi;
u16 flags;
u32 spinlock;
u8 channel;
u8 rssi_past[8];
u8 base_rates[16]; // terminated by a 0 entry
} Wifi_AccessPoint;

typedef struct WIFI_MAINSTRUCT {
// wifi status
u16 curChannel, reqChannel;
u16 curMode, reqMode;
u16 authlevel,authctr;
u32 flags9, flags7, reqPacketFlags;
u16 curReqFlags, reqReqFlags;
u32 counter7,bootcounter7;
char MacAddr[6];
u16 iptype,ipflags;
u32 ip,snmask,gateway;

// current AP data
char ssid7[34],ssid9[34];
u8 bssid7[6], bssid9[6];
u8 apmac7[6], apmac9[6];
char wepmode7, wepmode9;
char wepkeyid7, wepkeyid9;
u8 wepkey7[20],wepkey9[20];
u8 baserates7[16], baserates9[16];
u8 apchannel7, apchannel9;
u8 maxrate7;
u16 ap_rssi;
u16 pspoll_period;

// AP data
Wifi_AccessPoint aplist[WIFI_MAX_AP];

// wifi data
u32 rxbufIn, rxbufOut; // bufIn/bufOut have 2-byte granularity.
u16 rxbufData[WIFI_RXBUFFER_SIZE/2]; // send raw 802.11 data through! rxbuffer is for rx'd data, arm7->arm9 transfer

u32 txbufIn, txbufOut;
u16 txbufData[WIFI_TXBUFFER_SIZE/2]; // tx buffer is for data to tx, arm9->arm7 transfer

// stats data
u32 stats[NUM_WIFI_STATS];

u16 debug[30];

} Wifi_MainStruct;



//#endif

//Ces fonctions proviennent de wifi_arm7.h
#define WIFI_REG(ofs) (*((volatile u16 *)(0x04800000+(ofs))))
// Wifi regs
#define W_WEPKEY0  (((volatile u16 *)(0x04805F80)))
#define W_WEPKEY1  (((volatile u16 *)(0x04805FA0)))
#define W_WEPKEY2  (((volatile u16 *)(0x04805FC0)))
#define W_WEPKEY3  (((volatile u16 *)(0x04805FE0)))

#define W_MODE_RST  (*((volatile u16 *)(0x04800004)))
#define W_MODE_WEP  (*((volatile u16 *)(0x04800006)))
#define W_IF  	(*((volatile u16 *)(0x04800010)))
#define W_IE  	(*((volatile u16 *)(0x04800012)))
#define W_MACADDR  (((volatile u16 *)(0x04800018)))
#define W_BSSID  	(((volatile u16 *)(0x04800020)))
#define W_AIDS  	(*((volatile u16 *)(0x04800028)))
#define W_RETRLIMIT  (*((volatile u16 *)(0x0480002C)))
#define W_POWERSTATE	(*((volatile u16 *)(0x0480003C)))
#define W_RANDOM  (*((volatile u16 *)(0x04800044)))

#define W_BBSIOCNT  (*((volatile u16 *)(0x04800158)))
#define W_BBSIOWRITE	(*((volatile u16 *)(0x0480015A)))
#define W_BBSIOREAD  (*((volatile u16 *)(0x0480015C)))
#define W_BBSIOBUSY  (*((volatile u16 *)(0x0480015E)))
#define W_RFSIODATA2	(*((volatile u16 *)(0x0480017C)))
#define W_RFSIODATA1	(*((volatile u16 *)(0x0480017E)))
#define W_RFSIOBUSY  (*((volatile u16 *)(0x04800180)))

extern volatile Wifi_MainStruct * WifiData;

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

#include <NDS.h>
//#include "dsregs.h"
//#include "wifi_arm7.h"

//#include "spinlock.h" //.h file with code for spinlocking in it.

volatile Wifi_MainStruct * WifiData = 0;



//////////////////////////////////////////////////////////////////////////
//
//  Flash support functions
//
char FlashData[512];
void Read_Flash(int address, char * destination, int length) {
int i;
while(SPI_CR&0x80);
SPI_CR=0x8900;
SPI_DATA=3;
while(SPI_CR&0x80);
SPI_DATA=(address>>16)&255;
while(SPI_CR&0x80);
SPI_DATA=(address>>8)&255;
while(SPI_CR&0x80);
SPI_DATA=(address)&255;
while(SPI_CR&0x80);
for(i=0;i<length;i++) {
 SPI_DATA=0;
 while(SPI_CR&0x80);
 destination[i]=SPI_DATA;
}
}

void InitFlashData() {
Read_Flash(0,FlashData,512);
}

int ReadFlashByte(int address) {
if(address<0 || address>511) return 0;
return FlashData[address];  
}

int ReadFlashBytes(int address, int numbytes) {
int dataout=0;
int i;
for(i=0;i<numbytes;i++) {
 dataout |= ReadFlashByte(i+address)<<(i*8);
}
return dataout;
}
int ReadFlashHWord(int address) {
if(address<0 || address>510) return 0;
return ReadFlashBytes(address,2);
}
//////////////////////////////////////////////////////////////////////////
//
//  Other support
//
int Wifi_BBRead(int a) {
while(W_BBSIOBUSY&1);
W_BBSIOCNT=a | 0x6000;
while(W_BBSIOBUSY&1);
return W_BBSIOREAD;
}
int Wifi_BBWrite(int a, int B) {
int i;
i=0x2710;
while((W_BBSIOBUSY&1)) {
 if(!i--) return -1;
}
W_BBSIOWRITE=b;
W_BBSIOCNT=a | 0x5000;
i=0x2710;
while((W_BBSIOBUSY&1)) {
 if(!i--) return 0;
}
return 0;
}
void Wifi_RFWrite(int writedata) {
while(W_RFSIOBUSY&1);
W_RFSIODATA1=writedata;
W_RFSIODATA2=writedata>>16;
while(W_RFSIOBUSY&1);
}


//////////////////////////////////////////////////////////////////////////
//
//  Main functionality
//
int RF_Reglist[] = { 0x146, 0x148, 0x14A, 0x14C, 0x120, 0x122, 0x154, 0x144, 0x130, 0x132, 0x140, 0x142, 0x38, 0x124, 0x128, 0x150 };

void Wifi_RFInit() {
int i,j;
int channel_extrabits;
int numchannels;
int channel_extrabytes;
for(i=0;i<16;i++) {
 WIFI_REG(RF_Reglist[i])=ReadFlashHWord(0x44+i*2);
}
numchannels=ReadFlashByte(0x42);
channel_extrabits=ReadFlashByte(0x41);
channel_extrabytes=(channel_extrabits+7)/8;
WIFI_REG(0x184)=((channel_extrabits>>7)<<8) | (channel_extrabits&0x7F);
j=0xCE;
if(ReadFlashByte(0x40)==3) {
 for(i=0;i<numchannels;i++) {
 	Wifi_RFWrite(ReadFlashByte(j++)|(i<<8)|0x50000);
 }
} else {
 for(i=0;i<numchannels;i++) {
 	Wifi_RFWrite(ReadFlashBytes(j,channel_extrabytes));
 	j+=channel_extrabytes;
 }
}
}

void Wifi_BBInit() {
int i;
WIFI_REG(0x160)=0x0100;
for(i=0;i<0x69;i++) {
 Wifi_BBWrite(i,ReadFlashByte(0x64+i));
}
}

// 22 entry list
int MAC_Reglist[] = { 0x04, 0x08, 0x0A, 0x12, 0x10, 0x254, 0xB4, 0x80, 0x2A, 0x28, 0xE8, 0xEA, 0xEE, 0xEC, 0x1A2, 0x1A0, 0x110, 0xBC, 0xD4, 0xD8, 0xDA, 0x76 };
int MAC_Vallist[] = { 0, 0, 0, 0, 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 1, 0x3F03, 1, 0, 0x0800, 1, 3, 4, 0x0602, 0};
void Wifi_MacInit() {
int i;
for(i=0;i<22;i++) {
 WIFI_REG(MAC_Reglist[i]) = MAC_Vallist[i];
}
}


void Wifi_TxSetup() {
/*	switch(WIFI_REG(0x8006)&7) {
case 0: //
 // 4170,  4028, 4000
 // TxqEndData, TxqEndManCtrl, TxqEndPsPoll
 WIFI_REG(0x4024)=0xB6B8;
 WIFI_REG(0x4026)=0x1D46;
 WIFI_REG(0x416C)=0xB6B8;
 WIFI_REG(0x416E)=0x1D46;
 WIFI_REG(0x4790)=0xB6B8;
 WIFI_REG(0x4792)=0x1D46;
 WIFI_REG(0x80AE) = 1;
 break;
case 1: //
 // 4AA0, 4958, 4334
 // TxqEndData, TxqEndManCtrl, TxqEndBroadCast
 // 4238, 4000
 WIFI_REG(0x4234)=0xB6B8;
 WIFI_REG(0x4236)=0x1D46;
 WIFI_REG(0x4330)=0xB6B8;
 WIFI_REG(0x4332)=0x1D46;
 WIFI_REG(0x4954)=0xB6B8;
 WIFI_REG(0x4956)=0x1D46;
 WIFI_REG(0x4A9C)=0xB6B8;
 WIFI_REG(0x4A9E)=0x1D46;
 WIFI_REG(0x50C0)=0xB6B8;
 WIFI_REG(0x50C2)=0x1D46;
 //...
 break;
case 2:
 // 45D8, 4490, 4468
 // TxqEndData, TxqEndManCtrl, TxqEndPsPoll

 WIFI_REG(0x4230)=0xB6B8;
 WIFI_REG(0x4232)=0x1D46;
 WIFI_REG(0x4464)=0xB6B8;
 WIFI_REG(0x4466)=0x1D46;
 WIFI_REG(0x448C)=0xB6B8;
 WIFI_REG(0x448E)=0x1D46;
 WIFI_REG(0x45D4)=0xB6B8;
 WIFI_REG(0x45D6)=0x1D46;
 WIFI_REG(0x4BF8)=0xB6B8;
 WIFI_REG(0x4BFA)=0x1D46;
*/
 WIFI_REG(0x80AE)=0x000D;
//	}
}

void Wifi_RxSetup() {
WIFI_REG(0x8030) = 0x8000;
/*	switch(WIFI_REG(0x8006)&7) {
case 0:
 WIFI_REG(0x8050) = 0x4794;
 WIFI_REG(0x8056) = 0x03CA;
 // 17CC ?
 break;
case 1:
 WIFI_REG(0x8050) = 0x50C4;
 WIFI_REG(0x8056) = 0x0862;
 // 0E9C ?
 break;
case 2:
 WIFI_REG(0x8050) = 0x4BFC;
 WIFI_REG(0x8056) = 0x05FE;
 // 1364 ?
 break;
case 3:
 WIFI_REG(0x8050) = 0x4794;
 WIFI_REG(0x8056) = 0x03CA;
 // 17CC ?
 break;
}
*/
WIFI_REG(0x8050) = 0x4C00;
WIFI_REG(0x8056) = 0x0600;

WIFI_REG(0x8052) = 0x5F60;
WIFI_REG(0x805A) = (WIFI_REG(0x8050)&0x3FFF)>>1;
WIFI_REG(0x8062) = 0x5F5E;
WIFI_REG(0x8030) = 0x8001;
}


void Wifi_WakeUp() {
u32 i;
WIFI_REG(0x8036)=0;
for(i=0;i<100000;i++) i++;
WIFI_REG(0x8168)=0;

i=Wifi_BBRead(1);
Wifi_BBWrite(1,i&0x7f);
Wifi_BBWrite(1,i);
for(i=0;i<400000;i++) i++;

Wifi_RFInit();
}
void Wifi_Shutdown() {
int a;
if(ReadFlashByte(0x40)!=3) {
 Wifi_RFWrite(0xC008);
}
a=Wifi_BBRead(0x1E);
Wifi_BBWrite(0x1E,a|0x3F);
WIFI_REG(0x168)=0x800D;
WIFI_REG(0x36)=1;
}


void Wifi_CopyMacAddr(volatile void * dest, volatile void * src) {
((u16 *)dest)[0]=((u16 *)src)[0];
((u16 *)dest)[1]=((u16 *)src)[1];
((u16 *)dest)[2]=((u16 *)src)[2];
}

int Wifi_CmpMacAddr(volatile void * mac1,volatile  void * mac2) {
return (((u16 *)mac1)[0]==((u16 *)mac2)[0]) && (((u16 *)mac1)[1]==((u16 *)mac2)[1]) && (((u16 *)mac1)[2]==((u16 *)mac2)[2]);
}

//////////////////////////////////////////////////////////////////////////
//
//  MAC Copy functions
//
u16 inline Wifi_MACRead(u32 MAC_Base, u32 MAC_Offset) {
MAC_Base += MAC_Offset;
if(MAC_Base>=(WIFI_REG(0x52)&0x1FFE)) MAC_Base -= ((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE));
return WIFI_REG(0x4000+MAC_Base);
}

void Wifi_MACCopy(u16 * dest, u32 MAC_Base, u32 MAC_Offset, u32 length) {
int endrange,subval;
int thislength;
endrange = (WIFI_REG(0x52)&0x1FFE);
subval=((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE));
MAC_Base += MAC_Offset;
if(MAC_Base>=endrange) MAC_Base -= subval;
while(length>0) {
 thislength=length;
 if(thislength>(endrange-MAC_Base)) thislength=endrange-MAC_Base;
 length-=thislength;
 while(thislength>0) {
 	*(dest++) = WIFI_REG(0x4000+MAC_Base);
 	MAC_Base+=2;
 	thislength-=2;
 }
 MAC_Base-=subval;
}
}

void Wifi_MACWrite(u16 * src, u32 MAC_Base, u32 MAC_Offset, u32 length) {
int endrange,subval;
int thislength;
endrange = (WIFI_REG(0x52)&0x1FFE);
subval=((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE));
MAC_Base += MAC_Offset;
if(MAC_Base>=endrange) MAC_Base -= subval;
while(length>0) {
 thislength=length;
 if(length>(endrange-MAC_Base)) length=endrange-MAC_Base;
 length-=thislength;
 while(thislength>0) {
 	WIFI_REG(0x4000+MAC_Base) = *(src++);
 	MAC_Base+=2;
 	thislength-=2;
 }
 MAC_Base-=subval;
}
}
int Wifi_QueueRxMacData(u32 base, u32 len) {
int buflen, temp,macofs;
macofs=0;
buflen=(WifiData->rxbufIn-WifiData->rxbufOut-1)*2;
if(buflen<0) buflen += WIFI_RXBUFFER_SIZE;
if(buflen<len) { WifiData->stats[WSTAT_RXQUEUEDLOST]++; return 0; }
WifiData->stats[WSTAT_RXQUEUEDPACKETS]++;
WifiData->stats[WSTAT_RXQUEUEDBYTES]+=len;
temp=WIFI_RXBUFFER_SIZE-(WifiData->rxbufOut*2);
if(len>temp) {
 Wifi_MACCopy(WifiData->rxbufData+WifiData->rxbufOut,base,macofs,temp);
 macofs+=temp;
 len-=temp;
 WifiData->rxbufOut=0;
}
Wifi_MACCopy(WifiData->rxbufData+WifiData->rxbufOut,base,macofs,len);
WifiData->rxbufOut+=len/2;
if(WifiData->rxbufOut>=(WIFI_RXBUFFER_SIZE/2)) WifiData->rxbufOut-=(WIFI_RXBUFFER_SIZE/2);
return 1;
}

int Wifi_CheckTxBuf(s32 offset) {
offset+=WifiData->txbufIn;
if(offset>=WIFI_TXBUFFER_SIZE/2) offset-=WIFI_TXBUFFER_SIZE/2;
return WifiData->txbufData[offset];
}

// non-wrapping function.
int Wifi_CopyFirstTxData(s32 macbase) {
int seglen, readbase,max, packetlen,length;
packetlen=Wifi_CheckTxBuf(5);
readbase=WifiData->txbufIn;
length = (packetlen+12-4+1)/2;
max=WifiData->txbufOut-WifiData->txbufIn;
if(max<0) max+=WIFI_TXBUFFER_SIZE/2;
if(max<length) return 0;
while(length>0) {
 seglen=length;
 if(readbase+seglen>WIFI_TXBUFFER_SIZE/2) seglen=WIFI_TXBUFFER_SIZE/2-readbase;
 length-=seglen;
 while(seglen--) { WIFI_REG(0x4000+macbase)=WifiData->txbufData[readbase++]; macbase+=2; }
 if(readbase>=WIFI_TXBUFFER_SIZE/2) readbase-=WIFI_TXBUFFER_SIZE/2;
}
WifiData->txbufIn=readbase;

WifiData->stats[WSTAT_TXPACKETS]++;
WifiData->stats[WSTAT_TXBYTES]+=packetlen+12-4;
WifiData->stats[WSTAT_TXDATABYTES]+=packetlen-4;

return packetlen;
}



u16 arm7q[1024];
u16 arm7qlen = 0;

void Wifi_TxRaw(u16 * data, int datalen) {
datalen = (datalen+3)&(~3);
Wifi_MACWrite(data, 0, 0, datalen);
//	WIFI_REG(0xB8)=0x0001;
WIFI_REG(0xA8)=0x8000;
WifiData->stats[WSTAT_TXPACKETS]++;
WifiData->stats[WSTAT_TXBYTES]+=datalen;
WifiData->stats[WSTAT_TXDATABYTES]+=datalen-12;
}

int Wifi_TxCheck() {
if(WIFI_REG(0xA8)&0x8000) return 0;
return 1;
}


//////////////////////////////////////////////////////////////////////////
//
//  Wifi Interrupts
//
void Wifi_Intr_RxEnd() {
int base;
int packetlen;
int full_packetlen;
int dest_offset;
int i, cut, temp;
int tIME;
tIME=IME;
IME=0;
cut=0;

while(WIFI_REG(0x54)!=WIFI_REG(0x5A)) {
 base = WIFI_REG(0x5A)<<1;
 packetlen=Wifi_MACRead(base,8);
 full_packetlen=12+((packetlen+3)&(~3));
 WifiData->stats[WSTAT_RXPACKETS]++;
 WifiData->stats[WSTAT_RXBYTES]+=full_packetlen;
 WifiData->stats[WSTAT_RXDATABYTES]+=full_packetlen-12;

 
 // process packet here
 temp=Wifi_ProcessReceivedFrame(base,full_packetlen); // returns packet type
 if(temp&WifiData->reqPacketFlags) { // if packet type is requested, forward it to the rx queue
 	if(!Wifi_QueueRxMacData(base,full_packetlen)) {
   // failed, ignore for now.
 	}
 }

 base += full_packetlen;
 if(base>=(WIFI_REG(0x52)&0x1FFE)) base -= ((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE));
 WIFI_REG(0x5A)=base>>1;

 if(cut++>5) break;
}
IME=tIME;
}

#define CNT_STAT_START WSTAT_HW_1B0
#define CNT_STAT_NUM 18
u16 count_ofs_list[CNT_STAT_NUM] = {
0x1B0, 0x1B2, 0x1B4, 0x1B6, 0x1B8, 0x1BA, 0x1BC, 0x1BE, 0x1C0, 0x1C4, 0x1D0, 0x1D2, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0x1DC, 0x1DE
};
void Wifi_Intr_CntOverflow() {
int i;
int s,d;
s=CNT_STAT_START;
for(i=0;i<CNT_STAT_NUM;i++) {
 d=WIFI_REG(count_ofs_list[i]);
 WifiData->stats[s++]+=(d&0xFF);
 WifiData->stats[s++]+=((d>>8)&0xFF);
}
}

void Wifi_Intr_StartTx() {
}

void Wifi_Intr_TxEnd() { // assume that we can now tx something new.
if(arm7qlen) {
 Wifi_TxRaw(arm7q, arm7qlen);
 arm7qlen=0;
 return;
}
if((WifiData->txbufOut!=WifiData->txbufIn) && (!(WifiData->curReqFlags&WFLAG_REQ_APCONNECT) || WifiData->authlevel==WIFI_AUTHLEVEL_ASSOCIATED)) {
 if(Wifi_CopyFirstTxData(0)) {
 	if(WIFI_REG(0x4008)==0) { WIFI_REG(0x4008)=WifiData->maxrate7; } // if rate dne, fill it in.
 	if(WIFI_REG(0x400C)&0x4000) { // wep is enabled, fill in the IV.
   WIFI_REG(0x4024) = (W_RANDOM ^ (W_RANDOM<<7) ^ (W_RANDOM<<15))&0xFFFF;
   WIFI_REG(0x4026) = ((W_RANDOM ^ (W_RANDOM>>7))&0xFF) | (WifiData->wepkeyid7<<14);
 	}
 	//	WIFI_REG(0xB8)=0x0001;
 	WIFI_REG(0xA8)=0x8000;
        WIFI_REG(0xAE)=0x000D;
 }
}
}

void Wifi_Intr_TBTT() {
if(WIFI_REG(0xA8)&0x8000) {
 WIFI_REG(0xAE)=0x000D;
}
}

void Wifi_Intr_DoNothing() {
}



void Wifi_Interrupt() {
int wIF;
if(!WifiData) return;
if(!(WifiData->flags7&WFLAG_ARM7_RUNNING)) return;
wIF= W_IE & W_IF;
if(wIF& 0x0001) { W_IF=0x0001;  Wifi_Intr_RxEnd();  } // 0) Rx End
if(wIF& 0x0002) { W_IF=0x0002;  Wifi_Intr_TxEnd();  } // 1) Tx End
if(wIF& 0x0004) { W_IF=0x0004;  Wifi_Intr_DoNothing();  } // 2) Rx Cntup
if(wIF& 0x0008) { W_IF=0x0008;  Wifi_Intr_DoNothing();  } // 3) Tx Err
if(wIF& 0x0010) { W_IF=0x0010;  Wifi_Intr_CntOverflow();  } // 4) Count Overflow
if(wIF& 0x0020) { W_IF=0x0020;  Wifi_Intr_CntOverflow();  } // 5) AckCount Overflow
if(wIF& 0x0040) { W_IF=0x0040;  Wifi_Intr_DoNothing();  } // 6) Start Rx
if(wIF& 0x0080) { W_IF=0x0080;  Wifi_Intr_StartTx();  } // 7) Start Tx
if(wIF& 0x0100) { W_IF=0x0100;  Wifi_Intr_DoNothing();  } // 8) 
if(wIF& 0x0200) { W_IF=0x0200;  Wifi_Intr_DoNothing();  } // 9)
if(wIF& 0x0400) { W_IF=0x0400;  Wifi_Intr_DoNothing();  } //10)
if(wIF& 0x0800) { W_IF=0x0800;  Wifi_Intr_DoNothing();  } //11) RF Wakeup
if(wIF& 0x1000) { W_IF=0x1000;  Wifi_Intr_DoNothing();  } //12) MP End
if(wIF& 0x2000) { W_IF=0x2000;  Wifi_Intr_DoNothing();  } //13) ACT End
if(wIF& 0x4000) { W_IF=0x4000;  Wifi_Intr_TBTT();  } //14) TBTT
if(wIF& 0x8000) { W_IF=0x8000;  Wifi_Intr_DoNothing();  } //15) PreTBTT
IF=0x01000000; // now that we've cleared the wireless IF, kill the bit in regular IF.

}






void Wifi_Update() {
int i;
if(!WifiData) return;
  WifiData->stats[WSTAT_ARM7_UPDATES]++;
  WifiData->stats[WSTAT_DEBUG]=WIFI_REG(0xA8);
  if(WIFI_REG(0xA8)&0x8000) {
     WIFI_REG(0xAE)=0x000D;
  }
// check flags, to see if we need to change anything
switch(WifiData->curMode) {
case WIFIMODE_DISABLED:
 if(WifiData->reqMode!=WIFIMODE_DISABLED) {
 	Wifi_Start();
 	WifiData->curMode=WIFIMODE_NORMAL;
 }
 break;
case WIFIMODE_NORMAL: // main switcher function
 if(WifiData->reqMode==WIFIMODE_DISABLED) {
 	Wifi_Stop();
 	WifiData->curMode=WIFIMODE_DISABLED;
 	break;
 }
 if(WifiData->reqMode==WIFIMODE_SCAN) {
 	WifiData->counter7=WIFI_REG(0xFA); // timer hword 2 (each tick is 65.5ms)
 	WifiData->curMode=WIFIMODE_SCAN;
 	break;
 }
 if((WifiData->reqReqFlags ^ WifiData->curReqFlags) & WFLAG_REQ_APCONNECT) {
 	if(WifiData->curReqFlags& WFLAG_REQ_APCONNECT) { // already connected; disconnect
   WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
 	} else { // not connected - connect!
   if(WifiData->reqReqFlags&WFLAG_REQ_APCOPYVALUES) {
   	WifiData->wepkeyid7=WifiData->wepkeyid9;
   	WifiData->wepmode7=WifiData->wepmode9;
   	WifiData->apchannel7=WifiData->apchannel9;
   	Wifi_CopyMacAddr(WifiData->bssid7,WifiData->bssid9);
   	Wifi_CopyMacAddr(WifiData->apmac7,WifiData->apmac9);
   	for(i=0;i<20;i++) WifiData->wepkey7[i]=WifiData->wepkey9[i];
   	for(i=0;i<34;i++) WifiData->ssid7[i]=WifiData->ssid9[i];
   	for(i=0;i<16;i++) WifiData->baserates7[i]=WifiData->baserates9[i];
   	if(WifiData->reqReqFlags&WFLAG_REQ_APADHOC) WifiData->curReqFlags |= WFLAG_REQ_APADHOC; else WifiData->curReqFlags &= ~WFLAG_REQ_APADHOC;
   }
   for(i=0;i<10;i++) W_WEPKEY0[i]=W_WEPKEY1[i]=W_WEPKEY2[i]=W_WEPKEY3[i]=((u16 *)WifiData->wepkey7)[i];
   Wifi_SetWepMode(WifiData->wepmode7);
   // latch BSSID
   W_BSSID[0]= ((u16 *)WifiData->bssid7)[0];
   W_BSSID[1]= ((u16 *)WifiData->bssid7)[1];
   W_BSSID[2]= ((u16 *)WifiData->bssid7)[2];
   //WIFI_REG(0xD0) &= ~0x0400;
   WIFI_REG(0xD0) |= 0x0400;
   WifiData->reqChannel=WifiData->apchannel7;
   Wifi_SetChannel(WifiData->apchannel7);
   if(WifiData->curReqFlags&WFLAG_REQ_APADHOC) {
   	WifiData->authlevel=WIFI_AUTHLEVEL_ASSOCIATED;
   } else {
   	Wifi_SendOpenSystemAuthPacket();
   	WifiData->authlevel=WIFI_AUTHLEVEL_DISCONNECTED;
   }
           WifiData->txbufIn=WifiData->txbufOut; // empty tx buffer.
   WifiData->curReqFlags |= WFLAG_REQ_APCONNECT;
   WifiData->curMode=WIFIMODE_ASSOCIATE;
   WifiData->authctr=0;
 	}
 }
 break;
case WIFIMODE_SCAN:
 if(WifiData->reqMode!=WIFIMODE_SCAN) {
 	WifiData->curMode=WIFIMODE_NORMAL;
 	break;
 }
 if(((u16)(WIFI_REG(0xFA)-WifiData->counter7))>6) { // jump ship!
 	WifiData->counter7=WIFI_REG(0xFA);
 	WifiData->reqChannel++;
 	if(WifiData->reqChannel==14) WifiData->reqChannel=1;
 }
 break;
case WIFIMODE_ASSOCIATE:
 if(WifiData->authlevel==WIFI_AUTHLEVEL_ASSOCIATED) {
 	WifiData->curMode=WIFIMODE_ASSOCIATED;
 	break;
 }
 if(((u16)(WIFI_REG(0xFA)-WifiData->counter7))>20) { // ~1 second, reattempt connect stage
 	WifiData->counter7=WIFI_REG(0xFA);
 	WifiData->authctr++;
 	if(WifiData->authctr>WIFI_MAX_ASSOC_RETRY) {
   WifiData->curMode=WIFIMODE_CANNOTASSOCIATE;
   break;
 	}
 	switch(WifiData->authlevel) {
 	case WIFI_AUTHLEVEL_DISCONNECTED: // send auth packet
   if(!(WifiData->curReqFlags&WFLAG_REQ_APADHOC)) {
   	Wifi_SendOpenSystemAuthPacket();
   	break;
   }
   WifiData->authlevel=WIFI_AUTHLEVEL_ASSOCIATED;
   break;
 	case WIFI_AUTHLEVEL_DEASSOCIATED:
 	case WIFI_AUTHLEVEL_AUTHENTICATED: // send assoc packet
   Wifi_SendAssocPacket();
   break;
 	case WIFI_AUTHLEVEL_ASSOCIATED:
   WifiData->curMode=WIFIMODE_ASSOCIATED;
   break;
 	}
 }
 if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) {
 	WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
 	WifiData->curMode=WIFIMODE_NORMAL;
 	break;
 }
 break;
case WIFIMODE_ASSOCIATED:
 if((u16)(WIFI_REG(0xFA)-WifiData->pspoll_period)>WIFI_PS_POLL_CONST) {
 	WifiData->pspoll_period=WIFI_REG(0xFA);
 //	Wifi_SendPSPollFrame();
 }
 if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) {
        W_BSSID[0]= ((u16 *)WifiData->bssid7)[0];
        W_BSSID[1]= ((u16 *)WifiData->bssid7)[1];
        W_BSSID[2]= ((u16 *)WifiData->bssid7)[2];
        //WIFI_REG(0xD0) &= ~0x0400;
        WifiData->curMode=WIFIMODE_NORMAL;
        WifiData->authlevel=WIFI_AUTHLEVEL_DISCONNECTED;
 	if(WifiData->curReqFlags &WFLAG_REQ_APCONNECT) { // deassociate, then return
   WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
 	} else { // not connected for some reason, return.
   WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
   WifiData->curMode=WIFIMODE_ASSOCIATE;
 	}
        break;
 }
 if(WifiData->authlevel!=WIFI_AUTHLEVEL_ASSOCIATED) {
 	WifiData->curMode=WIFIMODE_ASSOCIATE;
 	break;
 }
 break;
case WIFIMODE_CANNOTASSOCIATE:
 if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) {
 	WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
 	WifiData->curMode=WIFIMODE_NORMAL;
 	break;
 }
 break;


}
if(WifiData->curChannel!=WifiData->reqChannel) {
 Wifi_SetChannel(WifiData->reqChannel);
}
// check Rx
Wifi_Intr_RxEnd();
// check if we need to tx anything
if(Wifi_TxCheck()) Wifi_Intr_TxEnd(); // easiest way to do so at the moment.
}




//////////////////////////////////////////////////////////////////////////
//
//  Wifi User-called Functions
//
void erasemem(void * mem, int length) {
int i;
char * m = (char *)mem;
for(i=0;i<length;i++)
 m[i]=0;
}


void Wifi_Init(u32 wifidata) {
WifiData = (Wifi_MainStruct *)wifidata;

POWERCNT7 |= 2; // enable power for the wifi
*((volatile u16 *)0x04000206) = 0x30; // ???

// reset/shutdown wifi:
WIFI_REG(0x4)=0xffff;
Wifi_Stop();
Wifi_Shutdown(); // power off wifi

WifiData->curChannel=1;
WifiData->reqChannel=1;
WifiData->curMode=WIFIMODE_DISABLED;
WifiData->reqMode=WIFIMODE_DISABLED;
WifiData->reqPacketFlags=WFLAG_PACKET_ALL & (~WFLAG_PACKET_BEACON);
WifiData->curReqFlags=0;
WifiData->reqReqFlags=0;
WifiData->maxrate7=0x0A;

int i;
for(i=0x4000;i<0x6000;i+=2) WIFI_REG(i)=0;

InitFlashData();

for(i=0;i<6;i++)  WifiData->MacAddr[i]=ReadFlashByte(0x36+i);

W_IE=0;
Wifi_WakeUp();

Wifi_MacInit();
Wifi_RFInit();
Wifi_BBInit();

// Set Default Settings
W_MACADDR[0]=((u16 *)WifiData->MacAddr)[0];
W_MACADDR[1]=((u16 *)WifiData->MacAddr)[1];
W_MACADDR[2]=((u16 *)WifiData->MacAddr)[2];

W_RETRLIMIT=7;
Wifi_SetMode(2);
Wifi_SetWepMode(WEPMODE_NONE);


Wifi_SetChannel(1);

Wifi_BBWrite(0x13, 0x00);
Wifi_BBWrite(0x35, 0x1F);

//	Wifi_Shutdown();

WifiData->flags7 |= WFLAG_ARM7_ACTIVE;
}

void Wifi_Deinit() {
Wifi_Stop();
POWERCNT7 &= ~2;
}

void Wifi_Start() {
int i, tIME;
tIME=IME;
IME=0;
Wifi_Stop();

//	Wifi_WakeUp();

WIFI_REG(0x8032) = 0x8000;
WIFI_REG(0x8134) = 0xFFFF;
WIFI_REG(0x802A) = 0;
W_AIDS           = 0;
WIFI_REG(0x80E8) = 1;
WIFI_REG(0x8038) = 0x0000;
WIFI_REG(0x20) = 0x0000;
WIFI_REG(0x22) = 0x0000;
WIFI_REG(0x24) = 0x0000;

Wifi_TxSetup();
Wifi_RxSetup();

WIFI_REG(0x8030) = 0x8000;
/*
switch(WIFI_REG(0x8006)&7) {
case 0: // infrastructure mode?
 W_IF=0xFFFF;
 W_IE=0x003F;
 WIFI_REG(0x81AE)=0x1fff;
 //WIFI_REG(0x81AA)=0x0400;
 WIFI_REG(0x80D0)=0xffff;
 WIFI_REG(0x80E0)=0x0008;
 WIFI_REG(0x8008)=0;
 WIFI_REG(0x800A)=0;
 WIFI_REG(0x80E8)=0;
 WIFI_REG(0x8004)=1;
 //SetStaState(0x40);
 break;
case 1: // ad-hoc mode? -- beacons are required to be created!
 W_IF=0xFFF;
 W_IE=0x703F;
 WIFI_REG(0x81AE)=0x1fff;
 WIFI_REG(0x81AA)=0; // 0x400
 WIFI_REG(0x80D0)=0x0301;
 WIFI_REG(0x80E0)=0x000D;
 WIFI_REG(0x8008)=0xE000;
 WIFI_REG(0x800A)=0;
 WIFI_REG(0x8004)=1;
 //??
 WIFI_REG(0x80EA)=1;
 WIFI_REG(0x80AE)=2;
 break;
case 2: // DS comms mode?
*/
 W_IF=0xFFFF;
 //W_IE=0xE03F;
 W_IE=0x40B3;
 WIFI_REG(0x81AE)=0x1fff;
 WIFI_REG(0x81AA)=0; //0x68
 W_BSSID[0]=0xFFFF;
 W_BSSID[1]=0xFFFF;
 W_BSSID[2]=0xFFFF;
 WIFI_REG(0x80D0)=0x0181; // 0x181
 WIFI_REG(0x80E0)=0x000B;
 WIFI_REG(0x8008)=0;
 WIFI_REG(0x800A)=0;
 WIFI_REG(0x8004)=1;
 WIFI_REG(0x80E8)=1;
 WIFI_REG(0x80EA)=1;
 //SetStaState(0x20);
/*
 break;
case 3:
case 4:
 break;
}
*/

WIFI_REG(0x8048)=0x0000;
Wifi_DisableTempPowerSave();
WIFI_REG(0x80AE)=0x0002;
W_POWERSTATE |= 2;
WIFI_REG(0xAC) = 0xFFFF;
i=0xFA0;
while(i!=0 && !(WIFI_REG(0x819C)&0x80)) i--;
WifiData->flags7 |=WFLAG_ARM7_RUNNING;
IME=tIME;
}

void Wifi_Stop() {
int tIME;
tIME=IME;
WifiData->flags7 &= ~WFLAG_ARM7_RUNNING;
W_IE=0;
WIFI_REG(0x8004) = 0;
WIFI_REG(0x80EA) = 0;
WIFI_REG(0x80E8) = 0;
WIFI_REG(0x8008) = 0;
WIFI_REG(0x800A) = 0;

WIFI_REG(0x80AC) = 0xFFFF;
WIFI_REG(0x80B4) = 0xFFFF;
//	Wifi_Shutdown();
IME=tIME;
}

void Wifi_SetChannel(int channel) {
int i;
if(channel<1 || channel>13) return;
channel-=1;
Wifi_RFWrite(ReadFlashBytes(0xf2+channel*6,3));
Wifi_RFWrite(ReadFlashBytes(0xf5+channel*6,3));
for(i=0;i<20000;i++) i++;
Wifi_BBWrite(0x1E, ReadFlashByte(0x146+channel));
WifiData->curChannel=channel+1;
}
void Wifi_SetWepKey(void * wepkey) {
int i;
for(i=0;i<16;i++) {
 W_WEPKEY0[i]=((u16 *)wepkey)[i];
 W_WEPKEY1[i]=((u16 *)wepkey)[i];
 W_WEPKEY2[i]=((u16 *)wepkey)[i];
 W_WEPKEY3[i]=((u16 *)wepkey)[i];
}
}

void Wifi_SetWepMode(int wepmode) {
if(wepmode<0 || wepmode>7) return;
W_MODE_WEP = (W_MODE_WEP & 0xFFC7) | (wepmode<<3);
}

void Wifi_SetBeaconPeriod(int beacon_period) {
if(beacon_period<0x10 || beacon_period>0x3E7) return;
WIFI_REG(0x8C)=beacon_period;
}

void Wifi_SetMode(int wifimode) {
if(wifimode>3 || wifimode<0) return;
W_MODE_WEP = (W_MODE_WEP& 0xfff8) | wifimode;
}
void Wifi_SetPreambleType(int preamble_type) {
if(preamble_type>1 || preamble_type<0) return;
WIFI_REG(0x80BC) = (WIFI_REG(0x80BC) & 0xFFBF) | (preamble_type<<6);
}
void Wifi_DisableTempPowerSave() {
WIFI_REG(0x8038) &= ~2;
WIFI_REG(0x8048) = 0;
}





//////////////////////////////////////////////////////////////////////////
//
//  802.11b system, tied in a bit with the :
//
int Wifi_TxQueue(u16 * data, int datalen) {
int i,j;
if(arm7qlen) {
 if(Wifi_TxCheck()) {
 	Wifi_TxRaw(arm7q,arm7qlen);
 	arm7qlen=0;
 	j=(datalen+1)>>1;
 	if(j>1024) return 0;
 	for(i=0;i<j;i++) arm7q[i]=data[i];
 	arm7qlen=datalen;
 	return 1;
 }
 return 0;
}
if(Wifi_TxCheck()) {
 Wifi_TxRaw(data,datalen);
 return 1;
}
arm7qlen=0;
j=(datalen+1)>>1;
if(j>1024) return 0;
for(i=0;i<j;i++) arm7q[i]=data[i];
arm7qlen=datalen;
return 1;
}

int Wifi_GenMgtHeader(u8 * data, u16 headerflags) {
// tx header
((u16 *)data)[0]=0;
((u16 *)data)[1]=0;
((u16 *)data)[2]=0;
((u16 *)data)[3]=0;
((u16 *)data)[4]=0;
((u16 *)data)[5]=0;
// fill in most header fields
((u16 *)data)[7]=0x0000;
Wifi_CopyMacAddr(data+16,WifiData->apmac7);
Wifi_CopyMacAddr(data+22,WifiData->MacAddr);
Wifi_CopyMacAddr(data+28,WifiData->bssid7);
((u16 *)data)[17]=0;

// fill in wep-specific stuff
//	if(WifiData->wepmode7!=0) {
//  ((u32 *)data)[9]=(W_RANDOM ^ (W_RANDOM<<7) ^ (W_RANDOM<<15))&0x0FFF | (WifiData->wepkeyid7<<30); // I'm lazy and certainly haven't done this to spec.
//  ((u16 *)data)[6]=0x4000 | headerflags;
//  return 28+12;
//	} else {
 ((u16 *)data)[6]=headerflags;
 return 24+12;
//	}
}

int Wifi_SendOpenSystemAuthPacket() {
// max size is 12+24+4+6 = 46
u8 data[64];
int i;
i=Wifi_GenMgtHeader(data,0x00B0);

((u16 *)(data+i))[0]=0; // Authentication algorithm number (0=open system)
((u16 *)(data+i))[1]=1; // Authentication sequence number
((u16 *)(data+i))[2]=0; // Authentication status code (reserved for this message, =0)

((u16 *)data)[4]=0x000A;
((u16 *)data)[5]=i+6-12+4;

Wifi_TxQueue(data, i+6);

}
int Wifi_SendAssocPacket() { // uses arm7 data in our struct
// max size is 12+24+4+34+4 = 66
u8 data[96];
int i,j,k,numrates;

i=Wifi_GenMgtHeader(data,0x0000);

if(WifiData->wepmode7) {
 ((u16 *)(data+i))[0]=0x0011; // CAPS info
} else {
 ((u16 *)(data+i))[0]=0x0001; // CAPS info
}

((u16 *)(data+i))[1]=WIFI_REG(0x8E); // Listen interval
i+=4;
data[i++]=0; // SSID element
data[i++]=WifiData->ssid7[0];
for(j=0;j<WifiData->ssid7[0];j++) data[i++]=WifiData->ssid7[1+j];

if((WifiData->baserates7[0]&0x7f)!=2) {
 for(j=1;j<16;j++) WifiData->baserates7[i]=WifiData->baserates7[j-1];
}
WifiData->baserates7[0]=0x82;
if((WifiData->baserates7[1]&0x7f)!=4) {
 for(j=2;j<16;j++) WifiData->baserates7[j]=WifiData->baserates7[j-1];
}
WifiData->baserates7[1]=0x04;

WifiData->baserates7[15]=0;
for(j=0;j<16;j++) if(WifiData->baserates7[j]==0) break;
numrates=j;
for(j=2;j<numrates;j++) WifiData->baserates7[j] &= 0x7F;

data[i++]=1; // rate set
data[i++]=numrates;
for(j=0;j<numrates;j++) data[i++]=WifiData->baserates7[j];

// reset header fields with needed data
((u16 *)data)[4]=0x000A;
((u16 *)data)[5]=i-12+4;

Wifi_TxQueue(data, i);
 
}

...

 

 

My file is too long. So i will send my files to the ones who want it.

Edited by yorel
Link to comment
Share on other sites

Space for pc program.

 

Aie AIe Aie... am I able to do this ??? :)

 

#include <winsock2.h>
#include <windows.h>
#include <Stdio.h>
#include <stdlib.h>
//#include <iostream.h>

#pragma comment(lib, "wsock32.lib")

int main(int argc, char * argv[]) {

SOCKET sock;
srand(GetTickCount());

printf("----------------------------------\n");
printf("Little game version 0.0000001\n");
printf("----------------------------------\n");

{
 WSADATA d;
 int i;
 i=WSAStartup(0x0002,&d);
 if(i==0) {
	 printf("Winsock 2.0 initialized correctly...\n");
 } else {
	 printf("Winsock failed to init.\n");
	 return 0;
 }
}

sock=socket(AF_INET,SOCK_DGRAM,0);
sockaddr_in sain;
sain.sin_family=AF_INET;
sain.sin_addr.S_un.S_addr=ADDR_ANY;
sain.sin_port=htons(8888);

if(bind(sock,(sockaddr *)&sain,sizeof(sain))) 
{
 printf("bind() error!\n");
 closesocket(sock);
 return 0;
}

char incomingbuf[1024];
char outgoingbuf[1024];

int datalen;
int sain_len;
sockaddr_in sender;
DWORD err;

int a=0;

printf("L'ordinateur est en train d'attendre la réception d'un message.\n");
printf("Apuyer sur 0 pour l'arrêter.\n");
printf("\n");
printf("\n");

while(0) //a<1000)
{
 sain_len=sizeof(sender);
 datalen=recvfrom(sock,incomingbuf,1023,0,(sockaddr *)&sender,&sain_len);
 
 if(datalen>0) 
 {
	 incomingbuf[datalen]=0;
	 printf("UDP Datagram from %i.%i.%i.%i:%i\n",sender.sin_addr.S_un.S_un_b.s_b1,sender.sin_addr.S_un.S_un_b.s_b2,sender.si
n_addr.S_un.S_un_b.s_b3,sender.sin_addr.S_un.S_un_b.s_b4,ntohs(sender.sin_port));
	 printf("Received '%s' [%i]\n",incomingbuf,datalen);

 } 
 else 
 {
	 err=WSAGetLastError();
	 Sleep(1);
 }
 printf("Valuer de a : %s \n",a);
 a++;

}



printf("Il nous faut maintenant envoyer l'obstacle.\n");
printf("Apuyer sur 0 pour l'arrêter.\n");
wsprintf(outgoingbuf,"%s|rnd=%i",incomingbuf,rand()&0xFF);
printf("Sent back: '%s' [%i]\n",outgoingbuf,strlen(outgoingbuf));
printf("\n");
printf("\n");
while(a<1000)
{
 sendto(sock,outgoingbuf,strlen(outgoingbuf)+1,0,(sockaddr *)&sender,sizeof(sender));
 a++; 	 
}

a=0;

printf("L'ordinateur est en train d'attendre la réception d'un message de réussite ou d'échec au jeu.\n");
printf("Apuyer sur 0 pour l'arrêter.\n");
printf("\n");
printf("\n");
while(0) //a<1000)
{
 sain_len=sizeof(sender);
 datalen=recvfrom(sock,incomingbuf,1023,0,(sockaddr *)&sender,&sain_len);
 
 if(datalen>0) 
 {
	 incomingbuf[datalen]=0;
	 printf("UDP Datagram from %i.%i.%i.%i:%i\n",sender.sin_addr.S_un.S_un_b.s_b1,sender.sin_addr.S_un.S_un_b.s_b2,sender.si
n_addr.S_un.S_un_b.s_b3,sender.sin_addr.S_un.S_un_b.s_b4,ntohs(sender.sin_port));
	 printf("Received '%s' [%i]\n",incomingbuf,datalen);

 } 
 else 
 {
	 err=WSAGetLastError();
	 Sleep(1);
 }
 printf("Valuer de a : %s \n",a);
 a++;

}

/*while(1) 
{
 sain_len=sizeof(sender);
 datalen=recvfrom(sock,incomingbuf,1023,0,(sockaddr *)&sender,&sain_len);
 printf("vache 3\n");

 if(datalen>0) {
	 
	 wsprintf(outgoingbuf,"%s|rnd=%i",incomingbuf,rand()&0xFF);
	 printf("Sent back: '%s' [%i]\n",outgoingbuf,strlen(outgoingbuf));
	 sendto(sock,outgoingbuf,strlen(outgoingbuf)+1,0,(sockaddr *)&sender,sizeof(sender));
 
	 
	 incomingbuf[datalen]=0;
	 printf("UDP Datagram from %i.%i.%i.%i:%i\n",sender.sin_addr.S_un.S_un_b.s_b1,sender.sin_addr.S_un.S_un_b.s_b2,sender.si
n_addr.S_un.S_un_b.s_b3,sender.sin_addr.S_un.S_un_b.s_b4,ntohs(sender.sin_port));
	 printf("Received '%s' [%i]\n",incomingbuf,datalen);

	 } else {
	 err=WSAGetLastError();
	 Sleep(1);
 }
}*/

closesocket(sock);

return 0;
}

Edited by yorel
Link to comment
Share on other sites

yorel: I think I begin to see your problem in doing this :\

Do you realize that the library is precompiled for general purpose use? You can just make a very small program (or base a program off of the "wifi_lib_test" source) and include the libraries.

 

-Stephen

Link to comment
Share on other sites

yorel: I think I begin to see your problem in doing this :\

Do you realize that the library is precompiled for general purpose use? You can just make a very small program (or base a program off of the "wifi_lib_test" source) and include the libraries.

 

-Stephen

 

 

Of course, i know but i had a lot of problems with that and with the makefile. I speak of them before yesterday. i try this solution ( only two files ) and it seems to work. I have only the two 'waranty' messages i told you today and a beautiful ".ds.gba" file. I remember that i had the first waranty message for the normal lib, too... so... If you want, i will send you my projects tomorrow. I will try something before.

 

If you have files for the pc side ( for example ) i like to have a copy.

Edited by yorel
Link to comment
Share on other sites

Well, good luck with that - I think it would have been a lot easier to just fix the makefile issues than to combine ALL the files into one - but hey, if it works, more power to you.

You asked about a pc-side copy - the udp test app linked (udp_test.c) is for unix, but I see you're working on a windows system. I've uploaded my PC-side source to http://akkit.org/dswifi/udp_test_win.cpp - this code should compile under windows with a sufficiently recent version of winsock and a decent compiler.

 

-Stephen

Edited by sgstair
Link to comment
Share on other sites

A stupid question about Notepad programmer :

 

How do you make a 'or' in a "while" or in a "if" ?

 

i tried |, ||, or, v ?

 

The 'help' don't help me... :)

 

 

Stephen : Have you an idea about my waranty message ? Sometimes, Notepad say nothing and make the file ds.gba.

 

Nb: i changed the main file.

Edited by yorel
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...