1 /**
2 *
3 * \file
4 *
5 * \brief NMC1500 IoT OTA Interface.
6 *
7 * Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
8 *
9 * \asf_license_start
10 *
11 * \page License
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright notice,
20 * this list of conditions and the following disclaimer in the documentation
21 * and/or other materials provided with the distribution.
22 *
23 * 3. The name of Atmel may not be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
29 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * \asf_license_stop
39 *
40 */
41
42
43
44 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
45 INCLUDES
46 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
47 #include "common/include/nm_common.h"
48 #include "driver/include/m2m_types.h"
49 #include "driver/include/m2m_ota.h"
50 #include "driver/source/m2m_hif.h"
51 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
52 MACROS
53 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
54
55 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
56 DATA TYPES
57 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
58 static tpfOtaUpdateCb gpfOtaUpdateCb = NULL;
59 static tpfOtaNotifCb gpfOtaNotifCb = NULL;
60
61
62 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
63 FUNCTION PROTOTYPES
64 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
65 /**
66 * @fn m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
67 * @brief WiFi call back function
68 * @param [in] u8OpCode
69 * HIF Opcode type.
70 * @param [in] u16DataSize
71 * HIF data length.
72 * @param [in] u32Addr
73 * HIF address.
74 * @param [in] grp
75 * HIF group type.
76 * @author
77 * @date
78 * @version 1.0
79 */
m2m_ota_cb(uint8 u8OpCode,uint16 u16DataSize,uint32 u32Addr)80 static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
81 {
82 sint8 ret = M2M_SUCCESS;
83 if(u8OpCode == M2M_OTA_RESP_NOTIF_UPDATE_INFO)
84 {
85 tstrOtaUpdateInfo strOtaUpdateInfo;
86 m2m_memset((uint8*)&strOtaUpdateInfo,0,sizeof(tstrOtaUpdateInfo));
87 ret = hif_receive(u32Addr,(uint8*)&strOtaUpdateInfo,sizeof(tstrOtaUpdateInfo),0);
88 if(ret == M2M_SUCCESS)
89 {
90 if(gpfOtaNotifCb)
91 gpfOtaNotifCb(&strOtaUpdateInfo);
92 }
93 }
94 else if (u8OpCode == M2M_OTA_RESP_UPDATE_STATUS)
95 {
96 tstrOtaUpdateStatusResp strOtaUpdateStatusResp;
97 m2m_memset((uint8*)&strOtaUpdateStatusResp,0,sizeof(tstrOtaUpdateStatusResp));
98 ret = hif_receive(u32Addr, (uint8*) &strOtaUpdateStatusResp,sizeof(tstrOtaUpdateStatusResp), 0);
99 if(ret == M2M_SUCCESS)
100 {
101 if(gpfOtaUpdateCb)
102 gpfOtaUpdateCb(strOtaUpdateStatusResp.u8OtaUpdateStatusType,strOtaUpdateStatusResp.u8OtaUpdateStatus);
103 }
104 }
105 else
106 {
107 M2M_ERR("Invaild OTA resp %d ?\n",u8OpCode);
108 }
109
110 }
111 /*!
112 @fn \
113 NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
114
115 @brief
116 Initialize the OTA layer.
117
118 @param [in] pfOtaUpdateCb
119 OTA Update callback function
120
121 @param [in] pfOtaNotifCb
122 OTA notify callback function
123
124 @return
125 The function SHALL return 0 for success and a negative value otherwise.
126 */
m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNotifCb)127 NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
128 {
129 sint8 ret = M2M_SUCCESS;
130
131 if(pfOtaUpdateCb){
132 gpfOtaUpdateCb = pfOtaUpdateCb;
133 }else{
134 M2M_ERR("Invaild Ota update cb\n");
135 }
136 if(pfOtaNotifCb){
137 gpfOtaNotifCb = pfOtaNotifCb;
138 }else{
139 M2M_ERR("Invaild Ota notify cb\n");
140 }
141
142 hif_register_cb(M2M_REQ_GROUP_OTA,m2m_ota_cb);
143
144 return ret;
145 }
146 /*!
147 @fn \
148 NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
149
150 @brief
151 Set the OTA url
152
153 @param [in] u8Url
154 The url server address
155
156 @return
157 The function SHALL return 0 for success and a negative value otherwise.
158 */
m2m_ota_notif_set_url(uint8 * u8Url)159 NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
160 {
161 sint8 ret = M2M_SUCCESS;
162 uint16 u16UrlSize = m2m_strlen(u8Url) + 1;
163 /*Todo: we may change it to data pkt but we need to give it higer priority
164 but the priorty is not implemnted yet in data pkt
165 */
166 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_NOTIF_SET_URL,u8Url,u16UrlSize,NULL,0,0);
167 return ret;
168
169 }
170
171 /*!
172 @fn \
173 NMI_API sint8 m2m_ota_notif_check_for_update(void);
174
175 @brief
176 check for ota update
177
178 @return
179 The function SHALL return 0 for success and a negative value otherwise.
180 */
m2m_ota_notif_check_for_update(void)181 NMI_API sint8 m2m_ota_notif_check_for_update(void)
182 {
183 sint8 ret = M2M_SUCCESS;
184 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE,NULL,0,NULL,0,0);
185 return ret;
186 }
187
188 /*!
189 @fn \
190 NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
191
192 @brief
193 Schedule OTA update
194
195 @param [in] u32Period
196 Period in days
197
198 @return
199 The function SHALL return 0 for success and a negative value otherwise.
200 */
m2m_ota_notif_sched(uint32 u32Period)201 NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
202 {
203 sint8 ret = M2M_SUCCESS;
204 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE,NULL,0,NULL,0,0);
205 return ret;
206 }
207
208 /*!
209 @fn \
210 NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl);
211
212 @brief
213 Request OTA start update using the downloaded url
214
215 @param [in] u8DownloadUrl
216 The download firmware url, you get it from device info
217
218 @return
219 The function SHALL return 0 for success and a negative value otherwise.
220
221 */
m2m_ota_start_update(uint8 * u8DownloadUrl)222 NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl)
223 {
224 sint8 ret = M2M_SUCCESS;
225 uint16 u16DurlSize = m2m_strlen(u8DownloadUrl) + 1;
226 /*Todo: we may change it to data pkt but we need to give it higer priority
227 but the priorty is not implemnted yet in data pkt
228 */
229 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_START_FW_UPDATE,u8DownloadUrl,u16DurlSize,NULL,0,0);
230 return ret;
231 }
232 /*!
233 @fn \
234 NMI_API sint8 m2m_ota_start_update_crt(uint8 * u8DownloadUrl);
235
236 @brief
237 Request OTA start for the Cortus app image.
238
239 @param [in] u8DownloadUrl
240 The cortus application image url.
241
242 @return
243 The function SHALL return 0 for success and a negative value otherwise.
244
245 */
m2m_ota_start_update_crt(uint8 * u8DownloadUrl)246 NMI_API sint8 m2m_ota_start_update_crt(uint8 * u8DownloadUrl)
247 {
248 sint8 ret = M2M_SUCCESS;
249 uint16 u16DurlSize = m2m_strlen(u8DownloadUrl) + 1;
250 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_START_CRT_UPDATE,u8DownloadUrl,u16DurlSize,NULL,0,0);
251 return ret;
252 }
253
254
255 /*!
256 @fn \
257 NMI_API sint8 m2m_ota_rollback(void);
258
259 @brief
260 Request OTA Rollback image
261
262 @return
263 The function SHALL return 0 for success and a negative value otherwise.
264 */
m2m_ota_rollback(void)265 NMI_API sint8 m2m_ota_rollback(void)
266 {
267 sint8 ret = M2M_SUCCESS;
268 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_ROLLBACK_FW,NULL,0,NULL,0,0);
269 return ret;
270 }
271 /*!
272 @fn \
273 NMI_API sint8 m2m_ota_rollback_crt(void);
274
275 @brief
276 Request Cortus application OTA Rollback image
277
278 @return
279 The function SHALL return 0 for success and a negative value otherwise.
280 */
m2m_ota_rollback_crt(void)281 NMI_API sint8 m2m_ota_rollback_crt(void)
282 {
283 sint8 ret = M2M_SUCCESS;
284 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_ROLLBACK_CRT,NULL,0,NULL,0,0);
285 return ret;
286 }
287
288 /*!
289 @fn \
290 NMI_API sint8 m2m_ota_abort(void);
291
292 @brief
293 Request OTA Abort
294
295 @return
296 The function SHALL return 0 for success and a negative value otherwise.
297 */
m2m_ota_abort(void)298 NMI_API sint8 m2m_ota_abort(void)
299 {
300 sint8 ret = M2M_SUCCESS;
301 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_ABORT,NULL,0,NULL,0,0);
302 return ret;
303 }
304
305
306 /*!
307 @fn \
308 NMI_API sint8 m2m_ota_switch_firmware(void);
309
310 @brief
311 Switch to the upgraded Firmware
312
313 @return
314 The function SHALL return 0 for success and a negative value otherwise.
315 */
m2m_ota_switch_firmware(void)316 NMI_API sint8 m2m_ota_switch_firmware(void)
317 {
318 sint8 ret = M2M_SUCCESS;
319 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_SWITCH_FIRMWARE,NULL,0,NULL,0,0);
320 return ret;
321 }
322 /*!
323 @fn \
324 NMI_API sint8 m2m_ota_switch_crt(void);
325
326 @brief
327 Switch to the upgraded cortus application.
328
329 @return
330 The function SHALL return 0 for success and a negative value otherwise.
331 */
m2m_ota_switch_crt(void)332 NMI_API sint8 m2m_ota_switch_crt(void)
333 {
334 sint8 ret = M2M_SUCCESS;
335 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_SWITCH_CRT_IMG,NULL,0,NULL,0,0);
336 return ret;
337 }
338
339 /*!
340 @fn \
341 NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev);
342
343 @brief
344 Get the OTA Firmware version.
345
346 @return
347 The function SHALL return 0 for success and a negative value otherwise.
348 */
m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)349 NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)
350 {
351 sint8 ret = M2M_SUCCESS;
352 ret = hif_chip_wake();
353 if(ret == M2M_SUCCESS)
354 {
355 ret = nm_get_ota_firmware_info(pstrRev);
356 hif_chip_sleep();
357 }
358 return ret;
359 }
360 #if 0
361 #define M2M_OTA_FILE "../../../m2m_ota.dat"
362 NMI_API sint8 m2m_ota_test(void)
363 {
364 uint32 page = 0;
365 uint8 buffer[1500];
366 uint32 u32Sz = 0;
367 sint8 ret = M2M_SUCCESS;
368 FILE *fp =NULL;
369 fp = fopen(M2M_OTA_FILE,"rb");
370 if(fp)
371 {
372 fseek(fp, 0L, SEEK_END);
373 u32Sz = ftell(fp);
374 fseek(fp, 0L, SEEK_SET);
375
376 while(u32Sz > 0)
377 {
378 {
379 page = (rand()%1400);
380
381 if((page<100)||(page>1400)) page = 1400;
382 }
383
384 if(u32Sz>page)
385 {
386 u32Sz-=page;
387 }
388 else
389 {
390 page = u32Sz;
391 u32Sz = 0;
392 }
393 printf("page %d\n", (int)page);
394 fread(buffer,page,1,fp);
395 ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_TEST|M2M_REQ_DATA_PKT,NULL,0,(uint8*)&buffer,page,0);
396 if(ret != M2M_SUCCESS)
397 {
398 M2M_ERR("\n");
399 }
400 nm_bsp_sleep(1);
401 }
402
403 }
404 else
405 {
406 M2M_ERR("nO err\n");
407 }
408 return ret;
409 }
410 #endif
411
412