main-common.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. *
  3. * Copyright (c) 2020 Project CHIP Authors
  4. * All rights reserved.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "main-common.h"
  19. #include "AllClustersCommandDelegate.h"
  20. #include "WindowCoveringManager.h"
  21. #include "include/tv-callbacks.h"
  22. #include <app-common/zap-generated/att-storage.h>
  23. #include <app-common/zap-generated/attribute-type.h>
  24. #include <app-common/zap-generated/attributes/Accessors.h>
  25. #include <app/CommandHandler.h>
  26. #include <app/clusters/identify-server/identify-server.h>
  27. #include <app/clusters/network-commissioning/network-commissioning.h>
  28. #include <app/server/Server.h>
  29. #include <app/util/af.h>
  30. #include <lib/support/CHIPMem.h>
  31. #include <new>
  32. #include <platform/DiagnosticDataProvider.h>
  33. #include <platform/PlatformManager.h>
  34. #include <signal.h>
  35. #include <system/SystemPacketBuffer.h>
  36. #include <transport/SessionManager.h>
  37. #include <transport/raw/PeerAddress.h>
  38. #if CHIP_DEVICE_LAYER_TARGET_DARWIN
  39. #include <platform/Darwin/NetworkCommissioningDriver.h>
  40. #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
  41. #include <platform/Darwin/WiFi/NetworkCommissioningWiFiDriver.h>
  42. #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
  43. #endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
  44. #if CHIP_DEVICE_LAYER_TARGET_LINUX
  45. #include <platform/Linux/NetworkCommissioningDriver.h>
  46. #endif // CHIP_DEVICE_LAYER_TARGET_LINUX
  47. #include <Options.h>
  48. using namespace chip;
  49. using namespace chip::app;
  50. using namespace chip::DeviceLayer;
  51. namespace {
  52. constexpr const char kChipEventFifoPathPrefix[] = "/tmp/chip_all_clusters_fifo_";
  53. LowPowerManager sLowPowerManager;
  54. NamedPipeCommands sChipNamedPipeCommands;
  55. AllClustersCommandDelegate sAllClustersCommandDelegate;
  56. chip::app::Clusters::WindowCovering::WindowCoveringManager sWindowCoveringManager;
  57. // TODO(#20664) REPL test will fail if signal SIGINT is not caught, temporarily keep following logic.
  58. // when the shell is enabled, don't intercept signals since it prevents the user from
  59. // using expected commands like CTRL-C to quit the application. (see issue #17845)
  60. // We should stop using signals for those faults, and move to a different notification
  61. // means, like a pipe. (see issue #19114)
  62. #if !defined(ENABLE_CHIP_SHELL)
  63. void OnRebootSignalHandler(int signum)
  64. {
  65. ChipLogDetail(DeviceLayer, "Caught signal %d", signum);
  66. // The BootReason attribute SHALL indicate the reason for the Node’s most recent boot, the real usecase
  67. // for this attribute is embedded system. In Linux simulation, we use different signals to tell the current
  68. // running process to terminate with different reasons.
  69. BootReasonType bootReason = BootReasonType::kUnspecified;
  70. switch (signum)
  71. {
  72. case SIGINT:
  73. bootReason = BootReasonType::kSoftwareReset;
  74. break;
  75. default:
  76. IgnoreUnusedVariable(bootReason);
  77. ChipLogError(NotSpecified, "Unhandled signal: Should never happens");
  78. chipDie();
  79. break;
  80. }
  81. Server::GetInstance().DispatchShutDownAndStopEventLoop();
  82. }
  83. void SetupSignalHandlers()
  84. {
  85. // sigaction is not used here because Tsan interceptors seems to
  86. // never dispatch the signals on darwin.
  87. signal(SIGINT, OnRebootSignalHandler);
  88. }
  89. #endif // !defined(ENABLE_CHIP_SHELL)
  90. } // namespace
  91. bool emberAfBasicClusterMfgSpecificPingCallback(chip::app::CommandHandler * commandObj)
  92. {
  93. emberAfSendDefaultResponse(emberAfCurrentCommand(), EMBER_ZCL_STATUS_SUCCESS);
  94. return true;
  95. }
  96. void OnIdentifyStart(::Identify *)
  97. {
  98. ChipLogProgress(Zcl, "OnIdentifyStart");
  99. }
  100. void OnIdentifyStop(::Identify *)
  101. {
  102. ChipLogProgress(Zcl, "OnIdentifyStop");
  103. }
  104. void OnTriggerEffect(::Identify * identify)
  105. {
  106. switch (identify->mCurrentEffectIdentifier)
  107. {
  108. case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK:
  109. ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK");
  110. break;
  111. case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE:
  112. ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE");
  113. break;
  114. case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY:
  115. ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY");
  116. break;
  117. case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE:
  118. ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE");
  119. break;
  120. default:
  121. ChipLogProgress(Zcl, "No identifier effect");
  122. return;
  123. }
  124. }
  125. static Identify gIdentify0 = {
  126. chip::EndpointId{ 0 }, OnIdentifyStart, OnIdentifyStop, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, OnTriggerEffect,
  127. };
  128. static Identify gIdentify1 = {
  129. chip::EndpointId{ 1 }, OnIdentifyStart, OnIdentifyStop, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, OnTriggerEffect,
  130. };
  131. // Network commissioning
  132. namespace {
  133. // This file is being used by platforms other than Linux, so we need this check to disable related features since we only
  134. // implemented them on linux.
  135. constexpr EndpointId kNetworkCommissioningEndpointMain = 0;
  136. constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE;
  137. #if CHIP_DEVICE_LAYER_TARGET_LINUX
  138. #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
  139. NetworkCommissioning::LinuxThreadDriver sThreadDriver;
  140. #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
  141. #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
  142. NetworkCommissioning::LinuxWiFiDriver sWiFiDriver;
  143. #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
  144. NetworkCommissioning::LinuxEthernetDriver sEthernetDriver;
  145. #endif // CHIP_DEVICE_LAYER_TARGET_LINUX
  146. #if CHIP_DEVICE_LAYER_TARGET_DARWIN
  147. #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
  148. NetworkCommissioning::DarwinWiFiDriver sWiFiDriver;
  149. #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
  150. NetworkCommissioning::DarwinEthernetDriver sEthernetDriver;
  151. #endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
  152. #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
  153. Clusters::NetworkCommissioning::Instance sThreadNetworkCommissioningInstance(kNetworkCommissioningEndpointMain, &sThreadDriver);
  154. #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
  155. #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
  156. Clusters::NetworkCommissioning::Instance sWiFiNetworkCommissioningInstance(kNetworkCommissioningEndpointSecondary, &sWiFiDriver);
  157. #endif
  158. Clusters::NetworkCommissioning::Instance sEthernetNetworkCommissioningInstance(kNetworkCommissioningEndpointMain, &sEthernetDriver);
  159. } // namespace
  160. void ApplicationInit()
  161. {
  162. #if !defined(ENABLE_CHIP_SHELL)
  163. SetupSignalHandlers();
  164. #endif // !defined(ENABLE_CHIP_SHELL)
  165. (void) kNetworkCommissioningEndpointMain;
  166. // Enable secondary endpoint only when we need it, this should be applied to all platforms.
  167. emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false);
  168. const bool kThreadEnabled = {
  169. #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
  170. LinuxDeviceOptions::GetInstance().mThread
  171. #else
  172. false
  173. #endif
  174. };
  175. const bool kWiFiEnabled = {
  176. #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
  177. LinuxDeviceOptions::GetInstance().mWiFi
  178. #else
  179. false
  180. #endif
  181. };
  182. if (kThreadEnabled && kWiFiEnabled)
  183. {
  184. #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
  185. sThreadNetworkCommissioningInstance.Init();
  186. #endif
  187. #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
  188. sWiFiNetworkCommissioningInstance.Init();
  189. #endif
  190. // Only enable secondary endpoint for network commissioning cluster when both WiFi and Thread are enabled.
  191. emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, true);
  192. }
  193. else if (kThreadEnabled)
  194. {
  195. #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
  196. sThreadNetworkCommissioningInstance.Init();
  197. #endif
  198. }
  199. else if (kWiFiEnabled)
  200. {
  201. #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
  202. // If we only enable WiFi on this device, "move" WiFi instance to main NetworkCommissioning cluster endpoint.
  203. sWiFiNetworkCommissioningInstance.~Instance();
  204. new (&sWiFiNetworkCommissioningInstance)
  205. Clusters::NetworkCommissioning::Instance(kNetworkCommissioningEndpointMain, &sWiFiDriver);
  206. sWiFiNetworkCommissioningInstance.Init();
  207. #endif
  208. }
  209. else
  210. {
  211. sEthernetNetworkCommissioningInstance.Init();
  212. }
  213. std::string path = kChipEventFifoPathPrefix + std::to_string(getpid());
  214. if (sChipNamedPipeCommands.Start(path, &sAllClustersCommandDelegate) != CHIP_NO_ERROR)
  215. {
  216. ChipLogError(NotSpecified, "Failed to start CHIP NamedPipeCommands");
  217. sChipNamedPipeCommands.Stop();
  218. }
  219. }
  220. void ApplicationExit()
  221. {
  222. if (sChipNamedPipeCommands.Stop() != CHIP_NO_ERROR)
  223. {
  224. ChipLogError(NotSpecified, "Failed to stop CHIP NamedPipeCommands");
  225. }
  226. }
  227. void emberAfLowPowerClusterInitCallback(EndpointId endpoint)
  228. {
  229. ChipLogProgress(NotSpecified, "TV Linux App: LowPower::SetDefaultDelegate");
  230. chip::app::Clusters::LowPower::SetDefaultDelegate(endpoint, &sLowPowerManager);
  231. }
  232. void emberAfWindowCoveringClusterInitCallback(chip::EndpointId endpoint)
  233. {
  234. sWindowCoveringManager.Init(endpoint);
  235. chip::app::Clusters::WindowCovering::SetDefaultDelegate(endpoint, &sWindowCoveringManager);
  236. chip::app::Clusters::WindowCovering::ConfigStatusUpdateFeatures(endpoint);
  237. }