TwlToolsRED/build/tools/sctools/copy_dst/src/mynuc.c

430 lines
12 KiB
C

#include <twl.h>
#include <twl/sea.h>
#include <twl/na.h>
// #include <TwlWiFi/nuc.h>
#include "netconnect.h"
#include "sitedefs.h"
#include "nuc.h"
#include "nuc_error_msg.h"
#include "mynuc.h"
#include "text.h"
#include "mprintf.h"
#include "logprintf.h"
#include "my_fs_util.h"
#define STRING_ANIM_CNT 20
static BOOL log_active = FALSE;
static FSFile *log_fd;
static FSFile log_fd_real;
static volatile NetConnectState NetConnect = NET_CONNECT_NONE;
// state管理
static struct
{
NucPhaseState state;
u32 count;
} TestState;
static inline void ChangeState(NucPhaseState state)
{
TestState.state = state;
TestState.count = 0;
}
// titleID 取得用
static NUCTitleId TitleIds[NUC_MAX_TITLE_UPDATE_COUNT];
static u32 TitleIdNum;
static u8 WorkForNA[NA_VERSION_DATA_WORK_SIZE];
static BOOL AllocFailTest = FALSE;
static void *alloc(u32 size, int align)
{
u32 *ptr = NULL, *realPtr = NULL;
u32 realSize;
OSIntrMode old;
old = OS_DisableInterrupts();
/* realSize is size plus alignment and header */
if (align < 4)
{
align = 4;
}
realSize = size + align + 4;
realPtr = (u32 *) OS_Alloc(realSize);
ptr = (u32 *)((((u32) realPtr) + 4 + align - 1) & ~(align - 1));
*((u32 *)(((u32)ptr) - 4)) = (u32) realPtr;
(void)OS_RestoreInterrupts( old );
end:
// SDK_ASSERT(((u32)ptr & (align - 1)) == 0);
if( ((u32)ptr & (align - 1)) != 0 ) {
return NULL;
}
return (void *) ptr;
}
static void free(void *p)
{
u32 realPtr = *((u32 *)(((u32)p) - 4));
OS_Free((void *) realPtr);
}
/*---------------------------------------------------------------------------*
Name: InitNupLib
Description: NUCライブラリを開始します。
*---------------------------------------------------------------------------*/
BOOL InitNupLib()
{
BOOL ret;
char *error_msg[] = {
"NUC_ERROR_NO_SPACE",
"NUC_ERROR_CONNECT",
"NUC_ERROR_INTERNET",
"NUC_ERROR_UPDATE"
};
ret = NUC_Init(alloc, free);
if (ret == FALSE) {
// NUC_Init() failed, error code=34416
miya_log_fprintf(log_fd, "NUC_Init() failed, error code=%d\n", NUC_GetLastError());
miya_log_fprintf(log_fd, " error type:%s\n", error_msg[ NUC_GetErrorType(NUC_GetLastError())] );
mprintf("NUC_Init() failed, error code=%d\n", NUC_GetLastError());
mprintf(" error type:%s\n", error_msg[ NUC_GetErrorType(NUC_GetLastError())] );
}
return ret;
}
/*---------------------------------------------------------------------------*
Name: StartNupCheck
Description: ダウンロードリスト一覧の取得を開始します。
*---------------------------------------------------------------------------*/
BOOL StartNupCheck(void)
{
BOOL ret;
TitleIdNum = sizeof(TitleIds) / sizeof(TitleIds[0]);
ret = NUC_CheckAsync(TitleIds, &TitleIdNum);
if (ret == FALSE)
{
miya_log_fprintf(log_fd, "NUC_CheckAsync() failed, error code=%d\n", NUC_GetLastError());
mprintf("NUC_CheckAsync() failed, error code=%d\n", NUC_GetLastError());
}
return ret;
}
/*---------------------------------------------------------------------------*
Name: ProgressNupCheck
Description: ダウンロードリスト一覧の取得状況を確認します
*---------------------------------------------------------------------------*/
NucStatus ProgressNupCheck(void)
{
u64 CurrentSize, TotalSize;
NucStatus status;
NUC_GetProgress(&CurrentSize, &TotalSize, &status);
if (status == NUC_STATUS_ERROR)
{
// NUC_GetProgress() failed in checking, error code=34303
miya_log_fprintf(log_fd, "NUC_GetProgress() failed in checking, error code=%d\n", NUC_GetLastError());
mprintf("NUC_GetProgress() failed in checking\n error code=%d\n", NUC_GetLastError());
}
if (TestState.count++ % STRING_ANIM_CNT == 0)
{
u32 num = (TestState.count / STRING_ANIM_CNT) % 3;
const char* msg[] = {
"Now checking list. ",
"Now checking list.. ",
"Now checking list... "};
mprintf("%s\r", msg[num]);
}
return status;
}
/*---------------------------------------------------------------------------*
Name: StartNupDownload
Description: ダウンロードを開始します。
*---------------------------------------------------------------------------*/
BOOL StartNupDownload(void)
{
/* こいつが呼ばれたらFSが切り離されてしまうのでリブートが必要 */
BOOL ret = NUC_DownloadAsync(TitleIds, TitleIdNum);
if (ret == FALSE)
{
miya_log_fprintf(log_fd, "NUP_DownloadAsync() failed, error code=%d\n", NUC_GetLastError());
mprintf("NUP_DownloadAsync() failed, error code=%d\n", NUC_GetLastError());
}
return ret;
}
/*---------------------------------------------------------------------------*
Name: ProgressNupDownload
Description: ダウンロードの進行状況を表示します。
*---------------------------------------------------------------------------*/
NucStatus ProgressNupDownload(void)
{
u64 CurrentSize, TotalSize;
NucStatus status;
NUC_GetProgress(&CurrentSize, &TotalSize, &status);
if (status == NUC_STATUS_ERROR)
{ // エラー発生
// NUC_GetProgress() failed in checking, error code=34303
miya_log_fprintf(log_fd, "NUC_GetProgress() failed in download, error code=%d\n", NUC_GetLastError());
mprintf("\nNUC_GetProgress() failed\n in download\n error code=%d\n", NUC_GetLastError());
}
if (TestState.count++ % STRING_ANIM_CNT == 0)
{
u32 num = (TestState.count / STRING_ANIM_CNT) % 3;
const char* msg[] = {
"Now downloading. ",
"Now downloading.. ",
"Now downloading... "};
mprintf("%s\r", msg[num]);
}
return status;
}
/*---------------------------------------------------------------------------*
Name: CleanNupLib
Description: NUCライブラリを終了します。
*---------------------------------------------------------------------------*/
BOOL CleanNupLib(void)
{
BOOL ret = NUC_Cleanup(TitleIds, TitleIdNum);
if (ret == FALSE)
{
miya_log_fprintf(log_fd, "NUP_CleanUp() failed, error code=%d\n", NUC_GetLastError());
mprintf( "NUP_CleanUp() failed, error code=%d\n", NUC_GetLastError());
}
return ret;
}
/*---------------------------------------------------------------------------*
Name: ProgressNetConnect
Description: ネットワーク接続を待ちます。
*---------------------------------------------------------------------------*/
void ProgressNetConnect(void)
{
if (TestState.count++ % STRING_ANIM_CNT == 0)
{
u32 num = (TestState.count / STRING_ANIM_CNT) % 3;
const char* msg[] = {
"Connecting network. ",
"Connecting network.. ",
"Connecting network..."};
mprintf("%s\r", msg[num]);
}
}
void ShowErrorMsg(int error_code)
{
if (error_code > 0) {
mprintf("Error Code:%d", error_code);
mprintf(" %s\n", GetPublicMsg(error_code));
mprintf(" %s\n", GetPrivateMsg(error_code));
miya_log_fprintf(log_fd, "Error Code:%d\n", error_code);
miya_log_fprintf(log_fd, "%s\n", GetPublicMsg(error_code));
miya_log_fprintf(log_fd, "%s\n", GetPrivateMsg(error_code));
}
else
{
miya_log_fprintf(log_fd, "%s\n", "Network Error occurred.\nTry again later.");
// ネットワークエラー時の表示メッセージ(暫定)
mprintf( "%s", "Network Error occurred.\nTry again later.\n");
}
}
BOOL my_numc_proc(void)
{
BOOL ret;
NucStatus status;
int error_code = 0;
ChangeState(PHASE_NUP_BREAK);
while(1) {
OS_Sleep( 16 ); /* OS_WaitVBlankIntrの代わり */
switch ( TestState.state ) {
case PHASE_NUP_BREAK:
mprintf("NUP Initialize\n");
miya_log_fprintf(log_fd, "NUP Initialize\n");
ret = InitNupLib();
if (ret == FALSE)
{ // エラー発生
ChangeState(PHASE_ERROR_OCCURRED);
error_code = NUC_GetLastError();
}
else
{
ChangeState(PHASE_NUP_READY);
}
break;
case PHASE_NUP_READY: // 更新情報の取得を開始します。
mprintf("NUP Check\n");
miya_log_fprintf(log_fd, "NUP Check\n");
ret = StartNupCheck();
if (ret == FALSE)
{ // エラー発生
error_code = NUC_GetLastError();
ChangeState(PHASE_NUP_CLEANUP);
}
else
{
ChangeState(PHASE_NUP_CHECK);
}
break;
case PHASE_NUP_CHECK: // 更新情報の取得状況を表示します。
status = ProgressNupCheck();
if (status == NUC_STATUS_ERROR)
{ // エラー発生
mprintf("\n");
miya_log_fprintf(log_fd, "\n");
ChangeState(PHASE_NUP_CLEANUP);
error_code = NUC_GetLastError();
}
else if (status == NUC_STATUS_COMPLETED)
{ // 更新リスト 取得終了
mprintf("\n");
miya_log_fprintf(log_fd, "\n");
if (TitleIdNum > 0 )
{ // ダウンロードへ
int i;
for (i = 0; i < TitleIdNum; i++) {
miya_log_fprintf(log_fd, "DL list:%3d:0x%llx\n", i, TitleIds[i]);
mprintf("DL list:%3d:0x%llx\n", i, TitleIds[i]);
}
ChangeState(PHASE_NUP_DOWNLOAD);
}
else
{ // 更新すべきものがない
mprintf("No title to update\n");
miya_log_fprintf(log_fd, "No title to update\n");
ChangeState(PHASE_NUP_CLEANUP);
}
}
break;
case PHASE_NUP_DOWNLOAD: // ダウンロードを開始します。
mprintf("NUP Download\n");
miya_log_fprintf(log_fd, "NUP Download\n");
ret = StartNupDownload();
if (ret == FALSE)
{ // エラー発生
ChangeState(PHASE_NUP_CLEANUP);
error_code = NUC_GetLastError();
}
else
{
ChangeState(PHASE_NUP_PROCESS);
}
break;
case PHASE_NUP_PROCESS: // ダウンロードの進行状況を表示します。
status = ProgressNupDownload();
if (status == NUC_STATUS_ERROR)
{ // エラー発生
mprintf("\n");
miya_log_fprintf(log_fd, "\n");
ChangeState(PHASE_NUP_CLEANUP);
error_code = NUC_GetLastError();
}
else if (status == NUC_STATUS_COMPLETED)
{ // ダウンロード完了
mprintf("\n");
miya_log_fprintf(log_fd, "\n");
ChangeState(PHASE_NUP_CLEANUP);
}
break;
case PHASE_NUP_CLEANUP: // NUPライブラリのクリーンアップ
mprintf("NUP Cleanup\n");
miya_log_fprintf(log_fd, "NUP Cleanup\n");
ret = CleanNupLib();
if (ret == FALSE && error_code == 0)
{ // 他でエラーが起こっていない場合のみ上書きします。
error_code = NUC_GetLastError();
}
// ネットの切断と後始末
ChangeState(PHASE_FINISHED);
break;
case PHASE_FINISHED: // ネットワークアップデートが正常終了しました。
if( error_code == 0 ) {
if (TitleIdNum > 0) {
miya_log_fprintf(log_fd, "%d file is updated\n", TitleIdNum);
mprintf("%d file is updated\n", TitleIdNum);
}
else {
miya_log_fprintf(log_fd, "Nothing is updated\n");
mprintf("Nothing is updated\n");
}
}
goto end;
break;
case PHASE_ERROR_OCCURRED: // エラーが発生しています。
ShowErrorMsg(error_code);
goto end;
break;
default:
break;
}
}
end:
if( error_code != 0 ) {
return FALSE;
}
else {
return TRUE;
}
}
FSFile *my_nuc_log_start(char *log_file_name )
{
log_fd = &log_fd_real;
log_active = Log_File_Open( log_fd, log_file_name );
if( !log_active ) {
log_fd = NULL;
}
miya_log_fprintf(log_fd, "%s START\n", __FUNCTION__);
return log_fd;
}
void my_nuc_log_end(void)
{
miya_log_fprintf(log_fd, "%s END\n\n", __FUNCTION__);
if( log_active ) {
Log_File_Close(log_fd);
}
}