wifi_config.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * File : wifi_config.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2018-09-04 ZeroFree first implementation
  23. * 2019-06-14 armink add easyflash v4.0 support
  24. */
  25. #include <rtthread.h>
  26. #ifdef BSP_USING_WIFI
  27. #include <wlan_mgnt.h>
  28. #include <wlan_cfg.h>
  29. #include <wlan_prot.h>
  30. #include <easyflash.h>
  31. #include <fal.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #if (EF_SW_VERSION_NUM < 0x40000)
  35. static char *str_base64_encode_len(const void *src, char *out, int input_length);
  36. static int str_base64_decode(const char *data, int input_length, char *decoded_data);
  37. static const unsigned char base64_table[65] =
  38. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  39. static const char base64_decode_table[256] =
  40. {
  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. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
  44. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  45. 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
  46. 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
  47. 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  48. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
  49. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  50. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  53. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  54. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  55. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  56. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  57. };
  58. static char *str_base64_encode_len(const void *src, char *out, int len)
  59. {
  60. unsigned char *pos;
  61. const unsigned char *end, *in;
  62. size_t olen;
  63. olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
  64. olen += olen / 72; /* line feeds */
  65. olen++; /* nul termination */
  66. end = (const unsigned char *)src + len;
  67. in = (const unsigned char *)src;
  68. pos = (unsigned char *)out;
  69. while (end - in >= 3)
  70. {
  71. *pos++ = base64_table[in[0] >> 2];
  72. *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
  73. *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
  74. *pos++ = base64_table[in[2] & 0x3f];
  75. in += 3;
  76. }
  77. if (end - in)
  78. {
  79. *pos++ = base64_table[in[0] >> 2];
  80. if (end - in == 1)
  81. {
  82. *pos++ = base64_table[(in[0] & 0x03) << 4];
  83. *pos++ = '=';
  84. }
  85. else
  86. {
  87. *pos++ = base64_table[((in[0] & 0x03) << 4) |
  88. (in[1] >> 4)];
  89. *pos++ = base64_table[(in[1] & 0x0f) << 2];
  90. }
  91. *pos++ = '=';
  92. }
  93. *pos = '\0';
  94. return (char *)out;
  95. }
  96. /*
  97. * return: length, 0 is error.
  98. */
  99. static int str_base64_decode(const char *data, int input_length, char *decoded_data)
  100. {
  101. int out_len;
  102. int i, j;
  103. if (input_length % 4 != 0) return 0;
  104. out_len = input_length / 4 * 3;
  105. if (data[input_length - 1] == '=') out_len--;
  106. if (data[input_length - 2] == '=') out_len--;
  107. for (i = 0, j = 0; i < input_length;)
  108. {
  109. uint32_t sextet_a = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
  110. uint32_t sextet_b = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
  111. uint32_t sextet_c = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
  112. uint32_t sextet_d = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
  113. uint32_t triple = (sextet_a << 3 * 6)
  114. + (sextet_b << 2 * 6)
  115. + (sextet_c << 1 * 6)
  116. + (sextet_d << 0 * 6);
  117. if (j < out_len) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
  118. if (j < out_len) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
  119. if (j < out_len) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
  120. }
  121. return out_len;
  122. }
  123. static int read_cfg(void *buff, int len)
  124. {
  125. char *wlan_cfg_info = RT_NULL;
  126. wlan_cfg_info = ef_get_env("wlan_cfg_info");
  127. if (wlan_cfg_info != RT_NULL)
  128. {
  129. str_base64_decode(wlan_cfg_info, rt_strlen(wlan_cfg_info), buff);
  130. return len;
  131. }
  132. else
  133. {
  134. return 0;
  135. }
  136. }
  137. static int get_len(void)
  138. {
  139. int len;
  140. char *wlan_cfg_len = RT_NULL;
  141. wlan_cfg_len = ef_get_env("wlan_cfg_len");
  142. if (wlan_cfg_len == RT_NULL)
  143. {
  144. len = 0;
  145. }
  146. else
  147. {
  148. len = atoi(wlan_cfg_len);
  149. }
  150. return len;
  151. }
  152. static int write_cfg(void *buff, int len)
  153. {
  154. char wlan_cfg_len[12] = {0};
  155. char *base64_buf = RT_NULL;
  156. base64_buf = rt_malloc(len * 4 / 3 + 4); /* 3-byte blocks to 4-byte, and the end. */
  157. if (base64_buf == RT_NULL)
  158. {
  159. return -RT_ENOMEM;
  160. }
  161. rt_memset(base64_buf, 0, len);
  162. /* interger to string */
  163. sprintf(wlan_cfg_len, "%d", len);
  164. /* set and store the wlan config lengths to Env */
  165. ef_set_env("wlan_cfg_len", wlan_cfg_len);
  166. str_base64_encode_len(buff, base64_buf, len);
  167. /* set and store the wlan config information to Env */
  168. ef_set_env("wlan_cfg_info", base64_buf);
  169. ef_save_env();
  170. rt_free(base64_buf);
  171. return len;
  172. }
  173. #else
  174. static int read_cfg(void *buff, int len)
  175. {
  176. size_t saved_len;
  177. ef_get_env_blob("wlan_cfg_info", buff, len, &saved_len);
  178. if (saved_len == 0)
  179. {
  180. return 0;
  181. }
  182. return len;
  183. }
  184. static int get_len(void)
  185. {
  186. int len;
  187. size_t saved_len;
  188. ef_get_env_blob("wlan_cfg_len", &len, sizeof(len), &saved_len);
  189. if (saved_len == 0)
  190. {
  191. return 0;
  192. }
  193. return len;
  194. }
  195. static int write_cfg(void *buff, int len)
  196. {
  197. /* set and store the wlan config lengths to Env */
  198. ef_set_env_blob("wlan_cfg_len", &len, sizeof(len));
  199. /* set and store the wlan config information to Env */
  200. ef_set_env_blob("wlan_cfg_info", buff, len);
  201. return len;
  202. }
  203. #endif /* (EF_SW_VERSION_NUM < 0x40000) */
  204. static const struct rt_wlan_cfg_ops ops =
  205. {
  206. read_cfg,
  207. get_len,
  208. write_cfg
  209. };
  210. void wlan_autoconnect_init(void)
  211. {
  212. fal_init();
  213. easyflash_init();
  214. rt_wlan_cfg_set_ops(&ops);
  215. rt_wlan_cfg_cache_refresh();
  216. }
  217. #endif