Skip to content

Commit

Permalink
Merge pull request #13191 from hrydgard/upnp-thread-ANR2ME
Browse files Browse the repository at this point in the history
Do UPnP on a thread to avoid stutter. Extracted from #13132 by ANR2ME
  • Loading branch information
hrydgard committed Jul 23, 2020
2 parents 8eac711 + a6e3bed commit 3403e28
Show file tree
Hide file tree
Showing 11 changed files with 342 additions and 119 deletions.
53 changes: 16 additions & 37 deletions Core/HLE/proAdhoc.cpp
Expand Up @@ -102,27 +102,14 @@ bool isPTPPortInUse(uint16_t port) {
return false;
}

char* mac2str(SceNetEtherAddr* mac) {
#if defined(_WIN32)
static __declspec(thread) char str[18] = ":::::";
#elif !PPSSPP_PLATFORM(MAC) && !PPSSPP_PLATFORM(IOS)
static __thread char str[18] = ":::::";
#else
// Temporary hack to avoid huge rebase conflicts. Remove this when applying the mac2str rewrite.
static char str[18] = ":::::";
#endif
if (mac == NULL) return str;
snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);

return str;
}
std::string mac2str(SceNetEtherAddr* mac) {
char str[18] = ":::::";

char* mac2str(SceNetEtherAddr* mac, char* str, size_t size) {
if (mac == NULL || str == NULL || size < 18) return NULL;

snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
if (mac != NULL) {
snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
}

return str;
return std::string(str);
}

SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac) {
Expand All @@ -131,8 +118,7 @@ SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * contex
SceNetAdhocMatchingMemberInternal * peer = findPeer(context, mac);
// Already existed
if (peer != NULL) {
char tmpmac[18];
WARN_LOG(SCENET, "Member Peer Already Existed! Updating [%s]", mac2str(mac, tmpmac));
WARN_LOG(SCENET, "Member Peer Already Existed! Updating [%s]", mac2str(mac).c_str());
peer->lastping = CoreTiming::GetGlobalTimeUsScaled();
}
// Member is not added yet
Expand All @@ -158,9 +144,8 @@ void addFriend(SceNetAdhocctlConnectPacketS2C * packet) {
SceNetAdhocctlPeerInfo * peer = findFriend(&packet->mac);
// Already existed
if (peer != NULL) {
char tmpmac[18];
u32 tmpip = packet->ip;
WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", mac2str(&packet->mac, tmpmac), inet_ntoa(*(struct in_addr*)&tmpip), packet->name.data); //inet_ntoa(*(in_addr*)&packet->ip)
WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", mac2str(&packet->mac).c_str(), inet_ntoa(*(struct in_addr*)&tmpip), packet->name.data); //inet_ntoa(*(in_addr*)&packet->ip)
peer->nickname = packet->name;
peer->mac_addr = packet->mac;
peer->ip_addr = packet->ip;
Expand Down Expand Up @@ -348,9 +333,8 @@ void deleteFriendByIP(uint32_t ip) {
else prev->next = peer->next;
*/

char tmpmac[18];
u32 tmpip = peer->ip_addr;
INFO_LOG(SCENET, "Removing Friend Peer %s [%s]", mac2str(&peer->mac_addr, tmpmac), inet_ntoa(*(struct in_addr *)&tmpip)); //inet_ntoa(*(in_addr*)&peer->ip_addr)
INFO_LOG(SCENET, "Removing Friend Peer %s [%s]", mac2str(&peer->mac_addr).c_str(), inet_ntoa(*(struct in_addr *)&tmpip)); //inet_ntoa(*(in_addr*)&peer->ip_addr)

// Free Memory
//free(peer);
Expand Down Expand Up @@ -501,8 +485,7 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun
// Spawn Established Event
spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL);

char tmpmac[18];
INFO_LOG(SCENET, "Accepting Peer %s", mac2str(&sibling->mac, tmpmac));
INFO_LOG(SCENET, "Accepting Peer %s", mac2str(&sibling->mac).c_str());
}
}
}
Expand Down Expand Up @@ -628,8 +611,7 @@ void deletePeer(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingMemberI
// Beginning Item
else context->peerlist = item->next;

char tmpmac[18];
INFO_LOG(SCENET, "Removing Member Peer %s", mac2str(&peer->mac, tmpmac));
INFO_LOG(SCENET, "Removing Member Peer %s", mac2str(&peer->mac).c_str());
}

// Free Peer Memory
Expand Down Expand Up @@ -904,8 +886,7 @@ void handleTimeout(SceNetAdhocMatchingContext * context)
spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); // This is the only code that use PSP_ADHOC_MATCHING_EVENT_TIMEOUT, should we let it timedout?
}

char tmpmac[18];
INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac, tmpmac), (context->timeout/1000));
INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac).c_str(), (context->timeout/1000));

