Usermode WiFi with devhook (with WPA enabled :D)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
mbf
Posts: 55
Joined: Fri Aug 18, 2006 7:43 pm

Usermode WiFi with devhook (with WPA enabled :D)

Post by mbf »

Looks like a few people including myself have been looking for a way to have WIFI with WPA enabled in their homebrew.

The main problem is that FW 1.5 does not provide WPA. The way to go if you don't want to upgrade and use eLoader is devhook to run 2.71. Alright, Devhook allows you to run homebrew since v.45 but only in user mode. The next problem is that the commonly used method to access WIFI is via kernel mode (to load the modules), unusable with Devhook right now.

Thanks to Chris Swindle and Fanjita, there's a way to load the modules from user mode: http://forums.ps2dev.org/viewtopic.php?t=5423

I hadn't seen any sample code to use this, so I thought I would give it a stab (I'm dying to use PMP VLC and PSP Radio over my WPA protected AP ;))... And it works! Here's a sample based on the resolver sample from the PSP SDK.

Important point: you can't use pspSdkInetInit() to initialize the Network modules since it calls sceNetApctlInit() with a stack size of 0x1000 by default. Just make your own and call sceNetApctlInit() with a stack size of at least 0x1400.

To compile the code below, just use the homebrew2xx sample from the Devhook SDK as a template, and add wifi_user.o to the OBJS line in the Makefile.

Enjoy :)

I'm going to recompile PSP Radio now ;)

Main.c:

Code: Select all

/*
	FW2.xx+devhook WIFI Sample
*/
#include <pspkernel.h>
#include <pspctrl.h>
#include <pspdebug.h>
#include <pspdisplay.h>
#include <psptypes.h>
#include <pspiofilemgr.h>
#include <pspnet.h>
#include <pspnet_inet.h>
#include <pspnet_apctl.h>
#include <pspnet_resolver.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/unistd.h>

#define MODULE_NAME "wifi_user_dh"

PSP_MODULE_INFO&#40;MODULE_NAME, 0x0000, 1, 1&#41;;

#define printf pspDebugScreenPrintf

#define PSP_NET_MODULE_COMMON 1
#define PSP_NET_MODULE_ADHOC 2
#define PSP_NET_MODULE_INET 3
#define PSP_NET MODULE_PARSEURI 4
#define PSP_NET_MODULE_PARSEHTTP 5
#define PSP_NET_MODULE_HTTP 6
#define PSP_NET_MODULE_SSL 7

extern int sceUtilityLoadNetModule&#40;int&#41;;
extern int sceUtilityUnloadNetModule&#40;int&#41;;

#define RESOLVE_NAME "google.com"

/* Exit callback */
int exit_callback&#40;int arg1, int arg2, void *common&#41;
&#123;
	sceKernelExitGame&#40;&#41;;

	return 0;
&#125;

/* Callback thread */
int CallbackThread&#40;SceSize args, void *argp&#41;
&#123;
	int cbid;

	cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;

	sceKernelSleepThreadCB&#40;&#41;;

	return 0;
&#125;

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks&#40;void&#41;
&#123;
	int thid = 0;

	thid = sceKernelCreateThread&#40;"update_thread", CallbackThread, 0x11, 0xFA0, 0, 0&#41;;
	if&#40;thid >= 0&#41;
	&#123;
		sceKernelStartThread&#40;thid, 0, 0&#41;;
	&#125;

	return thid;
&#125;

int pspUserInetInit&#40;&#41;
&#123;
	u32 retVal;

	retVal = sceNetInit&#40;0x20000, 0x20, 0x1000, 0x20, 0x1000&#41;;
	if &#40;retVal != 0&#41;
		return retVal;

	retVal = sceNetInetInit&#40;&#41;;
	if &#40;retVal != 0&#41;
		return retVal;

	retVal = sceNetResolverInit&#40;&#41;;
	if &#40;retVal != 0&#41;
		return retVal;
	
	retVal = sceNetApctlInit&#40;0x1400, 0x42&#41;; // increased stack size
	if &#40;retVal != 0&#41;
		return retVal;

	return 0;
&#125;

void do_resolver&#40;void&#41;
&#123;
	int rid = -1;
	char buf&#91;1024&#93;;
	struct in_addr addr;
	char name&#91;1024&#93;;

	do
	&#123;
		/* Create a resolver */
		if&#40;sceNetResolverCreate&#40;&rid, buf, sizeof&#40;buf&#41;&#41; < 0&#41;
		&#123;
			printf&#40;"Error creating resolver\n"&#41;;
			break;
		&#125;

		printf&#40;"Created resolver %08x\n", rid&#41;;

		/* Resolve a name to an ip address */
		if&#40;sceNetResolverStartNtoA&#40;rid, RESOLVE_NAME, &addr, 2, 3&#41; < 0&#41;
		&#123;
			printf&#40;"Error resolving %s\n", RESOLVE_NAME&#41;;
			break;
		&#125;

		printf&#40;"Resolved %s to %s\n", RESOLVE_NAME, inet_ntoa&#40;addr&#41;&#41;;

		/* Resolve the ip address to a name */
		if&#40;sceNetResolverStartAtoN&#40;rid, &addr, name, sizeof&#40;name&#41;, 2, 3&#41; < 0&#41;
		&#123;
			printf&#40;"Error resolving ip to name\n"&#41;;
			break;
		&#125;

		printf&#40;"Resolved ip to %s\n", name&#41;;
	&#125;
	while&#40;0&#41;;

	if&#40;rid >= 0&#41;
	&#123;
		sceNetResolverDelete&#40;rid&#41;;
	&#125;
