nifm.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "core/core.h"
  5. #include "core/hle/ipc_helpers.h"
  6. #include "core/hle/kernel/kernel.h"
  7. #include "core/hle/kernel/readable_event.h"
  8. #include "core/hle/kernel/writable_event.h"
  9. #include "core/hle/service/nifm/nifm.h"
  10. #include "core/hle/service/service.h"
  11. namespace Service::NIFM {
  12. class IScanRequest final : public ServiceFramework<IScanRequest> {
  13. public:
  14. explicit IScanRequest() : ServiceFramework("IScanRequest") {
  15. // clang-format off
  16. static const FunctionInfo functions[] = {
  17. {0, nullptr, "Submit"},
  18. {1, nullptr, "IsProcessing"},
  19. {2, nullptr, "GetResult"},
  20. {3, nullptr, "GetSystemEventReadableHandle"},
  21. {4, nullptr, "SetChannels"},
  22. };
  23. // clang-format on
  24. RegisterHandlers(functions);
  25. }
  26. };
  27. class IRequest final : public ServiceFramework<IRequest> {
  28. public:
  29. explicit IRequest(Core::System& system) : ServiceFramework("IRequest") {
  30. static const FunctionInfo functions[] = {
  31. {0, &IRequest::GetRequestState, "GetRequestState"},
  32. {1, &IRequest::GetResult, "GetResult"},
  33. {2, &IRequest::GetSystemEventReadableHandles, "GetSystemEventReadableHandles"},
  34. {3, &IRequest::Cancel, "Cancel"},
  35. {4, &IRequest::Submit, "Submit"},
  36. {5, nullptr, "SetRequirement"},
  37. {6, nullptr, "SetRequirementPreset"},
  38. {8, nullptr, "SetPriority"},
  39. {9, nullptr, "SetNetworkProfileId"},
  40. {10, nullptr, "SetRejectable"},
  41. {11, &IRequest::SetConnectionConfirmationOption, "SetConnectionConfirmationOption"},
  42. {12, nullptr, "SetPersistent"},
  43. {13, nullptr, "SetInstant"},
  44. {14, nullptr, "SetSustainable"},
  45. {15, nullptr, "SetRawPriority"},
  46. {16, nullptr, "SetGreedy"},
  47. {17, nullptr, "SetSharable"},
  48. {18, nullptr, "SetRequirementByRevision"},
  49. {19, nullptr, "GetRequirement"},
  50. {20, nullptr, "GetRevision"},
  51. {21, nullptr, "GetAppletInfo"},
  52. {22, nullptr, "GetAdditionalInfo"},
  53. {23, nullptr, "SetKeptInSleep"},
  54. {24, nullptr, "RegisterSocketDescriptor"},
  55. {25, nullptr, "UnregisterSocketDescriptor"},
  56. };
  57. RegisterHandlers(functions);
  58. auto& kernel = system.Kernel();
  59. event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
  60. "IRequest:Event1");
  61. event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
  62. "IRequest:Event2");
  63. }
  64. private:
  65. void Submit(Kernel::HLERequestContext& ctx) {
  66. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  67. IPC::ResponseBuilder rb{ctx, 2};
  68. rb.Push(RESULT_SUCCESS);
  69. }
  70. void GetRequestState(Kernel::HLERequestContext& ctx) {
  71. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  72. IPC::ResponseBuilder rb{ctx, 3};
  73. rb.Push(RESULT_SUCCESS);
  74. rb.Push<u32>(0);
  75. }
  76. void GetResult(Kernel::HLERequestContext& ctx) {
  77. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  78. IPC::ResponseBuilder rb{ctx, 2};
  79. rb.Push(RESULT_SUCCESS);
  80. }
  81. void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) {
  82. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  83. IPC::ResponseBuilder rb{ctx, 2, 2};
  84. rb.Push(RESULT_SUCCESS);
  85. rb.PushCopyObjects(event1.readable, event2.readable);
  86. }
  87. void Cancel(Kernel::HLERequestContext& ctx) {
  88. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  89. IPC::ResponseBuilder rb{ctx, 2};
  90. rb.Push(RESULT_SUCCESS);
  91. }
  92. void SetConnectionConfirmationOption(Kernel::HLERequestContext& ctx) {
  93. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  94. IPC::ResponseBuilder rb{ctx, 2};
  95. rb.Push(RESULT_SUCCESS);
  96. }
  97. Kernel::EventPair event1, event2;
  98. };
  99. class INetworkProfile final : public ServiceFramework<INetworkProfile> {
  100. public:
  101. explicit INetworkProfile() : ServiceFramework("INetworkProfile") {
  102. static const FunctionInfo functions[] = {
  103. {0, nullptr, "Update"},
  104. {1, nullptr, "PersistOld"},
  105. {2, nullptr, "Persist"},
  106. };
  107. RegisterHandlers(functions);
  108. }
  109. };
  110. class IGeneralService final : public ServiceFramework<IGeneralService> {
  111. public:
  112. IGeneralService(Core::System& system);
  113. private:
  114. void GetClientId(Kernel::HLERequestContext& ctx) {
  115. static constexpr u32 client_id = 1;
  116. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  117. IPC::ResponseBuilder rb{ctx, 4};
  118. rb.Push(RESULT_SUCCESS);
  119. rb.Push<u64>(client_id); // Client ID needs to be non zero otherwise it's considered invalid
  120. }
  121. void CreateScanRequest(Kernel::HLERequestContext& ctx) {
  122. LOG_DEBUG(Service_NIFM, "called");
  123. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  124. rb.Push(RESULT_SUCCESS);
  125. rb.PushIpcInterface<IScanRequest>();
  126. }
  127. void CreateRequest(Kernel::HLERequestContext& ctx) {
  128. LOG_DEBUG(Service_NIFM, "called");
  129. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  130. rb.Push(RESULT_SUCCESS);
  131. rb.PushIpcInterface<IRequest>(system);
  132. }
  133. void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
  134. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  135. IPC::ResponseBuilder rb{ctx, 2};
  136. rb.Push(RESULT_SUCCESS);
  137. }
  138. void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
  139. LOG_DEBUG(Service_NIFM, "called");
  140. ASSERT_MSG(ctx.GetReadBufferSize() == 0x17c, "NetworkProfileData is not the correct size");
  141. u128 uuid{};
  142. auto buffer = ctx.ReadBuffer();
  143. std::memcpy(&uuid, buffer.data() + 8, sizeof(u128));
  144. IPC::ResponseBuilder rb{ctx, 6, 0, 1};
  145. rb.Push(RESULT_SUCCESS);
  146. rb.PushIpcInterface<INetworkProfile>();
  147. rb.PushRaw<u128>(uuid);
  148. }
  149. void IsWirelessCommunicationEnabled(Kernel::HLERequestContext& ctx) {
  150. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  151. IPC::ResponseBuilder rb{ctx, 3};
  152. rb.Push(RESULT_SUCCESS);
  153. rb.Push<u8>(0);
  154. }
  155. void IsEthernetCommunicationEnabled(Kernel::HLERequestContext& ctx) {
  156. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  157. IPC::ResponseBuilder rb{ctx, 3};
  158. rb.Push(RESULT_SUCCESS);
  159. rb.Push<u8>(0);
  160. }
  161. void IsAnyInternetRequestAccepted(Kernel::HLERequestContext& ctx) {
  162. LOG_WARNING(Service_NIFM, "(STUBBED) called");
  163. IPC::ResponseBuilder rb{ctx, 3};
  164. rb.Push(RESULT_SUCCESS);
  165. rb.Push<u8>(0);
  166. }
  167. Core::System& system;
  168. };
  169. IGeneralService::IGeneralService(Core::System& system)
  170. : ServiceFramework("IGeneralService"), system(system) {
  171. static const FunctionInfo functions[] = {
  172. {1, &IGeneralService::GetClientId, "GetClientId"},
  173. {2, &IGeneralService::CreateScanRequest, "CreateScanRequest"},
  174. {4, &IGeneralService::CreateRequest, "CreateRequest"},
  175. {5, nullptr, "GetCurrentNetworkProfile"},
  176. {6, nullptr, "EnumerateNetworkInterfaces"},
  177. {7, nullptr, "EnumerateNetworkProfiles"},
  178. {8, nullptr, "GetNetworkProfile"},
  179. {9, nullptr, "SetNetworkProfile"},
  180. {10, &IGeneralService::RemoveNetworkProfile, "RemoveNetworkProfile"},
  181. {11, nullptr, "GetScanDataOld"},
  182. {12, nullptr, "GetCurrentIpAddress"},
  183. {13, nullptr, "GetCurrentAccessPointOld"},
  184. {14, &IGeneralService::CreateTemporaryNetworkProfile, "CreateTemporaryNetworkProfile"},
  185. {15, nullptr, "GetCurrentIpConfigInfo"},
  186. {16, nullptr, "SetWirelessCommunicationEnabled"},
  187. {17, &IGeneralService::IsWirelessCommunicationEnabled, "IsWirelessCommunicationEnabled"},
  188. {18, nullptr, "GetInternetConnectionStatus"},
  189. {19, nullptr, "SetEthernetCommunicationEnabled"},
  190. {20, &IGeneralService::IsEthernetCommunicationEnabled, "IsEthernetCommunicationEnabled"},
  191. {21, &IGeneralService::IsAnyInternetRequestAccepted, "IsAnyInternetRequestAccepted"},
  192. {22, nullptr, "IsAnyForegroundRequestAccepted"},
  193. {23, nullptr, "PutToSleep"},
  194. {24, nullptr, "WakeUp"},
  195. {25, nullptr, "GetSsidListVersion"},
  196. {26, nullptr, "SetExclusiveClient"},
  197. {27, nullptr, "GetDefaultIpSetting"},
  198. {28, nullptr, "SetDefaultIpSetting"},
  199. {29, nullptr, "SetWirelessCommunicationEnabledForTest"},
  200. {30, nullptr, "SetEthernetCommunicationEnabledForTest"},
  201. {31, nullptr, "GetTelemetorySystemEventReadableHandle"},
  202. {32, nullptr, "GetTelemetryInfo"},
  203. {33, nullptr, "ConfirmSystemAvailability"},
  204. {34, nullptr, "SetBackgroundRequestEnabled"},
  205. {35, nullptr, "GetScanData"},
  206. {36, nullptr, "GetCurrentAccessPoint"},
  207. {37, nullptr, "Shutdown"},
  208. {38, nullptr, "GetAllowedChannels"},
  209. };
  210. RegisterHandlers(functions);
  211. }
  212. class NetworkInterface final : public ServiceFramework<NetworkInterface> {
  213. public:
  214. explicit NetworkInterface(const char* name, Core::System& system)
  215. : ServiceFramework{name}, system(system) {
  216. static const FunctionInfo functions[] = {
  217. {4, &NetworkInterface::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
  218. {5, &NetworkInterface::CreateGeneralService, "CreateGeneralService"},
  219. };
  220. RegisterHandlers(functions);
  221. }
  222. void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
  223. LOG_DEBUG(Service_NIFM, "called");
  224. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  225. rb.Push(RESULT_SUCCESS);
  226. rb.PushIpcInterface<IGeneralService>(system);
  227. }
  228. void CreateGeneralService(Kernel::HLERequestContext& ctx) {
  229. LOG_DEBUG(Service_NIFM, "called");
  230. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  231. rb.Push(RESULT_SUCCESS);
  232. rb.PushIpcInterface<IGeneralService>(system);
  233. }
  234. private:
  235. Core::System& system;
  236. };
  237. void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
  238. std::make_shared<NetworkInterface>("nifm:a", system)->InstallAsService(service_manager);
  239. std::make_shared<NetworkInterface>("nifm:s", system)->InstallAsService(service_manager);
  240. std::make_shared<NetworkInterface>("nifm:u", system)->InstallAsService(service_manager);
  241. }
  242. } // namespace Service::NIFM