* Serialize the AutoConnectCredential instance and write it back to NVS. */
| 677 | * Serialize the AutoConnectCredential instance and write it back to NVS. |
| 678 | */ |
| 679 | size_t AutoConnectCredential::_commit(void) { |
| 680 | AC_CREDTBODY_t credtBody; |
| 681 | String ssid; |
| 682 | |
| 683 | // Calculate the serialization size for each entry and add the size of 'e' with the size of 'ss' to it. |
| 684 | size_t sz = 0; |
| 685 | for (const auto& credt : _credit) { |
| 686 | ssid = credt.first; |
| 687 | credtBody = credt.second; |
| 688 | sz += ssid.length() + sizeof('\0') + credtBody.password.length() + sizeof('\0') + sizeof(AC_CREDTBODY_t::bssid) + sizeof(AC_CREDTBODY_t::dhcp); |
| 689 | if (credtBody.dhcp == static_cast<uint8_t>(STA_STATIC)) { |
| 690 | for (uint8_t e = 0; e < sizeof(AC_CREDTBODY_t::ip) / sizeof(uint32_t); e++) |
| 691 | sz += sizeof(uint32_t); |
| 692 | } |
| 693 | } |
| 694 | // When the entry is not empty, the size of container terminator as '\0' must be added. |
| 695 | _containSize = sz + (_entries ? sizeof('\0') : 0); |
| 696 | // Calculate the nvs pool size for saving to NVS. Add size of 'e' and 'ss' field. |
| 697 | size_t psz = _containSize + sizeof(uint8_t) + sizeof(uint16_t); |
| 698 | |
| 699 | // Dump container to serialization pool and write it back to NVS. |
| 700 | uint8_t* credtPool = (uint8_t*)malloc(psz); |
| 701 | if (credtPool) { |
| 702 | uint16_t dp = 0; |
| 703 | credtPool[dp++] = _entries; // 'e' |
| 704 | credtPool[dp++] = (uint8_t)(psz & 0x00ff); // 'ss' low byte |
| 705 | credtPool[dp++] = (uint8_t)(psz >> 8); // 'ss' high byte |
| 706 | // Starts dump of credential entries |
| 707 | for (const auto& credt : _credit) { |
| 708 | ssid = credt.first; // Retrieve SSID |
| 709 | credtBody = credt.second; // Retrieve an entry |
| 710 | // SSID |
| 711 | size_t itemLen = ssid.length() + sizeof('\0'); |
| 712 | ssid.toCharArray(reinterpret_cast<char*>(&credtPool[dp]), itemLen); |
| 713 | // Password |
| 714 | dp += itemLen; |
| 715 | itemLen = credtBody.password.length() + sizeof('\0'); |
| 716 | credtBody.password.toCharArray(reinterpret_cast<char*>(&credtPool[dp]), itemLen); |
| 717 | // BSSID |
| 718 | dp += itemLen; |
| 719 | memcpy(&credtPool[dp], credtBody.bssid, sizeof(station_config_t::bssid)); |
| 720 | dp += sizeof(station_config_t::bssid); |
| 721 | // DHCP/Static IP indicator |
| 722 | credtPool[dp++] = (uint8_t)credtBody.dhcp; |
| 723 | // Static IP configuration |
| 724 | if (credtBody.dhcp == STA_STATIC) { |
| 725 | for (uint8_t e = 0; e < sizeof(AC_CREDTBODY_t::ip) / sizeof(uint32_t); e++) { |
| 726 | for (uint8_t b = 1; b <= sizeof(credtBody.ip[e]); b++) |
| 727 | credtPool[dp++] = ((uint8_t*)&credtBody.ip[e])[sizeof(credtBody.ip[e]) - b]; |
| 728 | } |
| 729 | } |
| 730 | } |
| 731 | if (_credit.size() > 0) |
| 732 | credtPool[dp] = '\0'; // Terminates a container |
| 733 | // Write back to the nvs |
| 734 | if (_pref->begin(AC_CREDENTIAL_NVSNAME, false)) { |
| 735 | sz = _pref->putBytes(AC_CREDENTIAL_NVSKEY, credtPool, psz); |
| 736 | _pref->end(); |