Merge pull request #14345 from ANR2ME/apctl

[APctl] Fix stuck issue when scanning AP to Recruit on MGS:PW
This commit is contained in:
Henrik Rydgård 2021-04-05 13:20:06 +02:00 committed by GitHub
commit bc4963b401
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 99 additions and 35 deletions

View File

@ -499,6 +499,12 @@ void __NetApctlCallbacks()
break;
case PSP_NET_APCTL_EVENT_SCAN_COMPLETE:
newState = PSP_NET_APCTL_STATE_DISCONNECTED;
if (error == 0)
apctlEvents.push_front({ newState, newState, PSP_NET_APCTL_EVENT_SCAN_STOP, 0 });
break;
case PSP_NET_APCTL_EVENT_SCAN_STOP:
newState = PSP_NET_APCTL_STATE_DISCONNECTED;
break;
@ -1158,7 +1164,7 @@ static int sceNetApctlGetState(u32 pStateAddr) {
return hleLogSuccessI(SCENET, 0);
}
return hleLogError(SCENET, -1, "apctl invalid arg");
return hleLogError(SCENET, -1, "apctl invalid arg"); // 0x8002013A or ERROR_NET_WLAN_INVALID_ARG ?
}
int NetApctl_ScanUser() {
@ -1175,13 +1181,12 @@ static int sceNetApctlScanUser() {
return NetApctl_ScanUser();
}
static int sceNetApctlGetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
WARN_LOG(SCENET, "UNTESTED %s(%08x, %08x)", __FUNCTION__, sizeAddr, bufAddr);
const int userInfoSize = 8;
int entries = 1;
if (!Memory::IsValidAddress(sizeAddr))
hleLogError(SCENET, -1, "apctl invalid arg");
int NetApctl_GetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
const int userInfoSize = 8; // 8 bytes per entry (next address + entry id)
// Faking 4 entries, games like MGS:PW Recruit will need to have a different AP for each entry
int entries = 4;
if (!Memory::IsValidAddress(sizeAddr) || !Memory::IsValidAddress(bufAddr))
return hleLogError(SCENET, -1, "apctl invalid arg"); // 0x8002013A or ERROR_NET_WLAN_INVALID_ARG ?
int size = Memory::Read_U32(sizeAddr);
// Return size required
@ -1195,10 +1200,10 @@ static int sceNetApctlGetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
break;
}
DEBUG_LOG(SCENET, "%s returning %d at %08x", __FUNCTION__, i, bufAddr + offset);
DEBUG_LOG(SCENET, "%s writing ID#%d to %08x", __FUNCTION__, i, bufAddr + offset);
// Pointer to next Network structure in list
Memory::Write_U32((i+1)*userInfoSize + bufAddr, bufAddr + offset);
Memory::Write_U32((i + 1) * userInfoSize + bufAddr, bufAddr + offset);
offset += 4;
// Entry ID
@ -1210,30 +1215,69 @@ static int sceNetApctlGetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
Memory::Write_U32(0, bufAddr + offset - userInfoSize);
}
return hleLogWarning(SCENET, 0, "untested");
return 0;
}
static int sceNetApctlGetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) {
WARN_LOG(SCENET, "UNTESTED %s(%i, %i, %08x)", __FUNCTION__, entryId, infoId, resultAddr);
static int sceNetApctlGetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
WARN_LOG(SCENET, "UNTESTED %s(%08x, %08x)", __FUNCTION__, sizeAddr, bufAddr);
return NetApctl_GetBSSDescIDListUser(sizeAddr, bufAddr);
}
int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) {
if (!Memory::IsValidAddress(resultAddr))
hleLogError(SCENET, -1, "apctl invalid arg");
return hleLogError(SCENET, -1, "apctl invalid arg"); // 0x8002013A or ERROR_NET_WLAN_INVALID_ARG ?
// Generate an SSID name
char dummySSID[APCTL_SSID_MAXLEN] = "WifiAP0";
dummySSID[6] += static_cast<char>(entryId);
switch (infoId) {
case PSP_NET_APCTL_DESC_IBSS: // IBSS, 6 bytes
Memory::WriteStruct(resultAddr, &netApctlInfo.bssid);
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.bssid);
else {
// Generate a BSSID/MAC address
char dummyMAC[ETHER_ADDR_LEN];
memset(dummyMAC, entryId, sizeof(dummyMAC));
// Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo)
dummyMAC[0] &= 0xfc;
Memory::WriteStruct(resultAddr, &dummyMAC);
}
break;
case PSP_NET_APCTL_DESC_SSID_NAME:
// Return 32 bytes
Memory::WriteStruct(resultAddr, &netApctlInfo.ssid);
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.ssid);
else {
Memory::WriteStruct(resultAddr, &dummySSID);
}
break;
case PSP_NET_APCTL_DESC_SSID_NAME_LENGTH:
// Return one 32-bit value
Memory::WriteStruct(resultAddr, &netApctlInfo.ssidLength);
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.ssidLength);
else {
// Calculate the SSID length
Memory::Write_U32((u32)strlen(dummySSID), resultAddr);
}
break;
case PSP_NET_APCTL_DESC_CHANNEL:
// FIXME: Return one 1 byte value or may be 32-bit if this is not a channel?
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.channel);
else {
// Generate channel for testing purposes, not even sure whether this is channel or not, MGS:PW seems to treat the data as u8
Memory::Write_U8(entryId, resultAddr);
}
break;
case PSP_NET_APCTL_DESC_SIGNAL_STRENGTH:
// Return 1 byte
Memory::WriteStruct(resultAddr, &netApctlInfo.strength);
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.strength);
else {
// Randomize signal strength between 1%~99% since games like MGS:PW are using signal strength to determine the strength of the recruit
Memory::Write_U8((int)(((float)rand() / (float)RAND_MAX) * 99.0 + 1.0), resultAddr);
}
break;
case PSP_NET_APCTL_DESC_SECURITY:
// Return one 32-bit value
@ -1243,20 +1287,38 @@ static int sceNetApctlGetBSSDescEntryUser(int entryId, int infoId, u32 resultAdd
return hleLogError(SCENET, ERROR_NET_APCTL_INVALID_CODE, "unknown info id");
}
return hleLogWarning(SCENET, 0, "untested");
return 0;
}
static int sceNetApctlGetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) {
WARN_LOG(SCENET, "UNTESTED %s(%i, %i, %08x)", __FUNCTION__, entryId, infoId, resultAddr);
return NetApctl_GetBSSDescEntryUser(entryId, infoId, resultAddr);
}
static int sceNetApctlScanSSID2() {
ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__);
WARN_LOG(SCENET, "UNTESTED %s() at %08x", __FUNCTION__, currentMIPS->pc);
return NetApctl_ScanUser();
}
/**************
* Arg1 = output buffer size being filled? (initially the same with Arg3 ?)
* Arg2 = output buffer? (linked list where the 1st 32-bit is the next address? followed by entry Id? ie. 8-bytes per entry?)
* Arg3 = max buffer size? (ie. 0x100 ?)
* Arg4 = input flag? (initially 0/1 ?)
***************/
static int sceNetApctlGetBSSDescIDList2(u32 Arg1, u32 Arg2, u32 Arg3, u32 Arg4) {
return hleLogError(SCENET, 0, "unimplemented");
WARN_LOG(SCENET, "UNTESTED %s(%08x, %08x, %08x, %08x) at %08x", __FUNCTION__, Arg1, Arg2, Arg3, Arg4, currentMIPS->pc);
return NetApctl_GetBSSDescIDListUser(Arg1, Arg2);
}
static int sceNetApctlGetBSSDescEntry2(u32 Arg1, u32 Arg2, u32 Arg3, u32 Arg4) {
return hleLogError(SCENET, 0, "unimplemented");
/**************
* Arg1 = a value returned from sceNetApctlGetBSSDescIDList2 ? entryId?
* Arg2 = input field type within the entry desc (ie. PSP_NET_APCTL_DESC_SSID_NAME ?)
* Arg3 = output buffer for retrieved entry data? (max size = 32 bytes? ie. APCTL_SSID_MAXLEN ? or similar to SceNetApctlInfoInternal union ?)
***************/
static int sceNetApctlGetBSSDescEntry2(int entryId, int infoId, u32 resultAddr) {
WARN_LOG(SCENET, "UNTESTED %s(%i, %i, %08x) at %08x", __FUNCTION__, entryId, infoId, resultAddr, currentMIPS->pc);
return NetApctl_GetBSSDescEntryUser(entryId, infoId, resultAddr);
}
static int sceNetResolverInit()
@ -1434,7 +1496,7 @@ const HLEFunction sceNetApctl[] = {
{0XA3E77E13, &WrapI_V<sceNetApctlScanSSID2>, "sceNetApctlScanSSID2", 'i', "" },
{0XE9B2E5E6, &WrapI_V<sceNetApctlScanUser>, "sceNetApctlScanUser", 'i', "" },
{0XF25A5006, &WrapI_UUUU<sceNetApctlGetBSSDescIDList2>, "sceNetApctlGetBSSDescIDList2", 'i', "xxxx" },
{0X2935C45B, &WrapI_UUUU<sceNetApctlGetBSSDescEntry2>, "sceNetApctlGetBSSDescEntry2", 'i', "xxxx" },
{0X2935C45B, &WrapI_IIU<sceNetApctlGetBSSDescEntry2>, "sceNetApctlGetBSSDescEntry2", 'i', "iix" },
{0X04776994, &WrapI_IIU<sceNetApctlGetBSSDescEntryUser>, "sceNetApctlGetBSSDescEntryUser", 'i', "iix" },
{0X6BDDCB8C, &WrapI_UU<sceNetApctlGetBSSDescIDListUser>, "sceNetApctlGetBSSDescIDListUser", 'i', "xx" },
{0X7CFAB990, &WrapI_UU<sceNetApctlAddInternalHandler>, "sceNetApctlAddInternalHandler", 'i', "xx" },

View File

@ -181,7 +181,8 @@ enum {
PSP_NET_APCTL_EVENT_INFO = 7,
PSP_NET_APCTL_EVENT_EAP_AUTH = 8,
PSP_NET_APCTL_EVENT_KEY_EXCHANGE = 9,
PSP_NET_APCTL_EVENT_RECONNECT = 10
PSP_NET_APCTL_EVENT_RECONNECT = 10,
PSP_NET_APCTL_EVENT_SCAN_STOP = 11 // FIXME: not sure what this is, MGS:PW seems to check this value within ApctlHandler during Recruit, related to sceNetApctlScanSSID2 ?
};
#define PSP_NET_APCTL_INFO_PROFILE_NAME 0
@ -204,17 +205,18 @@ enum {
#define PSP_NET_APCTL_INFO_START_BROWSER 17
#define PSP_NET_APCTL_INFO_WIFISP 18
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_NONE 0
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WEP 1
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WPA 2
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_UNSUPPORTED 3
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WPA_AES 4
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_NONE 0
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WEP 1
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WPA 2
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_UNSUPPORTED 3
#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WPA_AES 4
#define PSP_NET_APCTL_DESC_IBSS 0
#define PSP_NET_APCTL_DESC_SSID_NAME 1
#define PSP_NET_APCTL_DESC_SSID_NAME_LENGTH 2
#define PSP_NET_APCTL_DESC_SIGNAL_STRENGTH 4
#define PSP_NET_APCTL_DESC_SECURITY 5
#define PSP_NET_APCTL_DESC_IBSS 0
#define PSP_NET_APCTL_DESC_SSID_NAME 1
#define PSP_NET_APCTL_DESC_SSID_NAME_LENGTH 2
#define PSP_NET_APCTL_DESC_CHANNEL 3 // FIXME: not sure what this 3 is, may be Security Type based on the order of SceNetApctlInfoInternal ?
#define PSP_NET_APCTL_DESC_SIGNAL_STRENGTH 4
#define PSP_NET_APCTL_DESC_SECURITY 5
#ifdef _MSC_VER
#pragma pack(push,1)