You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

358 lines
8.5 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief WINC3400 IoT OTA Interface.
  6. *
  7. * Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Subject to your compliance with these terms, you may use Microchip
  14. * software and any derivatives exclusively with Microchip products.
  15. * It is your responsibility to comply with third party license terms applicable
  16. * to your use of third party software (including open source software) that
  17. * may accompany Microchip software.
  18. *
  19. * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
  20. * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
  21. * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
  22. * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
  23. * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
  24. * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
  25. * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
  26. * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
  27. * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
  28. * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  29. * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  30. *
  31. * \asf_license_stop
  32. *
  33. */
  34. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  35. INCLUDES
  36. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  37. #include "common/include/nm_common.h"
  38. #include "driver/include/m2m_types.h"
  39. #include "driver/include/m2m_ota.h"
  40. #include "driver/include/m2m_wifi.h"
  41. #include "driver/source/m2m_hif.h"
  42. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  43. MACROS
  44. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  45. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  46. DATA TYPES
  47. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  48. static tpfOtaUpdateCb gpfOtaUpdateCb = NULL;
  49. static tpfOtaNotifCb gpfOtaNotifCb = NULL;
  50. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  51. FUNCTION PROTOTYPES
  52. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  53. /**
  54. * @fn m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
  55. * @brief WiFi call back function
  56. * @param [in] u8OpCode
  57. * HIF Opcode type.
  58. * @param [in] u16DataSize
  59. * HIF data length.
  60. * @param [in] u32Addr
  61. * HIF address.
  62. * @param [in] grp
  63. * HIF group type.
  64. * @author
  65. * @date
  66. * @version 1.0
  67. */
  68. static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
  69. {
  70. sint8 ret = M2M_SUCCESS;
  71. if(u8OpCode == M2M_OTA_RESP_NOTIF_UPDATE_INFO)
  72. {
  73. tstrOtaUpdateInfo strOtaUpdateInfo;
  74. m2m_memset((uint8*)&strOtaUpdateInfo,0,sizeof(tstrOtaUpdateInfo));
  75. ret = hif_receive(u32Addr,(uint8*)&strOtaUpdateInfo,sizeof(tstrOtaUpdateInfo),0);
  76. if(ret == M2M_SUCCESS)
  77. {
  78. if(gpfOtaNotifCb)
  79. gpfOtaNotifCb(&strOtaUpdateInfo);
  80. }
  81. }
  82. else if (u8OpCode == M2M_OTA_RESP_UPDATE_STATUS)
  83. {
  84. tstrOtaUpdateStatusResp strOtaUpdateStatusResp;
  85. m2m_memset((uint8*)&strOtaUpdateStatusResp,0,sizeof(tstrOtaUpdateStatusResp));
  86. ret = hif_receive(u32Addr, (uint8*) &strOtaUpdateStatusResp,sizeof(tstrOtaUpdateStatusResp), 0);
  87. if(ret == M2M_SUCCESS)
  88. {
  89. if(gpfOtaUpdateCb)
  90. gpfOtaUpdateCb(strOtaUpdateStatusResp.u8OtaUpdateStatusType,strOtaUpdateStatusResp.u8OtaUpdateStatus);
  91. }
  92. }
  93. else
  94. {
  95. M2M_ERR("Invaild OTA resp %d ?\n",u8OpCode);
  96. }
  97. }
  98. /*!
  99. @fn \
  100. NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
  101. @brief
  102. Initialize the OTA layer.
  103. @param [in] pfOtaUpdateCb
  104. OTA Update callback function
  105. @param [in] pfOtaNotifCb
  106. OTA notify callback function
  107. @return
  108. The function SHALL return 0 for success and a negative value otherwise.
  109. */
  110. NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
  111. {
  112. sint8 ret = M2M_SUCCESS;
  113. if(pfOtaUpdateCb){
  114. gpfOtaUpdateCb = pfOtaUpdateCb;
  115. }else{
  116. M2M_ERR("Invaild Ota update cb\n");
  117. }
  118. if(pfOtaNotifCb){
  119. gpfOtaNotifCb = pfOtaNotifCb;
  120. }else{
  121. M2M_ERR("Invaild Ota notify cb\n");
  122. }
  123. hif_register_cb(M2M_REQ_GROUP_OTA,m2m_ota_cb);
  124. return ret;
  125. }
  126. /*!
  127. @fn \
  128. NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
  129. @brief
  130. Set the OTA url
  131. @param [in] u8Url
  132. The url server address
  133. @return
  134. The function SHALL return 0 for success and a negative value otherwise.
  135. */
  136. NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
  137. {
  138. sint8 ret = M2M_SUCCESS;
  139. uint16 u16UrlSize = m2m_strlen(u8Url) + 1;
  140. /*Todo: we may change it to data pkt but we need to give it higer priority
  141. but the priorty is not implemnted yet in data pkt
  142. */
  143. ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_START_UPDATE,u8Url,u16UrlSize,NULL,0,0);
  144. return ret;
  145. }
  146. /*!
  147. @fn \
  148. NMI_API sint8 m2m_ota_notif_check_for_update(void);
  149. @brief
  150. check for ota update
  151. @return
  152. The function SHALL return 0 for success and a negative value otherwise.
  153. */
  154. NMI_API sint8 m2m_ota_notif_check_for_update(void)
  155. {
  156. sint8 ret = M2M_SUCCESS;
  157. ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE,NULL,0,NULL,0,0);
  158. return ret;
  159. }
  160. /*!
  161. @fn \
  162. NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
  163. @brief
  164. Schedule OTA update
  165. @param [in] u32Period
  166. Period in days
  167. @return
  168. The function SHALL return 0 for success and a negative value otherwise.
  169. */
  170. NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
  171. {
  172. sint8 ret = M2M_SUCCESS;
  173. ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE,NULL,0,NULL,0,0);
  174. return ret;
  175. }
  176. /*!
  177. @fn \
  178. NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl);
  179. @brief
  180. Request OTA start update using the downloaded url
  181. @param [in] u8DownloadUrl
  182. The download firmware url, you get it from device info
  183. @return
  184. The function SHALL return 0 for success and a negative value otherwise.
  185. */
  186. NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl)
  187. {
  188. sint8 ret = M2M_SUCCESS;
  189. uint16 u16DurlSize = m2m_strlen(u8DownloadUrl) + 1;
  190. /*Todo: we may change it to data pkt but we need to give it higer priority
  191. but the priorty is not implemnted yet in data pkt
  192. */
  193. ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_START_UPDATE,u8DownloadUrl,u16DurlSize,NULL,0,0);
  194. return ret;
  195. }
  196. /*!
  197. @fn \
  198. NMI_API sint8 m2m_ota_rollback(void);
  199. @brief
  200. Request OTA Rollback image
  201. @return
  202. The function SHALL return 0 for success and a negative value otherwise.
  203. */
  204. NMI_API sint8 m2m_ota_rollback(void)
  205. {
  206. sint8 ret = M2M_SUCCESS;
  207. tstrM2mRev strRev;
  208. ret = m2m_ota_get_firmware_version(&strRev);
  209. if(ret == M2M_SUCCESS)
  210. {
  211. if(M2M_GET_HIF_BLOCK(strRev.u16FirmwareHifInfo) == M2M_HIF_BLOCK_VALUE)
  212. {
  213. ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_ROLLBACK,NULL,0,NULL,0,0);
  214. }
  215. else
  216. {
  217. ret = M2M_ERR_FAIL;
  218. }
  219. }
  220. return ret;
  221. }
  222. /*!
  223. @fn \
  224. NMI_API sint8 m2m_ota_abort(void);
  225. @brief
  226. Request OTA Abort
  227. @return
  228. The function SHALL return 0 for success and a negative value otherwise.
  229. */
  230. NMI_API sint8 m2m_ota_abort(void)
  231. {
  232. sint8 ret = M2M_SUCCESS;
  233. ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_ABORT,NULL,0,NULL,0,0);
  234. return ret;
  235. }
  236. /*!
  237. @fn \
  238. NMI_API sint8 m2m_ota_switch_firmware(void);
  239. @brief
  240. Switch to the upgraded Firmware
  241. @return
  242. The function SHALL return 0 for success and a negative value otherwise.
  243. */
  244. NMI_API sint8 m2m_ota_switch_firmware(void)
  245. {
  246. sint8 ret = M2M_SUCCESS;
  247. tstrM2mRev strRev;
  248. ret = m2m_ota_get_firmware_version(&strRev);
  249. if(ret == M2M_SUCCESS)
  250. {
  251. if(M2M_GET_HIF_BLOCK(strRev.u16FirmwareHifInfo) == M2M_HIF_BLOCK_VALUE)
  252. {
  253. ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_SWITCH_FIRMWARE,NULL,0,NULL,0,0);
  254. }
  255. else
  256. {
  257. ret = M2M_ERR_FAIL;
  258. }
  259. }
  260. return ret;
  261. }
  262. #if 0
  263. #define M2M_OTA_FILE "../../../m2m_ota.dat"
  264. NMI_API sint8 m2m_ota_test(void)
  265. {
  266. uint32 page = 0;
  267. uint8 buffer[1500];
  268. uint32 u32Sz = 0;
  269. sint8 ret = M2M_SUCCESS;
  270. FILE *fp =NULL;
  271. fp = fopen(M2M_OTA_FILE,"rb");
  272. if(fp)
  273. {
  274. fseek(fp, 0L, SEEK_END);
  275. u32Sz = ftell(fp);
  276. fseek(fp, 0L, SEEK_SET);
  277. while(u32Sz > 0)
  278. {
  279. {
  280. page = (rand()%1400);
  281. if((page<100)||(page>1400)) page = 1400;
  282. }
  283. if(u32Sz>page)
  284. {
  285. u32Sz-=page;
  286. }
  287. else
  288. {
  289. page = u32Sz;
  290. u32Sz = 0;
  291. }
  292. printf("page %d\n", (int)page);
  293. fread(buffer,page,1,fp);
  294. ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_TEST|M2M_REQ_DATA_PKT,NULL,0,(uint8*)&buffer,page,0);
  295. if(ret != M2M_SUCCESS)
  296. {
  297. M2M_ERR("\n");
  298. }
  299. nm_bsp_sleep(1);
  300. }
  301. }
  302. else
  303. {
  304. M2M_ERR("nO err\n");
  305. }
  306. return ret;
  307. }
  308. #endif