Moves proAdhoc extra functions to a separate file

This commit is contained in:
Igor Calabria 2013-11-10 01:26:31 +00:00
parent f3f0bc231b
commit 33f4b44061
4 changed files with 1328 additions and 1259 deletions

View File

@ -848,6 +848,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/HLE/sceNet.h
Core/HLE/sceNetAdhoc.cpp
Core/HLE/sceNetAdhoc.h
Core/HLE/proAdhoc.h
Core/HLE/proAdhoc.cpp
Core/HLE/sceOpenPSID.cpp
Core/HLE/sceOpenPSID.h
Core/HLE/sceP3da.cpp

700
Core/HLE/proAdhoc.cpp Normal file
View File

@ -0,0 +1,700 @@
#include "proAdhoc.h"
uint32_t fakePoolSize = 0;
SceNetAdhocMatchingContext * contexts = NULL;
int one = 1;
bool friendFinderRunning = false;
SceNetAdhocctlPeerInfo * friends = NULL;
SceNetAdhocctlScanInfo * networks = NULL;
int eventHandlerUpdate = -1;
int threadStatus = ADHOCCTL_STATE_DISCONNECTED;
int metasocket;
SceNetAdhocctlParameter parameter;
std::thread friendFinderThread;
recursive_mutex peerlock;
SceNetAdhocPdpStat * pdp[255];
SceNetAdhocPtpStat * ptp[255];
int isLocalMAC(const SceNetEtherAddr * addr) {
SceNetEtherAddr saddr;
getLocalMac(&saddr);
// Compare MAC Addresses
int match = memcmp((const void *)addr, (const void *)&saddr, ETHER_ADDR_LEN);
// Return Result
return (match == 0);
}
int isPDPPortInUse(uint16_t port) {
// Iterate Elements
int i = 0; for(; i < 255; i++) if(pdp[i] != NULL && pdp[i]->lport == port) return 1;
// Unused Port
return 0;
}
int isPTPPortInUse(uint16_t port) {
// Iterate Sockets
int i = 0; for(; i < 255; i++) if(ptp[i] != NULL && ptp[i]->lport == port) return 1;
// Unused Port
return 0;
}
void addFriend(SceNetAdhocctlConnectPacketS2C * packet) {
// Allocate Structure
SceNetAdhocctlPeerInfo * peer = (SceNetAdhocctlPeerInfo *)malloc(sizeof(SceNetAdhocctlPeerInfo));
// Allocated Structure
if(peer != NULL) {
// Clear Memory
memset(peer, 0, sizeof(SceNetAdhocctlPeerInfo));
// Link to existing Peers
peer->next = friends;
// Save Nickname
peer->nickname = packet->name;
// Save MAC Address
peer->mac_addr = packet->mac;
// Save IP Address
peer->ip_addr = packet->ip;
// Multithreading Lock
peerlock.lock();
// Link into Peerlist
friends = peer;
// Multithreading Unlock
peerlock.unlock();
}
}
void changeBlockingMode(int fd, int nonblocking) {
unsigned long on = 1;
unsigned long off = 0;
#ifdef _MSC_VER
if(nonblocking){
// Change to Non-Blocking Mode
ioctlsocket(fd,FIONBIO,&on);
}else {
// Change to Blocking Mode
ioctlsocket(fd, FIONBIO, &off);
}
#else
if(nonblocking == 1) fcntl(fd, F_SETFL, O_NONBLOCK);
else {
// Get Flags
int flags = fcntl(fd, F_GETFL);
// Remove Non-Blocking Flag
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
}
#endif
}
int countAvailableNetworks(void) {
// Network Count
int count = 0;
// Group Reference
SceNetAdhocctlScanInfo * group = networks;
// Count Groups
for(; group != NULL; group = group->next) count++;
// Return Network Count
return count;
}
void deleteAllPDP(void) {
// Iterate Element
int i = 0; for(; i < 255; i++) {
// Active Socket
if(pdp[i] != NULL) {
// Close Socket
closesocket(pdp[i]->id);
// Free Memory
free(pdp[i]);
// Delete Reference
pdp[i] = NULL;
}
}
}
void deleteAllPTP(void) {
// Iterate Element
int i = 0; for(; i < 255; i++) {
// Active Socket
if(ptp[i] != NULL) {
// Close Socket
closesocket(ptp[i]->id);
// Free Memory
free(ptp[i]);
// Delete Reference
ptp[i] = NULL;
}
}
}
void deleteFriendByIP(uint32_t ip) {
// Previous Peer Reference
SceNetAdhocctlPeerInfo * prev = NULL;
// Peer Pointer
SceNetAdhocctlPeerInfo * peer = friends;
// Iterate Peers
for(; peer != NULL; peer = peer->next) {
// Found Peer
if(peer->ip_addr == ip) {
// Multithreading Lock
peerlock.lock();
// Unlink Left (Beginning)
if(prev == NULL)friends = peer->next;
// Unlink Left (Other)
else prev->next = peer->next;
// Multithreading Unlock
peerlock.unlock();
// Free Memory
free(peer);
// Stop Search
break;
}
// Set Previous Reference
prev = peer;
}
}
int findFreeMatchingID(void) {
// Minimum Matching ID
int min = 1;
// Maximum Matching ID
int max = 0;
// Find highest Matching ID
SceNetAdhocMatchingContext * item = contexts; for(; item != NULL; item = item->next) {
// New Maximum
if(max < item->id) max = item->id;
}
// Find unoccupied ID
int i = min; for(; i < max; i++) {
// Found unoccupied ID
if(findMatchingContext(i) == NULL) return i;
}
// Append at virtual end
return max + 1;
}
SceNetAdhocMatchingContext * findMatchingContext(int id) {
// Iterate Matching Context List
SceNetAdhocMatchingContext * item = contexts; for(; item != NULL; item = item->next) { // Found Matching ID
if(item->id == id) return item;
}
// Context not found
return NULL;
}
void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node) {
// End of List
if(node == NULL) return;
// Increase Recursion Depth
freeFriendsRecursive(node->next);
// Free Memory
free(node);
}
int friendFinder(){
// Receive Buffer
int rxpos = 0;
uint8_t rx[1024];
// Chat Packet
SceNetAdhocctlChatPacketC2S chat;
chat.base.opcode = OPCODE_CHAT;
// Last Ping Time
uint64_t lastping = 0;
// Last Time Reception got updated
uint64_t lastreceptionupdate = 0;
uint64_t now;
// Finder Loop
while(friendFinderRunning) {
// Acquire Network Lock
//_acquireNetworkLock();
// Ping Server
now = real_time_now()*1000.0;
if(now - lastping >= 100) {
// Update Ping Time
lastping = now;
// Prepare Packet
uint8_t opcode = OPCODE_PING;
// Send Ping to Server
send(metasocket, (const char *)&opcode, 1,0);
}
// Send Chat Messages
//while(popFromOutbox(chat.message))
//{
// // Send Chat to Server
// sceNetInetSend(metasocket, (const char *)&chat, sizeof(chat), 0);
//}
// Wait for Incoming Data
int received = recv(metasocket, (char *)(rx + rxpos), sizeof(rx) - rxpos,0);
// Free Network Lock
//_freeNetworkLock();
// Received Data
if(received > 0) {
// Fix Position
rxpos += received;
// Log Incoming Traffic
//printf("Received %d Bytes of Data from Server\n", received);
INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received);
}
// Handle Packets
if(rxpos > 0) {
// BSSID Packet
if(rx[0] == OPCODE_CONNECT_BSSID) {
// Enough Data available
if(rxpos >= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) {
// Cast Packet
SceNetAdhocctlConnectBSSIDPacketS2C * packet = (SceNetAdhocctlConnectBSSIDPacketS2C *)rx;
// Update BSSID
parameter.bssid.mac_addr = packet->mac;
// Change State
threadStatus = ADHOCCTL_STATE_CONNECTED;
// Notify Event Handlers
CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0));
// Move RX Buffer
memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C));
// Fix RX Buffer Length
rxpos -= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C);
}
}
// Chat Packet
else if(rx[0] == OPCODE_CHAT) {
// Enough Data available
if(rxpos >= sizeof(SceNetAdhocctlChatPacketS2C)) {
// Cast Packet
SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx;
// Fix for Idiots that try to troll the "ME" Nametag
#ifdef _MSC_VER
if(stricmp((char *)packet->name.data, "ME") == 0) strcpy((char *)packet->name.data, "NOT ME");
#else
if(strcasecmp((char *)packet->name.data, "ME") == 0) strcpy((char *)packet->name.data, "NOT ME");
#endif
// Add Incoming Chat to HUD
//printf("Receive chat message %s", packet->base.message);
// Move RX Buffer
memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C));
// Fix RX Buffer Length
rxpos -= sizeof(SceNetAdhocctlChatPacketS2C);
}
}
// Connect Packet
else if(rx[0] == OPCODE_CONNECT) {
// Enough Data available
if(rxpos >= sizeof(SceNetAdhocctlConnectPacketS2C)) {
// Log Incoming Peer
INFO_LOG(SCENET,"Incoming Peer Data...");
// Cast Packet
SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx;
// Add User
addFriend(packet);
// Update HUD User Count
#ifdef LOCALHOST_AS_PEER
setUserCount(getActivePeerCount());
#else
// setUserCount(getActivePeerCount()+1);
#endif
// Move RX Buffer
memmove(rx, rx + sizeof(SceNetAdhocctlConnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectPacketS2C));
// Fix RX Buffer Length
rxpos -= sizeof(SceNetAdhocctlConnectPacketS2C);
}
}
// Disconnect Packet
else if(rx[0] == OPCODE_DISCONNECT) {
// Enough Data available
if(rxpos >= sizeof(SceNetAdhocctlDisconnectPacketS2C)) {
// Log Incoming Peer Delete Request
INFO_LOG(SCENET,"FriendFinder: Incoming Peer Data Delete Request...");
// Cast Packet
SceNetAdhocctlDisconnectPacketS2C * packet = (SceNetAdhocctlDisconnectPacketS2C *)rx;
// Delete User by IP
deleteFriendByIP(packet->ip);
// Update HUD User Count
#ifdef LOCALHOST_AS_PEER
setUserCount(_getActivePeerCount());
#else
//setUserCount(_getActivePeerCount()+1);
#endif
// Move RX Buffer
memmove(rx, rx + sizeof(SceNetAdhocctlDisconnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlDisconnectPacketS2C));
// Fix RX Buffer Length
rxpos -= sizeof(SceNetAdhocctlDisconnectPacketS2C);
}
}
// Scan Packet
else if(rx[0] == OPCODE_SCAN) {
// Enough Data available
if(rxpos >= sizeof(SceNetAdhocctlScanPacketS2C)) {
// Log Incoming Network Information
INFO_LOG(SCENET,"Incoming Group Information...");
// Cast Packet
SceNetAdhocctlScanPacketS2C * packet = (SceNetAdhocctlScanPacketS2C *)rx;
// Allocate Structure Data
SceNetAdhocctlScanInfo * group = (SceNetAdhocctlScanInfo *)malloc(sizeof(SceNetAdhocctlScanInfo));
// Allocated Structure Data
if(group != NULL)
{
// Clear Memory
memset(group, 0, sizeof(SceNetAdhocctlScanInfo));
// Link to existing Groups
group->next = networks;
// Copy Group Name
group->group_name = packet->group;
// Set Group Host
group->bssid.mac_addr = packet->mac;
// Link into Group List
networks = group;
}
// Move RX Buffer
memmove(rx, rx + sizeof(SceNetAdhocctlScanPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlScanPacketS2C));
// Fix RX Buffer Length
rxpos -= sizeof(SceNetAdhocctlScanPacketS2C);
}
}
// Scan Complete Packet
else if(rx[0] == OPCODE_SCAN_COMPLETE) {
// Log Scan Completion
INFO_LOG(SCENET,"FriendFinder: Incoming Scan complete response...");
// Change State
threadStatus = ADHOCCTL_STATE_DISCONNECTED;
// Notify Event Handlers
CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate,join32(ADHOCCTL_EVENT_SCAN, 0));
//int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++)
//{
// // Active Handler
// if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]);
//}
// Move RX Buffer
memmove(rx, rx + 1, sizeof(rx) - 1);
// Fix RX Buffer Length
rxpos -= 1;
}
}
// Original value was 10 ms, I think 100 is just fine
sleep_ms(100);
}
// Log Shutdown
INFO_LOG(SCENET, "FriendFinder: End of Friend Finder Thread");
// Return Success
return 0;
}
int getActivePeerCount(void) {
// Counter
int count = 0;
// #ifdef LOCALHOST_AS_PEER
// // Increase for Localhost
// count++;
// #endif
// Peer Reference
SceNetAdhocctlPeerInfo * peer = friends;
// Iterate Peers
for(; peer != NULL; peer = peer->next) {
// Increase Counter
count++;
}
// Return Result
return count;
}
int getLocalIp(sockaddr_in * SocketAddress){
#ifdef _MSC_VER
// Get local host name
char szHostName[128] = "";
if(::gethostname(szHostName, sizeof(szHostName))) {
// Error handling
}
// Get local IP addresses
struct hostent *pHost = 0;
pHost = ::gethostbyname(szHostName);
if(pHost) {
memcpy(&SocketAddress->sin_addr, pHost->h_addr_list[0], pHost->h_length);
return 0;
}
return -1;
#else
char ip[] = "192.168.12.1";
SocketAddress->sin_addr.s_addr = inet_addr("192.168.12.1");
return 0;
#endif
}
void getLocalMac(SceNetEtherAddr * addr){
uint8_t mac[] = {1, 2, 3, 4, 5, 6};
memcpy(addr,mac,ETHER_ADDR_LEN);
}
int getPTPSocketCount(void) {
// Socket Counter
int counter = 0;
// Count Sockets
int i = 0; for(; i < 255; i++) if(ptp[i] != NULL) counter++;
// Return Socket Count
return counter;
}
int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
int iResult = 0;
#ifdef _MSC_VER
WSADATA data;
iResult = WSAStartup(MAKEWORD(2,2),&data);
if(iResult != NOERROR){
ERROR_LOG(SCENET, "Wsa failed");
return iResult;
}
#endif
metasocket = INVALID_SOCKET;
metasocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
if(metasocket == INVALID_SOCKET){
ERROR_LOG(SCENET,"invalid socket");
return INVALID_SOCKET;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(27312); // Maybe read this from config too
// Resolve dns
addrinfo * resultAddr;
iResult = getaddrinfo(g_Config.proAdhocServer.c_str(),0,NULL,&resultAddr);
if(iResult != 0){
ERROR_LOG(SCENET, "Dns error\n");
return iResult;
}
server_addr.sin_addr.s_addr = ((sockaddr_in *)resultAddr->ai_addr)->sin_addr.s_addr;
iResult = connect(metasocket,(sockaddr *)&server_addr,sizeof(server_addr));
if(iResult == SOCKET_ERROR){
ERROR_LOG(SCENET,"Socket error");
return iResult;
}
memset(&parameter,0,sizeof(parameter));
strcpy((char *)&parameter.nickname.data, g_Config.sNickName.c_str());
parameter.channel = 1; // Fake Channel 1
// Prepare Login Packet
getLocalMac(&parameter.bssid.mac_addr);
SceNetAdhocctlLoginPacketC2S packet;
packet.base.opcode = OPCODE_LOGIN;
SceNetEtherAddr addres;
getLocalMac(&addres);
packet.mac = addres;
strcpy((char *)packet.name.data, g_Config.sNickName.c_str());
memcpy(packet.game.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN);
int sent = send(metasocket, (char*)&packet, sizeof(packet), 0);
changeBlockingMode(metasocket,1); // Change to non-blocking
if(sent > 0){
return 0;
}else{
return -1;
}
}
int isBroadcastMAC(const SceNetEtherAddr * addr) {
// Broadcast MAC
if(memcmp(addr->data, "\xFF\xFF\xFF\xFF\xFF\xFF", ETHER_ADDR_LEN) == 0) return 1;
// Normal MAC
return 0;
}
int resolveIP(uint32_t ip, SceNetEtherAddr * mac) {
sockaddr_in addr;
getLocalIp(&addr);
uint32 localIp = addr.sin_addr.s_addr;
if(ip == localIp){
getLocalMac(mac);
return 0;
}
// Multithreading Lock
peerlock.lock();
// Peer Reference
SceNetAdhocctlPeerInfo * peer = friends;
// Iterate Peers
for(; peer != NULL; peer = peer->next) {
// Found Matching Peer
if(peer->ip_addr == ip) {
// Copy Data
*mac = peer->mac_addr;
// Multithreading Unlock
peerlock.unlock();
// Return Success
return 0;
}
}
// Multithreading Unlock
peerlock.unlock();
// Peer not found
return -1;
}
int resolveMAC(SceNetEtherAddr * mac, uint32_t * ip) {
// Get Local MAC Address
SceNetEtherAddr localMac;
getLocalMac(&localMac);
// Local MAC Requested
if(memcmp(&localMac, mac, sizeof(SceNetEtherAddr)) == 0) {
// Get Local IP Address
sockaddr_in sockAddr;
getLocalIp(&sockAddr);
*ip = sockAddr.sin_addr.s_addr;
return 0; // return succes
}
// Multithreading Lock
peerlock.lock();
// Peer Reference
SceNetAdhocctlPeerInfo * peer = friends;
// Iterate Peers
for(; peer != NULL; peer = peer->next) {
// Found Matching Peer
if(memcmp(&peer->mac_addr, mac, sizeof(SceNetEtherAddr)) == 0) {
// Copy Data
*ip = peer->ip_addr;
// Multithreading Unlock
peerlock.unlock();
// Return Success
return 0;
}
}
// Multithreading Unlock
peerlock.unlock();
// Peer not found
return -1;
}
int validNetworkName(const SceNetAdhocctlGroupName * group_name) {
// Result
int valid = 1;
// Name given
if(group_name != NULL) {
// Iterate Name Characters
int i = 0; for(; i < ADHOCCTL_GROUPNAME_LEN && valid; i++) {
// End of Name
if(group_name->data[i] == 0) break;
// Not a digit
if(group_name->data[i] < '0' || group_name->data[i] > '9') {
// Not 'A' to 'Z'
if(group_name->data[i] < 'A' || group_name->data[i] > 'Z') {
// Not 'a' to 'z'
if(group_name->data[i] < 'a' || group_name->data[i] > 'z') {
// Invalid Name
valid = 0;
}
}
}
}
}
// Return Result
return valid;
}
u64 join32(u32 num1, u32 num2){
return (u64)num2 << 32 | num1;
}
void split64(u64 num, int buff[]){
int num1 = (int)(num&firstMask);
int num2 = (int)((num&secondMask)>>32);
buff[0] = num1;
buff[1] = num2;
}

