gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Wifi functions and classes

#168526 - hacker013 - Sat May 02, 2009 3:47 pm

hey,

I decided to switch to c++ and ported a basic wifi setup from c to c++ but now i'm getting some errors about pointers which point to functions.

Error message:
make -C arm7
make[1]: Entering directory `/c/UZProject/DSDEV/arm7'
wifi.cpp
arm-eabi-g++ -MMD -MP -MF /c/UZProject/DSDEV/arm7/build/wifi.d -g -Wall -O2 -mcp
u=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer -ffast-math -mthumb-interwork -I
/c/UZProject/DSDEV/arm7/include -I/c/UZProject/DSDEV/arm7/build -I/c/UZProject/DSDEV/arm7/source -I/c/UZProject/DSDEV/arm7/../dsdev_engine -I/c/devkitPro/libnds/include -I/c/UZProject/DSDEV/arm7/build -DARM7 -fno-rtti -fno-exceptions -fno-rtti -c /c/UZProject/DSDEV/arm7/../dsdev_engine/wifi.cpp -o wifi.o
c:/UZProject/DSDEV/arm7/../dsdev_engine/wifi.cpp: In constructor 'WIFI::WIFI()':

c:/UZProject/DSDEV/arm7/../dsdev_engine/wifi.cpp:38: error: argument of type 'void (WIFI::)()' does not match 'void (*)()'
c:/UZProject/DSDEV/arm7/../dsdev_engine/wifi.cpp: In member function 'void WIFI::arm7_fifo()':
c:/UZProject/DSDEV/arm7/../dsdev_engine/wifi.cpp:138: error: argument of type 'void (WIFI::)()' does not match 'void (*)()'
make[2]: *** [wifi.o] Error 1
make[1]: *** [build] Error 2
make[1]: Leaving directory `/c/UZProject/DSDEV/arm7'
make: *** [arm7/DSDEV.elf] Error 2

wifi.cpp
Code:
#include "wifi.h"

/* Basic WIFI Functions */

WIFI::WIFI() {
   #ifdef ARM9
   if(Wifi_CheckInit()) return;
   REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR; // enable & clear FIFO
   
   u32 Wifi_pass = Wifi_Init( WIFIINIT_OPTION_USELED );
      REG_IPC_FIFO_TX = 0x12345678;
      REG_IPC_FIFO_TX = Wifi_pass;
      
   *((volatile u16 *)0x0400010E) = 0; // disable timer3
      
   irqSet( IRQ_TIMER3, wifi_timer_50ms ); // setup timer IRQ
   irqEnable( IRQ_TIMER3 );
      irqSet( IRQ_FIFO_NOT_EMPTY, arm9_fifo ); // setup fifo IRQ
      irqEnable( IRQ_FIFO_NOT_EMPTY );
      
      REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ; // enable FIFO IRQ
      
      Wifi_SetSyncHandler( arm9_synctoarm7 ); // tell wifi lib to use our handler to notify arm7

   // set timer3
   *((volatile u16 *)0x0400010C) = -6553; // 6553.1 * 256 cycles = ~50ms;
   *((volatile u16 *)0x0400010E) = 0x00C2; // enable, irq, 1/256 clock
   
   while( !Wifi_CheckInit() ) { // wait for arm7 to be initted successfully
      swiWaitForVBlank();
   }
   #endif
   #ifdef ARM7
   irqSet( IRQ_WIFI, Wifi_Interrupt );
   irqEnable( IRQ_WIFI );

   //set up FIFO for wifi init and whatnot
   irqSet( IRQ_FIFO_NOT_EMPTY, arm7_fifo );
   irqEnable( IRQ_FIFO_NOT_EMPTY );
   REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR | IPC_FIFO_RECV_IRQ;
   #endif
};

WIFI::~WIFI() {
   #ifdef ARM9
   if( Wifi_CheckInit() )
   {
      Wifi_DisconnectAP();
      Wifi_DisableWifi();
      //just wait a while to give ARM7 a chance to finish off the wifi
      for( int j = 0; j < 30; ++j ) swiWaitForVBlank();
   }
   #endif
};

#ifdef ARM9
bool WIFI::auto_connect() {
   Wifi_AutoConnect();
   while( true ) {
      int i = Wifi_AssocStatus();
      if( i == ASSOCSTATUS_ASSOCIATED ) {
         return true;
      }
      if( i == ASSOCSTATUS_CANNOTCONNECT ) {
         return false;
      }
   }
};

/* Socket Wrapper */

int WIFI::send( int socket, const char * data ) {
   return send( socket, data, strlen( data ), 0 );
}

