DS as server

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

DS as server

Post by Derrik » Fri Apr 18, 2014 10:52 pm

I have been having trouble with the reliability of dswifi. For example, I have some code that does this:

1. Connect to access point with Wifi_InitDefault(WFC_CONNECT),
2. Setup UDP socket with sock = socket(AF_INET,SOCK_DGRAM,0),
3. Set family to AF_INET,
4. Set port to htons(8888),
5. Set address to INADDR_ANY,
6. Bind socket with this information via bind(sock, (struct sockaddr *)&sain, sizeof(sain)),
7. Enable non-blocking mode with int i = 1; ioctl(sock, FIONBIO, &i),
8. Change IP to inet_addr("192.168.1.3"),
9. Send connection request with sendto(sock, outBuf, length, 0, (struct sockaddr *)&saout, sizeof(saout)),
10. Continuously receive connection request with recvfrom(sock, rcvBuf, 6, 0, (struct sockaddr *)&sain, &rcvLen),

This code works 2 / 3 of the times I try it on my DS Lite and is unreliable but that is not the issue.

The problem is that this model is setup as the PC (192.168.1.3) being the server and the DS being the client.

What I actually want to do is have the other way around, so the DS is the server and accepts requests from any PC (clients).

However, when I remove steps 8 or 9, the DS will not receive any data from the PC even if nothing else has changed.

So the DS has to specify the IP that it wants to receive data from, and then send a request to that IP first before it will accept any data.

Why is this?

WinterMute
Site Admin
Posts: 1862
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: DS as server

Post by WinterMute » Sat Apr 19, 2014 2:46 am

Derrik wrote:
So the DS has to specify the IP that it wants to receive data from, and then send a request to that IP first before it will accept any data.

Why is this?
It doesn't. Here's some code I used which worked when I last checked :-

edit: at least it did before I edited out irrelevant parts badly ;) Code updated slightly

Code: Select all

#include <nds.h>
#include <dswifi9.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>

//---------------------------------------------------------------------------------
void waitButtonA() {
//---------------------------------------------------------------------------------
	while(1) {
		scanKeys();
		swiWaitForVBlank();
		if (keysDown() & KEY_A) break;
	}
}

//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------

	consoleDemoInit();

	printf("connecting ...\n");

	if(!Wifi_InitDefault(WFC_CONNECT)) {
		printf(" Failed to connect!\n");
		waitButtonA();
		return 0;
	}

	struct in_addr ip, gateway, mask, dns1, dns2;

	ip = Wifi_GetIPInfo(&gateway, &mask, &dns1, &dns2);
	printf("Connected: %s\n",inet_ntoa(ip));
	
	int sock_udp = socket(PF_INET, SOCK_DGRAM, 0);
	struct sockaddr_in sa_udp, sa_udp_remote;

	sa_udp.sin_family = AF_INET;
	sa_udp.sin_addr.s_addr = INADDR_ANY;
	sa_udp.sin_port = htons(17491);

	if(bind(sock_udp, (struct sockaddr*) &sa_udp, sizeof(sa_udp)) < 0) {
		printf(" UDP socket error\n");
		waitButtonA();
		return 0;
	}

	int i=1;

	ioctl(sock_udp,FIONBIO,&i);

	int dummy;
	char recvbuf[256];

	while(1) {
		int len = recvfrom(sock_udp, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*) &sa_udp_remote, &dummy);

		if (len!=-1) {
			if (strncmp(recvbuf,"ping",strlen("ping")) == 0) {
				int respSock = socket(PF_INET, SOCK_DGRAM, 0);
				sa_udp_remote.sin_family=AF_INET;
				sa_udp_remote.sin_port=htons(17491);
				sendto(respSock, "pong", strlen("pong"), 0, (struct sockaddr*) &sa_udp_remote,sizeof(sa_udp_remote));
			}
		}

		swiWaitForVBlank();
		scanKeys();
		if (keysDown() & KEY_START) break;
	}
	return 0;
}
Help keep devkitPro toolchains free, Donate today

Personal Blog

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: DS as server

Post by Derrik » Sat Apr 19, 2014 8:43 am

Cheers for the quick response, I'll test this code ASAP.

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: DS as server

Post by Derrik » Sat Apr 19, 2014 8:52 am

arm9.c:53:11: error: 'sock_tcp' undeclared (first use in this function)
arm9.c:35:4: warning: implicit declaration of function 'kprintf'

