wlan "simple" sample for 3.xx (simple_prx)

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

Moderators: cheriff, TyRaNiD

Post Reply
r0b3rt
Posts: 17
Joined: Mon May 26, 2008 6:43 am

wlan "simple" sample for 3.xx (simple_prx)

Post by r0b3rt »

Hy, I'm new here, and I have a question about running a sample program from PSPSDK on my PSP (3.90M33-3).

I am trying to make a simple tcp server/client for PSP and ../sdk/samples/net/simple looks interesting. I managed to compile it but when I run it I get a 80020148 error. That's probably because that sample is for 1.5 firmware version.

But i can't compile "simple_prx" sample (which should be for 3.xx). This is the output I get after 'make':

Code: Select all

psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O0 -G0 -Wall -g -D_PSP_FW_VERSION=150   -c -o main.o main.c
psp-build-exports -b exports.exp > exports.c
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O0 -G0 -Wall -g -D_PSP_FW_VERSION=150   -c -o exports.o exports.c
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O0 -G0 -Wall -g -D_PSP_FW_VERSION=150  -L. -L/usr/local/pspdev/psp/sdk/lib -specs=/usr/local/pspdev/psp/sdk/lib/prxspecs -Wl,-q,-T/usr/local/pspdev/psp/sdk/lib/linkfile.prx   main.o exports.o  -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o netsample.elf
psp-fixup-imports netsample.elf
psp-prxgen netsample.elf netsample.prx
rm exports.c
And I get a message:
main.c: in function 'start_server'
main.c:115: warning: passing argument 3 of 'accept' from incompatible pointer type.

This is line 115:

Code: Select all

new = accept(sock, (struct sockaddr *) &client, &size);
And no EBOOT.PBP is created.

So please help. What do I need to change to get the first sample to run or the second to compile properly?
Or maybe someone can send something similar (that works).

Thanks.
pspZorba
Posts: 156
Joined: Sat Sep 22, 2007 11:45 am
Location: NY

Post by pspZorba »

for your warning :
it is because size should be a socklen_t and not size_t, (I guess it is the same).

As it is a prx, it is normal that you don't have an eboot. You should have a file like xxxx.prx ( may be netsample.prx)
--pspZorba--
NO to K1.5 !
r0b3rt
Posts: 17
Joined: Mon May 26, 2008 6:43 am

Post by r0b3rt »

Hi.

socklen_t fixed the warning (thanks!) but I'm still a bit confused. EBOOT.PBP on PSP is like *.exe on windows. So if I want to run the sample I need a EBOOT.PBP. If I just copy prx and try to run it from XMB I get "Corrupted Data".

So do I need another main.c and a makefile, which will load functions from the prx?
And if so, why is there no module_start in the main.c, but there is a main function. And in exports.exp functions make_socket, start_server and connect_to_apctl are not mentioned.

I also tried to add "EXTRA_TARGETS = EBOOT.PBP" to the Makefile and EBOOT.PBP is built, but when I try to run it from XMB, my PSP freezes.

Thanks!
pspZorba
Posts: 156
Joined: Sat Sep 22, 2007 11:45 am
Location: NY

Post by pspZorba »

A prx is like a dll and yes you are right the eboot is like a windows exe.

Normally you need an eboot (another main.c, the prx stubs and makefile) to load end execute the functions contained in the prx.

But yes you should export the functions you want to use.

I don't know this SDK sample. I will try to have a look at it tonight if nobody else answered before.
--pspZorba--
NO to K1.5 !
r0b3rt
Posts: 17
Joined: Mon May 26, 2008 6:43 am

Post by r0b3rt »

I'll paste the code from the sample (.../pspdev/psp/sdk/samples/net/simple_prx) so it's all here for anyone who wants to help.

Main.c:

Code: Select all

