diff --git a/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp b/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp index b1f2e61865..dcf88f79b0 100644 --- a/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp @@ -1,6 +1,7 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" +#include "Emu/IdManager.h" #include "cellGame.h" #include "cellSysutil.h" @@ -89,20 +90,40 @@ error_code cellNetCtlInit() { cellNetCtl.warning("cellNetCtlInit()"); + auto net_ctl_manager = g_fxo->get(); + + if (net_ctl_manager->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_TERMINATED; + } + + net_ctl_manager->is_initialized = true; + return CELL_OK; } -error_code cellNetCtlTerm() +void cellNetCtlTerm() { cellNetCtl.warning("cellNetCtlTerm()"); - return CELL_OK; + auto net_ctl_manager = g_fxo->get(); + net_ctl_manager->is_initialized = false; } -error_code cellNetCtlGetState(vm::ptr state) +error_code cellNetCtlGetState(vm::ptr state) { cellNetCtl.trace("cellNetCtlGetState(state=*0x%x)", state); + if (!g_fxo->get()->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_INITIALIZED; + } + + if (!state) + { + return CELL_NET_CTL_ERROR_INVALID_ADDR; + } + *state = g_cfg.net.net_status; return CELL_OK; } @@ -111,6 +132,16 @@ error_code cellNetCtlAddHandler(vm::ptr handler, vm::ptrget()->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_INITIALIZED; + } + + if (!hid) + { + return CELL_NET_CTL_ERROR_INVALID_ADDR; + } + return CELL_OK; } @@ -118,6 +149,16 @@ error_code cellNetCtlDelHandler(s32 hid) { cellNetCtl.todo("cellNetCtlDelHandler(hid=0x%x)", hid); + if (!g_fxo->get()->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_INITIALIZED; + } + + if (hid > 3) + { + return CELL_NET_CTL_ERROR_INVALID_ID; + } + return CELL_OK; } @@ -125,6 +166,16 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr info) { cellNetCtl.todo("cellNetCtlGetInfo(code=0x%x (%s), info=*0x%x)", code, InfoCodeToName(code), info); + if (!g_fxo->get()->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_INITIALIZED; + } + + if (!info) + { + return CELL_NET_CTL_ERROR_INVALID_ADDR; + } + if (code == CELL_NET_CTL_INFO_ETHER_ADDR) { // dummy values set @@ -169,10 +220,30 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr info) return CELL_OK; } -error_code cellNetCtlNetStartDialogLoadAsync(vm::ptr param) +error_code cellNetCtlNetStartDialogLoadAsync(vm::cptr param) { cellNetCtl.error("cellNetCtlNetStartDialogLoadAsync(param=*0x%x)", param); + if (!g_fxo->get()->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_INITIALIZED; + } + + if (!param) + { + return CELL_NET_CTL_ERROR_INVALID_ADDR; + } + + if (param->type >= CELL_NET_CTL_NETSTART_TYPE_MAX) + { + return CELL_NET_CTL_ERROR_INVALID_TYPE; + } + + if (param->size != 12) + { + return CELL_NET_CTL_ERROR_INVALID_SIZE; + } + // TODO: Actually sign into PSN or an emulated network similar to PSN (ESN) // TODO: Properly open the dialog prompt for sign in sysutil_send_system_cmd(CELL_SYSUTIL_NET_CTL_NETSTART_LOADED, 0); @@ -185,6 +256,11 @@ error_code cellNetCtlNetStartDialogAbortAsync() { cellNetCtl.error("cellNetCtlNetStartDialogAbortAsync()"); + if (!g_fxo->get()->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_INITIALIZED; + } + return CELL_OK; } @@ -192,6 +268,21 @@ error_code cellNetCtlNetStartDialogUnloadAsync(vm::ptrget()->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_INITIALIZED; + } + + if (!result) + { + return CELL_NET_CTL_ERROR_INVALID_ADDR; + } + + if (result->size != 8) + { + return CELL_NET_CTL_ERROR_INVALID_SIZE; + } + result->result = CELL_NET_CTL_ERROR_DIALOG_CANCELED; sysutil_send_system_cmd(CELL_SYSUTIL_NET_CTL_NETSTART_UNLOADED, 0); @@ -202,9 +293,18 @@ error_code cellNetCtlGetNatInfo(vm::ptr natInfo) { cellNetCtl.todo("cellNetCtlGetNatInfo(natInfo=*0x%x)", natInfo); - if (natInfo->size == 0) + if (!g_fxo->get()->is_initialized) + { + return CELL_NET_CTL_ERROR_NOT_INITIALIZED; + } + + if (!natInfo) + { + return CELL_NET_CTL_ERROR_INVALID_ADDR; + } + + if (natInfo->size != 16 && natInfo->size != 20) { - cellNetCtl.error("cellNetCtlGetNatInfo : CELL_NET_CTL_ERROR_INVALID_SIZE"); return CELL_NET_CTL_ERROR_INVALID_SIZE; } diff --git a/rpcs3/Emu/Cell/Modules/cellNetCtl.h b/rpcs3/Emu/Cell/Modules/cellNetCtl.h index f7c7bb5b5a..29b053a9a5 100644 --- a/rpcs3/Emu/Cell/Modules/cellNetCtl.h +++ b/rpcs3/Emu/Cell/Modules/cellNetCtl.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "cellGame.h" @@ -104,11 +104,14 @@ enum // Wireless connection security measures enum { - CELL_NET_CTL_WLAN_SECURITY_NOAUTH = 0, - CELL_NET_CTL_WLAN_SECURITY_WEP = 1, - CELL_NET_CTL_WLAN_SECURITY_WPAPSK_TKIP = 2, - CELL_NET_CTL_WLAN_SECURITY_WPAPSK_AES = 3, - CELL_NET_CTL_WLAN_SECURITY_UNSUPPORTED = 4, + CELL_NET_CTL_WLAN_SECURITY_NOAUTH = 0, + CELL_NET_CTL_WLAN_SECURITY_WEP = 1, + CELL_NET_CTL_WLAN_SECURITY_WPAPSK_TKIP = 2, + CELL_NET_CTL_WLAN_SECURITY_WPAPSK_AES = 3, + CELL_NET_CTL_WLAN_SECURITY_UNSUPPORTED = 4, + CELL_NET_CTL_WLAN_SECURITY_WPA2PSK_TKIP = 5, + CELL_NET_CTL_WLAN_SECURITY_WPA2PSK_AES = 6, + CELL_NET_CTL_WLAN_SECURITY_WPAPSK_WPA2PSK = 7, }; // 802.1X settings @@ -167,6 +170,8 @@ enum CELL_NET_CTL_INFO_HTTP_PROXY_SERVER = 22, CELL_NET_CTL_INFO_HTTP_PROXY_PORT = 23, CELL_NET_CTL_INFO_UPNP_CONFIG = 24, + CELL_NET_CTL_INFO_RESERVED1 = 25, + CELL_NET_CTL_INFO_RESERVED2 = 26, }; // Network start dialogs @@ -174,6 +179,7 @@ enum { CELL_NET_CTL_NETSTART_TYPE_NET = 0, CELL_NET_CTL_NETSTART_TYPE_NP = 1, + CELL_NET_CTL_NETSTART_TYPE_MAX = 2, }; // Network start dialog statuses @@ -208,15 +214,28 @@ enum CELL_NET_CTL_NATINFO_NAT_TYPE_3 = 3, }; +enum +{ + CELL_NET_CTL_ETHER_ADDR_LEN = 6, + CELL_NET_CTL_BSSID_LEN = 6, + CELL_NET_CTL_SSID_LEN = 32, + CELL_NET_CTL_WLAN_SECURITY_KEY_LEN = (64 + 1), + CELL_NET_CTL_AUTH_NAME_LEN = (127 + 1), + CELL_NET_CTL_AUTH_KEY_LEN = (127 + 1), + CELL_NET_CTL_DHCP_HOSTNAME_LEN = (254 + 1), + CELL_NET_CTL_HOSTNAME_LEN = (255 + 1), + CELL_NET_CTL_IPV4_ADDR_STR_LEN = 16, +}; + struct CellNetCtlEtherAddr { - u8 data[6]; + u8 data[CELL_NET_CTL_ETHER_ADDR_LEN]; u8 padding[2]; }; struct CellNetCtlSSID { - u8 data[32]; + u8 data[CELL_NET_CTL_SSID_LEN]; u8 term; u8 padding[3]; }; @@ -232,19 +251,19 @@ union CellNetCtlInfo CellNetCtlSSID ssid; be_t wlan_security; be_t auth_8021x_type; - char auth_8021x_auth_name[128]; + char auth_8021x_auth_name[CELL_NET_CTL_AUTH_NAME_LEN]; u8 rssi; u8 channel; be_t ip_config; - char dhcp_hostname[256]; - char pppoe_auth_name[128]; - char ip_address[16]; - char netmask[16]; - char default_route[16]; - char primary_dns[16]; - char secondary_dns[16]; + char dhcp_hostname[CELL_NET_CTL_HOSTNAME_LEN]; + char pppoe_auth_name[CELL_NET_CTL_AUTH_NAME_LEN]; + char ip_address[CELL_NET_CTL_IPV4_ADDR_STR_LEN]; + char netmask[CELL_NET_CTL_IPV4_ADDR_STR_LEN]; + char default_route[CELL_NET_CTL_IPV4_ADDR_STR_LEN]; + char primary_dns[CELL_NET_CTL_IPV4_ADDR_STR_LEN]; + char secondary_dns[CELL_NET_CTL_IPV4_ADDR_STR_LEN]; be_t http_proxy_config; - char http_proxy_server[256]; + char http_proxy_server[CELL_NET_CTL_HOSTNAME_LEN]; be_t http_proxy_port; be_t upnp_config; }; @@ -307,13 +326,13 @@ static const char* InfoCodeToName(s32 code) enum { - CELL_GAMEUPDATE_RESULT_STATUS_NO_UPDATE = 0, - CELL_GAMEUPDATE_RESULT_STATUS_UPDATE_FOUND = 1, - CELL_GAMEUPDATE_RESULT_STATUS_MAINTENANCE = 2, - CELL_GAMEUPDATE_RESULT_STATUS_ERROR = 3, - CELL_GAMEUPDATE_RESULT_STATUS_CANCELLED = 4, - CELL_GAMEUPDATE_RESULT_STATUS_FINISHED = 5, - CELL_GAMEUPDATE_RESULT_STATUS_ABORTED = 6, + CELL_GAMEUPDATE_RESULT_STATUS_NO_UPDATE = 0, + CELL_GAMEUPDATE_RESULT_STATUS_UPDATE_FOUND = 1, + CELL_GAMEUPDATE_RESULT_STATUS_MAINTENANCE = 2, + CELL_GAMEUPDATE_RESULT_STATUS_ERROR = 3, + CELL_GAMEUPDATE_RESULT_STATUS_CANCELLED = 4, + CELL_GAMEUPDATE_RESULT_STATUS_FINISHED = 5, + CELL_GAMEUPDATE_RESULT_STATUS_ABORTED = 6, CELL_GAMEUPDATE_RESULT_STATUS_SYSTEM_UPDATE_NEEDED = 7 }; @@ -333,3 +352,8 @@ struct CellGameUpdateParam using CellGameUpdateCallback = void(s32 status, s32 error_code, vm::ptr userdata); using CellGameUpdateCallbackEx = void(vm::ptr result, vm::ptr userdata); + +struct cell_net_ctl_manager +{ + atomic_t is_initialized = false; +};