rendered paste body#include <pspkernel.h>
#include <pspmodulemgr.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <pspthreadman.h>
#include <pspctrl.h>
#include <pspsdk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pspnet.h>
#include <pspnet_adhoc.h>
#include <pspnet_adhocctl.h>
#include <pspnet_adhocmatching.h>
#include <pspnet_apctl.h>
#include <psputility.h>
#include <psputility_netmodules.h>
#include <pspwlan.h>
#define printf pspDebugScreenPrintf
#define MATCHING_JOINED 0x1 // Another PSP has joined
#define MATCHING_SELECTED 0x2 // Another PSP selected to match
#define MATCHING_REJECTED 0x4 // The request has been rejected
#define MATCHING_CANCELED 0x5 // The request has been cancelled
#define MATCHING_ESTABLISHED 0x7 // Both PSP's have agreed to connect, at this point Lumines
// closes the connection and creates a new one with just the
// two PSP's in it.
#define MATCHING_DISCONNECT 0xa // A PSP has quit, this does not include when the PSP crashes
PSP_MODULE_INFO("AdHoc", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
int adhocTerm();
/* exit callback */
int exit_callback(int arg1, int arg2, void *common){
adhocTerm();
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;
}
/* setup the callback thread */
int SetupCallbacks(void){
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0)
sceKernelStartThread(thid, 0, 0);
return thid;
}
// Define a few states for handling the adhoc events
#define PSP_LISTING 1
#define PSP_SELECTED 2
#define PSP_SELECTING 3
#define PSP_WAIT_EST 4
#define PSP_ESTABLISHED 5
int g_Server = 0;
int pdpId = 0;
int matchingId = 0;
int matchChanged = 0;
char g_mac[6];
int g_unk1=0;
int g_matchEvent=0;
int g_matchOptLen=0;
char g_matchOptData[1000];
int NetInit = 0;
int NetAdhocInit = 0;
int NetAdhocctlInit = 0;
int NetAdhocctlConnect = 0;
int NetAdhocPdpCreate = 0;
int NetAdhocMatchingInit = 0;
int NetAdhocMatchingCreate = 0;
int NetAdhocMatchingStart = 0;
//Void used to be pspAdhocMatchingCallback
void matchingCallback(int unk1, int event, char *mac2, int optLen, char *optData)
{
// This is called when there is an event, dont seem to be able to call
// procs from here otherwise it causes a crash
if(event==MATCHING_JOINED)
{
AddPsp(mac2, optData, optLen);
}
else if(event==MATCHING_DISCONNECT)
{
DelPsp(mac2);
}
else
{
g_unk1 = unk1;
g_matchEvent = event;
g_matchOptLen = optLen;
// Copy across the optional data
strncpy(g_matchOptData, optData, optLen);
// And the MAC address
memcpy(g_mac, mac2, sizeof(char) * 6);
matchChanged = 1;
}
}
int adhocInit(char *MatchingData)
{
char mac[6];
struct productStruct product;
ClearPspList();
strcpy(product.product, "ULUS99999");
product.unknown = 0;
u32 err;
printf("sceNetInit()\n");
err = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000);
if (err != 0)
return err;
NetInit = 1;
printf("sceNetAdhocInit()\n");
err = sceNetAdhocInit();
if (err != 0)
return err;
NetAdhocInit = 1;
printf("sceNetAdhocctlInit()\n");
err = sceNetAdhocctlInit(0x2000, 0x20, &product);
if (err != 0)
return err;
NetAdhocctlInit = 1;
// Connect
err = sceNetAdhocctlConnect("");
if (err != 0)
return err;
NetAdhocctlConnect = 1;
int stateLast = -1;
printf("Connecting...\n");
while (1)
{
int state;
err = sceNetAdhocctlGetState(&state);
if (err != 0)
{
printf("sceNetApctlGetState returns $%x\n", err);
sceKernelDelayThread(10*1000000); // 10sec to read before exit
return -1;
}
if (state > stateLast)
{
printf(" connection state %d of 1\n", state);
stateLast = state;
}
if (state == 1)
break; // connected
// wait a little before polling again
sceKernelDelayThread(50*1000); // 50ms
}
printf("Connected!\n");
sceWlanGetEtherAddr(mac);
printf("sceNetAdhocPdpCreate\n");
pdpId = sceNetAdhocPdpCreate(mac,
0x309, // 0x309 in lumines
0x400, // 0x400 in lumines
0); // 0 in lumines
if(pdpId <= 0)
{
printf("pdpId = %x\n", pdpId);
return -1;
}
NetAdhocPdpCreate = 1;
printf("sceNetAdhocMatchingInit()\n");
err = sceNetAdhocMatchingInit(0x20000);
if(err != 0)
{
printf("error = %x\n", err);
}
NetAdhocMatchingInit = 1;
printf("sceNetAdhocMatchingCreate()\n");
matchingId = sceNetAdhocMatchingCreate(3, 0xa, 0x22b, 0x800, 0x2dc6c0, 0x5b8d80, 3, 0x7a120, (void *)matchingCallback);
if(matchingId < 0)
{
printf("matchingId = %x\n", matchingId);
}
NetAdhocMatchingCreate = 1;
char tempStr[100];
tempStr[0] = '\0';
/*if(strlen(MatchingData))
{
strncpy(tempStr, strrchr(MatchingData, '/')+1, 100);
strrchr(tempStr, '.')[0] = '\0';
}*/
//printf("tempStr=%s\n", tempStr);
printf("sceNetAdhocMatchingStart()\n");
err = sceNetAdhocMatchingStart(matchingId, // 1 in lumines (presuming what is returned from create)
0x10, // 0x10
0x2000, // 0x2000
0x10, // 0x10
0x2000, // 0x2000
6,
"adhoc\0");
//strlen(tempStr)+1,
//tempStr);
if(err != 0)
{
printf("error = %x\n", err);
}
NetAdhocMatchingStart = 1;
// All the init functions have passed
return 0;
}
// Define a few states for handling the adhoc events
#define PSP_LISTING 1
#define PSP_SELECTED 2
#define PSP_SELECTING 3
#define PSP_WAIT_EST 4
#define PSP_ESTABLISHED 5
////////////////////////////////////////////////////////////////////////////////////
// This is just a quick and easy procedure to wait for a PSP to join, the following
// is what is done in Lumines:
//
// - Wait for a PSP to join
// - Add the PSP to the list of machines available
// - Wait for the user to select a PSP
// - Call sceMatchingSelectTarget
// - The other PSP will receive MATCHING_SELECTED event
// - The other PSP displays a message to accept or cancel
// - If accepted the other PSP calls sceMatchingSelectTarget
// - The first PSP receives MATCHING_ESTABLISHED
//
// In lumines they then close the connection and start a new adhoc connection
// with just those two machines in it.
///////////////////////////////////////////////////////////////////////////////////
int adhocSelect(void)
{
SceCtrlData m_PspPad;
int err = 0;
char mac[10];
char name[100];
int waitAccept = 0;
int currentState = PSP_LISTING;
int oldButtons = 0;
char tempStr[100];
for(;;)
{
sceCtrlReadBufferPositive(&m_PspPad, 1);
pspDebugScreenSetTextColor(0xFFFF);
switch(currentState)
{
case PSP_LISTING:
{
pspDebugScreenInit();
pspDebugScreenPrintf("Select a server to connect to, or triangle to return\n\n\n");
DisplayPspList();
g_Server = 0;
if(m_PspPad.Buttons != oldButtons)
{
if(m_PspPad.Buttons & PSP_CTRL_UP)
{
UpList();
}
if(m_PspPad.Buttons & PSP_CTRL_DOWN)
{
DownList();
}
if(m_PspPad.Buttons & PSP_CTRL_CROSS)
{
if(GetPspEntry(mac, name) > 0)
{
currentState = PSP_SELECTING;
sceNetAdhocMatchingSelectTarget(matchingId, mac, 0, 0);
}
}
if(m_PspPad.Buttons & PSP_CTRL_TRIANGLE)
return -1;
}
if(matchChanged)
{
if(g_matchEvent == MATCHING_SELECTED)
{
memcpy(mac, g_mac, 6);
strcpy(name, g_matchOptData);
currentState = PSP_SELECTED;
}
}
break;
}
case PSP_SELECTING:
{
pspDebugScreenInit();
sceNetEtherNtostr(mac, tempStr);
printf("Waiting for %s to accept the connection\nTo cancel press O\n", tempStr);
if(m_PspPad.Buttons != oldButtons)
{
if(m_PspPad.Buttons & PSP_CTRL_CIRCLE)
{
sceNetAdhocMatchingCancelTarget(matchingId, mac);
currentState = PSP_LISTING;
}
}
if(matchChanged)
{
if(g_matchEvent == MATCHING_SELECTED)
{
sceNetAdhocMatchingCancelTarget(matchingId, mac);
}
else if(g_matchEvent == MATCHING_ESTABLISHED)
{
currentState = PSP_ESTABLISHED;
}
else if(g_matchEvent == MATCHING_REJECTED)
{
currentState = PSP_LISTING;
}
}
break;
}
case PSP_SELECTED:
{
g_Server = 1;
pspDebugScreenInit();
sceNetEtherNtostr(mac, tempStr);
printf("%s has requested a connection\nTo accept the connection press X, to cancel press O\n", tempStr);
if(m_PspPad.Buttons != oldButtons)
{
if(m_PspPad.Buttons & PSP_CTRL_CIRCLE)
{
sceNetAdhocMatchingCancelTarget(matchingId, mac);
currentState = PSP_LISTING;
}
if(m_PspPad.Buttons & PSP_CTRL_CROSS)
{
sceNetAdhocMatchingSelectTarget(matchingId, mac, 0, 0);
currentState = PSP_WAIT_EST;
}
}
if(matchChanged)
{
if(g_matchEvent == MATCHING_CANCELED)
{
currentState = PSP_LISTING;
}
}
break;
}
case PSP_WAIT_EST:
{
if(matchChanged)
{
if(g_matchEvent == MATCHING_ESTABLISHED)
{
currentState = PSP_ESTABLISHED;
}
}
break;
}
}
matchChanged = 0;
oldButtons = m_PspPad.Buttons;
if(currentState == PSP_ESTABLISHED)
break;
sceDisplayWaitVblankStart();
}
char macAddr[10];
char *tempMac;
if(g_Server)
{
sceWlanGetEtherAddr(macAddr);
tempMac = macAddr;
}
else
{
tempMac = mac;
}
sceNetEtherNtostr(tempMac, tempStr);
char ssid[10];
sprintf(ssid, "%c%c%c%c%c%c", tempStr[9], tempStr[10], tempStr[12], tempStr[13],
tempStr[15], tempStr[16]);
adhocReconnect(ssid);
// We only get here if both PSP's have agreed to connect
//pspDebugScreenInit();
pspDebugScreenPrintf("\nConnected\n");
if(g_Server)
return 1;
else
return 0;
}
int adhocReconnect(char *ssid)
{
int err = 0;
// Disconnect Wifi
if(NetAdhocctlConnect)
{
printf("sceNetAdhocctlDisconnect\n");
err = sceNetAdhocctlDisconnect();
if(err != 0)
{
printf(" returned %x\n", err);
}
NetAdhocctlConnect = 0;
}
if(NetAdhocPdpCreate)
{
printf("sceNetAdhocPdpDelete\n");
err = sceNetAdhocPdpDelete(pdpId,0);
if(err != 0)
{
printf("sceNetAdhocPdpDelete returned %x\n", err);
}
NetAdhocPdpCreate = 0;
}
if(NetAdhocMatchingStart)
{
printf("sceNetAdhocMatchingStop\n");
err = sceNetAdhocMatchingStop(matchingId);
if(err != 0)
{
printf("sceNetAdhocMatchingStop returned %x\n", err);
}
NetAdhocMatchingStart = 0;
}
if(NetAdhocMatchingCreate)
{
printf("sceNetAdhocMatchingDelete\n");
err = sceNetAdhocMatchingDelete(matchingId);
if(err != 0)
{
printf("sceNetAdhocMatchingDelete returned %x\n", err);
}
NetAdhocMatchingCreate = 0;
}
if(NetAdhocMatchingInit)
{
printf("sceNetAdhocMatchingTerm\n");
err = sceNetAdhocMatchingTerm();
if(err != 0)
{
printf("sceNetAdhocMatchingTerm returned %x\n", err);
}
NetAdhocMatchingInit = 0;
}
int stateLast = -1;
while (1)
{
int state;
err = sceNetAdhocctlGetState(&state);
if (err != 0)
{
printf("sceNetApctlGetState returns $%x\n", err);
sceKernelDelayThread(10*1000000); // 10sec to read before exit
return -1;
}
if (state > stateLast)
{
printf(" connection state %d of 1\n", state);
stateLast = state;
}
if (state == 0)
break; // connected
// wait a little before polling again
sceKernelDelayThread(50*1000); // 50ms
}
// Now connect to the PSP using a new SSID
// Connect
err = sceNetAdhocctlConnect(ssid);
if (err != 0)
{
printf("err=%x\n", err);
for(;;)
sceDisplayWaitVblankStart();
return err;
}
NetAdhocctlConnect = 1;
stateLast = -1;
printf("Connecting...\n");
while (1)
{
int state;
err = sceNetAdhocctlGetState(&state);
if (err != 0)
{
printf("sceNetApctlGetState returns $%x\n", err);
sceKernelDelayThread(10*1000000); // 10sec to read before exit
return -1;
}
if (state > stateLast)
{
printf(" connection state %d of 1\n", state);
stateLast = state;
}
if (state == 1)
break; // connected
// wait a little before polling again
sceKernelDelayThread(50*1000); // 50ms
}
char macAddr[10];
sceWlanGetEtherAddr(macAddr);
printf("sceNetAdhocPdpCreate\n");
pdpId = sceNetAdhocPdpCreate(macAddr,
0x309, // 0x309 in lumines
0x800, // 0x400 in lumines
0); // 0 in lumines
if(pdpId <= 0)
{
printf("pdpId = %x\n", pdpId);
return -1;
}
NetAdhocPdpCreate = 1;
}
int adhocSend(void *buffer, int length)
{
int err=0;
err = sceNetAdhocPdpSend(pdpId,
&g_mac[0],
0x309,
buffer,
length,
0, // 0 in lumines
1); // 1 in lumines
return err;
}
// Used to send the data and wait for an ack
int adhocSendRecvAck(void *buffer, int length)
{
int err=0;
int recvTemp=0;
int recvLen=1;
int tempLen = length;
int sentCount = 0;
do
{
if(tempLen > 0x400)
{
tempLen = 0x400;
}
//pspDebugScreenPrintf("server waiting..1\n\n");
//sceKernelDelayThread(5000000);
err = adhocSend(buffer, tempLen);
if(err < 0)
return err;
//pspDebugScreenPrintf("server waiting..2\n\n");
//sceKernelDelayThread(5000000);
// wait for an ack
err = adhocRecvBlocked(&recvTemp, &recvLen);
if(err < 0)
{
pspDebugScreenPrintf("err=%x\n", err);
return err;
}
buffer += 0x400;
sentCount += 0x400;
tempLen = length - sentCount;
} while(sentCount < length);
return err;
}
// Used to receive data and then send an ack
int adhocRecvSendAck(void *buffer, unsigned int *length)
{
int temp=1;
int err=0;
int tempLen = *length;
int rcvdCount = 0;
do
{
if(tempLen > 0x400)
{
tempLen = 0x400;
}
err = adhocRecvBlocked(buffer, length);
if(err < 0)
return err;
err = adhocSend(&temp, 1);
rcvdCount += 0x400;
buffer += 0x400;
tempLen = *length - rcvdCount;
} while(rcvdCount < *length);
// wait for an ack
return err;
}
int adhocRecv(void *buffer, unsigned int *length)
{
int err=0;
int pdpStatLength=20;
unsigned int pdpRecvLength=0;
unsigned short port=0;
char mac[20];
pdpStatStruct pspStat;
err = sceNetAdhocGetPdpStat(&pdpStatLength, &pspStat);
if(err<0)
{
printf("error calling GetPdpStat, err=%x\n", err);
return err;
}
if(pspStat.rcvdData > 0)
{
pdpRecvLength = pspStat.rcvdData;
err = sceNetAdhocPdpRecv(pdpId,
mac,
&port,
buffer,
&length,
0, // 0 in lumines
1); // 1 in lumines
if(err<0)
{
printf("err=%x\n", err);
return err;
}
else
{
return 1;
}
}
return 0;
}
int adhocRecvBlocked(void *buffer, unsigned int *length)
{
char mac[20];
int port=309;
int err=0;
do
{
err = adhocRecv(buffer, length);
sceKernelDelayThread(1000);
} while (err == 0);
return err;
}
int adhocTerm()
{
u32 err;
if(NetAdhocctlConnect)
{
printf("sceNetAdhocctlDisconnect\n");
err = sceNetAdhocctlDisconnect();
if(err != 0)
{
printf(" returned %x\n", err);
}
NetAdhocctlConnect = 0;
}
if(NetAdhocPdpCreate)
{
printf("sceNetAdhocPdpDelete\n");
err = sceNetAdhocPdpDelete(pdpId,0);
if(err != 0)
{
printf("sceNetAdhocPdpDelete returned %x\n", err);
}
NetAdhocPdpCreate = 0;
}
if(NetAdhocMatchingStart)
{
printf("sceNetAdhocMatchingStop\n");
err = sceNetAdhocMatchingStop(matchingId);
if(err != 0)
{
printf("sceNetAdhocMatchingStop returned %x\n", err);
}
NetAdhocMatchingStart = 0;
}
if(NetAdhocMatchingCreate)
{
printf("sceNetAdhocMatchingDelete\n");
err = sceNetAdhocMatchingDelete(matchingId);
if(err != 0)
{
printf("sceNetAdhocMatchingDelete returned %x\n", err);
}
NetAdhocMatchingCreate = 0;
}
if(NetAdhocMatchingInit)
{
printf("sceNetAdhocMatchingTerm\n");
err = sceNetAdhocMatchingTerm();
if(err != 0)
{
printf("sceNetAdhocMatchingTerm returned %x\n", err);
}
NetAdhocMatchingInit = 0;
}
if(NetAdhocctlInit)
{
printf("sceNetAdhocctlTerm\n");
err = sceNetAdhocctlTerm();
if(err != 0)
{
printf("sceNetAdhocctlTerm returned %x\n", err);
}
NetAdhocctlInit = 0;
}
if(NetAdhocInit)
{
printf("\nTerminating Adhoc...");
int adhocTerm = sceNetAdhocTerm();
if (adhocTerm < 0) printf("Error terminating Adhoc 0x%08X", adhocTerm);
else printf("Done.");
sceKernelDelayThread(1000000*3);
NetAdhocInit = 0;
}
if(NetInit)
{
printf("sceNetTerm\n");
err = sceNetTerm();
if(err != 0)
{
printf("sceNetTerm returned %x\n", err);
}
NetInit = 0;
}
return 0; // assume it worked
}
/* var init */
int done, err, i, loop, server, size = 0;
unsigned int length;
char *data;
char send_buffer[128*1024];
char rec_buffer[128*1024];
int copy_file(const char *path, int service)
{
if (service == 1)
{
int fileCheck;
fileCheck = sceIoOpen(path, PSP_O_RDONLY, 0);
sceIoClose(fileCheck);
if(fileCheck > -1)
{
int fdin;
int fdout;
fdin = sceIoOpen(path, PSP_O_RDONLY, 0777);
if(fdin >= 0) {
int bytesRead = 1;
bytesRead = sceIoRead(fdin, send_buffer, sizeof(send_buffer));
char *data;
while((bytesRead > 0) && (fdout >= 0)) {
bytesRead = sceIoRead(fdin, send_buffer, sizeof(send_buffer));
}
data = send_buffer;
size = strlen(data);
adhocSend(&size, 4);
adhocSend(&send_buffer, size);
printf("\nSize of Data: %d", size);
printf("\nBytes Read: %d", bytesRead);
printf("\nBuffer: %s", send_buffer);
if(fdin >= 0) sceIoClose(fdin);
}
return 1;
}
}
else if (service == 2)
{
int fdout;
fdout = sceIoOpen(path, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
long int bytesWritten = 0;
int length = 4;
adhocRecvSendAck(&size, &length);
while((bytesWritten < size) && (fdout >= 0))
{
adhocRecvSendAck(&rec_buffer, &size);
bytesWritten = sceIoWrite(fdout, rec_buffer, sizeof(rec_buffer));
}
printf("\nSize of Data: %d", size);
printf("\nBytes Recieved: %d", sizeof(rec_buffer));
printf("\nBytes Written: %d", bytesWritten);
printf("\nBuffer: %s", rec_buffer);
if(fdout >= 0) sceIoClose(fdout);
return 1;
}
return 0;
}
int main(){
/* exit callback */
SetupCallbacks();
pspDebugScreenInit();
int utility = 0;
utility = sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
if (utility < 0)
{
printf("Error loading PSP_NET_MODULE_COMMON 0x%08X", utility);
}
utility = sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC);
if (utility < 0)
{
printf("Error loading PSP_NET_MODULE_ADHOC 0x%08X", utility);
}
server = 0; //We want to continue for as long as needed (server>=0)
while(server>=0) //server becomes -1 when trying to quit
{
pspDebugScreenSetXY(0,0);
/* adhoc initalise functions */
if((adhocInit("") >= 0) && ((server = adhocSelect()) >=0)){
printf("\n\n## AdHoc INITALISED ##\n\n");
sceKernelDelayThread(1000000);
/* Display server, or client */
if(server) printf("Server Assigned\n\n");
else printf("Client Assigned\n\n");
/* if this psp is the server */
if(server){
sceKernelDelayThread(1000000);
/* client must be waiting for server, so slight delay for server */
// alphabet string
data = "abcdefghijklmnopqrstuvwxyz";
size = sizeof(data);
printf("Sending data to the client.. size: %d \n", size);
err = adhocSendRecvAck(&size, 4); // let client know the size of data
printf("Done sending size: %d\ndata: %s\n", size, data);
sceKernelDelayThread(1000000);
err = adhocSendRecvAck(&data, 4); // send data as void
printf("Done sending data: %s\nsize: %d\n", data, size);
} else {
/* get data from server */
size = 0;
length = 4;
err = adhocRecvSendAck(&size, &length); // get size of data
printf("Done receiving size: %d \nlength: %d \n", size, length);
length = size;
err = adhocRecvSendAck(&data, &length); // get data
data = (char *)data; // type cast received data
printf("Received data from server: %s \n", data);
}
}
}
/* terminate adhoc */
adhocTerm();
sceKernelExitGame();
return 0;
}