forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

pspdev/sdk/net/simple_prx porting from 1.50 to 3.xx

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
mypspdev



Joined: 11 Jul 2007
Posts: 178

PostPosted: Thu Sep 27, 2007 7:17 am    Post subject: pspdev/sdk/net/simple_prx porting from 1.50 to 3.xx Reply with quote

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
View user's profile Send private message
Hellcat



Joined: 24 Jan 2007
Posts: 84

PostPosted: Thu Sep 27, 2007 8:24 pm    Post subject: Reply with quote

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
View user's profile Send private message
mypspdev



Joined: 11 Jul 2007
Posts: 178

PostPosted: Thu Sep 27, 2007 9:28 pm    Post subject: Reply with quote

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
View user's profile Send private message
mypspdev



Joined: 11 Jul 2007
Posts: 178

PostPosted: Fri Sep 28, 2007 9:49 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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