/*
 * 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 &#40;c&#41; 2005 James F <[email protected]>
 * Some small parts &#40;c&#41; 2005 PSPPet
 *
 * $Id&#58; main.c 1887 2006-05-01 03&#58;54&#58;06Z jim $
 * $HeadURL&#58; svn&#58;//svn.ps2dev.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&#40;MODULE_NAME, 0, 1, 1&#41;;
PSP_MAIN_THREAD_NAME&#40;"NetSample"&#41;;

#define SERVER_PORT 23

int make_socket&#40;uint16_t port&#41;
&#123;
	int sock;
	int ret;
	struct sockaddr_in name;

	sock = socket&#40;PF_INET, SOCK_STREAM, 0&#41;;
	if&#40;sock < 0&#41;
	&#123;
		return -1;
	&#125;

	name.sin_family = AF_INET;
	name.sin_port = htons&#40;port&#41;;
	name.sin_addr.s_addr = htonl&#40;INADDR_ANY&#41;;
	ret = bind&#40;sock, &#40;struct sockaddr *&#41; &name, sizeof&#40;name&#41;&#41;;
	if&#40;ret < 0&#41;
	&#123;
		return -1;
	&#125;

	return sock;
&#125;

/* Start a simple tcp echo server */
void start_server&#40;const char *szIpAddr&#41;
&#123;
	int ret;
	int sock;
	int new = -1;
	struct sockaddr_in client;
	size_t size;
	int readbytes;
	char data&#91;1024&#93;;
	fd_set set;
	fd_set setsave;

	/* Create a socket for listening */
	sock = make_socket&#40;SERVER_PORT&#41;;
	if&#40;sock < 0&#41;
	&#123;
		printf&#40;"Error creating server socket\n"&#41;;
		return;
	&#125;

	ret = listen&#40;sock, 1&#41;;
	if&#40;ret < 0&#41;
	&#123;
		printf&#40;"Error calling listen\n"&#41;;
		return;
	&#125;

	printf&#40;"Listening for connections ip %s port %d\n", szIpAddr, SERVER_PORT&#41;;

	FD_ZERO&#40;&set&#41;;
	FD_SET&#40;sock, &set&#41;;
	setsave = set;

	while&#40;1&#41;
	&#123;
		int i;
		set = setsave;
		if&#40;select&#40;FD_SETSIZE, &set, NULL, NULL, NULL&#41; < 0&#41;
		&#123;
			printf&#40;"select error\n"&#41;;
			return;
		&#125;

		for&#40;i = 0; i < FD_SETSIZE; i++&#41;
		&#123;
			if&#40;FD_ISSET&#40;i, &set&#41;&#41;
			&#123;
				int val = i;

				if&#40;val == sock&#41;
				&#123;
					new = accept&#40;sock, &#40;struct sockaddr *&#41; &client, &size&#41;;
					if&#40;new < 0&#41;
					&#123;
						printf&#40;"Error in accept %s\n", strerror&#40;errno&#41;&#41;;
						close&#40;sock&#41;;
						return;
					&#125;

					printf&#40;"New connection %d from %s&#58;%d\n", val, 
							inet_ntoa&#40;client.sin_addr&#41;,
							ntohs&#40;client.sin_port&#41;&#41;;

					write&#40;new, HELLO_MSG, strlen&#40;HELLO_MSG&#41;&#41;;

					FD_SET&#40;new, &setsave&#41;;
				&#125;
				else
				&#123;
					readbytes = read&#40;val, data, sizeof&#40;data&#41;&#41;;
					if&#40;readbytes <= 0&#41;
					&#123;
						printf&#40;"Socket %d closed\n", val&#41;;
						FD_CLR&#40;val, &setsave&#41;;
						close&#40;val&#41;;
					&#125;
					else
					&#123;
						write&#40;val, data, readbytes&#41;;
						printf&#40;"%.*s", readbytes, data&#41;;
					&#125;
				&#125;
			&#125;
		&#125;
	&#125;

	close&#40;sock&#41;;
&#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

		// 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;

/* Simple thread */
int main&#40;int argc, char **argv&#41;
&#123;
	int err;

	do
	&#123;
		if&#40;&#40;err = pspSdkInetInit&#40;&#41;&#41;&#41;
		&#123;
			printf&#40;MODULE_NAME "&#58; Error, could not initialise the network %08X\n", err&#41;;
			break;
		&#125;

		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;;

			start_server&#40;szMyIPAddr&#41;;
		&#125;
	&#125;
	while&#40;0&#41;;

	sceKernelSleepThread&#40;&#41;;

	return 0;