bool WIFI::socket_create( int * sock, char * host, int port, bool blocking ) {
   struct sockaddr_in servaddr;   
   if( ( *sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
      return false;
   }

   memset( &servaddr, 0, sizeof( servaddr ) );
   servaddr.sin_family = AF_INET;
   servaddr.sin_port = htons( port );

   if( !inet_aton( host, &servaddr.sin_addr ) ) {
      servaddr.sin_addr.s_addr = *(unsigned long *) gethostbyname( host )->h_addr_list[0];
   }

   if( blocking ) {
      if( !connect( *sock, (struct sockaddr *) &servaddr, sizeof( servaddr ) ) ) {
         return true;
      }
   } else {
      if( !connect( *sock, (struct sockaddr *) &servaddr, sizeof( servaddr ) ) ) {
         int i = 1;
         ioctl( *sock, FIONBIO, &i );
         return true;
      }
   }
     
   return false;
}

/* Intern WIFI Functions */

//wifi timer function, to update internals of sgIP
void WIFI::wifi_timer_50ms() {
   Wifi_Timer( 50 );
}

//notification function to send fifo message to arm7
void WIFI::arm9_synctoarm7() {
   REG_IPC_FIFO_TX=0x87654321;
}

//interrupt handler to receive fifo messages from arm7
void WIFI::arm9_fifo() {
   if( REG_IPC_FIFO_RX == 0x87654321 ) Wifi_Sync();
}

#endif
#ifdef ARM7
void WIFI::arm7_synctoarm9() {
   REG_IPC_FIFO_TX = 0x87654321;
}

//interrupt handler to allow incoming notifications from arm9, including wifi init request
void WIFI::arm7_fifo() {
   u32 msg = REG_IPC_FIFO_RX;

   if( msg == 0x12345678 ) {
      irqDisable( IRQ_FIFO_NOT_EMPTY );
      while( REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY ) {
         swiWaitForVBlank();
      }
      Wifi_Init( REG_IPC_FIFO_RX );
      Wifi_SetSyncHandler( arm7_synctoarm9 ); //allow wifi lib to notify arm9
      irqEnable( IRQ_FIFO_NOT_EMPTY );
   } else if( msg == 0x87654321 ) {
      Wifi_Sync();
   }
}
#endif


What i'm doing wrong and how can I fix this?
_________________
Website / Blog

Let the nds be with you.

#168528 - elhobbs - Sat May 02, 2009 4:05 pm

try declaring arm7_synctoarm9 as static. this will remove the hidden this pointer argument. it will also make it so you can not access any of the class members, but it should not be an issue for this function. you may still need a cast, but making it static will make it safe to cast.

#168589 - hacker013 - Fri May 08, 2009 12:20 pm

you mean moving it outside the class and declare it static of you mean declare it static inside the class? I tried the second and it didn't work.
_________________
Website / Blog

Let the nds be with you.

#168590 - Dwedit - Fri May 08, 2009 12:52 pm

It wants a void function which takes no arguments. All member functions of any class take in a hidden argument, the *this pointer.

Make the function named "arm9_synctoarm7" a static function. That way, it's part of the class, but is not part of an object. It has no access to any members of the class. A static function inside a class is just a normal function.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#168591 - elhobbs - Fri May 08, 2009 1:57 pm

like this
Code:
#include <nds.h>
#include <dswifi9.h>


class WIFI
{
   public:
      WIFI() {};
      static void arm7_synctoarm9() {
         REG_IPC_FIFO_TX = 0x87654321;
      }
};



//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
   Wifi_SetSyncHandler( WIFI::arm7_synctoarm9 ); //allow wifi lib to notify arm9
   
   while(1) {
      swiWaitForVBlank();
   }

}

also, make sure you are linking the dswifi9 library. add "-ldswifi9" to LIBS in your makefile.

any reason you are not just using the wifi startup code that is provided by the latest libnds/dswifi release?
Code:
   if(!Wifi_InitDefault(WFC_CONNECT)) {
      iprintf("Failed to connect!");
   }
your solution may have issues with the fifo system now used by libnds

#168593 - hacker013 - Fri May 08, 2009 4:15 pm

Because I want full control
_________________
Website / Blog

Let the nds be with you.

#168595 - elhobbs - Fri May 08, 2009 7:43 pm

unless you are using a fairly old version of libnds\dswifi then you are going to run into issues with the fifosystem. well, good luck with that...

#168596 - hacker013 - Fri May 08, 2009 7:51 pm

Can you suggest me then a better way to handle the fifo ?
_________________
Website / Blog

Let the nds be with you.