Mighty Max Posted July 10, 2006 Share Posted July 10, 2006 (edited) Heya, i must be doing something wrong, and i can't seem to find my error. I hope someone might help me here Set up: I am using Devkit R18 still. DsWifi Libs are build from CVS i last updated at 18:00 today. The NDS got the ip 10.0.0.17, the gateway 10.0.0.2 and the SNM 255.0.0.0 The WiFi lib works great when i connect to a remote (pushing some data to a PHP script) but the incoming connection from my PC via telnet does not work, it times out & no accept() call succeeds. The code to check for a connection is periodical called (500ms) and only returns error 11 (try again later) The code: if (listensock==0) { listensock = socket(AF_INET,SOCK_STREAM,0); sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_addr.s_addr = 0; // any sa.sin_port = htons (8668); sa.sin_zero[0] = 0; sa.sin_zero[1] = 0; sa.sin_zero[2] = 0; sa.sin_zero[3] = 0; sa.sin_zero[4] = 0; sa.sin_zero[5] = 0; sa.sin_zero[6] = 0; sa.sin_zero[7] = 0; int blockmode = 1; ioctl(listensock,FIONBIO,&blockmode); if (bind(listensock,(sockaddr *)&sa,sizeof(sa))) { createLayer[2]->GetElementByName("clientlist")->AddTextToList("bind failed",0); }; listen(listensock,1); }; if (listensock) { sockaddr_in sa; sa.sin_family = 0; sa.sin_addr.s_addr = 0; sa.sin_port = 0; sa.sin_zero[0] = 0; sa.sin_zero[1] = 0; sa.sin_zero[2] = 0; sa.sin_zero[3] = 0; sa.sin_zero[4] = 0; sa.sin_zero[5] = 0; sa.sin_zero[6] = 0; sa.sin_zero[7] = 0; int dummy = sizeof(sa); errno = 0; int clientSock = accept(listensock,(sockaddr *)&sa,&dummy); if ((accept>0) && (errno==0)){ createLayer[2]->GetElementByName("clientlist")->AddTextToList("[Slot Taken]",0); } else { // allways returns 11, not accepting any incoming connection char errtext[6]; sprintf(errtext,"%d",errno); createLayer[0]->GetElementByName("maplist")->AddTextToList(errtext,0); }; }; The telnet output (german)C:\WINDOWS\system32>telnet 10.0.0.17 8668 Verbindungsaufbau zu 10.0.0.17...Es konnte keine Verbindung mit dem Host hergest ellt werden, auf Port 8668: Verbinden fehlgeschlagenWhich just means: Could not create connection to host on port 8668 Anyone got any suggestions? Or sees my error? Edited July 10, 2006 by Mighty Max Link to comment Share on other sites More sharing options...
sgstair Posted July 11, 2006 Share Posted July 11, 2006 Ok, firstly;since you've set the socket to nonblocking mode, all ordinarily blocking calls (including accept()) will return immediately, so you must wait in a loop if you want to use them; I'm assuming you are deallocating the socket right after it "fails to accept()", so of course the pc won't connect to it See the following:int newsock=0; if(listensock) { while(1) { newsock = accept(listensock,(sockaddr *)&sa,&dummy); if(newsock>0) break; if(errno!=EWOULDBLOCK) { // handle a more "fatal" error } } // shiny new socket in newsock, ready to be used. } Bug me if you need more infos. -Stephen Link to comment Share on other sites More sharing options...
Mighty Max Posted July 11, 2006 Author Share Posted July 11, 2006 (edited) Ok, firstly;since you've set the socket to nonblocking mode, all ordinarily blocking calls (including accept()) will return immediately, so you must wait in a loop if you want to use them; I'm assuming you are deallocating the socket right after it "fails to accept()", so of course the pc won't connect to it The socket is kept open between the accept tries. Only on leaving the menu the socket is shut down. The routine displays the "11" as errno in the corresponding menu elements each run through. I have just checked that this socket isn't reinitialized. It's only created once. I need the accept be non-blocking tho, as i allow the server to edit the gamesettings while waiting for the connections. Ok select() would be the next choice here and i'll try if that solves my problems. :edit: After setting listensock to blocking mode and using select() before using accept() gets me nowhere either. select() does not signal an incoming connection. If i just call accept() in blocking mode, it just never returns. Edited July 11, 2006 by Mighty Max Link to comment Share on other sites More sharing options...
sgstair Posted July 13, 2006 Share Posted July 13, 2006 first of all 11==EWOULDBLOCK - of course it's going to be 11.Secondly, see the code loop I posted - though I didn't explicitly make mention of it, it is quite possible to do other things than check the accept() in the while(1) or in a similar construct - hope this gives you an idea of how to do it.don't use select() for this, of course.... though accept() in blocking mode should eventually return if you connect to the socket. Certainly use the non-blocking mode, but try to use it similar to a way I demonstrated. -Stephen Link to comment Share on other sites More sharing options...
Mighty Max Posted July 13, 2006 Author Share Posted July 13, 2006 (edited) I know i can do other things in this loop too, but not return to the calling function which i need to. It is a timer based in the gui. staying in there means the gui stopping to respond to other events. And i do so. The calls are allready embedded in a big loop, that handles drawing of the gui & sending events to the seperate handler. One of them is the timer which does the above. Problem is it just never notice any incoming connection. It's not that i see a EWOULDBLOCK and stop asking, but there never returns anything else on continously accept() calls. Edited July 13, 2006 by Mighty Max Link to comment Share on other sites More sharing options...
Mighty Max Posted July 13, 2006 Author Share Posted July 13, 2006 (edited) I have noe stripped everything off, and just did the network code to accept an incoming connection. #include <nds.h> #include <malloc.h> #include <string.h> #include <nds/arm9/console.h> //basic print funcionality #include <stdio.h> extern "C" { #include <dswifi9.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <errno.h> void *sgIP_malloc(int size) { return malloc(size); } void sgIP_free(void * ptr) { free(ptr); } // sgIP_dbgprint only needed in debug version void sgIP_dbgprint(char * txt, ...) { } }; // wifi timer function, to update internals of sgIP void Timer_50ms(void) { Wifi_Timer(50); } // notification function to send fifo message to arm7 void arm9_synctoarm7() { // send fifo message REG_IPC_FIFO_TX=0x87654321; } // interrupt handler to receive fifo messages from arm7 void arm9_fifo() { // check incoming fifo messages u32 value = REG_IPC_FIFO_RX; if(value == 0x87654321) Wifi_Sync(); } void InitNetwork(void) { REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR; u32 Wifi_pass = Wifi_Init(WIFIINIT_OPTION_USELED); REG_IPC_FIFO_TX=0x12345678; REG_IPC_FIFO_TX=Wifi_pass; TIMER0_CR = 0; irqSet(IRQ_TIMER0, Timer_50ms); irqEnable(IRQ_TIMER0); irqSet(IRQ_FIFO_NOT_EMPTY, arm9_fifo); irqEnable(IRQ_FIFO_NOT_EMPTY); REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ; Wifi_SetSyncHandler(arm9_synctoarm7); TIMER0_DATA = -6553; // 6553.1 * 256 cycles = ~50ms; TIMER0_CR = 0x00C2; // enable, irq, 1/256 clock }; int main(void) { WAIT_CR = 0xE800; powerON(POWER_ALL_2D); powerOFF(POWER_SWAP_LCDS); irqInit(); irqEnable(IRQ_VBLANK); //enable vram and map it to the right places vramSetMainBanks( VRAM_A_MAIN_BG_0x6000000, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD ); //set the video mode videoSetMode( MODE_0_2D | DISPLAY_BG0_ACTIVE //turn on background 0 ); // black backdrop BG_PALETTE[0]=RGB15(0,0,0); BG0_CR = BG_MAP_BASE(31);//use bg0 for the text BG_PALETTE[255] = RGB15(31,31,31);//by default font rendered with color 255 //consoleInit() is a lot more flexible but this gets you up and running quick consoleInitDefault((u16*)SCREEN_BASE_BLOCK(31), (u16*)CHAR_BASE_BLOCK(0), 16); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); iprintf("Starting Wifi\n"); InitNetwork(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); Wifi_EnableWifi(); Wifi_ScanMode(); iprintf("Searching default AP\n"); // wait for "default" AP to show up in the known AP list bool connect=false; while (!connect) { int APs = Wifi_GetNumAP(); int i; iprintf("\x1b[2;0HAPs:\n"); for (i=0;i<APs;i++) { Wifi_AccessPoint wap; Wifi_GetAPData(i,&wap); iprintf(wap.ssid); iprintf(" -\n"); if (strcmp(wap.ssid,"default")==0) { // we are on local lan, only one net available no routin // we dont need no gateway & snm then therefor Wifi_SetIP(0x0A00000A,0,0,0,0); Wifi_ConnectAP(&wap,0,0,0); connect = true; }; }; }; iprintf("connecting to AP ... "); while (Wifi_AssocStatus()!=ASSOCSTATUS_ASSOCIATED) { }; iprintf("associated\n"); Wifi_SetIP(0x0A00000A,0,0,0,0); int listensock = 0; listensock = socket(AF_INET,SOCK_STREAM,0); sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_addr.s_addr = 0; // any sa.sin_port = htons (8668); sa.sin_zero[0] = 0; sa.sin_zero[1] = 0; sa.sin_zero[2] = 0; sa.sin_zero[3] = 0; sa.sin_zero[4] = 0; sa.sin_zero[5] = 0; sa.sin_zero[6] = 0; sa.sin_zero[7] = 0; int blockmode = 1; ioctl(listensock,FIONBIO,&blockmode); if (bind(listensock,(sockaddr *)&sa,sizeof(sa))) { // bind failed iprintf("bind failed\n"); }; if (listen(listensock,1)) { // bind failed iprintf("listen failed\n"); }; sa.sin_family = 0; sa.sin_addr.s_addr = 0; sa.sin_port = 0; sa.sin_zero[0] = 0; sa.sin_zero[1] = 0; sa.sin_zero[2] = 0; sa.sin_zero[3] = 0; sa.sin_zero[4] = 0; sa.sin_zero[5] = 0; sa.sin_zero[6] = 0; sa.sin_zero[7] = 0; int dummy = sizeof(sa); int newsock; iprintf("checking for incomin connections\n"); while (1) { errno = 0; int newsock = accept(listensock,(sockaddr *)&sa,&dummy); if(newsock>0) break; if(errno!=EWOULDBLOCK) { // handle a more "fatal" error iprintf("[FATAL]\n"); }; }; iprintf("Success!\n"); while (1); } The arm7 code is the same as in wifi_example1. No positive result either. A telnet to 10.0.0.10 port 8668 here (IP: 0x0A00000A) cant connect. The PC has ip 10.0.0.16, and is associated in to the same AP. Edited July 13, 2006 by Mighty Max Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now