&#125;

int module_stop&#40;SceSize args, void *argp&#41;
&#123;
	&#40;void&#41; pspSdkInetTerm&#40;&#41;;

	return 0;
&#125;

exports.exp:

Code: Select all

# Define the exports for the prx
PSP_BEGIN_EXPORTS

# These four lines are mandatory &#40;although you can add other functions like module_stop&#41;
# syslib is a psynonym for the single mandatory export.
PSP_EXPORT_START&#40;syslib, 0, 0x8000&#41;
PSP_EXPORT_FUNC&#40;module_start&#41;
PSP_EXPORT_FUNC&#40;module_stop&#41;
PSP_EXPORT_VAR&#40;module_info&#41;
PSP_EXPORT_END

PSP_END_EXPORTS
Makefile:

Code: Select all

TARGET = netsample
OBJS = main.o

PRX_EXPORTS=exports.exp
BUILD_PRX=1

INCDIR = 
CFLAGS = -O0 -G0 -Wall -g
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

LIBDIR =

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

You'd be better off converting the 'simple' sample to 3xx from 1.5.

The simple_prx is a sample that shows how to create the 'simple' sample as a prx.

Here you go:

Code: Select all

/*
 * PSP Software Development Kit - http&#58;//www.pspdev.org
 * -----------------------------------------------------------------------
 * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
 *
 * main.c - Simple elf based network example.
 *
 * Copyright &#40;c&#41; 2005 James F <[email protected]>
 * Some small parts &#40;c&#41; 2005 PSPPet
 *
 * $Id&#58; main.c 1887 2006-05-01 03&#58;54&#58;06Z jim $
 * $HeadURL&#58; svn&#58;//svn.ps2dev.org/psp/trunk/pspsdk/src/samples/net/simple/main.c $
 */
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.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 <psputility.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <errno.h>

#define printf pspDebugScreenPrintf

#define MODULE_NAME "NetSample"
#define HELLO_MSG   "Hello there. Type away.\r\n"

PSP_MODULE_INFO&#40;MODULE_NAME, PSP_MODULE_USER, 1, 1&#41;;
PSP_HEAP_SIZE_KB&#40;20480&#41;;

static int running = 1;

/* Exit callback */
int exit_callback&#40;int arg1, int arg2, void *common&#41;
&#123;
	running = 0;
	
	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, PSP_THREAD_ATTR_USER, 0&#41;;
	if&#40;thid >= 0&#41;
	&#123;
		sceKernelStartThread&#40;thid, 0, 0&#41;;
	&#125;

	return thid;
&#125;

#define SERVER_PORT 23

int make_socket&#40;uint16_t port&#41;
&#123;
	int sock;
	int ret;
	struct sockaddr_in name;

	sock = socket&#40;PF_INET, SOCK_STREAM, 0&#41;;
	if&#40;sock < 0&#41;
	&#123;
		return -1;
	&#125;

	name.sin_family = AF_INET;
	name.sin_port = htons&#40;port&#41;;
	name.sin_addr.s_addr = htonl&#40;INADDR_ANY&#41;;
	ret = bind&#40;sock, &#40;struct sockaddr *&#41; &name, sizeof&#40;name&#41;&#41;;
	if&#40;ret < 0&#41;
	&#123;
		return -1;
	&#125;

	return sock;
&#125;

