 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
mypspdev
Joined: 11 Jul 2007 Posts: 178
|
Posted: Thu Sep 27, 2007 7:17 am Post subject: pspdev/sdk/net/simple_prx porting from 1.50 to 3.xx |
|
|
exports.exp as it is without changes required
New Makefile:
| Code: | TARGET = netsample
OBJS = main.o
PRX_EXPORTS=exports.exp
BUILD_PRX=1
USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1
INCDIR =
CFLAGS = -O0 -G0 -Wall -g
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LDFLAGS = -mno-crt0 -nostartfiles
LIBDIR =
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak |
New main.c for prx:
| Code: | #include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.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 <errno.h>
#define MODULE_NAME "NetSample"
#define HELLO_MSG "Hello there. Type away.\r\n"
PSP_MODULE_INFO(MODULE_NAME, 0x1006, 1, 1);
PSP_MAIN_THREAD_ATTR(0);
PSP_MAIN_THREAD_NAME("NetSample");
#define SERVER_PORT 23
int make_socket(uint16_t port)
{
int sock;
int ret;
struct sockaddr_in name;
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
return -1;
}
name.sin_family = AF_INET;
name.sin_port = htons(port);
name.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(sock, (struct sockaddr *) &name, sizeof(name));
if(ret < 0)
{
return -1;
}
return sock;
}
/* Start a simple tcp echo server */
void start_server(const char *szIpAddr)
{
int ret;
int sock;
int new = -1;
struct sockaddr_in client;
size_t size;
int readbytes;
char data[1024];
fd_set set;
fd_set setsave;
/* Create a socket for listening */
sock = make_socket(SERVER_PORT);
if(sock < 0)
{
printf("Error creating server socket\n");
return;
}
ret = listen(sock, 1);
if(ret < 0)
{
printf("Error calling listen\n");
return;
}
printf("Listening for connections ip %s port %d\n", szIpAddr, SERVER_PORT);
FD_ZERO(&set);
FD_SET(sock, &set);
setsave = set;
while(1)
{
int i;
set = setsave;
if(select(FD_SETSIZE, &set, NULL, NULL, NULL) < 0)
{
printf("select error\n");
return;
}
for(i = 0; i < FD_SETSIZE; i++)
{
if(FD_ISSET(i, &set))
{
int val = i;
if(val == sock)
{
new = accept(sock, (struct sockaddr *) &client, &size);
if(new < 0)
{
printf("Error in accept %s\n", strerror(errno));
close(sock);
return;
}
printf("New connection %d from %s:%d\n", val,
inet_ntoa(client.sin_addr),
ntohs(client.sin_port));
write(new, HELLO_MSG, strlen(HELLO_MSG));
FD_SET(new, &setsave);
}
else
{
readbytes = read(val, data, sizeof(data));
if(readbytes <= 0)
{
printf("Socket %d closed\n", val);
FD_CLR(val, &setsave);
close(val);
}
else
{
write(val, data, readbytes);
printf("%.*s", readbytes, data);
}
}
}
}
}
close(sock);
}
/* 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
// wait a little before polling again
sceKernelDelayThread(50*1000); // 50ms
}
printf(MODULE_NAME ": Connected!\n");
if(err != 0)
{
return 0;
}
return 1;
}
/* Simple thread */
int main(int argc, char **argv)
{
int err;
do
{
if((err = pspSdkInetInit()))
{
printf(MODULE_NAME ": Error, could not initialise the network %08X\n", err);
break;
}
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");
start_server(szMyIPAddr);
}
}
while(0);
sceKernelSleepThread();
return 0;
}
int module_start(SceSize args, void *argp)
{
return 0;
}
int module_stop(SceSize args, void *argp)
{
(void) pspSdkInetTerm();
return 0;
}
/*
int module_stop()
{
return 0;
}
*/ |
I've errors when run make: a lot of undefined reference.
It does not happen if I delete from Makefile:
USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1
How to avoid the problem? thanks |
|
| Back to top |
|
 |
