hello,
i`m trying to modify psp controller sample,
i`m able to send udp packets and read them on the pc,
but when i try to call sceNetInetRecvfrom psp always freezes,
i would be very grateful if someone can have a look on this
piece of code, i`m sure i`m missung something obvious...
(or maybe there is sample for this somewhere?)
thanks,
wojciech
SOCKET sock = sceNetInetSocket(AF_INET, SOCK_DGRAM, 0);
if (sock & 0x80000000)
{
printf("Could not connect.");
return;
}
sockaddr_in addrTo;
addrTo.sin_family = AF_INET;
addrTo.sin_port = htons(g_serverPort);
addrTo.sin_addr[0] = g_serverAddr[0];
addrTo.sin_addr[1] = g_serverAddr[1];
addrTo.sin_addr[2] = g_serverAddr[2];
addrTo.sin_addr[3] = g_serverAddr[3];
sockaddr_in addrListen;
addrListen.sin_family = AF_INET;
addrListen.sin_port = htons(100); // port 100 - arbitrary
addrListen.sin_addr[0] = 10;
addrListen.sin_addr[1] = 0;
addrListen.sin_addr[2] = 2;
addrListen.sin_addr[3] = 1;
while(done!=1){
char buffer[128];
sockaddr_in addrFrom;
int cbAddrFrom = sizeof(addrFrom);
sceNetInetRecvfrom(sock, (u8*)buffer, sizeof(buffer), 0, &addrFrom, &cbAddrFrom);
unsigned char packet[8];
sceNetInetSendto( sock, packet, sizeof( packet ), 0, &addrTo, sizeof(addrTo) );
}
receive udp packets?
sceNetInetRecvfrom (or recvfrom in standard unix sockets) is a blocking call, it blocks untill it receives a packet.
I guess that this is what is happening.
If you don't want it to block, then investigate using select (http://www.lowtek.com/sockets/select.html) or making it nonblocking and polling it manually.
I also recommend you use the standard unix sockets functionality that is available in the sdk rather than the sceNetInet functions.
I guess that this is what is happening.
If you don't want it to block, then investigate using select (http://www.lowtek.com/sockets/select.html) or making it nonblocking and polling it manually.
I also recommend you use the standard unix sockets functionality that is available in the sdk rather than the sceNetInet functions.
Fairly good one for tcp:
http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html
Can't really find one for udp, but feel free to post when you get stuck.
Danzel.
http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html
Can't really find one for udp, but feel free to post when you get stuck.
Danzel.
This my a simple tool I wrote for use with PSPRadio and the WiFi logging stuff. It's intended to run in a Linux shell, but should work on all bsd socket compatible platforms.
Code: Select all
/*
Simple server application for receiving logdata from PSPRadio.
Copyright (C) 2006 Jesper Sandberg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#define BUFSIZE 1024
void Die(char *message)
{
perror(message);
exit(1);
}
int main (int argc, char *argv[])
{
int sock;
struct sockaddr_in log_server;
struct sockaddr_in log_client;
char buffer[BUFSIZE];
unsigned int client_len, server_len;
int received = 0;
fprintf(stdout, "LogTool v0.1 - Written for use with PSPRadio\n\n");
if (argc != 2)
{
fprintf(stderr, "Usage: %s <port>\n", argv[0]);
exit(1);
}
/* Create UDP socket */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
Die("Failed to create socket..");
}
/* Create sockaddr structure */
memset(&log_server, 0, sizeof(log_server));
log_server.sin_family = AF_INET;
log_server.sin_addr.s_addr = htonl(INADDR_ANY);
log_server.sin_port = htons(atoi(argv[1]));
/* Bind the socket */
server_len = sizeof(log_server);
if (bind(sock, (struct sockaddr *) &log_server, server_len) < 0)
{
Die("Failed to bind server socket");
}
/* Run until cancelled */
while (1)
{
/* Receive datagram from client */
client_len = sizeof(log_client);
if ((received = recvfrom(sock, buffer, BUFSIZE, 0, (struct sockaddr *) &log_client, &client_len)) < 0)
{
Die("Failed to receive message from client..");
}
buffer[received] = 0x00;
fprintf(stdout, "> %s\n", buffer);
}
exit(0);
}
Br, Sandberg
Well I looked at your code. I have to mention that you need to open two sockets. One for sending and one for receiving. Here is my code.
This code isn't only mine. I give thanks to PSPPet, PVNC and other great developers out here.
This is how I set up my send and receive for UDP. I made a program that outputs the control buttons and receives JPG images. I still trying to get the PSP to transmit all the time without waiting for the JPG image, but getting it to multithread the two has been a chore for me.
Well anywayz what you are missing is a Bind command on your receive and a Connect command on your send.
Code: Select all
int init_UDP_send()
{
SOCKET sockOut;
struct sockaddr_in addrOut;
SceCtrlData pad;
sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
int done = 0;
int redraw = 1;
while(!done)
{
sceCtrlReadBufferPositive(&pad, 1);
if(redraw)
{
pgFillvram(0);
pgPrint2(5,0,gray, "Choose IP Address");
IP_Render(IP_s,4,8);
pgPrint(7,30,midnightblue,"Press X, O when done, HOME to Cancel");
pgScreenFlipV();
redraw = 0;
}
if(pad.Buttons != 0x02040000)
{
if(pad.Buttons & CURSOR_LEFT)
{
IP_s--;
if(IP_s<0) IP_s=16;
}
if(pad.Buttons & CURSOR_RIGHT)
{
IP_s++;
if(IP_s>16) IP_s=0;
}
if(pad.Buttons & CURSOR_UP)
{
IP_Plus(IP_s);
}
if(pad.Buttons & CURSOR_DOWN)
{
IP_Minus(IP_s);
}
if(pad.Buttons & CROSS)
done = 1;
if(pad.Buttons & CIRCLE)
done = 1;
if(pad.Buttons & EXIT)
{
break;
}
redraw = 1;
pgWaitVn(10);
}
}
sockOut = sceNetInetSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
my_printn("socket returned ", sockOut, "\n");
addrOut.sin_family = AF_INET;
addrOut.sin_port = htons(IP_p);
addrOut.sin_addr[0] = (int)(IP_h>>24);
addrOut.sin_addr[1] = (int)(IP_h>>16)&0xff;
addrOut.sin_addr[2] = (int)(IP_h>>8)&0xff;
addrOut.sin_addr[3] = (int)(IP_h)&0xff;
int buffersize = 0;
int junk = 1024;
if (sceNetInetGetsockopt(sockOut, SOL_SOCKET, SO_SNDBUF, (char *)&buffersize,
&junk) < 0);
int err;
err = sceNetInetConnect(sockOut, (struct sockaddr*)&addrOut,sizeof(addrOut));
// any
return sockOut;
}
int init_UDP_receive()
{
SOCKET sockListen = 0;
sockListen = sceNetInetSocket(AF_INET, SOCK_DGRAM, 0);
u32 timeout = 1000;
u32 err;
addrListen.sin_family = AF_INET;
addrListen.sin_port = htons(100); // port 100 - arbitrary
addrListen.sin_addr[0] = 0;
addrListen.sin_addr[1] = 0;
addrListen.sin_addr[2] = 0;
addrListen.sin_addr[3] = 0;
err = sceNetInetSetsockopt(sockListen, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
err = sceNetInetBind(sockListen, &addrListen, sizeof(addrListen));
return sockListen;
}
void IP_Render(int s, int x, int y) {
char HostText[] = "000.000.000.000:00000";
sprintf(HostText, "%3i.%3i.%3i.%3i:%5i", (IP_h>>24), (IP_h>>16)&0xff, (IP_h>>8)&0xff, IP_h&0xff, IP_p);
if(s<12) { // convert packed to dotted
int g = s / 3;
int d = s % 3;
s=g*4+d;
} else {
s+=4;
}
pgPrint2(x,y,white, HostText);
pgPrint2((x+s),(y+1),red, "^");
}
void IP_Minus(int s) {
long b, g, d = 100;
if(s<12) {
g = s / 3;
s %= 3;
while(s) { d/=10; s--; }
b = (IP_h>>((3-g)*8))&0xff;
IP_h &= ~(0xff<<((3-g)*8));
if (b-d>=0) b-=d;
else b=0;
IP_h |= b<<((3-g)*8);
} else {
s -= 12;
d = 10000;
while(s) { d/=10; s--; }
if (IP_p-d>=0) IP_p-=d;
else IP_p = 0;
}
}
void IP_Plus(int s) {
long b, g, d = 100;
if(s<12) {
g = s / 3;
s %= 3;
while(s) { d/=10; s--; }
b = (IP_h>>((3-g)*8))&0xff;
IP_h &= ~(0xff<<((3-g)*8));
if (b+d<=0xff) b+=d;
else b = 0xff;
IP_h |= b<<((3-g)*8);
} else {
s -= 12;
d = 10000;
while(s) { d/=10; s--; }
if (IP_p-d<=0xffff) IP_p+=d;
else IP_p = 0xffff;
}
}
This code isn't only mine. I give thanks to PSPPet, PVNC and other great developers out here.
This is how I set up my send and receive for UDP. I made a program that outputs the control buttons and receives JPG images. I still trying to get the PSP to transmit all the time without waiting for the JPG image, but getting it to multithread the two has been a chore for me.
Well anywayz what you are missing is a Bind command on your receive and a Connect command on your send.
There is no need to open two sockets ? You can send and receive using the same socket. The addition to my original code above works fine using only one socket.
if ((received = recvfrom(sock, buffer, BUFSIZE, 0, (struct sockaddr *) &log_client, &client_len)) < 0)
{
Die("Failed to receive message from client..");
}
if (sendto(sock, buffer, received, 0, (struct sockaddr *) &log_client, sizeof(log_client)) != received)
{
Die("Couldn't send all data..");
}
Br, Sandberg