Jump to content

yorel

Members+
  • Posts

    29
  • Joined

  • Last visited

Posts posted by yorel

  1. 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.

  2. It was not funny to copy all ( it takes me a lot of time ) but there were too many errors and "makefile and me", we are not good friend.

     

    Thanks a lot for the windows file, i try it tomorrow. :naughty:

  3. i'm actually on my home pc ( 350Mz, 98... ) I do a rebuild tomorrow (8h30 for me in belgium ^^ ) at the university.

     

    the warnings are all the same. I have two times the first one and five or six the second one. I have no more errors, so i have a beautiful "ds.gba" file.

     

    EDIT : So, here all the warnings message but i doubt that it will be very usefull.

     

    > "make"

    main.c

    c:/Projects/HelloWorld/source/main.c:809: warning: 'struct sockaddr' declared inside parameter list

    c:/Projects/HelloWorld/source/main.c:809: warning: its scope is only this definition or declaration, which is probably not what you want

    c:/Projects/HelloWorld/source/main.c:869: warning: 'struct sockaddr' declared inside parameter list

    c:/Projects/HelloWorld/source/main.c:922: warning: 'struct sockaddr' declared inside parameter list

    c:/Projects/HelloWorld/source/main.c: In function 'main':

    c:/Projects/HelloWorld/source/main.c:1082: warning: type-punning to incomplete type might break strict-aliasing rules

    c:/Projects/HelloWorld/source/main.c:1082: warning: passing argument 2 of 'bind' from incompatible pointer type

    c:/Projects/HelloWorld/source/main.c:1110: warning: type-punning to incomplete type might break strict-aliasing rules

    c:/Projects/HelloWorld/source/main.c:1110: warning: passing argument 5 of 'sendto' from incompatible pointer type

    c:/Projects/HelloWorld/source/main.c:1118: warning: type-punning to incomplete type might break strict-aliasing rules

    c:/Projects/HelloWorld/source/main.c:1118: warning: passing argument 5 of 'recvfrom' from incompatible pointer type

    c:/Projects/HelloWorld/source/main.c:1177: warning: type-punning to incomplete type might break strict-aliasing rules

    c:/Projects/HelloWorld/source/main.c:1177: warning: passing argument 5 of 'sendto' from incompatible pointer type

    c:/Projects/HelloWorld/source/main.c:1187: warning: type-punning to incomplete type might break strict-aliasing rules

    c:/Projects/HelloWorld/source/main.c:1187: warning: passing argument 5 of 'sendto' from incompatible pointer type

    arm-elf-g++ -g -mthumb-interwork -mno-fpu -L/c/devkitPro/PAlib/lib -specs=ds_arm9.specs main.o wifi_arm7.o -Lc:/devkitPro/PAlib//lib -lpa9 -L/c/devkitPro/libnds/lib -lnds9 -o build.elf

    Nintendo DS rom tool 1.24 - Oct 19 2005 20:26:11 by Rafael Vuijk (aka DarkFader)

    built... HelloWorld.ds.gba

    dsbuild 1.21 - Oct 19 2005

    using default loader

     

    > Process Exit Code: 0

    > Time Taken: 00:08

     

    The code is in the 'little demo game topic'. I send it to sgstair@akkit.org, too.

  4. 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.

  5. I have one more question :

     

    How can i do to delete these 'warning' message :

     

    1°)

     

    c:/.../main.c:809: warning: 'struct sockaddr' declared inside parameter list

    c:/.../main.c:809: warning: its scope is only this definition or declaration, which is probably not what you want

     

    int bind(int socket,const struct sockaddr * addr, int addr_len) {;};

     

    2°)

     

    c:/.../main.c:1187: warning: type-punning to incomplete type might break strict-aliasing rules

    c:/.../main.c:1187: warning: passing argument 5 of 'sendto' from incompatible pointer type

     

    int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len) {... };
    
    ...
    
    sendto(sock,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&sain,sizeof(sain));

  6. 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;
    }

  7. Indeed, i change the struct sockadress_in of file and these errors have vanished... for others... Bouh Bouh Bouh...

     

    i'm going to try an other solution. i have to do a conversation between a PC and a DS...

     

    Jl

  8. i have some problem with the file sgIP_sockets.c of the lib source. I'm trying to compile ( devkitpro ) but some errors with pointers appear...

     

    it is said :

    "In file included from c:/Projects/HelloWorld/source/main.c:8:

    C:\...\source\sgIP_sockets.c:81: warning: 'struct sockaddr_in' declared inside parameter list

    C:\...\source\sgIP_sockets.c:81: warning: its scope is only this definition or declaration, which is probably not what you want

    C:\...\source\sgIP_sockets.c: In function 'bind':

    C:\...\source\sgIP_sockets.c:89: error: dereferencing pointer to incomplete type

    C:\...\source\sgIP_sockets.c:90: error: dereferencing pointer to incomplete type"

     

    I have the same type of problem in function 'sendto' and recvfrom.

     

    I have tried some possibility but none seem to work...

     

    The code :

     

    int bind(int socket, struct sockaddr_in *addr, int addr_len) 
    {
    ...
    retval=sgIP_UDP_Bind((sgIP_Record_UDP *)socketlist[socket].conn_ptr,
    ((struct sockaddr_in *)addr)->sin_port, //PROB HERE
    ((struct sockaddr_in *)addr)->sin_addr.s_addr); // PROB HERE
    }

     

    The function sgi^p_UDP_Bind is :

     

    int sgIP_UDP_Bind(sgIP_Record_UDP * rec, int srcport, unsigned long srcip)

     

    I have tried a cast, &, *... i don't find. :P

  9. Ok, well. For 'wifi me' solution.

     

    You will need to have :

     

    A GBA flash card (50 euro)

    A PCI/PCMIA WIFI card (30 euro) like these ones on this site : http://ralink.rapla.net/

     

    I have :

    -Xport 2.0B ( Charmed labs )

    -Belkin F5D7000

     

    You dl and install all the files of this web site : http://users.belgacom.net/bn967347/download.htm

    Attention, put the file wifime in 'data' in wmb !!! ( read instructions )

     

    You put the file you want to test on your DS on the flash card with the software sold with your flash card. ! "ds.gba" file !

     

    You open a "DOS window", you search the file wmb.exe with the command "cd Name_of_the_directory_you_want_enter" and "dir". Then, you write "wmb.exe -data wifime".

     

    You go on your DS, you go in "download menu". Normaly, you will have the possibility to dl 'Firefly'. Click Yes... It dl the files to make the application on the flash card starts correctly. ( in other case, you will have two white screen on your ds... sometimes only one... )

     

    Ok ?

  10. 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.

  11. 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...

  12. 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.

  13. Hello,

     

    I have some stupid (?) questions. Could you answer me ?

     

    What are exactly the BaseBand and the RF chips ?

     

    What are spinlock and WIFI_AUTHLEVEL ? ( wifi_shared.h )

     

    I know what is SSID but BSSID ? RSSI ?

     

    I read somewhere that only the ARM7 was able to use Wifi's registers but i see the file wifi_arm9.h and wifi_arm9.c. So, i'm a little disappointed.

     

    There is a great function in wifi_arm7.c : Wifi_ProcessReceivedFrame. Is-it possible to have more explanation about the code ? what is for ?

  14. Surely. I told him that, already. :huh:

     

    For the moment, i'm studying for my exam's... they will be hard... :cry:

     

    So, I will take a look to all the projects with wifi after these. Thanks. :ph34r:

     

    I have chosen some PCI card but i will buy one after these, too.

  15. He is probably doing his degree project so often these things will be fairly difficult, and not necessarily the best way to do it.  It's probably just a test of his software coding and electrical engineering skills.

     

    I think it would be cool though, and useful, a security guard could keep an eye on the camera's while doing his rounds, or laying on a couch.

     

    I'm trying to succeed my fourth in engineer. This project has to prepare students to the big one...

  16. So, if that application is selected, i will have to find a trick...

     

    I will contact Natrium. He seems to be very nice.

     

    Nb : for the project, it's the Ds's wifi that i have to use.

  17. What kind of camera / auto / etc are you trying to remote control? are they native wifi devices? or is there some other thing controlling them and using wifi?

     

    It's certainly not impossible to do a remote control on DS at the moment, but it may not be easy.

     

    -Stephen

     

    I guess that there is some other thing controlling them and using wifi but actually, i ask myself if it is already defined. I must ask that to the person in charge of that.

×
×
  • Create New...