Hellcat
Joined: 24 Jan 2007 Posts: 84
|
Posted: Thu Sep 27, 2007 8:24 pm Post subject: |
|
|
Yap, sounds familiar....
When compiling against kernel libraries most user functions stay out.
And it doesn't help much to put them back in (with adding the libs to the makefile).... 3.xx kernel is pretty restrictive, it's doesn't allow much user functions used from kernel modules.
I just have four days of headache behind me fighting with 3.xx kernel.
Put all your code in a simple usermode module and make another one (kernel mode, this time) that exports some functions that "channel" or "bridge" you over.
You call your exported function, that does the kernel calls.
And it's best to keep it minimum.
I think I also read the network stuff doesn't need kernel on higher FWs anymore.... is that right? |
|
| Back to top |
|
 |
mypspdev
Joined: 11 Jul 2007 Posts: 178
|
Posted: Thu Sep 27, 2007 9:28 pm Post subject: |
|
|
Hi!
here is where I am.
TARGET: I'd like to run a server
WAY: re-using the /net/simple_prx example with the technique used for sio (see post)
I've created the simple.prx:
simple server prx main:
| Code: |
/*
* PSP Software Development Kit - http://www.pspdev.org
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* main.c - Simple prx based network example. Must load the net modules
* before running.
*
* Copyright (c) 2005 James F <tyranid@gmail.com>
* Some small parts (c) 2005 PSPPet
*
* $Id: main.c 1887 2006-05-01 03:54:06Z jim $
* $HeadURL: svn://svn.pspdev.org/psp/trunk/pspsdk/src/samples/net/simple_prx/main.c $
*/
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.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 <errno.h>
#define MODULE_NAME "NetSample"
#define HELLO_MSG "Hello there. Type away.\r\n"
PSP_MODULE_INFO(MODULE_NAME, 0x1006, 1, 1);
PSP_MAIN_THREAD_ATTR(0);
PSP_MAIN_THREAD_NAME("NetSample");
#define SERVER_PORT 23
int make_socket(uint16_t port)
{
int sock;
int ret;
struct sockaddr_in name;
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
return -1;
}
name.sin_family = AF_INET;
name.sin_port = htons(port);
name.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(sock, (struct sockaddr *) &name, sizeof(name));
if(ret < 0)
{
return -1;
}
return sock;
}
/* Start a simple tcp echo server */
void start_server(const char *szIpAddr)
{
int ret;
int sock;
int new = -1;
struct sockaddr_in client;
size_t size;
int readbytes;
char data[1024];
fd_set set;
fd_set setsave;
/* Create a socket for listening */
sock = make_socket(SERVER_PORT);
if(sock < 0)
{
printf("Error creating server socket\n");
return;
}
ret = listen(sock, 1);
if(ret < 0)
{
printf("Error calling listen\n");
return;
}
printf("Listening for connections ip %s port %d\n", szIpAddr, SERVER_PORT);
FD_ZERO(&set);
FD_SET(sock, &set);
setsave = set;
while(1)
{
int i;
set = setsave;
if(select(FD_SETSIZE, &set, NULL, NULL, NULL) < 0)
{
printf("select error\n");
return;
}
for(i = 0; i < FD_SETSIZE; i++)
{
if(FD_ISSET(i, &set))
{
int val = i;
if(val == sock)
{
new = accept(sock, (struct sockaddr *) &client, &size);
if(new < 0)
{
printf("Error in accept %s\n", strerror(errno));
close(sock);
return;
}
printf("New connection %d from %s:%d\n", val,
inet_ntoa(client.sin_addr),
ntohs(client.sin_port));
write(new, HELLO_MSG, strlen(HELLO_MSG));
FD_SET(new, &setsave);
}
else
{
readbytes = read(val, data, sizeof(data));
if(readbytes <= 0)
{
printf("Socket %d closed\n", val);
FD_CLR(val, &setsave);
close(val);
}
else
{
write(val, data, readbytes);
printf("%.*s", readbytes, data);
}
}
}
}
}
close(sock);
}
/* 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
// wait a little before polling again
sceKernelDelayThread(50*1000); // 50ms
}
printf(MODULE_NAME ": Connected!\n");
if(err != 0)
{
return 0;
}
return 1;
}
/* Simple thread */
int prxmain(int argc, char **argv)
{
int err;
do
{
if((err = pspSdkInetInit()))
{
printf(MODULE_NAME ": Error, could not initialise the network %08X\n", err);
break;
}
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");
start_server(szMyIPAddr);
}
}
while(0);
sceKernelSleepThread();
return 0;
}
int module_stop(SceSize args, void *argp)
{
(void) pspSdkInetTerm();
return 0;
}
int module_start(SceSize args, void *argp)
{
return 0;
}
|
main function has been substituted with prxmain.
PSP_MODULE_INFO(MODULE_NAME, 0x1006, 1, 1);
PSP_MAIN_THREAD_ATTR(0);
has been adapted.
Makefile for generating NetSample.prx:
| Code: |
TARGET = NetSample
OBJS = main.o
PRX_EXPORTS=exports.exp
BUILD_PRX=1
INCDIR =
CFLAGS = -O0 -G0 -Wall -g
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS = -mno-crt0 -nostartfiles
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
|
of course it's forbidden to set-up
USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1
Then the exports.exp with the function to be called to create the net_thread: prxmain:
| Code: | # Define the exports for the prx
PSP_BEGIN_EXPORTS
# These four lines are mandatory (although you can add other functions like module_stop)
# syslib is a psynonym for the single mandatory export.
PSP_EXPORT_START(syslib, 0, 0x8000)
PSP_EXPORT_FUNC(module_start)
PSP_EXPORT_FUNC(module_stop)
PSP_EXPORT_VAR(module_info)
PSP_EXPORT_END
# Export our function
PSP_EXPORT_START(NetSample, 0, 0x4001)
PSP_EXPORT_FUNC(prxmain)
PSP_EXPORT_END
PSP_END_EXPORTS
|
The prx works: I've compiled NetSample.prx and the NetSample.S.
Then I have the main 3.xx program,
| Code: |
PSP_MODULE_INFO("MyServer", 0, 1, 0);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
PSP_HEAP_SIZE_KB(5000);
////////////////////////////////
// Functions imported from prx:
////////////////////////////////
int prxmain(void);
|
with load and call:
| Code: |
void NetSample()
{
SceUID modid;
u32 oldButtons = 0;
pspDebugScreenInit();
pspDebugScreenClear();
pspDebugScreenSetXY(0, 1);
printf("Call to exsternal PRX\n");
modid = pspSdkLoadStartModule("./prx/NetSample.prx", PSP_MEMORY_PARTITION_KERNEL);
if (modid < 0)
{
pspDebugScreenPrintf("Error 0x%08X loading/starting NetSample.prx.\n", modid);
sceKernelDelayThread(5*1000*1000);
return -1;
}
pspDebugScreenPrintf("Module ID %08X\n", modid);
prxmain();
// pspDebugScreenPrintf("Back from PRX %i\n", k);
printf("Press START to continue\n");
for (;;)
{
sceCtrlReadBufferPositive(&pad, 1);
if (oldButtons != pad.Buttons)
{
if (pad.Buttons & PSP_CTRL_START)
{
break;
}
}
oldButtons = pad.Buttons;
sceDisplayWaitVblankStart();
sceKernelDelayThread(50000);
}
}
|
When running it, error loading NetSample.prx.
Any suggestion is appreciated so much ....
The same program is correctly calling another prx with a simple int value back sent.
Thanks |
|
| Back to top |
|
 |
mypspdev
Joined: 11 Jul 2007 Posts: 178
|
Posted: Fri Sep 28, 2007 9:49 pm Post subject: |
|
|
Just tp share what I learned:
to run wifilanscan and simple (which a server on port 23), under 3.xx, just substitute net Initialization with something like:
sceUtilityLoadNetModule(1);
sceUtilityLoadNetModule(3);
thid = sceKernelCreateThread("scan_net_thread", scan_net_thread, 16, 256*1024, 0, NULL);
and do not run it as kernel mode.
Now thay've been ported to 3.xx. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|