Apply Upstream code (2021-03-15)
[platform/upstream/connectedhomeip.git] / src / include / platform / internal / GenericConnectivityManagerImpl_Thread.cpp
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    Copyright (c) 2019 Nest Labs, Inc.
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
19 /**
20  *    @file
21  *          Provides an generic implementation of ConnectivityManager features
22  *          for use on platforms that support Thread.
23  */
24
25 #ifndef GENERIC_CONNECTIVITY_MANAGER_IMPL_THREAD_CPP
26 #define GENERIC_CONNECTIVITY_MANAGER_IMPL_THREAD_CPP
27
28 #include <platform/internal/CHIPDeviceLayerInternal.h>
29 #include <platform/internal/GenericConnectivityManagerImpl_Thread.h>
30 #include <support/CodeUtils.h>
31
32 namespace chip {
33 namespace DeviceLayer {
34 namespace Internal {
35
36 template <class ImplClass>
37 void GenericConnectivityManagerImpl_Thread<ImplClass>::_OnPlatformEvent(const ChipDeviceEvent * event)
38 {
39     // Define some short-hands for various interesting event conditions.
40     const bool threadConnChanged = (event->Type == DeviceEventType::kThreadConnectivityChange &&
41                                     event->ThreadConnectivityChange.Result != kConnectivity_NoChange);
42     const bool threadAddrChanged = (event->Type == DeviceEventType::kThreadStateChange && event->ThreadStateChange.AddressChanged);
43     const bool threadNetDataChanged =
44         (event->Type == DeviceEventType::kThreadStateChange && event->ThreadStateChange.NetDataChanged);
45     const bool fabricMembershipChanged = (event->Type == DeviceEventType::kFabricMembershipChange);
46
47     // If any of the above events has occurred, assess whether there's been a change in
48     // service connectivity via Thread.
49     if (threadConnChanged || threadAddrChanged || threadNetDataChanged || fabricMembershipChanged)
50     {
51         UpdateServiceConnectivity();
52     }
53 }
54
55 template <class ImplClass>
56 ConnectivityManager::ThreadMode GenericConnectivityManagerImpl_Thread<ImplClass>::_GetThreadMode()
57 {
58     if (mFlags.Has(Flags::kIsApplicationControlled))
59     {
60         return ConnectivityManager::kThreadMode_ApplicationControlled;
61     }
62
63     return ThreadStackMgrImpl().IsThreadEnabled() ? ConnectivityManager::kThreadMode_Enabled
64                                                   : ConnectivityManager::kThreadMode_Disabled;
65 }
66
67 template <class ImplClass>
68 CHIP_ERROR GenericConnectivityManagerImpl_Thread<ImplClass>::_SetThreadMode(ConnectivityManager::ThreadMode val)
69 {
70     CHIP_ERROR err = CHIP_NO_ERROR;
71
72     VerifyOrExit(val == ConnectivityManager::kThreadMode_Enabled || val == ConnectivityManager::kThreadMode_Disabled ||
73                      val == ConnectivityManager::kThreadMode_ApplicationControlled,
74                  err = CHIP_ERROR_INVALID_ARGUMENT);
75
76     if (val == ConnectivityManager::kThreadMode_ApplicationControlled)
77     {
78         mFlags.Set(Flags::kIsApplicationControlled);
79     }
80     else
81     {
82         mFlags.Clear(Flags::kIsApplicationControlled);
83
84         err = ThreadStackMgrImpl().SetThreadEnabled(val == ConnectivityManager::kThreadMode_Enabled);
85         SuccessOrExit(err);
86     }
87
88 exit:
89     return err;
90 }
91
92 template <class ImplClass>
93 void GenericConnectivityManagerImpl_Thread<ImplClass>::UpdateServiceConnectivity()
94 {
95     constexpr bool haveServiceConnectivity = false;
96
97     // If service connectivity via Thread has changed, post an event signaling the change.
98     if (mFlags.Has(Flags::kHaveServiceConnectivity) != haveServiceConnectivity)
99     {
100         ChipLogProgress(DeviceLayer, "ConnectivityManager: Service connectivity via Thread %s",
101                         (haveServiceConnectivity) ? "ESTABLISHED" : "LOST");
102
103         mFlags.Set(Flags::kHaveServiceConnectivity, haveServiceConnectivity);
104
105         {
106             ChipDeviceEvent event;
107             event.Clear();
108             event.Type = DeviceEventType::kServiceConnectivityChange;
109             event.ServiceConnectivityChange.ViaThread.Result =
110                 (haveServiceConnectivity) ? kConnectivity_Established : kConnectivity_Lost;
111             event.ServiceConnectivityChange.Overall.Result = event.ServiceConnectivityChange.ViaThread.Result;
112             PlatformMgr().PostEvent(&event);
113         }
114     }
115 }
116
117 } // namespace Internal
118 } // namespace DeviceLayer
119 } // namespace chip
120
121 #endif // GENERIC_CONNECTIVITY_MANAGER_IMPL_THREAD_CPP