This is what I get when compiling at the moment, though I haven't updated since 2008 - 1 moment please!

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: DS as server

Post by Derrik » Sat Apr 19, 2014 8:55 am

Same errors on the latest version, though I fixed it with:

kprintf -> printf
sock_tcp -> sock_udp

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: DS as server

Post by Derrik » Sat Apr 19, 2014 9:04 am

I inserted the following line after if (len!=-1) {
printf("got\n");

Just so I can see what's going on.

My DS Lite says:

connecting
Connected: 192.168.1.3

On my PC, I am using packet sender to send to 192.168.1.3 with port 17491 sending ASCII of dsboot with UDP selected. My DS goes not ever say "got".

I assure that the setup worked yesterday when I was sending to the PC and then waiting for a response. My devkitARM, libnds, etc have all just been updated through devkitPro Updater tool.

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: DS as server

Post by Derrik » Sat Apr 19, 2014 10:01 am

Sorry for so many posts in a row, but I tried your application dslink, and got these outputs:

DS:

dslink ... connecting ...
Connected: 192.168.1.3

PC:
dslink.exe -a 192.168.1.3 test.nds
Connection to 192.168.1.3 failed

So now I'm sure that this is not my code, this is probably a bug in dswifi.

I am testing with a DS Lite running latest version of flashme.

There is a workaround to this bug, if your DS specifies the PC's IP address and then sends arbitrary data to the PC first, then it will be able to receive data from PC afterwards.

But for some reason, the DS refuses to act as a server.

I have 7 different DSes including originals, lites, and 3DSes so I'll test this application with some other DSes and see if it's maybe a problem with my router, flashme or broken wifi module on the DS I am currently using to test.

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: DS as server

Post by Derrik » Sat Apr 19, 2014 10:12 am

I've tried several DSes, with several flashcards, none of which are working. So I don't know what's going on, whether it's my router or what. I have yet to try with TCP sockets though, so I only know for sure that UDP is affected by this.

I noticed that you uploaded the source to the client (PC) of dslink here:

https://github.com/WinterMute/dslink-host

But never uploaded the server (DS) source; please could you send that to me?

WinterMute
Site Admin
Posts: 1862
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: DS as server

Post by WinterMute » Sat Apr 19, 2014 12:26 pm

Derrik wrote:arm9.c:53:11: error: 'sock_tcp' undeclared (first use in this function)
arm9.c:35:4: warning: implicit declaration of function 'kprintf'

This is what I get when compiling at the moment, though I haven't updated since 2008 - 1 moment please!
I badly edited out some irrelevant parts - the listen was for a tcp socket I removed from the code. kprintf was a simple printf implementation in the project I nicked the code from.
Derrik wrote:I inserted the following line after if (len!=-1) {
printf("got\n");

Just so I can see what's going on.

My DS Lite says:

connecting
Connected: 192.168.1.3

On my PC, I am using packet sender to send to 192.168.1.3 with port 17491 sending ASCII of dsboot with UDP selected. My DS goes not ever say "got".
Again, I messed up the code I pasted a bit. I changed the string used to get the length but not the string getting compared ... oops.

I'll try & build this a bit later & test it locally but I've updated the original code I posted.
Help keep devkitPro toolchains free, Donate today

Personal Blog

WinterMute
Site Admin
Posts: 1862
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: DS as server

Post by WinterMute » Sat Apr 19, 2014 12:37 pm

Derrik wrote:Sorry for so many posts in a row, but I tried your application dslink, and got these outputs:

DS:

dslink ... connecting ...
Connected: 192.168.1.3

PC:
dslink.exe -a 192.168.1.3 test.nds
Connection to 192.168.1.3 failed

So now I'm sure that this is not my code, this is probably a bug in dswifi.
dslink uses a tcp connection and the application works for others quite reliably so I'm pretty sure that there's something odd going on with your network.

What happens if you don't specify the address of the DS?
There is a workaround to this bug, if your DS specifies the PC's IP address and then sends arbitrary data to the PC first, then it will be able to receive data from PC afterwards.
Do you have some kind of firewall software on the PC?

I'm clutching at straws here a bit but it does sound like something is blocking packets going to the DS until a packet is received from the DS.
Help keep devkitPro toolchains free, Donate today

Personal Blog

Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests