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