586
Core/HLE/proAdhoc.h Normal file
View File

@ -0,0 +1,586 @@
#pragma once
#include "Common/ChunkFile.h"
#include "../Config.h"
#include "Core/HLE/HLE.h"
#include "../CoreTiming.h"
#include "Core/HLE/sceNetAdhoc.h"
#include "native/base/timeutil.h"
#include "native/base/mutex.h"
#include "sceKernel.h"
#include "sceKernelThread.h"
#include "sceKernelMutex.h"
#include "sceUtility.h"
#include "net/resolve.h"
#include <thread>
// Net stuff
#ifdef _MSC_VER
#include <WS2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#endif
#ifdef _MSC_VER
#define PACK
#else
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket close
#define PACK __attribute__((packed))
#endif
// psp strutcs and definitions
#define ADHOCCTL_MODE_ADHOC 0
#define ADHOCCTL_MODE_GAMEMODE 1
// Event Types for Event Handler
#define ADHOCCTL_EVENT_CONNECT 1
#define ADHOCCTL_EVENT_DISCONNECT 2
#define ADHOCCTL_EVENT_SCAN 3
// Internal Thread States
#define ADHOCCTL_STATE_DISCONNECTED 0
#define ADHOCCTL_STATE_CONNECTED 1
#define ADHOCCTL_STATE_SCANNING 2
#define ADHOCCTL_STATE_GAMEMODE 3
// Kernel Utility Netconf Adhoc Types
#define UTILITY_NETCONF_TYPE_CONNECT_ADHOC 2
#define UTILITY_NETCONF_TYPE_CREATE_ADHOC 4
#define UTILITY_NETCONF_TYPE_JOIN_ADHOC 5
// Kernel Utility States
#define UTILITY_NETCONF_STATUS_NONE 0
#define UTILITY_NETCONF_STATUS_INITIALIZE 1
#define UTILITY_NETCONF_STATUS_RUNNING 2
#define UTILITY_NETCONF_STATUS_FINISHED 3
#define UTILITY_NETCONF_STATUS_SHUTDOWN 4
// PTP Connection States
#define PTP_STATE_CLOSED 0
#define PTP_STATE_LISTEN 1
#define PTP_STATE_ESTABLISHED 4
#ifdef _MSC_VER
#pragma pack(push, 1)
#endif
// Ethernet Address
#define ETHER_ADDR_LEN 6
typedef struct SceNetEtherAddr {
uint8_t data[ETHER_ADDR_LEN];
} PACK SceNetEtherAddr;
// Adhoc Virtual Network Name
#define ADHOCCTL_GROUPNAME_LEN 8
typedef struct SceNetAdhocctlGroupName {
uint8_t data[ADHOCCTL_GROUPNAME_LEN];
} PACK SceNetAdhocctlGroupName;
// Virtual Network Host Information
typedef struct SceNetAdhocctlBSSId {
SceNetEtherAddr mac_addr;
uint8_t padding[2];
} PACK SceNetAdhocctlBSSId;
// Virtual Network Information
typedef struct SceNetAdhocctlScanInfo {
struct SceNetAdhocctlScanInfo * next;
s32_le channel;
SceNetAdhocctlGroupName group_name;
SceNetAdhocctlBSSId bssid;
s32_le mode;
} PACK SceNetAdhocctlScanInfo;
// Player Nickname
#define ADHOCCTL_NICKNAME_LEN 128
typedef struct SceNetAdhocctlNickname {
uint8_t data[ADHOCCTL_NICKNAME_LEN];
} PACK SceNetAdhocctlNickname;
// Active Virtual Network Information
typedef struct SceNetAdhocctlParameter {
s32_le channel;
SceNetAdhocctlGroupName group_name;
SceNetAdhocctlBSSId bssid;
SceNetAdhocctlNickname nickname;
} PACK SceNetAdhocctlParameter;
// Peer Information
typedef struct SceNetAdhocctlPeerInfo {
SceNetAdhocctlPeerInfo * next;
SceNetAdhocctlNickname nickname;
SceNetEtherAddr mac_addr;
u32_le ip_addr;
uint8_t padding[2];
u64_le last_recv;
} PACK SceNetAdhocctlPeerInfo;
// Peer Information with u32 pointers
typedef struct SceNetAdhocctlPeerInfoEmu {
u32_le next; // Changed the pointer to u32
SceNetAdhocctlNickname nickname;
SceNetEtherAddr mac_addr;
u32_le ip_addr;
u32 padding; // Changed the pointer to u32
u64_le last_recv;
} SceNetAdhocctlPeerInfoEmu;
// Game Mode Peer List
#define ADHOCCTL_GAMEMODE_MAX_MEMBERS 16
typedef struct SceNetAdhocctlGameModeInfo {
s32_le num;
SceNetEtherAddr member[ADHOCCTL_GAMEMODE_MAX_MEMBERS];
} PACK SceNetAdhocctlGameModeInfo;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
// Adhoc ID (Game Product Key)
#define ADHOCCTL_ADHOCID_LEN 9
typedef struct SceNetAdhocctlAdhocId {
s32_le type;
uint8_t data[ADHOCCTL_ADHOCID_LEN];
uint8_t padding[3];
} SceNetAdhocctlAdhocId;
// Socket Polling Event Listener
struct SceNetAdhocPollSd {
s32_le id;
s32_le events;
s32_le revents;
};
// PDP Socket Status
struct SceNetAdhocPdpStat {
struct SceNetAdhocPdpStat * next;
s32_le id;
SceNetEtherAddr laddr;
u16_le lport;
u32_le rcv_sb_cc;
};
// PTP Socket Status
struct SceNetAdhocPtpStat {
u32_le next; // Changed the pointer to u32
s32_le id;
SceNetEtherAddr laddr;
SceNetEtherAddr paddr;
u16_le lport;
u16_le pport;
u32_le snd_sb_cc;
u32_le rcv_sb_cc;
s32_le state;
};
// Gamemode Optional Peer Buffer Data
struct SceNetAdhocGameModeOptData {
u32_le size;
u32_le flag;
u64_le last_recv;
};
// Gamemode Buffer Status
struct SceNetAdhocGameModeBufferStat {
struct SceNetAdhocGameModeBufferStat * next;
s32_le id;
void * ptr;
u32_le size;
u32_le master;
SceNetAdhocGameModeOptData opt;
};
// Internal Matching Peer Information
typedef struct SceNetAdhocMatchingMemberInternal {
// Next Peer
struct SceNetAdhocMatchingMemberInternal * next;
// MAC Address
SceNetEtherAddr mac;
// State Variable
s32_le state;
// Send in Progress
s32_le sending;
// Last Heartbeat
u64_le lastping;
} SceNetAdhocMatchingMemberInternal;
// Matching handler
struct SceNetAdhocMatchingHandlerArgs {
s32_le id;
s32_le event;
SceNetEtherAddr * peer;
s32_le optlen;
void * opt;
};
struct SceNetAdhocMatchingHandler {
u32_le entryPoint;
};
// Thread Message Stack Item
typedef struct ThreadMessage {
// Next Thread Message
struct ThreadMessage * next;
// Stack Event Opcode
u32_le opcode;
// Target MAC Address
SceNetEtherAddr mac;
// Optional Data Length
s32_le optlen;
} ThreadMessage;
// Established Peer
// Context Information
typedef struct SceNetAdhocMatchingContext {
// Next Context
struct SceNetAdhocMatchingContext * next;
// Externally Visible ID
s32_le id;
// Matching Mode (HOST, CLIENT, P2P)
s32_le mode;
// Running Flag (1 = running, 0 = created)
s32_le running;
// Maximum Number of Peers (for HOST, P2P)
s32_le maxpeers;
// Local MAC Address
SceNetEtherAddr mac;
// Peer List for Connectees
SceNetAdhocMatchingMemberInternal * peerlist;
// Local PDP Port
u16_le port;
// Local PDP Socket
s32_le socket;
// Receive Buffer Length
s32_le rxbuflen;
// Receive Buffer
uint8_t * rxbuf;
// Hello Broadcast Interval (Microseconds)
u32_le hello_int;
// Keep-Alive Broadcast Interval (Microseconds)
u32_le keepalive_int;
// Resend Interval (Microseconds)
u32_le resend_int;
// Resend-Counter
s32_le resendcounter;
// Keep-Alive Counter
s32_le keepalivecounter;
// Event Handler
SceNetAdhocMatchingHandler handler;
// Hello Data Length
u32_le hellolen;
// Hello Data
void * hello;
// Event Caller Thread
s32_le event_thid;
// IO Handler Thread
s32_le input_thid;
// Event Caller Thread Message Stack
s32_le event_stack_lock;
ThreadMessage * event_stack;
// IO Handler Thread Message Stack
s32_le input_stack_lock;
ThreadMessage * input_stack;
} SceNetAdhocMatchingContext;
// End of psp definitions
#define OPCODE_PING 0
#define OPCODE_LOGIN 1
#define OPCODE_CONNECT 2
#define OPCODE_DISCONNECT 3
#define OPCODE_SCAN 4
#define OPCODE_SCAN_COMPLETE 5
#define OPCODE_CONNECT_BSSID 6
#define OPCODE_CHAT 7
// PSP Product Code
#define PRODUCT_CODE_LENGTH 9
#ifdef _MSC_VER
#pragma pack(push,1)
#endif
typedef struct {
// Game Product Code (ex. ULUS12345)
char data[PRODUCT_CODE_LENGTH];
} PACK SceNetAdhocctlProductCode;
// Basic Packet
typedef struct {
uint8_t opcode;
} PACK SceNetAdhocctlPacketBase;
// C2S Login Packet
typedef struct {
SceNetAdhocctlPacketBase base;
SceNetEtherAddr mac;
SceNetAdhocctlNickname name;
SceNetAdhocctlProductCode game;
} PACK SceNetAdhocctlLoginPacketC2S;
// C2S Connect Packet
typedef struct {
SceNetAdhocctlPacketBase base;
SceNetAdhocctlGroupName group;
} PACK SceNetAdhocctlConnectPacketC2S;
// C2S Chat Packet
typedef struct {
SceNetAdhocctlPacketBase base;
char message[64];
} PACK SceNetAdhocctlChatPacketC2S;
// S2C Connect Packet
typedef struct {
SceNetAdhocctlPacketBase base;
SceNetAdhocctlNickname name;
SceNetEtherAddr mac;
uint32_t ip;
} PACK SceNetAdhocctlConnectPacketS2C;
// S2C Disconnect Packet
typedef struct {
SceNetAdhocctlPacketBase base;
uint32_t ip;
} PACK SceNetAdhocctlDisconnectPacketS2C;
// S2C Scan Packet
typedef struct {
SceNetAdhocctlPacketBase base;
SceNetAdhocctlGroupName group;
SceNetEtherAddr mac;
} PACK SceNetAdhocctlScanPacketS2C;
// S2C Connect BSSID Packet
typedef struct {
SceNetAdhocctlPacketBase base;
SceNetEtherAddr mac;
} PACK SceNetAdhocctlConnectBSSIDPacketS2C;
// S2C Chat Packet
typedef struct {
SceNetAdhocctlChatPacketC2S base;
SceNetAdhocctlNickname name;
} PACK SceNetAdhocctlChatPacketS2C;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
// Aux vars
extern int metasocket;
extern SceNetAdhocctlParameter parameter;
extern std::thread friendFinderThread;
extern recursive_mutex peerlock;
extern SceNetAdhocPdpStat * pdp[255];
extern SceNetAdhocPtpStat * ptp[255];
extern uint32_t fakePoolSize;
extern SceNetAdhocMatchingContext * contexts;
extern int one;
extern bool friendFinderRunning;
extern SceNetAdhocctlPeerInfo * friends;
extern SceNetAdhocctlScanInfo * networks;
extern int eventHandlerUpdate;
extern int threadStatus;
// End of Aux vars
/**
* Local MAC Check
* @param saddr To-be-checked MAC Address
* @return 1 if valid or... 0
*/
int isLocalMAC(const SceNetEtherAddr * addr);
/**
* PDP Port Check
* @param port To-be-checked Port
* @return 1 if in use or... 0
*/
int isPDPPortInUse(uint16_t port);
/**
* Check whether PTP Port is in use or not
* @param port To-be-checked Port Number
* @return 1 if in use or... 0
*/
int isPTPPortInUse(uint16_t port);
/**
* Add Friend to Local List
* @param packet Friend Information
*/
void addFriend(SceNetAdhocctlConnectPacketS2C * packet);
/**
* Changes the Blocking Mode of the socket
* @param fd File Descriptor of the socket
* @param nonblocking 1 to set to nonblock and 0 to set blocking
*/
void changeBlockingMode(int fd, int nonblocking);
/**
* Count Virtual Networks by analyzing the Friend List
* @return Number of Virtual Networks
*/
int countAvailableNetworks();
/**
* Closes & Deletes all PDP Sockets
*/
void deleteAllPDP(void);
/**
* Closes & Deletes all PTP sockets
*/
void deleteAllPTP(void);
/**
* Delete Friend from Local List
* @param ip Friend IP
*/
void deleteFriendByIP(uint32_t ip);
/**
* Find Free Matching ID
* @return First unoccupied Matching ID
*/
int findFreeMatchingID(void);
/**
* Find Internal Matching Context for Matching ID
* @param id Matching ID
* @return Matching Context Pointer or... NULL
*/
SceNetAdhocMatchingContext * findMatchingContext(int id);
/**
* Recursive Memory Freeing-Helper for Friend-Structures
* @param node Current Node in List
*/
void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node);
/**
* Friend Finder Thread (Receives Peer Information)
* @param args Length of argp in Bytes (Unused)
* @param argp Argument (Unused)
* @return Unused Value - Return 0
*/
int friendFinder();
/**
* Return Number of active Peers in the same Network as the Local Player
* @return Number of active Peers
*/
int getActivePeerCount(void);
/**
* Returns the locall Ip of this machine, TODO: Implement the linux version
* @param SocketAddres OUT: local ip
*/
int getLocalIp(sockaddr_in * SocketAddress);
/**
* Joins two 32 bits number into a 64 bit one
* @param num1: first number
* @param num2: second number
* @return Single 64 bit number
*/
#define firstMask 0x00000000FFFFFFFF
#define secondMask 0xFFFFFFFF00000000
u64 join32(u32 num1, u32 num2);
/**
* Splits a 64 bit number into two 32 bit ones
* @param num: The number to be split
* @param buf OUT: Array containing the split numbers
*/
void split64(u64 num, int buff[]);
/**
* Returns the local mac, TODO: Read from Config file
* @param addr OUT: Local Mac
*/
void getLocalMac(SceNetEtherAddr * addr);
/**
* PTP Socket Counter
* @return Number of internal PTP Sockets
*/
int getPTPSocketCount(void);
/**
* Initialize Networking Components for Adhocctl Emulator
* @param adhoc_id Game Product Code
* @param server_ip Server IP
* @return 0 on success or... -1
*/
int initNetwork(SceNetAdhocctlAdhocId *adhocid);
/**
* Broadcast MAC Check
* @param addr To-be-checked MAC Address
* @return 1 if Broadcast MAC or... 0
*/
int isBroadcastMAC(const SceNetEtherAddr * addr);
/**
* Resolve IP to MAC
* @param ip Peer IP Address
* @param mac OUT: Peer MAC
* @return 0 on success or... ADHOC_NO_ENTRY
*/
int resolveIP(uint32_t ip, SceNetEtherAddr * mac);
/**
* Resolve MAC to IP
* @param mac Peer MAC Address
* @param ip OUT: Peer IP
* @return 0 on success or... ADHOC_NO_ENTRY
*/
int resolveMAC(SceNetEtherAddr * mac, uint32_t * ip);
/**
* Check whether Network Name contains only valid symbols
* @param group_name To-be-checked Network Name
* @return 1 if valid or... 0
*/
int validNetworkName(const SceNetAdhocctlGroupName * groupname);

File diff suppressed because it is too large Load Diff