wifi_config.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-09-04 ZeroFree first implementation
  9. * 2019-06-14 armink add easyflash v4.0 support
  10. */
  11. #include <rtthread.h>
  12. #ifdef BSP_USING_WIFI
  13. #include <wlan_mgnt.h>
  14. #include <wlan_cfg.h>
  15. #include <wlan_prot.h>
  16. #include <easyflash.h>
  17. #include <fal.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #if (EF_SW_VERSION_NUM < 0x40000)
  21. static char *str_base64_encode_len(const void *src, char *out, int input_length);
  22. static int str_base64_decode(const char *data, int input_length, char *decoded_data);
  23. static const unsigned char base64_table[65] =
  24. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  25. static const char base64_decode_table[256] =
  26. {
  27. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  28. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  29. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
  30. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  31. 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
  32. 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
  33. 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  34. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
  35. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  36. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  37. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  38. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  39. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  40. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  41. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  42. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  43. };
  44. static char *str_base64_encode_len(const void *src, char *out, int len)
  45. {
  46. unsigned char *pos;
  47. const unsigned char *end, *in;
  48. size_t olen;
  49. olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
  50. olen += olen / 72; /* line feeds */
  51. olen++; /* nul termination */
  52. end = (const unsigned char *)src + len;
  53. in = (const unsigned char *)src;
  54. pos = (unsigned char *)out;
  55. while (end - in >= 3)
  56. {
  57. *pos++ = base64_table[in[0] >> 2];
  58. *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
  59. *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
  60. *pos++ = base64_table[in[2] & 0x3f];
  61. in += 3;
  62. }
  63. if (end - in)
  64. {
  65. *pos++ = base64_table[in[0] >> 2];
  66. if (end - in == 1)
  67. {
  68. *pos++ = base64_table[(in[0] & 0x03) << 4];
  69. *pos++ = '=';
  70. }
  71. else
  72. {
  73. *pos++ = base64_table[((in[0] & 0x03) << 4) |
  74. (in[1] >> 4)];
  75. *pos++ = base64_table[(in[1] & 0x0f) << 2];
  76. }
  77. *pos++ = '=';
  78. }
  79. *pos = '\0';
  80. return (char *)out;
  81. }
  82. /*
  83. * return: length, 0 is error.
  84. */
  85. static int str_base64_decode(const char *data, int input_length, char *decoded_data)
  86. {
  87. int out_len;
  88. int i, j;
  89. if (input_length % 4 != 0) return 0;
  90. out_len = input_length / 4 * 3;
  91. if (data[input_length - 1] == '=') out_len--;
  92. if (data[input_length - 2] == '=') out_len--;
  93. for (i = 0, j = 0; i < input_length;)
  94. {
  95. uint32_t sextet_a = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
  96. uint32_t sextet_b = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
  97. uint32_t sextet_c = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
  98. uint32_t sextet_d = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
  99. uint32_t triple = (sextet_a << 3 * 6)
  100. + (sextet_b << 2 * 6)
  101. + (sextet_c << 1 * 6)
  102. + (sextet_d << 0 * 6);
  103. if (j < out_len) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
  104. if (j < out_len) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
  105. if (j < out_len) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
  106. }
  107. return out_len;
  108. }
  109. static int read_cfg(void *buff, int len)
  110. {
  111. char *wlan_cfg_info = RT_NULL;
  112. wlan_cfg_info = ef_get_env("wlan_cfg_info");
  113. if (wlan_cfg_info != RT_NULL)
  114. {
  115. str_base64_decode(wlan_cfg_info, rt_strlen(wlan_cfg_info), buff);
  116. return len;
  117. }
  118. else
  119. {
  120. return 0;
  121. }
  122. }
  123. static int get_len(void)
  124. {
  125. int len;
  126. char *wlan_cfg_len = RT_NULL;
  127. wlan_cfg_len = ef_get_env("wlan_cfg_len");
  128. if (wlan_cfg_len == RT_NULL)
  129. {
  130. len = 0;
  131. }
  132. else
  133. {
  134. len = atoi(wlan_cfg_len);
  135. }
  136. return len;
  137. }
  138. static int write_cfg(void *buff, int len)
  139. {
  140. char wlan_cfg_len[12] = {0};
  141. char *base64_buf = RT_NULL;
  142. base64_buf = rt_malloc(len * 4 / 3 + 4); /* 3-byte blocks to 4-byte, and the end. */
  143. if (base64_buf == RT_NULL)
  144. {
  145. return -RT_ENOMEM;
  146. }
  147. rt_memset(base64_buf, 0, len);
  148. /* interger to string */
  149. sprintf(wlan_cfg_len, "%d", len);
  150. /* set and store the wlan config lengths to Env */
  151. ef_set_env("wlan_cfg_len", wlan_cfg_len);
  152. str_base64_encode_len(buff, base64_buf, len);
  153. /* set and store the wlan config information to Env */
  154. ef_set_env("wlan_cfg_info", base64_buf);
  155. ef_save_env();
  156. rt_free(base64_buf);
  157. return len;
  158. }
  159. #else
  160. static int read_cfg(void *buff, int len)
  161. {
  162. size_t saved_len;
  163. ef_get_env_blob("wlan_cfg_info", buff, len, &saved_len);
  164. if (saved_len == 0)
  165. {
  166. return 0;
  167. }
  168. return len;
  169. }
  170. static int get_len(void)
  171. {
  172. int len;
  173. size_t saved_len;
  174. ef_get_env_blob("wlan_cfg_len", &len, sizeof(len), &saved_len);
  175. if (saved_len == 0)
  176. {
  177. return 0;
  178. }
  179. return len;
  180. }
  181. static int write_cfg(void *buff, int len)
  182. {
  183. /* set and store the wlan config lengths to Env */
  184. ef_set_env_blob("wlan_cfg_len", &len, sizeof(len));
  185. /* set and store the wlan config information to Env */
  186. ef_set_env_blob("wlan_cfg_info", buff, len);
  187. return len;
  188. }
  189. #endif /* (EF_SW_VERSION_NUM < 0x40000) */
  190. static const struct rt_wlan_cfg_ops ops =
  191. {
  192. read_cfg,
  193. get_len,
  194. write_cfg
  195. };
  196. void wlan_autoconnect_init(void)
  197. {
  198. fal_init();
  199. easyflash_init();
  200. rt_wlan_cfg_set_ops(&ops);
  201. rt_wlan_cfg_cache_refresh();
  202. }
  203. #endif