Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / include / platform / internal / GenericSoftwareUpdateManagerImpl_BDX.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2019 Google LLC.
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  *          Contains non-inline method definitions for the
22  *          GenericSoftwareUpdateManagerImpl<> template.
23  */
24
25 #ifndef GENERIC_SOFTWARE_UPDATE_MANAGER_IMPL_BDX_CPP
26 #define GENERIC_SOFTWARE_UPDATE_MANAGER_IMPL_BDX_CPP
27
28 #if CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER
29
30 #include <core/CHIPCore.h>
31 #include <platform/PlatformManager.h>
32 #include <platform/SoftwareUpdateManager.h>
33 #include <platform/internal/CHIPDeviceLayerInternal.h>
34 #include <platform/internal/GenericSoftwareUpdateManagerImpl_BDX.h>
35
36 namespace chip {
37 namespace DeviceLayer {
38 namespace Internal {
39
40 using namespace ::chip::TLV;
41 using namespace ::chip::Profiles;
42 using namespace ::chip::Profiles::Common;
43 using namespace ::chip::Profiles::BulkDataTransfer;
44
45 // Fully instantiate the generic implementation class in whatever compilation unit includes this file.
46 template class GenericSoftwareUpdateManagerImpl_BDX<SoftwareUpdateManagerImpl>;
47
48 template <class ImplClass>
49 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::DoInit(void)
50 {
51     CHIP_ERROR err;
52
53     mBinding     = NULL;
54     mURI         = NULL;
55     mBDXTransfer = NULL;
56     mStartOffset = 0;
57
58     err = mBDXClient.Init(&ExchangeMgr);
59
60     return err;
61 }
62
63 template <class ImplClass>
64 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::StartImageDownload(char * aURI, uint64_t aStartOffset)
65 {
66     CHIP_ERROR err;
67
68     VerifyOrExit(aURI != NULL, err = CHIP_ERROR_INVALID_ARGUMENT);
69
70     mURI         = aURI;
71     mStartOffset = aStartOffset;
72
73     mBinding = ExchangeMgr.NewBinding(HandleBindingEvent, NULL);
74     VerifyOrExit(mBinding != NULL, err = CHIP_ERROR_NO_MEMORY);
75
76     err = mBinding->BeginConfiguration()
77               .Target_ServiceEndpoint(CHIP_DEVICE_CONFIG_FILE_DOWNLOAD_ENDPOINT_ID)
78               .Transport_UDP_WRM()
79               .Exchange_ResponseTimeoutMsec(CHIP_DEVICE_CONFIG_FILE_DOWNLOAD_RESPOSNE_TIMEOUT)
80               .Security_SharedCASESession()
81               .PrepareBinding();
82
83 exit:
84     return err;
85 }
86
87 template <class ImplClass>
88 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::StartDownload(void)
89 {
90     CHIP_ERROR err;
91
92     ReferencedString uri;
93     uri.init((uint16_t) strlen(mURI), mURI);
94
95     BDXHandlers handlers = {
96         NULL, // SendAcceptHandler
97         ReceiveAcceptHandler,
98         ReceiveRejectHandler,
99         NULL, // GetBlockHandler
100         BlockReceiveHandler,
101         XferErrorHandler,
102         XferDoneHandler,
103         ErrorHandler,
104     };
105
106     VerifyOrExit(mBDXTransfer == NULL, err = CHIP_ERROR_INCORRECT_STATE);
107
108     err = mBDXClient.NewTransfer(mBinding, handlers, uri, this, mBDXTransfer);
109     SuccessOrExit(err);
110
111     // Release our reference to the binding, as it's no longer needed.
112     mBinding->Release();
113     mBinding = NULL;
114
115     /*
116      * This implementation only supports downloading a software image from an offset
117      * provided by the application till the end of file. The 0 value in mLength field
118      * below indicates that expected length of the transfer is unknown by the initiator
119      * at this point and hence the remainder of the file starting from the offset
120      * mentioned above is expected to be downloaded in the transfer.
121      */
122     mBDXTransfer->mMaxBlockSize = CHIP_DEVICE_CONFIG_SWU_BDX_BLOCK_SIZE;
123     mBDXTransfer->mStartOffset  = mStartOffset;
124     mBDXTransfer->mLength       = 0;
125
126     err = mBDXClient.InitBdxReceive(*mBDXTransfer, true, false, false, NULL);
127     SuccessOrExit(err);
128
129 exit:
130     if (err != CHIP_NO_ERROR)
131     {
132         ResetState();
133     }
134     return err;
135 }
136
137 template <class ImplClass>
138 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::ReceiveAcceptHandler(BDXTransfer * aXfer,
139                                                                                  ReceiveAccept * aReceiveAcceptMsg)
140 {
141     return CHIP_NO_ERROR;
142 }
143
144 template <class ImplClass>
145 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::ReceiveRejectHandler(BDXTransfer * aXfer, StatusReport * aReport)
146 {
147     GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
148
149     // Release all resources.
150     self->ResetState();
151
152     // If the BDX transfer was rejected by the server with a status report containing status code
153     // kStatus_LengthMismatch, it specifically means that the start offset requested by the application
154     // in the BDX request is greater than or equal to the length of the file being downloaded. In the context
155     // of this implementation, it means that file download is complete since the end of file has already been
156     // reached.
157     //
158     if (aReport->mProfileId == kChipProfile_BDX && aReport->mStatusCode == kStatus_LengthMismatch)
159     {
160         self->Impl()->DownloadComplete();
161     }
162     else
163     {
164         self->Impl()->SoftwareUpdateFailed(CHIP_ERROR_STATUS_REPORT_RECEIVED, aReport);
165     }
166 }
167
168 template <class ImplClass>
169 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::BlockReceiveHandler(BDXTransfer * xfr, uint64_t aLength, uint8_t * aDataBlock,
170                                                                           bool aIsLastBlock)
171 {
172     CHIP_ERROR err;
173     GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
174
175     err = self->Impl()->StoreImageBlock(aLength, aDataBlock);
176     if (err == CHIP_DEVICE_ERROR_SOFTWARE_UPDATE_ABORTED)
177     {
178         return;
179     }
180     else if (err != CHIP_NO_ERROR)
181     {
182         self->ResetState();
183         self->Impl()->SoftwareUpdateFailed(err, NULL);
184     }
185 }
186
187 template <class ImplClass>
188 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::XferErrorHandler(BDXTransfer * aXfer, StatusReport * aReport)
189 {
190     GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
191
192     self->ResetState();
193     self->Impl()->SoftwareUpdateFailed(CHIP_ERROR_STATUS_REPORT_RECEIVED, aReport);
194 }
195
196 template <class ImplClass>
197 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::XferDoneHandler(BDXTransfer * aXfer)
198 {
199     GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
200
201     self->ResetState();
202     self->Impl()->DownloadComplete();
203 }
204
205 template <class ImplClass>
206 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::ErrorHandler(BDXTransfer * aXfer, CHIP_ERROR aErrorCode)
207 {
208     GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
209
210     self->ResetState();
211     self->Impl()->SoftwareUpdateFailed(aErrorCode, NULL);
212 }
213
214 template <class ImplClass>
215 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::HandleBindingEvent(void * appState, ::chip::Binding::EventType aEvent,
216                                                                          const ::chip::Binding::InEventParam & aInParam,
217                                                                          ::chip::Binding::OutEventParam & aOutParam)
218 {
219     CHIP_ERROR err                                         = CHIP_NO_ERROR;
220     StatusReport * statusReport                            = NULL;
221     GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
222
223     switch (aEvent)
224     {
225     case chip::Binding::kEvent_PrepareFailed:
226         ChipLogProgress(
227             DeviceLayer, "Failed to prepare Software Update BDX binding: %s",
228             (aInParam.PrepareFailed.Reason == CHIP_ERROR_STATUS_REPORT_RECEIVED)
229                 ? StatusReportStr(aInParam.PrepareFailed.StatusReport->mProfileId, aInParam.PrepareFailed.StatusReport->mStatusCode)
230                 : ErrorStr(aInParam.PrepareFailed.Reason));
231         statusReport = aInParam.PrepareFailed.StatusReport;
232         err          = aInParam.PrepareFailed.Reason;
233         break;
234
235     case chip::Binding::kEvent_BindingFailed:
236         ChipLogProgress(DeviceLayer, "Software Update BDX binding failed: %s", ErrorStr(aInParam.BindingFailed.Reason));
237         err = aInParam.PrepareFailed.Reason;
238         break;
239
240     case chip::Binding::kEvent_BindingReady:
241         ChipLogProgress(DeviceLayer, "Software Update BDX binding ready");
242         err = self->StartDownload();
243         break;
244
245     default:
246         chip::Binding::DefaultEventHandler(appState, aEvent, aInParam, aOutParam);
247     }
248
249     if (err != CHIP_NO_ERROR)
250     {
251         self->ResetState();
252         self->Impl()->SoftwareUpdateFailed(err, statusReport);
253     }
254 }
255
256 template <class ImplClass>
257 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::AbortDownload(void)
258 {
259     ResetState();
260 }
261
262 template <class ImplClass>
263 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::ResetState(void)
264 {
265     if (mBinding != NULL)
266     {
267         mBinding->Release();
268         mBinding = NULL;
269     }
270     mURI = NULL;
271     if (mBDXTransfer)
272     {
273         mBDXTransfer->Shutdown();
274         mBDXTransfer = NULL;
275     }
276     mStartOffset = 0;
277 }
278
279 template <class ImplClass>
280 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::GetUpdateSchemeList(
281     ::chip::Profiles::SoftwareUpdate::UpdateSchemeList * aUpdateSchemeList)
282 {
283     uint8_t supportedSchemes[] = { Profiles::SoftwareUpdate::kUpdateScheme_BDX };
284     aUpdateSchemeList->init(ArraySize(supportedSchemes), supportedSchemes);
285
286     return CHIP_NO_ERROR;
287 }
288
289 } // namespace Internal
290 } // namespace DeviceLayer
291 } // namespace chip
292
293 #endif // CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER
294 #endif // GENERIC_SOFTWARE_UPDATE_MANAGER_IMPL_BDX_CPP