&#125;

/* Connect to an access point */
int connect_to_apctl&#40;int config&#41;
&#123;
	int err;
	int stateLast = -1;

	/* Connect using the first profile */
	err = sceNetApctlConnect&#40;config&#41;;
	if &#40;err != 0&#41;
	&#123;
		printf&#40;MODULE_NAME "&#58; sceNetApctlConnect returns %08X\n", err&#41;;
		return 0;
	&#125;

	printf&#40;MODULE_NAME "&#58; Connecting...\n"&#41;;
	while &#40;1&#41;
	&#123;
		int state;
		err = sceNetApctlGetState&#40;&state&#41;;
		if &#40;err != 0&#41;
		&#123;
			printf&#40;MODULE_NAME "&#58; sceNetApctlGetState returns $%x\n", err&#41;;
			break;
		&#125;
		if &#40;state > stateLast&#41;
		&#123;
			printf&#40;"  connection state %d of 4\n", state&#41;;
			stateLast = state;
		&#125;
		if &#40;state == 4&#41;
			break;  // connected with static IP o_O

		// wait a little before polling again
		sceKernelDelayThread&#40;50*1000&#41;; // 50ms
	&#125;
	printf&#40;MODULE_NAME "&#58; Connected!\n"&#41;;

	if&#40;err != 0&#41;
	&#123;
		return 0;
	&#125;

	return 1;
&#125;

int main&#40;void&#41;
&#123;
	int res;
	pspDebugScreenInit&#40;&#41;;
	SetupCallbacks&#40;&#41;;

	// Load WIFI modules
	res = sceUtilityLoadNetModule&#40;PSP_NET_MODULE_COMMON&#41;;
	printf&#40;"sceUtilityLoadNetModule&#40;PSP_NET_MODULE_COMMON&#41; returned %08X\n", res&#41;;
	res = sceUtilityLoadNetModule&#40;PSP_NET_MODULE_INET&#41;;
	printf&#40;"sceUtilityLoadNetModule&#40;PSP_NET_MODULE_INET&#41; returned %08X\n", res&#41;;

	if&#40;&#40;res = pspUserInetInit&#40;&#41;&#41;&#41;
	&#123;
		printf&#40;MODULE_NAME "&#58; Error, could not initialise the network %08X\n", res&#41;;
	&#125;
	else
	&#123;
		if&#40;connect_to_apctl&#40;1&#41;&#41;
		&#123;
			// connected, get my IPADDR and run test
			char szMyIPAddr&#91;32&#93;;
			if &#40;sceNetApctlGetInfo&#40;8, szMyIPAddr&#41; != 0&#41;
				strcpy&#40;szMyIPAddr, "unknown IP address"&#41;;
			printf&#40;"IP address&#58; %s\n", szMyIPAddr&#41;;
			do_resolver&#40;&#41;;
		&#125;
	&#125;

    sceKernelSleepThread&#40;&#41;;
	return 0;
&#125;
wifi_user.S:

Code: Select all

    .set noreorder

#include "pspstub.s"

    STUB_START   "sceUtility",0x40010000,0x00020005
    STUB_FUNC   0x1579a159,sceUtilityLoadNetModule
    STUB_FUNC   0x64d50c56,sceUtilityUnloadNetModule
    STUB_END
Last edited by mbf on Mon Aug 21, 2006 11:22 pm, edited 1 time in total.
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

very nice :)
...now i can finally get a WPA router
without the need for firmware updates

for testing purposes of course ;)
10011011 00101010 11010111 10001001 10111010
TheBuzzer
Posts: 49
Joined: Mon Feb 06, 2006 10:02 am

Post by TheBuzzer »

interesting. the devhook vshex addons got to be in kernal mode only and the homebrews got to be in usermode only. quite funny.
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

above post is irrelevant
10011011 00101010 11010111 10001001 10111010
mbf
Posts: 55
Joined: Fri Aug 18, 2006 7:43 pm

Post by mbf »

Corrected the STUB_START (there are only 2 imports, not 34). Quick question: Would it confluict with other imports for sceUtility (imports from the PSPSDK)?

Ok, my first tests with PSP Radio are a half success: I got it to compile and connect to the network. However, the background images don't display, the text rendering is weird and it crashes during playback (even from the MS). It also crashes when parsing the SHOUTcast XML (seems to be a bug in PSP Radio), the weird thing being that it doesn't crash in 1.5. WIP....

Porting from 1.5 to DH+2.71 is harder than one would have thought :-/

