/*---------------------------------------------------------------------------* Project: Horizon File: Shop.cpp Copyright 2009 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev$ *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include "Shop.h" #include "CommonLogger.h" using namespace ES_NAMESPACE; using namespace EC_NAMESPACE; #define NIM_UNREGISTER_RESULT_CHECK(result) \ do { \ if (result.IsFailure()) \ { \ ECCustomerSupportCode csc; \ NN_UTIL_PANIC_IF_FAILED( \ nn::nim::Shop::GetCustomerSupportCode(&csc)); \ COMMON_LOGGER("CSCode: %d\n", csc); \ nn::dbg::PrintResult(result); \ s_Result = result; \ goto LABEL_FINALIZE; \ } \ } while(0) namespace { nn::Result s_Result = nn::ResultSuccess(); const size_t UNREGISTER_THREAD_STACK_SIZE = 0x1000; nn::os::Thread s_UnregisterThread; nn::os::StackBuffer s_UnregisterThreadStack; static const size_t ecBufferSize = 128 * 1024; static u8 ecBufffer[ecBufferSize]; #ifndef NN_SWITCH_DISABLE_DEBUG_PRINT // 空文字列と NULL ポインタをそれぞれ と NULL として返す const char* Cstr(const char* p) { return p ? (p[0] ? p : "") : "NULL"; } // ECTicketVersions を出力 void PrintECTicketVersions(const ECTicketVersions& ticketVersions) { if (ticketVersions.nTicketVersions == 0) { NN_LOG("No TicketVersions\n"); return; } NN_LOG("----- ECTicketVersions -----\n"); for (u32 i = 0; i < ticketVersions.nTicketVersions; i++) { ECTicketVersion version = ticketVersions.ticketVersions[i]; NN_LOG("%03d: 0x%016llx v%d\n", i, version.ticketId, version.version); } NN_LOG("---------------------------\n"); } // ECAccountInfo の情報を出力 void PrintECAccountInfo(const ECAccountInfo& accountInfo) { NN_LOG("========== ECAccountInfo ==========\n"); NN_LOG("accountId\n %s\n", Cstr(accountInfo.accountId)); NN_LOG("accountStatus\n %s\n", Cstr(accountInfo.accountStatus)); if (accountInfo.accountBalance == NULL) { NN_LOG("accountBalance\n NULL\n"); } else { NN_LOG("accountBalance->amount\n %s\n", Cstr(accountInfo.accountBalance->amount)); NN_LOG("accountBalance->currency\n %s\n", Cstr(accountInfo.accountBalance->currency)); } if (accountInfo.agreedEULAVersion == NULL) { NN_LOG("agreedEULAVersion\n NULL\n"); } else { NN_LOG("agreedEULAVersion\n %lld\n", *accountInfo.agreedEULAVersion); } if (accountInfo.latestEULAVersion == NULL) { NN_LOG("latestEULAVersion\n NULL\n"); } else { NN_LOG("latestEULAVersion\n %lld\n", *accountInfo.latestEULAVersion); } NN_LOG("country\n %s\n", Cstr(accountInfo.country)); NN_LOG("extAccountId\n %s\n", Cstr(accountInfo.extAccountId)); NN_LOG("deviceToken\n %s\n", Cstr(accountInfo.deviceToken)); NN_LOG("weakToken\n %s\n", Cstr(accountInfo.weakToken)); NN_LOG("isStandbyMode\n %d\n", accountInfo.isStandbyMode); if (accountInfo.owned == NULL) { NN_LOG("owned\n NULL\n"); } else { PrintECTicketVersions(*(accountInfo.owned)); } } #endif //NN_SWITCH_DISABLE_DEBUG_PRINT nn::Result PrintNetworkSetting() { nn::ac::NetworkSetting networkSetting; NN_UTIL_RETURN_IF_FAILED(nn::ac::LoadNetworkSetting(0, networkSetting)); COMMON_LOGGER("SSID: %s\n", networkSetting.wireless.essidSecurity.ssid); COMMON_LOGGER("DNS : %d.%d.%d.%d\n", networkSetting.ip.dns[0][0], networkSetting.ip.dns[0][1], networkSetting.ip.dns[0][2], networkSetting.ip.dns[0][3]); return nn::ResultSuccess(); } nn::Result ConnectNetwork() { nn::Result result = nn::ResultSuccess(); nn::ac::Config config; result = nn::ac::CreateDefaultConfig(&config); NN_UTIL_RETURN_IF_FAILED(result); result = nn::ac::ConnectWithoutEula(config); NN_UTIL_RETURN_IF_FAILED(result); NN_LOG("Success nn::ac::ConnectWithoutEula\n"); NN_UTIL_RETURN_IF_FAILED(PrintNetworkSetting()); return nn::ResultSuccess(); } nn::Result InitializeInternal() { nn::Result result = nn::ResultSuccess(); result = nn::ac::InitializeInternal(); NN_UTIL_RETURN_IF_FAILED(result); result = ConnectNetwork(); NN_UTIL_RETURN_IF_FAILED(result); return nn::ResultSuccess(); } nn::Result FinalizeInternal() { nn::Result result = nn::ResultSuccess(); nn::ac::CloseAll(); result = nn::ac::FinalizeInternal(); NN_UTIL_RETURN_IF_FAILED(result); return nn::ResultSuccess(); } } namespace ConsoleRestore{ // メイン関数 void ShopOperationSingleThreadFunc(ShopOperation op) { nn::Result result = nn::ResultSuccess(); NN_LOG("util::ac::Initialize\n"); InitializeInternal(); /* ------------------------------------------------------------------- Initialize -------------------------------------------------------------------- */ NN_LOG("nim::InitializeForShop\n"); result = nn::nim::InitializeForShop(); NIM_UNREGISTER_RESULT_CHECK(result); /* ------------------------------------------------------------------- SetParameter -------------------------------------------------------------------- */ NN_LOG("nim::Shop::SetTIN\n"); result = nn::nim::Shop::SetTin(NIM_TIN); NIM_UNREGISTER_RESULT_CHECK(result); switch(op) { case SHOP_OPERATION_CONNECT_ONLY: { // Connectするのみ /* ------------------------------------------------------------------- Connect -------------------------------------------------------------------- */ NN_LOG("nim::Shop::Connect\n"); ECAccountInfo* pAccountInfo; result = nn::nim::Shop::Connect(&pAccountInfo, ecBufffer, ecBufferSize); NIM_UNREGISTER_RESULT_CHECK(result); #ifndef NN_SWITCH_DISABLE_DEBUG_PRINT PrintECAccountInfo(*pAccountInfo); NN_LOG("\n"); #endif //NN_SWITCH_DISABLE_DEBUG_PRINT } break; case SHOP_OPERATION_GET_IVS: { // IVSを取得する result = nn::nim::Shop::ImportIvsFromInfrastructure(); NIM_UNREGISTER_RESULT_CHECK(result); } break; case SHOP_OPERATION_UNREGISTER: { /* ------------------------------------------------------------------- Connect -------------------------------------------------------------------- */ NN_LOG("nim::Shop::Connect\n"); ECAccountInfo* pAccountInfo; result = nn::nim::Shop::Connect(&pAccountInfo, ecBufffer, ecBufferSize); NIM_UNREGISTER_RESULT_CHECK(result); #ifndef NN_SWITCH_DISABLE_DEBUG_PRINT PrintECAccountInfo(*pAccountInfo); NN_LOG("\n"); #endif //NN_SWITCH_DISABLE_DEBUG_PRINT if (pAccountInfo->accountStatus && pAccountInfo->accountStatus[0] == 'R') { /* --------------------------------------------------------------- Unregister ---------------------------------------------------------------- */ NN_LOG("nim::Shop::Unregister\n"); result = nn::nim::Shop::Unregister(); NIM_UNREGISTER_RESULT_CHECK(result); } else { NN_LOG("Not registered.\n"); } } break; } LABEL_FINALIZE: /* ------------------------------------------------------------------- Finalize -------------------------------------------------------------------- */ NN_LOG("nim::FinalizeForShop\n"); result = nn::nim::FinalizeForShop(); NIM_UNREGISTER_RESULT_CHECK(result); NN_LOG("util::ac::Initialize\n"); FinalizeInternal(); } void StartShopOperationSingle(ShopOperation op) { NN_LOG("Start ShopOperationSingle"); s_Result = nn::ResultSuccess(); s_UnregisterThread.Start(ShopOperationSingleThreadFunc, op, s_UnregisterThreadStack); } void FinishShopOperationSingle() { NN_LOG("Finalize ShopOperationSingle\n"); s_UnregisterThread.Join(); s_UnregisterThread.Finalize(); } bool IsShopOperationSingleFinished() { return s_UnregisterThread.IsValid() && !s_UnregisterThread.IsAlive(); } nn::Result GetShopOperationSingleResult() { return s_Result; } }