nmflash.c
Go to the documentation of this file.
1 
37 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
38 INCLUDES
39 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
41 #include "driver/source/nmflash.h"
43 #include "nmdrv.h"
44 //#include "main.h"
45 
46 #include "ISConstants.h"
47 //#include "compiler.h"
48 #define malloc MALLOC
49 #define free FREE
50 
51 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
52 GLOBALS
53 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
56 
62 
63 
64 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
65 FUNCTIONS
66 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
67 
68 static sint8 winc_flash_compare(uint8 *pu8Buf, uint32 u32Offset, uint32 u32Size)
69 {
70  sint8 ret = M2M_SUCCESS;
71  uint8 buf[128];
72  uint32 offset = 0;
73 
74  while (offset < u32Size)
75  {
76  uint32 chunk_sz = sizeof(buf);
77  if (chunk_sz > u32Size - offset)
78  chunk_sz = u32Size - offset;
79  ret = spi_flash_read(buf, u32Offset + offset, chunk_sz);
80  if (ret != M2M_SUCCESS)
81  break;
82  ret = m2m_memcmp(buf, pu8Buf + offset, chunk_sz);
83  if (ret != 0)
84  break;
85  offset += chunk_sz;
86  }
87  return ret;
88 }
89 
90 sint8 winc_flash_write_verify(uint8 *pu8Buf, uint32 u32Offset, uint32 u32Size)
91 {
92  sint8 ret = M2M_ERR_FAIL;
93  uint8 count = 20;
94 
95  while ((ret != M2M_SUCCESS) && (count-- > 0))
96  {
97  ret = spi_flash_write(pu8Buf, u32Offset, u32Size);
98  if (ret == M2M_SUCCESS)
99  ret = winc_flash_compare(pu8Buf, u32Offset, u32Size);
100  }
101  return ret;
102 }
104 {
105  sint8 ret = FLASH_RETURN_OK;
106  if (pstrPersistentInfo->u8ModeFlags & FLASH_MODE_FLAGS_UNCHANGED)
107  {
108  pstrPersistentInfo->u8ModeFlags &= ~FLASH_MODE_FLAGS_UNCHANGED;
110  gu8Changed = 1;
111  else
112  ret = FLASH_ERR_WINC_ACCESS;
113  }
114  return ret;
115 }
116 
117 static uint8 crc7(uint8 crc, const uint8 *buff, uint16 len)
118 {
119  uint8 reg = crc;
120  uint16 i;
121  for(i = 0; i < len; i++)
122  {
123  uint16 g;
124  for(g = 0; g < 8; g++)
125  {
126  uint8 inv = (((buff[i] << g) & 0x80) >> 7) ^ ((reg >> 6) & 1);
127  reg = ((reg << 1) & 0x7f) ^ (9 * inv);
128  }
129  }
130  return reg;
131 }
132 static sint8 read_control_sector(tstrOtaControlSec *pstrControlSec, uint32 u32Offset)
133 {
134  sint8 s8Ret = spi_flash_read((uint8*)pstrControlSec, u32Offset, sizeof(tstrOtaControlSec));
135  if (s8Ret == M2M_SUCCESS)
136  {
137  if (pstrControlSec->u32OtaMagicValue != OTA_MAGIC_VALUE)
138  s8Ret = M2M_ERR_FAIL;
139  if (pstrControlSec->u32OtaControlSecCrc != crc7(0x7f, (uint8*)pstrControlSec, sizeof(tstrOtaControlSec) - 4))
140  s8Ret = M2M_ERR_FAIL;
141  }
142  return s8Ret;
143 }
145 {
146  sint8 ret = M2M_ERR_FAIL;
147 
149  if (ret == M2M_SUCCESS)
150  {
151  pstrControlSec->u32OtaSequenceNumber++;
152  pstrControlSec->u32OtaControlSecCrc = crc7(0x7f, (uint8*)pstrControlSec, sizeof(tstrOtaControlSec) - 4);
154  if (ret == M2M_SUCCESS)
155  {
157  if (ret == M2M_SUCCESS)
158  {
159  pstrControlSec->u32OtaSequenceNumber++;
160  pstrControlSec->u32OtaControlSecCrc = crc7(0x7f, (uint8*)pstrControlSec, sizeof(tstrOtaControlSec) - 4);
162  }
163  }
164  }
165  return ret;
166 }
168 {
169  static tstrOtaControlSec strControlSec = {0};
170  sint8 s8Ret = M2M_SUCCESS;
171  uint8 bUpdate = false;
172 
173  if ((enuOp != CS_INITIALIZE) && (strControlSec.u32OtaMagicValue != OTA_MAGIC_VALUE))
174  {
175  if (param != NULL)
176  *param = 0;
177  return M2M_ERR_FAIL;
178  }
179 
180  switch (enuOp)
181  {
182  case CS_INITIALIZE:
183  s8Ret = read_control_sector(&strControlSec, M2M_CONTROL_FLASH_OFFSET);
184  if (s8Ret != M2M_SUCCESS)
185  {
186  s8Ret = read_control_sector(&strControlSec, M2M_BACKUP_FLASH_OFFSET);
187  if (s8Ret == M2M_SUCCESS)
188  {
189  /*
190  * Reinstate the control sector from backup.
191  */
193  if (s8Ret == M2M_SUCCESS)
194  s8Ret = winc_flash_write_verify((uint8*)&strControlSec, M2M_CONTROL_FLASH_OFFSET, sizeof(tstrOtaControlSec));
195  }
196  }
197  break;
198  case CS_INVALIDATE_RB:
199  // Update trashes the backup sector, so we need to avoid unnecessary updates.
201  {
203  bUpdate = true;
204  }
205  break;
206  case CS_VALIDATE_RB:
207  // Update trashes the backup sector, so we need to avoid unnecessary updates.
209  {
211  bUpdate = true;
212  }
213  break;
214  case CS_VALIDATE_SWITCH:
216  // intentional fallthrough.
217  case CS_SWITCH:
219  {
220  uint32 tmp = strControlSec.u32OtaCurrentworkingImagOffset;
221  strControlSec.u32OtaCurrentworkingImagOffset = strControlSec.u32OtaRollbackImageOffset;
222  strControlSec.u32OtaRollbackImageOffset = tmp;
223  bUpdate = true;
224  }
225  else
226  s8Ret = M2M_ERR_FAIL;
227  break;
228  case CS_GET_ACTIVE:
229  if (param == NULL)
230  s8Ret = M2M_ERR_FAIL;
231  else
232  *param = strControlSec.u32OtaCurrentworkingImagOffset;
233  break;
234  case CS_GET_INACTIVE:
235  if (param == NULL)
236  s8Ret = M2M_ERR_FAIL;
237  else
238  *param = strControlSec.u32OtaRollbackImageOffset;
239  break;
240  case CS_DEINITIALIZE:
241  m2m_memset((uint8*)&strControlSec, 0, sizeof(tstrOtaControlSec));
242  break;
243  default:
244  s8Ret = M2M_ERR_FAIL;
245  }
246  if (bUpdate)
247  {
248  s8Ret = update_control_sector(&strControlSec);
249  M2M_INFO("CS update:%d %s\n", enuOp, (s8Ret==M2M_SUCCESS)?"":"Failed");
250  }
251  return s8Ret;
252 }
253 static sint8 local_access_ptr(tenuFlashDataFnCtl enuCtl, void *pvStr)
254 {
255  sint8 s8Ret = M2M_ERR_FAIL;
256  static uint8 *pu8Location = NULL;
257  static uint8 u8Flags = 0;
258 
259  switch (enuCtl)
260  {
262  {
263  tstrDataAccessInitParams *init_params = (tstrDataAccessInitParams*)pvStr;
264  u8Flags = init_params->u8Flags;
265  pu8Location = gpu8Location;
266  s8Ret = M2M_SUCCESS;
267  }
268  break;
269  case FLASH_DATA_FN_DATA:
270  if (pu8Location != NULL)
271  {
272  tstrDataAccessParams *params = (tstrDataAccessParams*)pvStr;
273  if (u8Flags & FLASH_FN_FLAGS_WRITE)
274  m2m_memcpy(pu8Location, params->pu8Buf + params->u32DataOffset, params->u32DataSize);
275  if (u8Flags & FLASH_FN_FLAGS_READ)
276  m2m_memcpy(params->pu8Buf + params->u32DataOffset, pu8Location, params->u32DataSize);
277  pu8Location += params->u32DataSize;
278  s8Ret = M2M_SUCCESS;
279  }
280  break;
283  u8Flags = 0;
284  pu8Location = NULL;
285  s8Ret = M2M_SUCCESS;
286  break;
287  }
288  return s8Ret;
289 }
290 static sint8 winc_flash_access(tenuFlashDataFnCtl enuCtl, void *pvStr)
291 {
292  sint8 s8Ret = M2M_ERR_FAIL;
293  static uint32 u32CurrentAddr = 0;
294  static uint8 u8Flags = 0;
295 
296  switch (enuCtl)
297  {
299  {
300  tstrDataAccessInitParams *init_params = (tstrDataAccessInitParams*)pvStr;
301  printf("FA Init: 0x%lx Fg 0x%02x Sz 0x%lx \n", gu32LocationId, init_params->u8Flags, init_params->u32TotalSize);
302  u8Flags = init_params->u8Flags;
303  switch (gu32LocationId)
304  {
305  case MEM_ID_WINC_FLASH:
306  u32CurrentAddr = 0;
307  break;
308  case MEM_ID_WINC_ACTIVE:
309  s8Ret = access_control_sector(CS_GET_ACTIVE, &u32CurrentAddr);
310  break;
312  s8Ret = access_control_sector(CS_GET_INACTIVE, &u32CurrentAddr);
313  /* If we're about to write to the inactive partition, mark it as invalid. */
314  if ((s8Ret == M2M_SUCCESS) && (u8Flags & (FLASH_FN_FLAGS_WRITE | FLASH_FN_FLAGS_ERASE)))
316  break;
317  case MEM_ID_NONE:
318  s8Ret = M2M_ERR_FAIL;
319  break;
320  default:
321  u32CurrentAddr = gu32LocationId;
322  break;
323  }
324  if (u8Flags & FLASH_FN_FLAGS_READ_SURROUNDING)
325  {
326  init_params->u32AlignmentSize = FLASH_SECTOR_SZ;
327  init_params->u32StartAlignment = u32CurrentAddr & (FLASH_SECTOR_SZ - 1);
328  }
329  s8Ret = M2M_SUCCESS;
330  }
331  break;
332  case FLASH_DATA_FN_DATA:
333  {
334  tstrDataAccessParams *params = (tstrDataAccessParams*)pvStr;
335  if (u8Flags & FLASH_FN_FLAGS_COMPARE_BEFORE)
336  {
337  printf("c-");
338  // If contents match already, return success
339  s8Ret = winc_flash_compare(params->pu8Buf + params->u32DataOffset, u32CurrentAddr, params->u32DataSize);
340  if (s8Ret == M2M_SUCCESS)
341  goto END;
342  }
343  if (u8Flags & FLASH_FN_FLAGS_READ_SURROUNDING)
344  {
345  uint32 prefill_sz = params->u32DataOffset;
346  uint32 postfill_sz = params->u32BufSize - (params->u32DataOffset + params->u32DataSize);
347  if (prefill_sz > 0)
348  {
349  printf("r-");
350  s8Ret = spi_flash_read(params->pu8Buf, u32CurrentAddr - prefill_sz, prefill_sz);
351  if (s8Ret != M2M_SUCCESS)
352  goto END;
353  }
354  if (postfill_sz > 0)
355  {
356  printf("-r");
357  s8Ret = spi_flash_read(params->pu8Buf + params->u32BufSize - postfill_sz, u32CurrentAddr + params->u32DataSize, postfill_sz);
358  if (s8Ret != M2M_SUCCESS)
359  goto END;
360  }
361  }
362  if (u8Flags & FLASH_FN_FLAGS_BACKUP)
363  {
364  if (params->u32BufSize > params->u32DataSize)
365  {
366  printf("b");
368  if (s8Ret == M2M_SUCCESS)
369  s8Ret = prepare_backup(u32CurrentAddr - params->u32DataOffset);
370  if (s8Ret != M2M_SUCCESS)
371  goto END;
372  }
373  }
374  if (u8Flags & FLASH_FN_FLAGS_ERASE)
375  {
376  printf("e");
377  s8Ret = spi_flash_erase(u32CurrentAddr, params->u32DataSize);
378  if (s8Ret != M2M_SUCCESS)
379  goto END;
380  }
381  if (u8Flags & FLASH_FN_FLAGS_WRITE)
382  {
383  printf("W");
384  if (u8Flags & FLASH_FN_FLAGS_READ_SURROUNDING)
385  s8Ret = spi_flash_write(params->pu8Buf, u32CurrentAddr - params->u32DataOffset, params->u32BufSize);
386  else
387  s8Ret = spi_flash_write(params->pu8Buf + params->u32DataOffset, u32CurrentAddr, params->u32DataSize);
388  if (s8Ret != M2M_SUCCESS)
389  goto END;
390  }
391  if (u8Flags & FLASH_FN_FLAGS_COMPARE_AFTER)
392  {
393  printf("-c");
394  // If contents do not match, return failure
395  if (u8Flags & FLASH_FN_FLAGS_READ_SURROUNDING)
396  s8Ret = winc_flash_compare(params->pu8Buf, u32CurrentAddr - params->u32DataOffset, params->u32BufSize);
397  else
398  s8Ret = winc_flash_compare(params->pu8Buf + params->u32DataOffset, u32CurrentAddr, params->u32DataSize);
399  if (s8Ret != M2M_SUCCESS)
400  goto END;
401  }
402  if (u8Flags & FLASH_FN_FLAGS_READ)
403  {
404  printf("R");
405  s8Ret = spi_flash_read(params->pu8Buf + params->u32DataOffset, u32CurrentAddr, params->u32DataSize);
406  if (s8Ret != M2M_SUCCESS)
407  goto END;
408  }
409 END:
410  u32CurrentAddr += params->u32DataSize;
411  }
412  break;
415  printf(" FA End 0x%lx\n", u32CurrentAddr);
416  u8Flags = 0;
417  u32CurrentAddr = 0;
418  s8Ret = M2M_SUCCESS;
419  break;
420  }
421  return s8Ret;
422 }
423 
425 {
426  if (ppfFn != NULL)
427  *ppfFn = local_access_ptr;
428  gpu8Location = pu8Ptr;
429 }
430 void set_internal_info(tpfDataAccessFn *ppfFn, uint32 u32LocationId)
431 {
432  if (ppfFn != NULL)
433  *ppfFn = winc_flash_access;
434  gu32LocationId = u32LocationId;
435 }
437 {
438  if (pfFn == winc_flash_access)
439  return true;
440  return false;
441 }
443 {
444  sint8 ret = FLASH_RETURN_OK;
445  uint32 u32BackupAddr = FLASH_BACKUP_STORE_OFFSET;
446  tstrBackup strBackup;
447 
448  while (u32BackupAddr < FLASH_BACKUP_STORE_OFFSET + FLASH_BACKUP_STORE_SZ)
449  {
450  sint8 status = spi_flash_read((uint8*)&strBackup, u32BackupAddr, sizeof(tstrBackup));
451  if ((status == M2M_SUCCESS) && (strBackup.enuTransferStatus == BACKUP_STATUS_ACTIVE))
452  {
453  uint8 *pu8Buff = malloc(strBackup.u32Size);
454  if (pu8Buff == NULL)
455  {
456  ret = FLASH_ERR_INTERNAL;
457  goto ERR;
458  }
459  status = spi_flash_read(pu8Buff, strBackup.u32SourceAddr, strBackup.u32Size);
460  if (status == M2M_SUCCESS)
461  {
462  status = spi_flash_erase(strBackup.u32DestinationAddr, strBackup.u32Size);
463  if (status == M2M_SUCCESS)
464  {
465  status = winc_flash_write_verify(pu8Buff, strBackup.u32DestinationAddr, strBackup.u32Size);
466  if (status == M2M_SUCCESS)
467  {
468  strBackup.enuTransferStatus = BACKUP_STATUS_DONE;
469  status = winc_flash_write_verify((uint8*)&strBackup.enuTransferStatus, u32BackupAddr, FLASH_BACKUP_STA_SZ);
470  }
471  }
472  }
473  free(pu8Buff);
474  }
475  if (status != M2M_SUCCESS)
476  {
477  ret = FLASH_ERR_WINC_ACCESS;
478  goto ERR;
479  }
480  u32BackupAddr += sizeof(tstrBackup);
481  }
482 ERR:
483  return ret;
484 }
486 {
487  sint8 s8Ret = M2M_ERR_FAIL;
488  uint32 u32BackupAddr = FLASH_BACKUP_STORE_OFFSET;
490 
491  s8Ret = spi_flash_read((uint8*)&enuStatus, u32BackupAddr, sizeof(enuStatus));
492  if ((s8Ret != M2M_SUCCESS) || (enuStatus != BACKUP_STATUS_EMPTY))
493  {
494  u32BackupAddr += sizeof(tstrBackup);
495  s8Ret = spi_flash_read((uint8*)&enuStatus, u32BackupAddr, sizeof(enuStatus));
496  if ((s8Ret == M2M_SUCCESS) && (enuStatus != BACKUP_STATUS_EMPTY))
497  s8Ret = M2M_ERR_FAIL;
498  }
499  if (s8Ret == M2M_SUCCESS)
500  {
502  s8Ret = winc_flash_write_verify((uint8*)&strBackup.enuTransferStatus, u32BackupAddr, FLASH_BACKUP_STA_SZ);
503  if (s8Ret == M2M_SUCCESS)
504  {
505  s8Ret = winc_flash_write_verify((uint8*)&strBackup, u32BackupAddr, sizeof(strBackup));
506  if (s8Ret == M2M_SUCCESS)
507  {
508  strBackup.enuTransferStatus = BACKUP_STATUS_ACTIVE;
509  s8Ret = winc_flash_write_verify((uint8*)&strBackup.enuTransferStatus, u32BackupAddr, FLASH_BACKUP_STA_SZ);
510  }
511  }
512  }
513  return s8Ret;
514 }
516 {
517  sint8 s8Ret = M2M_ERR_FAIL;
518  uint32 u32OffsetActive = 0;
519  uint32 u32OffsetInactive = 0;
520 
522  if (s8Ret == M2M_SUCCESS)
523  {
524  s8Ret = access_control_sector(CS_GET_ACTIVE, &u32OffsetActive);
525  if (s8Ret == M2M_SUCCESS)
526  {
527  s8Ret = access_control_sector(CS_GET_INACTIVE, &u32OffsetInactive);
528  if (s8Ret == M2M_SUCCESS)
529  *pu8Target = (u32OffsetInactive > u32OffsetActive) ? 1 : 0;
530  }
532  }
533  return s8Ret;
534 }
536 {
537  sint8 s8Ret = M2M_ERR_FAIL;
538  if ((pstrHdr == NULL) || (pu16Size == NULL))
539  goto ERR;
540 
541  /* Set default size out to maximum. */
542  *pu16Size = 0xFFFF;
543  switch (pstrHdr->strPubKey.u32PubKeyType)
544  {
547  goto ERR;
549  goto ERR;
550  *pu16Size = sizeof(tstrRootCertEntryHeader) + ((pstrHdr->strPubKey.strRsaKeyInfo.u16NSz + 0x3) & ~0x3) + ((pstrHdr->strPubKey.strRsaKeyInfo.u16ESz + 0x3) & ~0x3);
551  s8Ret = M2M_SUCCESS;
552  break;
555  goto ERR;
556  *pu16Size = sizeof(tstrRootCertEntryHeader) + ((pstrHdr->strPubKey.strEcsdaKeyInfo.u16KeySz + 0x3) & ~0x3) * 2;
557  s8Ret = M2M_SUCCESS;
558  break;
559  case 0xFFFFFFFF:
560  // Invalid. May indicate end of list. Fail with size set to 0.
561  *pu16Size = 0;
562  break;
563  default:
564  // Corrupt header.
565  break;
566  }
567 ERR:
568  return s8Ret;
569 }
570 sint8 rootcert_access(tenuFlashAccessItemMode enuMode, tstrRootCertEntryHeader *pstrReferenceHdr, uint16 *pu16EntrySize, uint8 *pu8Buff, uint32 *pu32Offset)
571 {
572  sint8 ret = FLASH_RETURN_OK;
573  sint8 status = M2M_SUCCESS;
574  uint8 au8RootCertSig[] = M2M_TLS_ROOTCER_FLASH_SIG;
575  tstrRootCertEntryHeader strEntryHeader;
576  /* Previous version used 0-identifiers to indicate removed entries. Use last 20 bytes of pu8Buff to help us check for them. */
577  uint8 *pu8Zero = pu8Buff + M2M_TLS_ROOTCER_FLASH_SZ - sizeof(pstrReferenceHdr->au8SHA1NameHash);
578  uint32 u32StoreOffset = 0;
579  uint32 u32Entries = 0;
580 
581  m2m_memset(pu8Zero, 0, sizeof(pstrReferenceHdr->au8SHA1NameHash));
582  /* Use pu8SectionBuffer to read signature. */
583  status = spi_flash_read(pu8Buff, M2M_TLS_ROOTCER_FLASH_OFFSET, sizeof(au8RootCertSig));
584  if ((status != M2M_SUCCESS) || m2m_memcmp(pu8Buff, au8RootCertSig, sizeof(au8RootCertSig)))
585  {
586  /*
587  * Root certificate section is not initialized. We could try to initialize it
588  * here, but for now just fail.
589  */
590  ret = FLASH_ERR_WINC_ACCESS;
591  goto ERR;
592  }
593 
594  /*
595  * By default assume we'll get to the end of the flash store without finding what we need
596  * (matching entry or space to add new entry). If we break while loop before reaching end of
597  * store then we'll change ret accordingly. */
598  if (enuMode == FLASH_ITEM_ADD)
599  ret = FLASH_ERR_SIZE;
600  else
602 
603  u32StoreOffset = *pu32Offset = sizeof(tstrRootCertFlashHeader);
604  while (u32StoreOffset + sizeof(tstrRootCertEntryHeader) < M2M_TLS_ROOTCER_FLASH_SZ)
605  {
606  uint16 u16EntrySize = 0;
607  status = spi_flash_read((uint8*)&strEntryHeader, M2M_TLS_ROOTCER_FLASH_OFFSET + u32StoreOffset, sizeof(tstrRootCertEntryHeader));
608  if (status != M2M_SUCCESS)
609  {
610  ret = FLASH_ERR_WINC_ACCESS;
611  break;
612  }
613  status = rootcert_get_size(&strEntryHeader, &u16EntrySize);
614  if (status != M2M_SUCCESS)
615  {
616  // Found the end of the list. We are done. If we are adding an entry, check the space here.
617  if ((enuMode == FLASH_ITEM_ADD) && ((*pu32Offset + *pu16EntrySize) <= M2M_TLS_ROOTCER_FLASH_SZ))
618  {
619  u32Entries++;
620  ret = FLASH_RETURN_OK;
621  }
622  break;
623  }
624 
625  // If we are here we know that u32EntrySize is sane.
626  if (m2m_memcmp(pu8Zero, (uint8*)pstrReferenceHdr, sizeof(strEntryHeader.au8SHA1NameHash)))
627  {
628  // Entry is not empty.
629  status = spi_flash_read(pu8Buff + *pu32Offset, M2M_TLS_ROOTCER_FLASH_OFFSET + u32StoreOffset, u16EntrySize);
630  if (status != M2M_SUCCESS)
631  {
632  ret = FLASH_ERR_WINC_ACCESS;
633  break;
634  }
635  if (enuMode == FLASH_ITEM_READIDX)
636  {
637  if (u32Entries == *(uint32*)pstrReferenceHdr)
638  {
639  // Found entry. pu16EntrySize is used to output size.
640  *pu16EntrySize = u16EntrySize;
641  ret = FLASH_RETURN_OK;
642  break;
643  }
644  }
645  else if (!m2m_memcmp(strEntryHeader.au8SHA1NameHash, (uint8*)pstrReferenceHdr, sizeof(strEntryHeader.au8SHA1NameHash)))
646  {
647  if (enuMode == FLASH_ITEM_ADD)
648  {
649  // Found a match. Cannot add.
651  break;
652  }
653  if (enuMode == FLASH_ITEM_READ)
654  {
655  // Found a match. pu16EntrySize is used to output size.
656  *pu16EntrySize = u16EntrySize;
657  ret = FLASH_RETURN_OK;
658  break;
659  }
660  if (enuMode == FLASH_ITEM_REMOVE)
661  {
662  // Found a match. Continue, to complete entry count.
663  ret = FLASH_RETURN_OK;
664  // Cancel out increment of u32BuffOffset.
665  *pu32Offset -= u16EntrySize;
666  }
667  }
668  *pu32Offset += u16EntrySize;
669  u32Entries++;
670  }
671  u32StoreOffset += u16EntrySize;
672  }
673  if (ret == FLASH_RETURN_OK)
674  ((tstrRootCertFlashHeader*)(void*)pu8Buff)->u32nCerts = u32Entries;
675 ERR:
676  return ret;
677 }
678 
680 {
681  /*
682  * Errors before start of first transfer will be reported as parameter errors.
683  * This means the information is insufficient to allow us to begin.
684  */
685  sint8 ret = FLASH_RETURN_OK;
686  sint8 status = M2M_ERR_FAIL;
687 
688  tpfDataAccessFn pfWriteFn = pstrFlashAccess->pfDestinationFn;
689  tpfDataAccessFn pfReadFn = pstrFlashAccess->pfSourceFn;
690  tstrDataAccessInitParams read_init_params = {pstrFlashAccess->u32Size, FLASH_FN_FLAGS_READ, 0, 0};
691  tstrDataAccessInitParams write_init_params = {pstrFlashAccess->u32Size, FLASH_FN_FLAGS_WRITE, 0, 0};
692  uint32 u32BytesTransferred = 0;
693  uint32 u32BytesRemaining = pstrFlashAccess->u32Size;
694  uint8 *pu8Buff = NULL;
695 
697  write_init_params.u8Flags |= FLASH_FN_FLAGS_COMPARE_BEFORE;
699  {
700  write_init_params.u8Flags |= FLASH_FN_FLAGS_ERASE;
702  {
703  write_init_params.u8Flags |= FLASH_FN_FLAGS_READ_SURROUNDING;
705  write_init_params.u8Flags |= FLASH_FN_FLAGS_BACKUP;
706  }
707  }
709  write_init_params.u8Flags |= FLASH_FN_FLAGS_COMPARE_AFTER;
710 
712  {
714  {
715  ret = FLASH_ERR_WINC_ACCESS;
716  goto ERR;
717  }
718  set_changed_flag(&pstrFlashAccess->strPersistentInfo);
719  ret = recover_backup();
720  if (ret < 0)
721  goto ERR;
722  }
723  /*
724  * Initialize control sector. Even if we don't need to access it, this at
725  * least ensures that the control sector is not relying on the flash backup sector.
726  */
728  if (status != M2M_SUCCESS && (pstrFlashAccess->strPersistentInfo.u8ModeFlags & FLASH_MODE_FLAGS_CS))
729  {
730  ret = FLASH_ERR_WINC_ACCESS;
731  goto ERR;
732  }
733 
734  if (pfReadFn != NULL)
735  {
736  /* Prepare for read. */
737 
738  status = pfReadFn(FLASH_DATA_FN_INITIALIZE, &read_init_params);
739  if (status != M2M_SUCCESS)
740  {
741  if (is_internal_info(pfReadFn))
742  ret = FLASH_ERR_WINC_ACCESS;
743  else
745  pfReadFn(FLASH_DATA_FN_TERMINATE, NULL);
746  goto ERR;
747  }
748  }
749  if (pfWriteFn != NULL)
750  {
751  /* Prepare for write. */
752  status = pfWriteFn(FLASH_DATA_FN_INITIALIZE, &write_init_params);
753  if (status != M2M_SUCCESS)
754  {
755  if (is_internal_info(pfWriteFn))
756  ret = FLASH_ERR_WINC_ACCESS;
757  else
759  goto TERMINATE;
760  }
761  }
762  if (u32BytesRemaining > 0)
763  {
764  if (u32BytesRemaining > FLASH_SECTOR_SIZE)
765  pu8Buff = malloc(FLASH_SECTOR_SIZE);
766  else if (write_init_params.u32AlignmentSize > 1)
767  pu8Buff = malloc(write_init_params.u32AlignmentSize);
768  else
769  pu8Buff = malloc(u32BytesRemaining);
770  if (pu8Buff == NULL)
771  {
772  ret = FLASH_ERR_INTERNAL;
773  goto TERMINATE;
774  }
775  }
776 
777  while (u32BytesRemaining > 0)
778  {
779  tstrDataAccessParams params = {pu8Buff, FLASH_SECTOR_SIZE, 0, FLASH_SECTOR_SIZE};
780 
781  if (u32BytesTransferred > 0)
782  write_init_params.u32StartAlignment = 0;
783  if (write_init_params.u32AlignmentSize > 1)
784  {
785  params.u32DataOffset = write_init_params.u32StartAlignment & (write_init_params.u32AlignmentSize-1);
786  params.u32DataSize = write_init_params.u32AlignmentSize - params.u32DataOffset;
787  }
788 
789  if (params.u32DataSize > u32BytesRemaining)
790  params.u32DataSize = u32BytesRemaining;
791 
792  /* Read. */
793  if (pfReadFn != NULL)
794  {
795  status = pfReadFn(FLASH_DATA_FN_DATA, &params);
796  if (status != M2M_SUCCESS)
797  {
798  if (is_internal_info(pfReadFn))
799  ret = FLASH_ERR_WINC_ACCESS;
800  else
802  break;
803  }
804  }
805 
806  /* Write. */
807  if (pfWriteFn != NULL)
808  {
809  if (is_internal_info(pfWriteFn))
810  {
811  ret = set_changed_flag(&pstrFlashAccess->strPersistentInfo);
812  if (ret < 0)
813  break;
814  }
815  status = pfWriteFn(FLASH_DATA_FN_DATA, &params);
816  if (status != M2M_SUCCESS)
817  {
818  if (is_internal_info(pfWriteFn))
819  ret = FLASH_ERR_WINC_ACCESS;
820  else
822  break;
823  }
824  }
825 
826  u32BytesTransferred += params.u32DataSize;
827  u32BytesRemaining -= params.u32DataSize;
828  }
829 
830  if (u32BytesRemaining > 0)
831  {
832 TERMINATE:
833  if (pfReadFn != NULL)
834  pfReadFn(FLASH_DATA_FN_TERMINATE, NULL);
835  if (pfWriteFn != NULL)
836  pfWriteFn(FLASH_DATA_FN_TERMINATE, NULL);
837  goto ERR;
838  }
839  else
840  {
841  if (pfReadFn != NULL)
842  pfReadFn(FLASH_DATA_FN_COMPLETE, NULL);
843  if (pfWriteFn != NULL)
844  pfWriteFn(FLASH_DATA_FN_COMPLETE, NULL);
845  }
846 
848  {
849  tenuCSOp enuOp;
850  ret = set_changed_flag(&pstrFlashAccess->strPersistentInfo);
851  if (ret < 0)
852  goto ERR;
854  {
856  enuOp = CS_VALIDATE_SWITCH;
857  else
858  enuOp = CS_VALIDATE_RB;
859  }
860  else
861  enuOp = CS_SWITCH;
862  status = access_control_sector(enuOp, NULL);
863  if (status != M2M_SUCCESS)
864  {
865  ret = FLASH_ERR_WINC_ACCESS;
866  goto ERR;
867  }
868  }
869 
872  gu8Success = 1;
873 ERR:
874  if (pu8Buff != NULL)
875  free(pu8Buff);
877  return ret;
878 }
NMI_API void m2m_memcpy(uint8 *pDst, uint8 *pSrc, uint32 sz)
Copy specified number of bytes from source buffer to destination buffer.
Definition: nm_common.c:36
#define FLASH_ERR_WINC_CONFLICT
Definition: m2m_flash.h:78
#define M2M_ERR_FAIL
Definition: nm_common.h:63
uint8 is_internal_info(tpfDataAccessFn pfFn)
Definition: nmflash.c:436
#define malloc
Definition: nmflash.c:48
#define FLASH_ACCESS_OPTION_USE_BACKUP
Definition: nmflash.h:103
#define FLASH_FN_FLAGS_READ_SURROUNDING
Definition: nmflash.h:63
uint32 u32OtaControlSecCrc
Definition: m2m_types.h:2139
#define M2M_TLS_ROOTCER_FLASH_SIG
sint8 rootcert_get_size(tstrRootCertEntryHeader *pstrHdr, uint16 *pu16Size)
Definition: nmflash.c:535
signed char sint8
Range of values between -128 to 127.
Definition: nm_bsp.h:111
sint8 winc_flash_write_verify(uint8 *pu8Buf, uint32 u32Offset, uint32 u32Size)
Definition: nmflash.c:90
static sint8 read_control_sector(tstrOtaControlSec *pstrControlSec, uint32 u32Offset)
Definition: nmflash.c:132
#define FLASH_BACKUP_STA_SZ
Definition: nmflash.h:207
NMI_API sint8 m2m_memcmp(uint8 *pu8Buff1, uint8 *pu8Buff2, uint32 u32Size)
Compare specified number of data bytes in pu8Buff1 and pu8Buff2 and decide if they all match...
Definition: nm_common.c:116
tenuFlashDataFnCtl
Control parameter for tpfDataAccessFn.
Definition: m2m_flash.h:94
uint32 u32OtaRollbackImageOffset
Definition: m2m_types.h:2119
This module contains WINC3400 M2M driver APIs declarations.
static sint8 update_control_sector(tstrOtaControlSec *pstrControlSec)
Definition: nmflash.c:144
#define FLASH_MODE_FLAGS_CS_SWITCH
Definition: nmflash.h:51
#define FLASH_MODE_FLAGS_CS_VALIDATE_IMAGE
Definition: nmflash.h:53
#define FLASH_ACCESS_OPTION_COMPARE_AFTER
Definition: nmflash.h:115
uint32 u32OtaRollbackImageValidStatus
Definition: m2m_types.h:2121
#define FLASH_ACCESS_OPTION_COMPARE_BEFORE
Definition: nmflash.h:109
#define FLASH_ERR_INTERNAL
Definition: m2m_flash.h:82
tenuBackupStatus
Definition: nmflash.h:144
uint32 u32OtaMagicValue
Definition: m2m_types.h:2105
#define FLASH_FN_FLAGS_BACKUP
Definition: nmflash.h:68
tpfDataAccessFn pfDestinationFn
Definition: nmflash.h:196
#define M2M_SUCCESS
Definition: nm_common.h:51
Header of a root certificate entry in flash.
Definition: m2m_types.h:1907
#define FLASH_MODE_FLAGS_DATA_IN_BACKUP
Definition: nmflash.h:55
tenuCSOp
Definition: nmflash.h:123
size_t count(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:3206
#define NULL
Definition: nm_bsp.h:52
tenuFlashAccessStatus enuTransferStatus
Definition: nmflash.h:185
tstrRootCertRsaKeyInfo strRsaKeyInfo
Definition: m2m_types.h:1892
static uint32 gu32LocationId
Definition: nmflash.c:54
#define FLASH_BACKUP_STORE_OFFSET
Definition: nmflash.h:209
tenuFlashAccessItemMode
Transfer modes available for accessing items in WINC flash stores such as TLS root certificate store...
Definition: nmflash.h:171
static sint8 winc_flash_compare(uint8 *pu8Buf, uint32 u32Offset, uint32 u32Size)
Definition: nmflash.c:68
unsigned short uint16
Range of values between 0 to 65535.
Definition: nm_bsp.h:96
sint8 image_get_target(uint8 *pu8Target)
Definition: nmflash.c:515
#define FLASH_FN_FLAGS_READ
Definition: nmflash.h:82
sint8 recover_backup(void)
Definition: nmflash.c:442
#define FLASH_MODE_FLAGS_CS
Definition: nmflash.h:50
#define FLASH_ERR_LOCAL_ACCESS
Definition: m2m_flash.h:69
This structure contains data for local data access (read, erase or write).
Definition: nmflash.h:251
This struct contains the Control Section. The Control Section is used to define the working image and...
Definition: m2m_types.h:2104
static sint8 set_changed_flag(tstrFlashAccessPersistent *pstrPersistentInfo)
Definition: nmflash.c:103
uint8 gu8Reset
Definition: nmflash.c:61
uint8 gu8Init
Definition: nmflash.c:60
#define FLASH_ERR_SIZE
Definition: m2m_flash.h:73
sint8 spi_flash_read(uint8 *pu8Buf, uint32 u32Addr, uint32 u32Sz)
Read a specified portion of data from SPI Flash. .
Definition: spi_flash.c:505
#define FLASH_FN_FLAGS_COMPARE_AFTER
Definition: nmflash.h:78
#define FLASH_FN_FLAGS_WRITE
Definition: nmflash.h:74
#define printf(...)
Definition: evb_tasks.h:36
#define OTA_MAGIC_VALUE
Definition: m2m_types.h:345
tpfDataAccessFn pfSourceFn
Definition: nmflash.h:197
NMI_API void m2m_memset(uint8 *pBuf, uint8 val, uint32 sz)
Set specified number of data bytes in specified data buffer to specified value.
Definition: nm_common.c:58
sint8 rootcert_access(tenuFlashAccessItemMode enuMode, tstrRootCertEntryHeader *pstrReferenceHdr, uint16 *pu16EntrySize, uint8 *pu8Buff, uint32 *pu32Offset)
Definition: nmflash.c:570
sint8 spi_flash_erase(uint32 u32Offset, uint32 u32Sz)
Erase a specified portion of SPI Flash. .
Definition: spi_flash.c:616
#define M2M_CONTROL_FLASH_OFFSET
#define free
Definition: nmflash.c:49
#define M2M_CONTROL_FLASH_SZ
#define M2M_TLS_ROOTCER_FLASH_OFFSET
uint32 u32OtaCurrentworkingImagOffset
Definition: m2m_types.h:2113
uint32 u32Size
Definition: nmflash.h:198
uint32 u32OtaSequenceNumber
Definition: m2m_types.h:2109
tenuBackupStatus enuTransferStatus
Definition: nmflash.h:202
tstrFlashAccessPersistent strPersistentInfo
Definition: nmflash.h:195
#define HOST_CONTROL_FLASH_OFFSET
SPI Flash.
#define FLASH_ACCESS_OPTION_ERASE_FIRST
Definition: nmflash.h:89
#define FLASH_SECTOR_SZ
Definition: spi_flash_map.h:55
uint32 u32DataOffset
Definition: nmflash.h:257
tstrRootCertEcdsaKeyInfo strEcsdaKeyInfo
Definition: m2m_types.h:1894
#define FLASH_FN_FLAGS_ERASE
Definition: nmflash.h:71
#define OTA_STATUS_VALID
Definition: m2m_types.h:337
#define M2M_TLS_ROOTCER_FLASH_SZ
uint8 gu8Changed
Definition: nmflash.c:59
#define FLASH_SECTOR_SIZE
Definition: nmflash.h:46
static uint8 * gpu8Location
Definition: nmflash.c:55
Header of the root certificate flash storage area.
Definition: m2m_types.h:1923
sint8(* tpfDataAccessFn)(tenuFlashDataFnCtl enuCtl, void *pvStr)
A function of this type is used for local data access. It can be implemented to handle simple RAM acc...
Definition: m2m_flash.h:229
#define M2M_BACKUP_FLASH_OFFSET
#define FLASH_ACCESS_OPTION_KEEP_SURROUNDING
Definition: nmflash.h:96
#define M2M_BACKUP_FLASH_SZ
#define M2M_INFO(...)
Definition: nm_debug.h:83
static sint8 access_control_sector(tenuCSOp enuOp, uint32 *param)
Definition: nmflash.c:167
static sint8 local_access_ptr(tenuFlashDataFnCtl enuCtl, void *pvStr)
Definition: nmflash.c:253
unsigned long uint32
Range of values between 0 to 4294967295.
Definition: nm_bsp.h:103
#define OTA_STATUS_INVALID
Definition: m2m_types.h:341
uint16 gu16LastAccessId
Definition: nmflash.c:57
void set_internal_info_ptr(tpfDataAccessFn *ppfFn, uint8 *pu8Ptr)
Definition: nmflash.c:424
tstrRootCertPubKeyInfo strPubKey
Definition: m2m_types.h:1912
sint8 spi_flash_write(uint8 *pu8Buf, uint32 u32Offset, uint32 u32Sz)
Write a specified portion of data to SPI Flash. .
Definition: spi_flash.c:539
WINC Flash Interface.
uint8 gu8Success
Definition: nmflash.c:58
unsigned char uint8
Range of values between 0 to 255.
Definition: nm_bsp.h:89
void set_internal_info(tpfDataAccessFn *ppfFn, uint32 u32LocationId)
Definition: nmflash.c:430
#define FLASH_ERR_WINC_ACCESS
Definition: m2m_flash.h:71
#define FLASH_BACKUP_STORE_SZ
Definition: nmflash.h:208
static sint8 winc_flash_access(tenuFlashDataFnCtl enuCtl, void *pvStr)
Definition: nmflash.c:290
#define FLASH_MODE_FLAGS_UNCHANGED
Definition: nmflash.h:54
static uint8 crc7(uint8 crc, const uint8 *buff, uint16 len)
Definition: nmflash.c:117
#define FLASH_FN_FLAGS_COMPARE_BEFORE
Definition: nmflash.h:59
sint8 transfer_run(tstrFlashAccess *pstrFlashAccess)
Definition: nmflash.c:679
This structure contains parameters for initializing a local data access (read, erase or write)...
Definition: nmflash.h:226
#define FLASH_RETURN_OK
Definition: nmflash.h:45
sint8 prepare_backup(uint32 u32Target)
Definition: nmflash.c:485
WINC3400 Flash Interface.


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:58