Regarding kernel mode.... can anyone think of a way to gain kernel mode access under DEVHOOK, or at least run apps in a PSPLINK-like environment for easier debugging (DH allows you to load almost whatever modules you like... not sure if those are usable from userland though)
danzel
Posts: 182
Joined: Fri Nov 04, 2005 11:03 pm

Post by danzel »

What about the bug in 2.5/2.6 that allowed us to get kernel access for downgrading?

Not sure if anyone has tryed it on 2.7/2.71 yet, it was discovered after they were released so it may still be around.
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Re: Usermode WiFi with devhook (with WPA enabled :D)

Post by jimparis »

mbf wrote:Important point: you can't use pspSdkInetInit() to initialize the Network modules since it calls sceNetApctlInit() with a stack size of 0x1000 by default. Just make your own and call sceNetApctlInit() with a stack size of at least 0x1400.
I increased the stack to 0x1400 in pspSdkInetInit in rev. 1992.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

TheBuzzer wrote:interesting. the devhook vshex addons got to be in kernal mode only and the homebrews got to be in usermode only. quite funny.
There are reasons for that, it's not done on purpose.
Hint: a lot of things changed in 2.00+
mbf
Posts: 55
Joined: Fri Aug 18, 2006 7:43 pm

Post by mbf »

danzel wrote:What about the bug in 2.5/2.6 that allowed us to get kernel access for downgrading?

Not sure if anyone has tryed it on 2.7/2.71 yet, it was discovered after they were released so it may still be around.
I'd rather go the devhook way... EBOOTS for devhook have to be "special" PRXes and are loaded by devhook from plain2x.prx (as far as I understand from the little English docs). My main goal for that would mainly be using PSPLINK ;)
jimparis wrote:I increased the stack to 0x1400 in pspSdkInetInit in rev. 1992
Thanks. Looks like I updated right before that :( Have sceUtilityLoadNetModule() and sceUtilityUnloadNetModule() been added too?

I've finally managed to get it working. The problem was that the default heap size is 16KB under devhook... Since my built is based on the Static build, it was not initialized properly. PSP Radio with WPA WIFI rocks :) I'll submit the diff to Raf tomorrow.
Last edited by mbf on Wed Aug 23, 2006 12:00 am, edited 2 times in total.
Fanjita
Posts: 217
Joined: Wed Sep 28, 2005 9:31 am

Post by Fanjita »

danzel wrote:What about the bug in 2.5/2.6 that allowed us to get kernel access for downgrading?

Not sure if anyone has tryed it on 2.7/2.71 yet, it was discovered after they were released so it may still be around.
It's still present in 2.7 and 2.71.
Most likely it's the reason that 2.8 was released.
Got a v2.0-v2.80 firmware PSP? Download the eLoader here to run homebrew on it!
The PSP Homebrew Database needs you!
mbf
Posts: 55
Joined: Fri Aug 18, 2006 7:43 pm

Post by mbf »

mbf wrote:
jimparis wrote:I increased the stack to 0x1400 in pspSdkInetInit in rev. 1992
Thanks. Looks like I updated right before that :( Have sceUtilityLoadNetModule() and sceUtilityUnloadNetModule() been added too?
Stupid me, you've submitted the changes after my post. Thanks again Jim. I'll post a diff for sceUtility later on.
mbf
Posts: 55
Joined: Fri Aug 18, 2006 7:43 pm

Post by mbf »

Patch for PSP Radio sent to raf (@sourceforege.net) hope he'll get it :)

EDIT: Source+binaries available here: http://www.megaupload.com/?d=KE3YSLI2
lusid
Posts: 3
Joined: Wed Aug 23, 2006 8:08 am

Post by lusid »

Thank you.

There is a repeatable crash when using the home button to exit. The normal exit method works fine.
mbf
Posts: 55
Joined: Fri Aug 18, 2006 7:43 pm

Post by mbf »

Yes, it tends to crash when exitting via the home button. But I don't know if it comes from the DH build or if it's the same with the 1.5 and eLoader versions.
EDIT: note that the only code change I made was to load the network modules in user mode. The rest was just compile and link according to DH's requirements.
lusid
Posts: 3
Joined: Wed Aug 23, 2006 8:08 am

Post by lusid »

1.5 Doesn't crash there. I don't have an eLoader test environment at the moment, but I seem to recall the home button not working at all under eLoader so the that code may have never needed to execute under a static build before.

Anyway, thanks again for the build. I wish more of the userland eboots were ported to devhook.
zaide
Posts: 1
Joined: Sat Aug 26, 2006 8:49 am

Post by zaide »

mbf can you post your eboot.pbp? for dummies peoples who don't want to install the compilator on their linux juste for that ;)
mbf
Posts: 55
Joined: Fri Aug 18, 2006 7:43 pm

Post by mbf »

See one of the posts above.... Raf also released a new version of PSP Radio with a devhook version here (take PSPRadio0.38.12_DH.zip). Please use the PSP Radio forums if you need any help with that.
Post Reply