PSP Networking refactor
This commit is contained in:
+165
-345
@@ -5,390 +5,210 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "networkpsp.h"
|
||||
#include "network/network.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/string.h"
|
||||
#include "assert/assert.h"
|
||||
#include <psphttp.h>
|
||||
#include <pspnet.h>
|
||||
#include <pspnet_inet.h>
|
||||
#include <pspnet_apctl.h>
|
||||
#include "display/displaysdl2.h"
|
||||
|
||||
static networkpsp_t NETWORK_PSP;
|
||||
|
||||
/* ---- HTTP thread ---- */
|
||||
|
||||
static int networkPspMapMethod(const networkhttprequestmethod_t method) {
|
||||
switch(method) {
|
||||
case NETWORK_HTTP_REQUEST_METHOD_POST: return PSP_HTTP_METHOD_POST;
|
||||
case NETWORK_HTTP_REQUEST_METHOD_HEAD: return PSP_HTTP_METHOD_HEAD;
|
||||
case NETWORK_HTTP_REQUEST_METHOD_GET:
|
||||
default:
|
||||
return PSP_HTTP_METHOD_GET;
|
||||
}
|
||||
}
|
||||
|
||||
static void networkPspHTTPThread(thread_t *thread) {
|
||||
assertNotNull(thread, "Thread must not be NULL");
|
||||
assertNotNull(thread->data, "Thread data must not be NULL");
|
||||
|
||||
networkhttppendingitem_t *item = (networkhttppendingitem_t *)thread->data;
|
||||
int templateId = -1;
|
||||
int connId = -1;
|
||||
int reqId = -1;
|
||||
|
||||
templateId = sceHttpCreateTemplate(NETWORK_PSP_AGENT, PSP_HTTP_VERSION_1_1, 1);
|
||||
if(templateId < 0) {
|
||||
stringCopy(item->errorMessage, "sceHttpCreateTemplate failed",
|
||||
NETWORK_ERROR_MESSAGE_MAX - 1);
|
||||
item->isError = true;
|
||||
goto done;
|
||||
}
|
||||
|
||||
connId = sceHttpCreateConnectionWithURL(templateId, item->url, 0);
|
||||
if(connId < 0) {
|
||||
stringCopy(item->errorMessage, "sceHttpCreateConnectionWithURL failed",
|
||||
NETWORK_ERROR_MESSAGE_MAX - 1);
|
||||
item->isError = true;
|
||||
goto done;
|
||||
}
|
||||
|
||||
unsigned int contentLength = item->hasBody ? (unsigned int)strlen(item->body) : 0;
|
||||
reqId = sceHttpCreateRequestWithURL(
|
||||
connId, networkPspMapMethod(item->method), item->url,
|
||||
(SceULong64)contentLength
|
||||
);
|
||||
if(reqId < 0) {
|
||||
stringCopy(item->errorMessage, "sceHttpCreateRequestWithURL failed",
|
||||
NETWORK_ERROR_MESSAGE_MAX - 1);
|
||||
item->isError = true;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < item->headerCount; i++) {
|
||||
sceHttpAddExtraHeader(reqId, item->headerKeys[i], item->headerVals[i], 0);
|
||||
}
|
||||
#include <pspsdk.h>
|
||||
|
||||
errorret_t networkPSPInit() {
|
||||
// Requests the PSP to load the network modules.
|
||||
int ret;
|
||||
if(item->hasBody) {
|
||||
ret = sceHttpSendRequest(reqId, item->body, contentLength);
|
||||
} else {
|
||||
ret = sceHttpSendRequest(reqId, NULL, 0);
|
||||
}
|
||||
if(ret < 0) {
|
||||
stringCopy(item->errorMessage, "sceHttpSendRequest failed",
|
||||
NETWORK_ERROR_MESSAGE_MAX - 1);
|
||||
item->isError = true;
|
||||
goto done;
|
||||
}
|
||||
|
||||
int statusCode = 0;
|
||||
ret = sceHttpGetStatusCode(reqId, &statusCode);
|
||||
if(ret < 0) {
|
||||
stringCopy(item->errorMessage, "sceHttpGetStatusCode failed",
|
||||
NETWORK_ERROR_MESSAGE_MAX - 1);
|
||||
item->isError = true;
|
||||
goto done;
|
||||
}
|
||||
item->status = (uint16_t)statusCode;
|
||||
|
||||
/* Read response body in chunks into the fixed buffer. */
|
||||
size_t written = 0;
|
||||
char_t buf[512];
|
||||
while(1) {
|
||||
int read = sceHttpReadData(reqId, buf, sizeof(buf));
|
||||
if(read <= 0) break;
|
||||
|
||||
size_t space = NETWORK_HTTP_RESPONSE_MAX - 1 - written;
|
||||
size_t copy = (size_t)read;
|
||||
if(copy > space) copy = space;
|
||||
if(copy > 0) {
|
||||
memcpy(item->responseBody + written, buf, copy);
|
||||
written += copy;
|
||||
item->responseBody[written] = '\0';
|
||||
}
|
||||
if(space == 0) break;
|
||||
}
|
||||
|
||||
item->isError = false;
|
||||
|
||||
done:
|
||||
if(reqId >= 0) sceHttpDeleteRequest(reqId);
|
||||
if(connId >= 0) sceHttpDeleteConnection(connId);
|
||||
if(templateId >= 0) sceHttpDeleteTemplate(templateId);
|
||||
|
||||
threadMutexLock(&NETWORK_PSP.resultsMutex);
|
||||
item->resultReady = true;
|
||||
threadMutexUnlock(&NETWORK_PSP.resultsMutex);
|
||||
}
|
||||
|
||||
/* ---- Dialog state machine (pumped every frame) ---- */
|
||||
|
||||
static void networkPspPumpDialog() {
|
||||
switch(sceUtilityNetconfGetStatus()) {
|
||||
case PSP_UTILITY_DIALOG_VISIBLE:
|
||||
sceUtilityNetconfUpdate(1);
|
||||
break;
|
||||
|
||||
case PSP_UTILITY_DIALOG_QUIT:
|
||||
sceUtilityNetconfShutdownStart();
|
||||
break;
|
||||
|
||||
case PSP_UTILITY_DIALOG_FINISHED: {
|
||||
int apState = 0;
|
||||
sceNetApctlGetState(&apState);
|
||||
if(apState == PSP_NET_APCTL_STATE_GOT_IP) {
|
||||
sceUtilityLoadNetModule(PSP_NET_MODULE_HTTP);
|
||||
sceUtilityLoadNetModule(PSP_NET_MODULE_SSL);
|
||||
sceHttpInit(NETWORK_PSP_HTTP_HEAP_SIZE);
|
||||
NETWORK_PSP.state = NETWORK_PSP_STATE_CONNECTED;
|
||||
if(NETWORK_PSP.onConnected) NETWORK_PSP.onConnected(NETWORK_PSP.connectionUser);
|
||||
} else {
|
||||
NETWORK_PSP.state = NETWORK_PSP_STATE_FAILED;
|
||||
if(NETWORK_PSP.onFailed) {
|
||||
errorstate_t errState;
|
||||
errState.code = ERROR_NOT_OK;
|
||||
errState.message = (char_t *)"WiFi connection failed or cancelled";
|
||||
errState.lines = (char_t *)"";
|
||||
errorret_t err;
|
||||
err.code = ERROR_NOT_OK;
|
||||
err.state = &errState;
|
||||
NETWORK_PSP.onFailed(err, NETWORK_PSP.connectionUser);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Public API ---- */
|
||||
|
||||
errorret_t networkPspInit() {
|
||||
memoryZero(&NETWORK_PSP, sizeof(networkpsp_t));
|
||||
threadMutexInit(&NETWORK_PSP.resultsMutex);
|
||||
NETWORK_PSP.state = NETWORK_PSP_STATE_DISCONNECTED;
|
||||
|
||||
/* Load base net modules (FW 2.00+ style). HTTP/SSL loaded after connection. */
|
||||
int ret;
|
||||
ret = sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
|
||||
if(ret < 0) errorThrow("sceUtilityLoadNetModule(COMMON) failed: 0x%08X", ret);
|
||||
|
||||
if(ret < 0) errorThrow("Failed to init NET COMMON: 0x%08X", ret);
|
||||
|
||||
ret = sceUtilityLoadNetModule(PSP_NET_MODULE_INET);
|
||||
if(ret < 0) errorThrow("sceUtilityLoadNetModule(INET) failed: 0x%08X", ret);
|
||||
if(ret < 0) errorThrow("Failed to init NET INET: 0x%08X", ret);
|
||||
|
||||
/* Init the network stack. */
|
||||
ret = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000);
|
||||
// ret = sceUtilityLoadNetModule(PSP_NET_MODULE_PARSEURI);
|
||||
// if(ret < 0) errorThrow("Failed to init NET PARSEURI: 0x%08X", ret);
|
||||
|
||||
// ret = sceUtilityLoadNetModule(PSP_NET_MODULE_PARSEHTTP);
|
||||
// if(ret < 0) errorThrow("Failed to init NET PARSEHTTP: 0x%08X", ret);
|
||||
|
||||
// ret = sceUtilityLoadNetModule(PSP_NET_MODULE_SSL);
|
||||
// if(ret < 0) errorThrow("Failed to init NET SSL: 0x%08X", ret);
|
||||
|
||||
// ret = sceUtilityLoadNetModule(PSP_NET_MODULE_HTTP);
|
||||
// if(ret < 0) errorThrow("Failed to init NET HTTP: 0x%08X", ret);
|
||||
|
||||
// Init the PSP network stack.
|
||||
ret = sceNetInit(0x20000, 0x20, 4096, 0x20, 4096);
|
||||
if(ret < 0) errorThrow("sceNetInit failed: 0x%08X", ret);
|
||||
|
||||
ret = sceNetInetInit();
|
||||
if(ret < 0) errorThrow("sceNetInetInit failed: 0x%08X", ret);
|
||||
|
||||
ret = sceNetResolverInit();
|
||||
if(ret < 0) errorThrow("sceNetResolverInit failed: 0x%08X", ret);
|
||||
|
||||
ret = sceNetApctlInit(0x1800, 0x30);
|
||||
if(ret < 0) errorThrow("sceNetApctlInit failed: 0x%08X", ret);
|
||||
|
||||
// ret = sceSslInit(0x28000);
|
||||
// if(ret < 0) errorThrow("sceSslInit failed: 0x%08X", ret);
|
||||
|
||||
// ret = sceHttpInit(0x25800);
|
||||
// if(ret < 0) errorThrow("sceHttpInit failed: 0x%08X", ret);
|
||||
|
||||
// ret = sceHttpsInit(0, 0, 0, 0);
|
||||
// if(ret < 0) errorThrow("sceHttpsInit failed: 0x%08X", ret);
|
||||
|
||||
// ret = sceHttpsLoadDefaultCert(0, 0);
|
||||
// if(ret < 0) errorThrow("sceHttpsLoadDefaultCert failed: 0x%08X", ret);
|
||||
|
||||
// ret = sceHttpLoadSystemCookie();
|
||||
// if(ret < 0) errorThrow("sceHttpLoadSystemCookie failed: 0x%08X", ret);
|
||||
|
||||
// All good.
|
||||
errorOk();
|
||||
}
|
||||
|
||||
bool_t networkPspIsConnected() {
|
||||
return NETWORK_PSP.state == NETWORK_PSP_STATE_CONNECTED;
|
||||
}
|
||||
errorret_t networkPSPUpdate() {
|
||||
int ret;
|
||||
if(
|
||||
NETWORK.state == NETWORK_STATE_CONNECTING ||
|
||||
NETWORK.state == NETWORK_STATE_DISCONNECTING
|
||||
) {
|
||||
switch(sceUtilityNetconfGetStatus()) {
|
||||
case PSP_UTILITY_DIALOG_INIT:
|
||||
break;
|
||||
|
||||
void networkPspRequestConnection(
|
||||
void (*onConnected)(void *user),
|
||||
void (*onFailed)(errorret_t error, void *user),
|
||||
void *user
|
||||
) {
|
||||
assertNotNull(onConnected, "onConnected must not be NULL");
|
||||
assertNotNull(onFailed, "onFailed must not be NULL");
|
||||
case PSP_UTILITY_DIALOG_NONE:
|
||||
printf("Diag none?\n");
|
||||
NETWORK.state = NETWORK_STATE_DISCONNECTED;
|
||||
errorThrow("PSP Netconf dialog disappeared without result");
|
||||
break;
|
||||
|
||||
NETWORK_PSP.onConnected = onConnected;
|
||||
NETWORK_PSP.onFailed = onFailed;
|
||||
NETWORK_PSP.connectionUser = user;
|
||||
NETWORK_PSP.state = NETWORK_PSP_STATE_DIALOG;
|
||||
case PSP_UTILITY_DIALOG_VISIBLE:
|
||||
// 1 is mandatory?
|
||||
ret = sceUtilityNetconfUpdate(1);
|
||||
if(ret != 0) {
|
||||
errorThrow("sceUtilityNetconfUpdate failed: 0x%08X", ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case PSP_UTILITY_DIALOG_QUIT:
|
||||
ret = sceUtilityNetconfShutdownStart();
|
||||
if(ret != 0) {
|
||||
errorThrow("sceUtilityNetconfShutdownStart failed: 0x%08X", ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case PSP_UTILITY_DIALOG_FINISHED:
|
||||
// Did we connect?
|
||||
int apState = 0;
|
||||
sceNetApctlGetState(&apState);
|
||||
|
||||
/* Configure and launch the netconf WiFi dialog.
|
||||
* The dialog is pumped each frame in networkPspUpdate; it must not block. */
|
||||
memoryZero(&NETWORK_PSP.dialogAdhoc, sizeof(NETWORK_PSP.dialogAdhoc));
|
||||
memoryZero(&NETWORK_PSP.dialogData, sizeof(NETWORK_PSP.dialogData));
|
||||
NETWORK_PSP.dialogData.base.size = sizeof(pspUtilityNetconfData);
|
||||
NETWORK_PSP.dialogData.base.language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
|
||||
NETWORK_PSP.dialogData.base.buttonSwap = PSP_UTILITY_ACCEPT_CROSS;
|
||||
NETWORK_PSP.dialogData.base.graphicsThread = 17;
|
||||
NETWORK_PSP.dialogData.base.accessThread = 19;
|
||||
NETWORK_PSP.dialogData.base.fontThread = 18;
|
||||
NETWORK_PSP.dialogData.base.soundThread = 16;
|
||||
NETWORK_PSP.dialogData.action = PSP_NETCONF_ACTION_CONNECTAP;
|
||||
NETWORK_PSP.dialogData.adhocparam = &NETWORK_PSP.dialogAdhoc;
|
||||
if(apState == PSP_NET_APCTL_STATE_GOT_IP) {
|
||||
NETWORK.state = NETWORK_STATE_CONNECTED;
|
||||
assertNotNull(
|
||||
NETWORK.platform.onConnected,
|
||||
"Network platform onConnected callback should be set."
|
||||
);
|
||||
NETWORK.platform.onConnected(NETWORK.platform.onConnectedUser);
|
||||
} else {
|
||||
printf("Offline.\n");
|
||||
NETWORK.state = NETWORK_STATE_DISCONNECTED;
|
||||
|
||||
int ret = sceUtilityNetconfInitStart(&NETWORK_PSP.dialogData);
|
||||
if(ret < 0) {
|
||||
NETWORK_PSP.state = NETWORK_PSP_STATE_FAILED;
|
||||
errorstate_t errState;
|
||||
errState.code = ERROR_NOT_OK;
|
||||
errState.message = (char_t *)"sceUtilityNetconfInitStart failed";
|
||||
errState.lines = (char_t *)"";
|
||||
errorret_t err;
|
||||
err.code = ERROR_NOT_OK;
|
||||
err.state = &errState;
|
||||
onFailed(err, user);
|
||||
}
|
||||
}
|
||||
assertNotNull(
|
||||
NETWORK.platform.onFailed,
|
||||
"Network platform onFailed callback should be set."
|
||||
);
|
||||
|
||||
errorret_t networkPspUpdate() {
|
||||
if(NETWORK_PSP.state == NETWORK_PSP_STATE_DIALOG) {
|
||||
networkPspPumpDialog();
|
||||
errorOk();
|
||||
}
|
||||
|
||||
if(NETWORK_PSP.state == NETWORK_PSP_STATE_FAILED) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
/* Drain completed HTTP requests on the main thread. */
|
||||
for(int32_t i = 0; i < NETWORK_HTTP_PENDING_MAX; i++) {
|
||||
threadMutexLock(&NETWORK_PSP.resultsMutex);
|
||||
|
||||
networkhttppendingitem_t *item = &NETWORK_PSP.requests[i];
|
||||
if(!item->used || !item->resultReady) {
|
||||
threadMutexUnlock(&NETWORK_PSP.resultsMutex);
|
||||
continue;
|
||||
errorret_t error = errorThrowImpl(
|
||||
&NETWORK.errorState,
|
||||
ERROR_NOT_OK,
|
||||
__FILE__, __func__, __LINE__,
|
||||
"Failed to connect to network"
|
||||
);
|
||||
NETWORK.platform.onFailed(error, NETWORK.platform.onConnectedUser);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
errorThrow("Unknown PSP Netconf dialog status: %d", sceUtilityNetconfGetStatus());
|
||||
}
|
||||
|
||||
bool_t isError = item->isError;
|
||||
uint16_t status = item->status;
|
||||
networkhttpcallback_t cb = item->callback;
|
||||
networkhttperrorcallback_t errCb = item->errorCallback;
|
||||
void *user = item->user;
|
||||
const char_t *responseBody = item->responseBody;
|
||||
const char_t *errorMessage = item->errorMessage;
|
||||
|
||||
threadMutexUnlock(&NETWORK_PSP.resultsMutex);
|
||||
|
||||
if(isError) {
|
||||
errorstate_t errState;
|
||||
errState.code = ERROR_NOT_OK;
|
||||
errState.message = (char_t *)errorMessage;
|
||||
errState.lines = (char_t *)"";
|
||||
errorret_t err;
|
||||
err.code = ERROR_NOT_OK;
|
||||
err.state = &errState;
|
||||
errCb(err, user);
|
||||
} else {
|
||||
cb(status, responseBody, NULL, 0, user);
|
||||
}
|
||||
|
||||
threadMutexLock(&NETWORK_PSP.resultsMutex);
|
||||
item->used = false;
|
||||
item->resultReady = false;
|
||||
threadMutexUnlock(&NETWORK_PSP.resultsMutex);
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t networkPspDispose() {
|
||||
if(NETWORK_PSP.state == NETWORK_PSP_STATE_CONNECTED) {
|
||||
sceHttpEnd();
|
||||
sceUtilityUnloadNetModule(PSP_NET_MODULE_SSL);
|
||||
sceUtilityUnloadNetModule(PSP_NET_MODULE_HTTP);
|
||||
}
|
||||
|
||||
errorret_t networkPSPDispose() {
|
||||
sceNetApctlTerm();
|
||||
sceNetResolverTerm();
|
||||
sceNetInetTerm();
|
||||
sceNetTerm();
|
||||
|
||||
sceUtilityUnloadNetModule(PSP_NET_MODULE_HTTP);
|
||||
sceUtilityUnloadNetModule(PSP_NET_MODULE_INET);
|
||||
sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON);
|
||||
|
||||
threadMutexDispose(&NETWORK_PSP.resultsMutex);
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void networkPspHTTPRequest(
|
||||
const char_t *url,
|
||||
const networkhttprequestmethod_t method,
|
||||
const char_t *bodyOrNull,
|
||||
const networkhttpheader_t *headers,
|
||||
const uint32_t headerCount,
|
||||
void *user,
|
||||
networkhttpcallback_t callback,
|
||||
networkhttperrorcallback_t errorCallback
|
||||
) {
|
||||
assertStrLenMin(url, 1, "URL must be non-empty");
|
||||
assertStrLenMax(url, NETWORK_HTTP_URL_MAX, "URL exceeds maximum length");
|
||||
assertNotNull(callback, "Callback must be non-NULL");
|
||||
assertNotNull(errorCallback, "Error callback must be non-NULL");
|
||||
assertTrue(headerCount == 0 || headers != NULL, "Headers must not be NULL when headerCount > 0");
|
||||
|
||||
if(NETWORK_PSP.state != NETWORK_PSP_STATE_CONNECTED) {
|
||||
errorstate_t errState;
|
||||
errState.code = ERROR_NOT_OK;
|
||||
errState.message = (char_t *)"Network not connected";
|
||||
errState.lines = (char_t *)"";
|
||||
errorret_t err;
|
||||
err.code = ERROR_NOT_OK;
|
||||
err.state = &errState;
|
||||
errorCallback(err, user);
|
||||
return;
|
||||
}
|
||||
|
||||
threadMutexLock(&NETWORK_PSP.resultsMutex);
|
||||
|
||||
networkhttppendingitem_t *item = NULL;
|
||||
for(int32_t i = 0; i < NETWORK_HTTP_PENDING_MAX; i++) {
|
||||
if(!NETWORK_PSP.requests[i].used) {
|
||||
item = &NETWORK_PSP.requests[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!item) {
|
||||
threadMutexUnlock(&NETWORK_PSP.resultsMutex);
|
||||
errorstate_t errState;
|
||||
errState.code = ERROR_NOT_OK;
|
||||
errState.message = (char_t *)"No free HTTP request slots";
|
||||
errState.lines = (char_t *)"";
|
||||
errorret_t err;
|
||||
err.code = ERROR_NOT_OK;
|
||||
err.state = &errState;
|
||||
errorCallback(err, user);
|
||||
return;
|
||||
}
|
||||
|
||||
memoryZero(item, sizeof(networkhttppendingitem_t));
|
||||
item->used = true;
|
||||
|
||||
threadMutexUnlock(&NETWORK_PSP.resultsMutex);
|
||||
|
||||
stringCopy(item->url, url, NETWORK_HTTP_URL_MAX - 1);
|
||||
item->method = method;
|
||||
|
||||
if(bodyOrNull != NULL) {
|
||||
assertStrLenMax(bodyOrNull, NETWORK_HTTP_BODY_MAX, "Body exceeds maximum length");
|
||||
stringCopy(item->body, bodyOrNull, NETWORK_HTTP_BODY_MAX - 1);
|
||||
item->hasBody = true;
|
||||
}
|
||||
|
||||
uint32_t hdrCount = headerCount;
|
||||
if(hdrCount > NETWORK_HTTP_HEADER_MAX) hdrCount = NETWORK_HTTP_HEADER_MAX;
|
||||
item->headerCount = hdrCount;
|
||||
for(uint32_t i = 0; i < hdrCount; i++) {
|
||||
assertStrLenMax(headers[i].key, NETWORK_HTTP_HEADER_KEY_MAX, "Header key exceeds maximum length");
|
||||
assertStrLenMax(headers[i].value, NETWORK_HTTP_HEADER_VAL_MAX, "Header value exceeds maximum length");
|
||||
stringCopy(item->headerKeys[i], headers[i].key, NETWORK_HTTP_HEADER_KEY_MAX - 1);
|
||||
stringCopy(item->headerVals[i], headers[i].value, NETWORK_HTTP_HEADER_VAL_MAX - 1);
|
||||
}
|
||||
|
||||
item->callback = callback;
|
||||
item->errorCallback = errorCallback;
|
||||
item->user = user;
|
||||
|
||||
threadInit(&item->thread, networkPspHTTPThread);
|
||||
item->thread.data = item;
|
||||
threadStartRequest(&item->thread);
|
||||
bool_t networkPSPIsConnected() {
|
||||
return NETWORK.state == NETWORK_STATE_CONNECTED;
|
||||
}
|
||||
|
||||
bool_t networkPspIsConnectionModalOpen() {
|
||||
return sceUtilityNetconfGetStatus() == PSP_UTILITY_DIALOG_VISIBLE;
|
||||
void networkPSPRequestConnection(
|
||||
void (*onConnected)(void *user),
|
||||
void (*onFailed)(errorret_t error, void *user),
|
||||
void (*onDisconnect)(errorret_t error, void *user),
|
||||
void *user
|
||||
) {
|
||||
assertTrue(
|
||||
NETWORK.state == NETWORK_STATE_CONNECTING,
|
||||
"Network host should be in a connecting state."
|
||||
);
|
||||
|
||||
NETWORK.platform.onConnected = onConnected;
|
||||
NETWORK.platform.onFailed = onFailed;
|
||||
NETWORK.platform.onConnectedUser = user;
|
||||
|
||||
memoryZero(&NETWORK.platform.dialogData, sizeof(NETWORK.platform.dialogData));
|
||||
memoryZero(&NETWORK.platform.dialogAdhoc, sizeof(NETWORK.platform.dialogAdhoc));
|
||||
|
||||
// This is all related to getting the PSP online, refer to;
|
||||
// https://github.com/joel16/CMFileManager-PSP/blob/00dab16c64cd48bf6452fc274a3b898d77c39a8d/app/source/net.cpp#L97
|
||||
// since I follow this implementation closely.
|
||||
NETWORK.platform.dialogData.base.size = sizeof(pspUtilityNetconfData);
|
||||
NETWORK.platform.dialogData.base.language = systemPSPGetLanguage();
|
||||
NETWORK.platform.dialogData.base.buttonSwap = systemPSPGetCrossButtonSetting();
|
||||
NETWORK.platform.dialogData.base.graphicsThread = 17;
|
||||
NETWORK.platform.dialogData.base.accessThread = 19;
|
||||
NETWORK.platform.dialogData.base.fontThread = 18;
|
||||
NETWORK.platform.dialogData.base.soundThread = 16;
|
||||
NETWORK.platform.dialogData.action = PSP_NETCONF_ACTION_CONNECTAP;
|
||||
NETWORK.platform.dialogData.adhocparam = (
|
||||
&NETWORK.platform.dialogAdhoc
|
||||
);
|
||||
|
||||
|
||||
int ret = sceUtilityNetconfInitStart(&NETWORK.platform.dialogData);
|
||||
if(ret < 0) {
|
||||
assertUnreachable("Failed to init netconf");
|
||||
}
|
||||
// At this point, PSP is in control.
|
||||
}
|
||||
|
||||
void networkPSPRequestDisconection(
|
||||
void (*onComplete)(void *user),
|
||||
void *user
|
||||
) {
|
||||
assertTrue(
|
||||
NETWORK.state == NETWORK_STATE_DISCONNECTING,
|
||||
"Network host should be in a disconnecting state."
|
||||
);
|
||||
|
||||
NETWORK.platform.onComplete = onComplete;
|
||||
NETWORK.platform.onCompleteUser = user;
|
||||
|
||||
int ret = sceUtilityNetconfShutdownStart();
|
||||
if(ret < 0) {
|
||||
assertUnreachable("Failed to start netconf shutdown");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user