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(MODULE_NAME, 0x0000, 1, 1);
#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(int);
extern int sceUtilityUnloadNetModule(int);
#define RESOLVE_NAME "google.com"
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
sceKernelExitGame();
return 0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
int pspUserInetInit()
{
u32 retVal;
retVal = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000);
if (retVal != 0)
return retVal;
retVal = sceNetInetInit();
if (retVal != 0)
return retVal;
retVal = sceNetResolverInit();
if (retVal != 0)
return retVal;
retVal = sceNetApctlInit(0x1400, 0x42); // increased stack size
if (retVal != 0)
return retVal;
return 0;
}
void do_resolver(void)
{
int rid = -1;
char buf[1024];
struct in_addr addr;
char name[1024];
do
{
/* Create a resolver */
if(sceNetResolverCreate(&rid, buf, sizeof(buf)) < 0)
{
printf("Error creating resolver\n");
break;
}
printf("Created resolver %08x\n", rid);
/* Resolve a name to an ip address */
if(sceNetResolverStartNtoA(rid, RESOLVE_NAME, &addr, 2, 3) < 0)
{
printf("Error resolving %s\n", RESOLVE_NAME);
break;
}
printf("Resolved %s to %s\n", RESOLVE_NAME, inet_ntoa(addr));
/* Resolve the ip address to a name */
if(sceNetResolverStartAtoN(rid, &addr, name, sizeof(name), 2, 3) < 0)
{
printf("Error resolving ip to name\n");
break;
}
printf("Resolved ip to %s\n", name);
}
while(0);
if(rid >= 0)
{
sceNetResolverDelete(rid);
}
}
/* Connect to an access point */
int connect_to_apctl(int config)
{
int err;
int stateLast = -1;
/* Connect using the first profile */
err = sceNetApctlConnect(config);
if (err != 0)
{
printf(MODULE_NAME ": sceNetApctlConnect returns %08X\n", err);
return 0;
}
printf(MODULE_NAME ": Connecting...\n");
while (1)
{
int state;
err = sceNetApctlGetState(&state);
if (err != 0)
{
printf(MODULE_NAME ": sceNetApctlGetState returns $%x\n", err);
break;
}
if (state > stateLast)
{
printf(" connection state %d of 4\n", state);
stateLast = state;
}
if (state == 4)
break; // connected with static IP o_O
// wait a little before polling again
sceKernelDelayThread(50*1000); // 50ms
}
printf(MODULE_NAME ": Connected!\n");
if(err != 0)
{
return 0;
}
return 1;
}
int main(void)
{
int res;
pspDebugScreenInit();
SetupCallbacks();
// Load WIFI modules
res = sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
printf("sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON) returned %08X\n", res);
res = sceUtilityLoadNetModule(PSP_NET_MODULE_INET);
printf("sceUtilityLoadNetModule(PSP_NET_MODULE_INET) returned %08X\n", res);
if((res = pspUserInetInit()))
{
printf(MODULE_NAME ": Error, could not initialise the network %08X\n", res);
}
else
{
if(connect_to_apctl(1))
{
// connected, get my IPADDR and run test
char szMyIPAddr[32];
if (sceNetApctlGetInfo(8, szMyIPAddr) != 0)
strcpy(szMyIPAddr, "unknown IP address");
printf("IP address: %s\n", szMyIPAddr);
do_resolver();
}
}
sceKernelSleepThread();
return 0;
}
Code: Select all
.set noreorder
#include "pspstub.s"
STUB_START "sceUtility",0x40010000,0x00020005
STUB_FUNC 0x1579a159,sceUtilityLoadNetModule
STUB_FUNC 0x64d50c56,sceUtilityUnloadNetModule
STUB_END