/* Start a simple tcp echo server */
void start_server&#40;const char *szIpAddr&#41;
&#123;
	int ret;
	int sock;
	int new = -1;
	struct sockaddr_in client;
	socklen_t size;
	int readbytes;
	char data&#91;1024&#93;;
	fd_set set;
	fd_set setsave;

	/* Create a socket for listening */
	sock = make_socket&#40;SERVER_PORT&#41;;
	if&#40;sock < 0&#41;
	&#123;
		printf&#40;"Error creating server socket\n"&#41;;
		return;
	&#125;

	ret = listen&#40;sock, 1&#41;;
	if&#40;ret < 0&#41;
	&#123;
		printf&#40;"Error calling listen\n"&#41;;
		return;
	&#125;

	printf&#40;"Listening for connections ip %s port %d\n", szIpAddr, SERVER_PORT&#41;;

	FD_ZERO&#40;&set&#41;;
	FD_SET&#40;sock, &set&#41;;
	setsave = set;
	
	struct timeval timeout;
	
	timeout.tv_sec = 1;
	timeout.tv_usec = 0;

	while&#40;running&#41;
	&#123;
		int i;
		set = setsave;
		
		if&#40;select&#40;FD_SETSIZE, &set, NULL, NULL, NULL&#41; < 0&#41;
		&#123;
			printf&#40;"select error\n"&#41;;
			return;
		&#125;

		for&#40;i = 0; i < FD_SETSIZE; i++&#41;
		&#123;
			
			if&#40;FD_ISSET&#40;i, &set&#41;&#41;
			&#123;
				int val = i;

				if&#40;val == sock&#41;
				&#123;
					new = accept&#40;sock, &#40;struct sockaddr *&#41; &client, &size&#41;;

					if&#40;new < 0&#41;
					&#123;
						printf&#40;"Error in accept %s\n", strerror&#40;errno&#41;&#41;;
						close&#40;sock&#41;;
						return;
					&#125;

					printf&#40;"New connection %d from %s&#58;%d\n", val, 
							inet_ntoa&#40;client.sin_addr&#41;,
							ntohs&#40;client.sin_port&#41;&#41;;

					write&#40;new, HELLO_MSG, strlen&#40;HELLO_MSG&#41;&#41;;

					FD_SET&#40;new, &setsave&#41;;
				&#125;
				else
				&#123;
					readbytes = read&#40;val, data, sizeof&#40;data&#41;&#41;;
					if&#40;readbytes <= 0&#41;
					&#123;
						printf&#40;"Socket %d closed\n", val&#41;;
						FD_CLR&#40;val, &setsave&#41;;
						close&#40;val&#41;;
					&#125;
					else
					&#123;
						write&#40;val, data, readbytes&#41;;
						printf&#40;"%.*s", readbytes, data&#41;;
					&#125;
				&#125;
			&#125;
		&#125;
	&#125;

	close&#40;sock&#41;;
&#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;running&#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

		// 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;

/* Simple thread */
int main&#40;int argc, char **argv&#41;
&#123;
	SetupCallbacks&#40;&#41;;

	pspDebugScreenInit&#40;&#41;;

	sceUtilityLoadModule&#40;PSP_MODULE_NET_COMMON&#41;;
	
	sceUtilityLoadModule&#40;PSP_MODULE_NET_INET&#41;;
	
	int err;
	
	while&#40;running&#41;
	&#123;
		if&#40;&#40;err = pspSdkInetInit&#40;&#41;&#41;&#41;
		&#123;
			printf&#40;MODULE_NAME "&#58; Error, could not initialise the network %08X\n", err&#41;;
			break;
		&#125;

		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;;

			start_server&#40;szMyIPAddr&#41;;
		&#125;
	&#125;
	
	pspSdkInetTerm&#40;&#41;;
	
	sceKernelExitGame&#40;&#41;;

	return 0;
&#125;

Code: Select all

TARGET = netsample
OBJS = main.o

INCDIR = 
CFLAGS = -O0 -G0 -Wall -g
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

BUILD_PRX = 1

LIBDIR =

EXTRA_TARGETS = EBOOT.PBP

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
r0b3rt
Posts: 17
Joined: Mon May 26, 2008 6:43 am

Post by r0b3rt »

Thanks for the help, the code works great.
Perhaps it would be good to put it in sdk/samples/net.
illostos
Posts: 7
Joined: Wed May 14, 2008 4:59 pm

Post by illostos »

does anyone knows how to send data over the network? we try to create a remote control for a mobile robot with a wlan host on it, but we need to send him data (with the arrow keys forward, backward, left, right and with the L+R Buttons slower and faster)

but were in the code can i implement this?
And before we can send something, the other side, in our case the ct'bot from heise has to accept the socket connection?
with when i read this right the socket, the ip adress, what is &client and &size in this case?
Post Reply