3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2019 Google LLC.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * Contains non-inline method definitions for the
22 * GenericSoftwareUpdateManagerImpl<> template.
25 #ifndef GENERIC_SOFTWARE_UPDATE_MANAGER_IMPL_BDX_CPP
26 #define GENERIC_SOFTWARE_UPDATE_MANAGER_IMPL_BDX_CPP
28 #if CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER
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>
37 namespace DeviceLayer {
40 using namespace ::chip::TLV;
41 using namespace ::chip::Profiles;
42 using namespace ::chip::Profiles::Common;
43 using namespace ::chip::Profiles::BulkDataTransfer;
45 // Fully instantiate the generic implementation class in whatever compilation unit includes this file.
46 template class GenericSoftwareUpdateManagerImpl_BDX<SoftwareUpdateManagerImpl>;
48 template <class ImplClass>
49 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::DoInit(void)
58 err = mBDXClient.Init(&ExchangeMgr);
63 template <class ImplClass>
64 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::StartImageDownload(char * aURI, uint64_t aStartOffset)
68 VerifyOrExit(aURI != NULL, err = CHIP_ERROR_INVALID_ARGUMENT);
71 mStartOffset = aStartOffset;
73 mBinding = ExchangeMgr.NewBinding(HandleBindingEvent, NULL);
74 VerifyOrExit(mBinding != NULL, err = CHIP_ERROR_NO_MEMORY);
76 err = mBinding->BeginConfiguration()
77 .Target_ServiceEndpoint(CHIP_DEVICE_CONFIG_FILE_DOWNLOAD_ENDPOINT_ID)
79 .Exchange_ResponseTimeoutMsec(CHIP_DEVICE_CONFIG_FILE_DOWNLOAD_RESPOSNE_TIMEOUT)
80 .Security_SharedCASESession()
87 template <class ImplClass>
88 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::StartDownload(void)
93 uri.init((uint16_t) strlen(mURI), mURI);
95 BDXHandlers handlers = {
96 NULL, // SendAcceptHandler
99 NULL, // GetBlockHandler
106 VerifyOrExit(mBDXTransfer == NULL, err = CHIP_ERROR_INCORRECT_STATE);
108 err = mBDXClient.NewTransfer(mBinding, handlers, uri, this, mBDXTransfer);
111 // Release our reference to the binding, as it's no longer needed.
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.
122 mBDXTransfer->mMaxBlockSize = CHIP_DEVICE_CONFIG_SWU_BDX_BLOCK_SIZE;
123 mBDXTransfer->mStartOffset = mStartOffset;
124 mBDXTransfer->mLength = 0;
126 err = mBDXClient.InitBdxReceive(*mBDXTransfer, true, false, false, NULL);
130 if (err != CHIP_NO_ERROR)
137 template <class ImplClass>
138 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::ReceiveAcceptHandler(BDXTransfer * aXfer,
139 ReceiveAccept * aReceiveAcceptMsg)
141 return CHIP_NO_ERROR;
144 template <class ImplClass>
145 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::ReceiveRejectHandler(BDXTransfer * aXfer, StatusReport * aReport)
147 GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
149 // Release all resources.
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
158 if (aReport->mProfileId == kChipProfile_BDX && aReport->mStatusCode == kStatus_LengthMismatch)
160 self->Impl()->DownloadComplete();
164 self->Impl()->SoftwareUpdateFailed(CHIP_ERROR_STATUS_REPORT_RECEIVED, aReport);
168 template <class ImplClass>
169 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::BlockReceiveHandler(BDXTransfer * xfr, uint64_t aLength, uint8_t * aDataBlock,
173 GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
175 err = self->Impl()->StoreImageBlock(aLength, aDataBlock);
176 if (err == CHIP_DEVICE_ERROR_SOFTWARE_UPDATE_ABORTED)
180 else if (err != CHIP_NO_ERROR)
183 self->Impl()->SoftwareUpdateFailed(err, NULL);
187 template <class ImplClass>
188 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::XferErrorHandler(BDXTransfer * aXfer, StatusReport * aReport)
190 GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
193 self->Impl()->SoftwareUpdateFailed(CHIP_ERROR_STATUS_REPORT_RECEIVED, aReport);
196 template <class ImplClass>
197 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::XferDoneHandler(BDXTransfer * aXfer)
199 GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
202 self->Impl()->DownloadComplete();
205 template <class ImplClass>
206 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::ErrorHandler(BDXTransfer * aXfer, CHIP_ERROR aErrorCode)
208 GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
211 self->Impl()->SoftwareUpdateFailed(aErrorCode, NULL);
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)
219 CHIP_ERROR err = CHIP_NO_ERROR;
220 StatusReport * statusReport = NULL;
221 GenericSoftwareUpdateManagerImpl_BDX<ImplClass> * self = &SoftwareUpdateMgrImpl();
225 case chip::Binding::kEvent_PrepareFailed:
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;
235 case chip::Binding::kEvent_BindingFailed:
236 ChipLogProgress(DeviceLayer, "Software Update BDX binding failed: %s", ErrorStr(aInParam.BindingFailed.Reason));
237 err = aInParam.PrepareFailed.Reason;
240 case chip::Binding::kEvent_BindingReady:
241 ChipLogProgress(DeviceLayer, "Software Update BDX binding ready");
242 err = self->StartDownload();
246 chip::Binding::DefaultEventHandler(appState, aEvent, aInParam, aOutParam);
249 if (err != CHIP_NO_ERROR)
252 self->Impl()->SoftwareUpdateFailed(err, statusReport);
256 template <class ImplClass>
257 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::AbortDownload(void)
262 template <class ImplClass>
263 void GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::ResetState(void)
265 if (mBinding != NULL)
273 mBDXTransfer->Shutdown();
279 template <class ImplClass>
280 CHIP_ERROR GenericSoftwareUpdateManagerImpl_BDX<ImplClass>::GetUpdateSchemeList(
281 ::chip::Profiles::SoftwareUpdate::UpdateSchemeList * aUpdateSchemeList)
283 uint8_t supportedSchemes[] = { Profiles::SoftwareUpdate::kUpdateScheme_BDX };
284 aUpdateSchemeList->init(ArraySize(supportedSchemes), supportedSchemes);
286 return CHIP_NO_ERROR;
289 } // namespace Internal
290 } // namespace DeviceLayer
293 #endif // CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER
294 #endif // GENERIC_SOFTWARE_UPDATE_MANAGER_IMPL_BDX_CPP