1
+ /*
2
+ *
3
+ * Copyright (c) 2023 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
+
19
+ #include < platform/internal/CHIPDeviceLayerInternal.h>
20
+ #include < platform/silabs/multi-ota/OTAMultiImageProcessorImpl.h>
21
+ #include < platform/silabs/multi-ota/SiWx917/OTAWiFiFirmwareProcessor.h>
22
+
23
+ #include < app/clusters/ota-requestor/OTARequestorInterface.h>
24
+ #include " wfx_host_events.h"
25
+ #include < platform/silabs/SilabsConfig.h>
26
+ #ifdef __cplusplus
27
+ extern " C" {
28
+ #endif
29
+ #include " sl_si91x_driver.h"
30
+ #ifdef SLI_SI91X_MCU_INTERFACE
31
+ #include " sl_si91x_hal_soc_soft_reset.h"
32
+ #endif
33
+ #ifdef __cplusplus
34
+ }
35
+ #endif
36
+
37
+ #define RPS_HEADER 1
38
+ #define RPS_DATA 2
39
+
40
+ #define SL_STATUS_FW_UPDATE_DONE SL_STATUS_SI91X_NO_AP_FOUND
41
+ uint8_t flag = RPS_HEADER;
42
+
43
+ namespace chip {
44
+
45
+ // Define static memebers
46
+ bool OTAWiFiFirmwareProcessor::mReset = false ;
47
+
48
+ CHIP_ERROR OTAWiFiFirmwareProcessor::Init ()
49
+ {
50
+ ReturnErrorCodeIf (mCallbackProcessDescriptor == nullptr , CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED);
51
+ mAccumulator .Init (sizeof (Descriptor));
52
+ #if OTA_ENCRYPTION_ENABLE
53
+ mUnalignmentNum = 0 ;
54
+ #endif
55
+
56
+ return CHIP_NO_ERROR;
57
+ }
58
+
59
+ CHIP_ERROR OTAWiFiFirmwareProcessor::Clear ()
60
+ {
61
+ OTATlvProcessor::ClearInternal ();
62
+ mAccumulator .Clear ();
63
+ mDescriptorProcessed = false ;
64
+ #if OTA_ENCRYPTION_ENABLE
65
+ mUnalignmentNum = 0 ;
66
+ #endif
67
+
68
+ return CHIP_NO_ERROR;
69
+ }
70
+
71
+ CHIP_ERROR OTAWiFiFirmwareProcessor::ProcessInternal (ByteSpan & block)
72
+ {
73
+ int32_t status = SL_STATUS_OK;
74
+ // Store the header of the OTA file
75
+ static uint8_t writeBuffer[kAlignmentBytes ] __attribute__ ((aligned (4 ))) = { 0 };
76
+ // Used to tranfer other block to processor
77
+ static uint8_t writeDataBuffer[1024 ] __attribute__ ((aligned (4 ))) = { 0 };
78
+
79
+ if (!mDescriptorProcessed )
80
+ {
81
+ ReturnErrorOnFailure (ProcessDescriptor (block));
82
+ #if OTA_ENCRYPTION_ENABLE
83
+ /* 16 bytes to used to store undecrypted data because of unalignment */
84
+ mAccumulator .Init (requestedOtaMaxBlockSize + 16 );
85
+ #endif
86
+ }
87
+
88
+ #if OTA_ENCRYPTION_ENABLE
89
+ MutableByteSpan mBlock = MutableByteSpan (mAccumulator .data (), mAccumulator .GetThreshold ());
90
+ memcpy (&mBlock [0 ], &mBlock [requestedOtaMaxBlockSize], mUnalignmentNum );
91
+ memcpy (&mBlock [mUnalignmentNum ], block.data (), block.size ());
92
+
93
+ if (mUnalignmentNum + block.size () < requestedOtaMaxBlockSize)
94
+ {
95
+ uint32_t mAlignmentNum = (mUnalignmentNum + block.size ()) / 16 ;
96
+ mAlignmentNum = mAlignmentNum * 16 ;
97
+ mUnalignmentNum = (mUnalignmentNum + block.size ()) % 16 ;
98
+ memcpy (&mBlock [requestedOtaMaxBlockSize], &mBlock [mAlignmentNum ], mUnalignmentNum );
99
+ mBlock .reduce_size (mAlignmentNum );
100
+ }
101
+ else
102
+ {
103
+ mUnalignmentNum = mUnalignmentNum + block.size () - requestedOtaMaxBlockSize;
104
+ mBlock .reduce_size (requestedOtaMaxBlockSize);
105
+ }
106
+
107
+ OTATlvProcessor::vOtaProcessInternalEncryption (mBlock );
108
+ block = mBlock ;
109
+ #endif
110
+
111
+ if (flag == RPS_HEADER)
112
+ {
113
+ memcpy (&writeBuffer, block.data (), kAlignmentBytes );
114
+ // Send RPS header which is received as first chunk
115
+ status = sl_si91x_fwup_start (writeBuffer);
116
+ status = sl_si91x_fwup_load (writeBuffer, kAlignmentBytes );
117
+ flag = RPS_DATA;
118
+ memcpy (&writeDataBuffer, block.data () + kAlignmentBytes , (block.size () - kAlignmentBytes ));
119
+ status = sl_si91x_fwup_load (writeDataBuffer, (block.size () - kAlignmentBytes ));
120
+ }
121
+ else if (flag == RPS_DATA)
122
+ {
123
+ memcpy (&writeDataBuffer, block.data (), block.size ());
124
+ // Send RPS content
125
+ status = sl_si91x_fwup_load (writeDataBuffer, block.size ());
126
+ if (status != SL_STATUS_OK)
127
+ {
128
+ // When TA recived all the blocks it will return SL_STATUS_FW_UPDATE_DONE status
129
+ if (status == SL_STATUS_FW_UPDATE_DONE)
130
+ {
131
+ mReset = true ;
132
+ }
133
+ else
134
+ {
135
+ ChipLogError (SoftwareUpdate, " ERROR: In HandleProcessBlock sl_si91x_fwup_load() error %ld" , status);
136
+ return CHIP_ERROR_CANCELLED;
137
+ }
138
+ }
139
+ }
140
+
141
+ return CHIP_NO_ERROR;
142
+ }
143
+
144
+ CHIP_ERROR OTAWiFiFirmwareProcessor::ProcessDescriptor (ByteSpan & block)
145
+ {
146
+ ReturnErrorOnFailure (mAccumulator .Accumulate (block));
147
+ ReturnErrorOnFailure (mCallbackProcessDescriptor (static_cast <void *>(mAccumulator .data ())));
148
+
149
+ mDescriptorProcessed = true ;
150
+ mAccumulator .Clear ();
151
+
152
+ return CHIP_NO_ERROR;
153
+ }
154
+
155
+ CHIP_ERROR OTAWiFiFirmwareProcessor::ApplyAction ()
156
+ {
157
+ // This reboots the device
158
+ if (mReset )
159
+ {
160
+ ChipLogProgress (SoftwareUpdate, " WiFi Device OTA update complete" );
161
+ #ifdef SLI_SI91X_MCU_INTERFACE // only for SoC
162
+ // send system reset request to reset the MCU and upgrade the m4 image
163
+ ChipLogProgress (SoftwareUpdate, " SoC Soft Reset initiated!" );
164
+ // Reboots the device
165
+ sl_si91x_soc_soft_reset ();
166
+ #endif
167
+ }
168
+ return CHIP_NO_ERROR;
169
+ }
170
+
171
+ CHIP_ERROR OTAWiFiFirmwareProcessor::FinalizeAction ()
172
+ {
173
+ // TODO: Not requied by 917 OTA updated keeping this function to execute any other command before soft reset of the TA
174
+ return CHIP_NO_ERROR;
175
+ }
176
+
177
+ } // namespace chip
0 commit comments