// Delete Peer from List
deletePeer(context, peer);
Expand Down Expand Up @@ -1236,8 +1217,7 @@ int friendFinder(){
// Cast Packet
SceNetAdhocctlConnectBSSIDPacketS2C* packet = (SceNetAdhocctlConnectBSSIDPacketS2C*)rx;

char tmpmac[18];
INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac, tmpmac));
INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac).c_str());
// From JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?)
/*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) {
setState(ADHOCCTL_STATE_GAMEMODE);
Expand Down Expand Up @@ -1316,7 +1296,7 @@ int friendFinder(){

// Log Incoming Peer
u32_le ipaddr = packet->ip;
INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT [%s][%s][%s]", mac2str(&packet->mac), inet_ntoa(*(in_addr*)&ipaddr), packet->name.data);
INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT [%s][%s][%s]", mac2str(&packet->mac).c_str(), inet_ntoa(*(in_addr*)&ipaddr), packet->name.data);

// Add User
addFriend(packet);
Expand Down Expand Up @@ -1661,12 +1641,11 @@ uint16_t getLocalPort(int sock) {
}

int getSockMaxSize(int udpsock) {
#if !defined(SO_MAX_MSG_SIZE)
#define SO_MAX_MSG_SIZE 0x2003
#endif
int n = 1500; // Typical MTU size as default
#if defined(SO_MAX_MSG_SIZE) // May not be available on all platform
socklen_t m = sizeof(n);
getsockopt(udpsock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*)&n, &m);
#endif
return n;
}

Expand Down
3 changes: 1 addition & 2 deletions Core/HLE/proAdhoc.h
Expand Up @@ -893,8 +893,7 @@ bool isPDPPortInUse(uint16_t port);
*/
bool isPTPPortInUse(uint16_t port);

char* mac2str(SceNetEtherAddr* mac);
char* mac2str(SceNetEtherAddr* mac, char* str, size_t size = 18);
std::string mac2str(SceNetEtherAddr* mac);

/*
* Matching Members
Expand Down
4 changes: 2 additions & 2 deletions Core/HLE/proAdhocServer.cpp
Expand Up @@ -1685,13 +1685,13 @@ int proAdhocServerThread(int port) // (int argc, char * argv[])
INFO_LOG(SCENET, "AdhocServer: Listening for Connections on TCP Port %u", port); //SERVER_PORT

// Port forward
g_PortManager.Add(IP_PROTOCOL_TCP, port);
UPnP_Add(IP_PROTOCOL_TCP, port); // g_PortManager.Add(IP_PROTOCOL_TCP, port);

// Enter Server Loop
result = server_loop(server);

// Remove Port mapping
g_PortManager.Remove(IP_PROTOCOL_TCP, port);
UPnP_Remove(IP_PROTOCOL_TCP, port); // g_PortManager.Remove(IP_PROTOCOL_TCP, port);

// Notify User
INFO_LOG(SCENET, "AdhocServer: Shutdown complete");
Expand Down
22 changes: 7 additions & 15 deletions Core/HLE/sceNet.cpp
Expand Up @@ -123,32 +123,24 @@ void __NetInit() {

InitLocalhostIP();

char tmpmac[18];
SceNetEtherAddr mac;
getLocalMac(&mac);
INFO_LOG(SCENET, "LocalHost IP will be %s [MAC: %s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac));

// Only initialize when UPnP is enabled since it takes a few seconds to detect UPnP device (may affect people who don't have UPnP device)
if (g_Config.bEnableUPnP) {
// TODO: May be we should initialize & cleanup somewhere else than here for PortManager to be used as general purpose for whatever port forwarding PPSSPP needed
g_PortManager.Initialize();
}
INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac).c_str());

// TODO: May be we should initialize & cleanup somewhere else than here for PortManager to be used as general purpose for whatever port forwarding PPSSPP needed
__UPnPInit();

__ResetInitNetLib();
}

void __NetShutdown() {
// Network Cleanup
Net_Term();

__ResetInitNetLib();

// Since PortManager supposed to be general purpose for whatever port forwarding PPSSPP needed, may be we shouldn't clear & restore ports in here? it will be cleared and restored by PortManager's destructor when exiting PPSSPP anyway
if (g_PortManager.GetInitState() == UPNP_INITSTATE_DONE) {
g_PortManager.Clear();
g_PortManager.Restore();
g_PortManager.Terminate();
}
__UPnPShutdown();
}

static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) {
Expand Down Expand Up @@ -424,7 +416,7 @@ static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) {
}
}

VERBOSE_LOG(SCENET, "sceNetEtherStrton - [%s]", mac2str((SceNetEtherAddr*)Memory::GetPointer(macPtr)));
VERBOSE_LOG(SCENET, "sceNetEtherStrton - [%s]", mac2str((SceNetEtherAddr*)Memory::GetPointer(macPtr)).c_str());
// Seems to maybe kinda return the last value. Probably returns void.
//return value;
}
Expand Down

0 comments on commit 3403e28

Please sign in to comment.