1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-08-06 tyx the first version
9 */
10
11 #include <rtthread.h>
12 #include <wlan_cfg.h>
13
14 #define DBG_ENABLE
15 #ifdef RT_WLAN_CFG_DEBUG
16 #define DBG_LEVEL DBG_LOG
17 #else
18 #define DBG_LEVEL DBG_INFO
19 #endif
20 #define DBG_SECTION_NAME "WLAN.cfg"
21 #define DBG_COLOR
22 #include <rtdbg.h>
23
24 #define WLAN_CFG_LOCK() (rt_mutex_take(&cfg_mutex, RT_WAITING_FOREVER))
25 #define WLAN_CFG_UNLOCK() (rt_mutex_release(&cfg_mutex))
26
27 #if RT_WLAN_CFG_INFO_MAX < 1
28 #error "The minimum configuration is 1"
29 #endif
30
31 struct cfg_save_info_head
32 {
33 rt_uint32_t magic;
34 rt_uint32_t len;
35 rt_uint32_t num;
36 rt_uint32_t crc;
37 };
38
39 struct rt_wlan_cfg_des
40 {
41 rt_uint32_t num;
42 struct rt_wlan_cfg_info *cfg_info;
43 };
44
45 static struct rt_wlan_cfg_des *cfg_cache;
46 static const struct rt_wlan_cfg_ops *cfg_ops;
47 static struct rt_mutex cfg_mutex;
48
49 /*
50 * CRC16_CCITT
51 */
rt_wlan_cal_crc(rt_uint8_t * buff,int len)52 static rt_uint16_t rt_wlan_cal_crc(rt_uint8_t *buff, int len)
53 {
54 rt_uint16_t wCRCin = 0x0000;
55 rt_uint16_t wCPoly = 0x1021;
56 rt_uint8_t wChar = 0;
57
58 while (len--)
59 {
60 wChar = *(buff++);
61 wCRCin ^= (wChar << 8);
62 for (int i = 0; i < 8; i++)
63 {
64 if (wCRCin & 0x8000)
65 wCRCin = (wCRCin << 1) ^ wCPoly;
66 else
67 wCRCin = wCRCin << 1;
68 }
69 }
70 return wCRCin;
71 }
72
rt_wlan_cfg_init(void)73 void rt_wlan_cfg_init(void)
74 {
75 /* init cache memory */
76 if (cfg_cache == RT_NULL)
77 {
78 cfg_cache = rt_malloc(sizeof(struct rt_wlan_cfg_des));
79 if (cfg_cache != RT_NULL)
80 {
81 rt_memset(cfg_cache, 0, sizeof(struct rt_wlan_cfg_des));
82 }
83 /* init mutex lock */
84 rt_mutex_init(&cfg_mutex, "wlan_cfg", RT_IPC_FLAG_FIFO);
85 }
86 }
87
rt_wlan_cfg_set_ops(const struct rt_wlan_cfg_ops * ops)88 void rt_wlan_cfg_set_ops(const struct rt_wlan_cfg_ops *ops)
89 {
90 rt_wlan_cfg_init();
91
92 WLAN_CFG_LOCK();
93 /* save ops pointer */
94 cfg_ops = ops;
95 WLAN_CFG_UNLOCK();
96 }
97
98 /* save config data */
rt_wlan_cfg_cache_save(void)99 rt_err_t rt_wlan_cfg_cache_save(void)
100 {
101 rt_err_t err = RT_EOK;
102 struct cfg_save_info_head *info_pkg;
103 int len = 0;
104
105 if ((cfg_ops == RT_NULL) || (cfg_ops->write_cfg == RT_NULL))
106 return RT_EOK;
107
108 WLAN_CFG_LOCK();
109 len = sizeof(struct cfg_save_info_head) + sizeof(struct rt_wlan_cfg_info) * cfg_cache->num;
110 info_pkg = rt_malloc(len);
111 if (info_pkg == RT_NULL)
112 {
113 WLAN_CFG_UNLOCK();
114 return -RT_ENOMEM;
115 }
116 info_pkg->magic = RT_WLAN_CFG_MAGIC;
117 info_pkg->len = len;
118 info_pkg->num = cfg_cache->num;
119 /* CRC */
120 info_pkg->crc = rt_wlan_cal_crc((rt_uint8_t *)cfg_cache->cfg_info, sizeof(struct rt_wlan_cfg_info) * cfg_cache->num);
121 rt_memcpy(((rt_uint8_t *)info_pkg) + sizeof(struct cfg_save_info_head),
122 cfg_cache->cfg_info, sizeof(struct rt_wlan_cfg_info) * cfg_cache->num);
123 if (cfg_ops->write_cfg(info_pkg, len) != len)
124 err = -RT_ERROR;
125 rt_free(info_pkg);
126 WLAN_CFG_UNLOCK();
127 return err;
128 }
129
rt_wlan_cfg_cache_refresh(void)130 rt_err_t rt_wlan_cfg_cache_refresh(void)
131 {
132 int len = 0, i, j;
133 struct cfg_save_info_head *head;
134 void *data;
135 struct rt_wlan_cfg_info *t_info, *cfg_info;
136 rt_uint32_t crc;
137 rt_bool_t equal_flag;
138
139 /* cache is full! exit */
140 if (cfg_cache == RT_NULL || cfg_cache->num >= RT_WLAN_CFG_INFO_MAX)
141 return -RT_ERROR;
142
143 /* check callback */
144 if ((cfg_ops == RT_NULL) ||
145 (cfg_ops->get_len == RT_NULL) ||
146 (cfg_ops->read_cfg == RT_NULL))
147 return -RT_ERROR;
148
149 WLAN_CFG_LOCK();
150 /* get data len */
151 if ((len = cfg_ops->get_len()) <= 0)
152 {
153 WLAN_CFG_UNLOCK();
154 return -RT_ERROR;
155 }
156
157 head = rt_malloc(len);
158 if (head == RT_NULL)
159 {
160 WLAN_CFG_UNLOCK();
161 return -RT_ERROR;
162 }
163 /* get data */
164 if (cfg_ops->read_cfg(head, len) != len)
165 {
166 rt_free(head);
167 WLAN_CFG_UNLOCK();
168 return -RT_ERROR;
169 }
170 /* get config */
171 data = ((rt_uint8_t *)head) + sizeof(struct cfg_save_info_head);
172 crc = rt_wlan_cal_crc((rt_uint8_t *)data, len - sizeof(struct cfg_save_info_head));
173 LOG_D("head->magic:0x%08x RT_WLAN_CFG_MAGIC:0x%08x", head->magic, RT_WLAN_CFG_MAGIC);
174 LOG_D("head->len:%d len:%d", head->len, len);
175 LOG_D("head->num:%d num:%d", head->num, (len - sizeof(struct cfg_save_info_head)) / sizeof(struct rt_wlan_cfg_info));
176 LOG_D("hred->crc:0x%04x crc:0x%04x", head->crc, crc);
177 /* check */
178 if ((head->magic != RT_WLAN_CFG_MAGIC) ||
179 (head->len != len) ||
180 (head->num != (len - sizeof(struct cfg_save_info_head)) / sizeof(struct rt_wlan_cfg_info)) ||
181 (head->crc != crc))
182 {
183 rt_free(head);
184 WLAN_CFG_UNLOCK();
185 return -RT_ERROR;
186 }
187
188 /* remove duplicate config */
189 cfg_info = (struct rt_wlan_cfg_info *)data;
190 for (i = 0; i < head->num; i++)
191 {
192 equal_flag = RT_FALSE;
193 for (j = 0; j < cfg_cache->num; j++)
194 {
195 if ((cfg_cache->cfg_info[j].info.ssid.len == cfg_info[i].info.ssid.len) &&
196 (rt_memcmp(&cfg_cache->cfg_info[j].info.ssid.val[0], &cfg_info[i].info.ssid.val[0],
197 cfg_cache->cfg_info[j].info.ssid.len) == 0) &&
198 (rt_memcmp(&cfg_cache->cfg_info[j].info.bssid[0], &cfg_info[i].info.bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0))
199 {
200 equal_flag = RT_TRUE;
201 break;
202 }
203 }
204
205 if (cfg_cache->num >= RT_WLAN_CFG_INFO_MAX)
206 {
207 break;
208 }
209
210 if (equal_flag == RT_FALSE)
211 {
212 t_info = rt_realloc(cfg_cache->cfg_info, sizeof(struct rt_wlan_cfg_info) * (cfg_cache->num + 1));
213 if (t_info == RT_NULL)
214 {
215 rt_free(head);
216 WLAN_CFG_UNLOCK();
217 return -RT_ERROR;
218 }
219 cfg_cache->cfg_info = t_info;
220 cfg_cache->cfg_info[cfg_cache->num] = cfg_info[i];
221 cfg_cache->num ++;
222 }
223 }
224
225 rt_free(head);
226 WLAN_CFG_UNLOCK();
227 return RT_EOK;
228 }
229
rt_wlan_cfg_get_num(void)230 int rt_wlan_cfg_get_num(void)
231 {
232 rt_wlan_cfg_init();
233
234 return cfg_cache->num;
235 }
236
rt_wlan_cfg_read(struct rt_wlan_cfg_info * cfg_info,int num)237 int rt_wlan_cfg_read(struct rt_wlan_cfg_info *cfg_info, int num)
238 {
239 rt_wlan_cfg_init();
240
241 if ((cfg_info == RT_NULL) || (num <= 0))
242 return 0;
243 /* copy data */
244 WLAN_CFG_LOCK();
245 num = cfg_cache->num > num ? num : cfg_cache->num;
246 rt_memcpy(&cfg_cache->cfg_info[0], cfg_info, sizeof(struct rt_wlan_cfg_info) * num);
247 WLAN_CFG_UNLOCK();
248
249 return num;
250 }
251
rt_wlan_cfg_save(struct rt_wlan_cfg_info * cfg_info)252 rt_err_t rt_wlan_cfg_save(struct rt_wlan_cfg_info *cfg_info)
253 {
254 rt_err_t err = RT_EOK;
255 struct rt_wlan_cfg_info *t_info;
256 int idx = -1, i = 0;
257
258 rt_wlan_cfg_init();
259
260 /* parameter check */
261 if ((cfg_info == RT_NULL) || (cfg_info->info.ssid.len == 0))
262 {
263 return -RT_EINVAL;
264 }
265 /* if (iteam == cache) exit */
266 WLAN_CFG_LOCK();
267 for (i = 0; i < cfg_cache->num; i++)
268 {
269 if ((cfg_cache->cfg_info[i].info.ssid.len == cfg_info->info.ssid.len) &&
270 (rt_memcmp(&cfg_cache->cfg_info[i].info.ssid.val[0], &cfg_info->info.ssid.val[0],
271 cfg_cache->cfg_info[i].info.ssid.len) == 0) &&
272 (rt_memcmp(&cfg_cache->cfg_info[i].info.bssid[0], &cfg_info->info.bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0))
273 {
274 idx = i;
275 break;
276 }
277 }
278
279 if ((idx == 0) && (cfg_cache->cfg_info[i].key.len == cfg_info->key.len) &&
280 (rt_memcmp(&cfg_cache->cfg_info[i].key.val[0], &cfg_info->key.val[0], cfg_info->key.len) == 0))
281 {
282 WLAN_CFG_UNLOCK();
283 return RT_EOK;
284 }
285
286 /* not find iteam with cache, Add iteam to the head */
287 if ((idx == -1) && (cfg_cache->num < RT_WLAN_CFG_INFO_MAX))
288 {
289 t_info = rt_realloc(cfg_cache->cfg_info, sizeof(struct rt_wlan_cfg_info) * (cfg_cache->num + 1));
290 if (t_info == RT_NULL)
291 {
292 WLAN_CFG_UNLOCK();
293 return -RT_ENOMEM;
294 }
295 cfg_cache->cfg_info = t_info;
296 cfg_cache->num ++;
297 }
298
299 /* move cache info */
300 i = (i >= RT_WLAN_CFG_INFO_MAX ? RT_WLAN_CFG_INFO_MAX - 1 : i);
301 for (; i; i--)
302 {
303 cfg_cache->cfg_info[i] = cfg_cache->cfg_info[i - 1];
304 }
305 /* add iteam to head */
306 cfg_cache->cfg_info[i] = *cfg_info;
307 WLAN_CFG_UNLOCK();
308
309 /* save info to flash */
310 err = rt_wlan_cfg_cache_save();
311
312 return err;
313 }
314
rt_wlan_cfg_read_index(struct rt_wlan_cfg_info * cfg_info,int index)315 int rt_wlan_cfg_read_index(struct rt_wlan_cfg_info *cfg_info, int index)
316 {
317 rt_wlan_cfg_init();
318
319 if ((cfg_info == RT_NULL) || (index < 0))
320 return 0;
321
322 WLAN_CFG_LOCK();
323 if (index >= cfg_cache->num)
324 {
325 WLAN_CFG_UNLOCK();
326 return 0;
327 }
328 /* copy data */
329 *cfg_info = cfg_cache->cfg_info[index];
330 WLAN_CFG_UNLOCK();
331 return 1;
332 }
333
rt_wlan_cfg_delete_index(int index)334 int rt_wlan_cfg_delete_index(int index)
335 {
336 struct rt_wlan_cfg_info *cfg_info;
337 int i;
338
339 rt_wlan_cfg_init();
340
341 if (index < 0)
342 return -1;
343
344 WLAN_CFG_LOCK();
345 if (index >= cfg_cache->num)
346 {
347 WLAN_CFG_UNLOCK();
348 return -1;
349 }
350
351 /* malloc new mem */
352 cfg_info = rt_malloc(sizeof(struct rt_wlan_cfg_info) * (cfg_cache->num - 1));
353 if (cfg_info == RT_NULL)
354 {
355 WLAN_CFG_UNLOCK();
356 return -1;
357 }
358 /* copy data to new mem */
359 for (i = 0; i < cfg_cache->num; i++)
360 {
361 if (i < index)
362 {
363 cfg_info[i] = cfg_cache->cfg_info[i];
364 }
365 else if (i > index)
366 {
367 cfg_info[i - 1] = cfg_cache->cfg_info[i];
368 }
369 }
370 rt_free(cfg_cache->cfg_info);
371 cfg_cache->cfg_info = cfg_info;
372 cfg_cache->num --;
373 WLAN_CFG_UNLOCK();
374
375 return 0;
376 }
377
rt_wlan_cfg_delete_all(void)378 void rt_wlan_cfg_delete_all(void)
379 {
380 rt_wlan_cfg_init();
381
382 /* delete all iteam */
383 WLAN_CFG_LOCK();
384 cfg_cache->num = 0;
385 rt_free(cfg_cache->cfg_info);
386 cfg_cache->cfg_info = RT_NULL;
387 WLAN_CFG_UNLOCK();
388 }
389
rt_wlan_cfg_dump(void)390 void rt_wlan_cfg_dump(void)
391 {
392 int index = 0;
393 struct rt_wlan_info *info;
394 struct rt_wlan_key *key;
395 char *security;
396
397 rt_wlan_cfg_init();
398
399 rt_kprintf(" SSID PASSWORD MAC security chn\n");
400 rt_kprintf("------------------------------- ------------------------------- ----------------- -------------- ---\n");
401 for (index = 0; index < cfg_cache->num; index ++)
402 {
403 info = &cfg_cache->cfg_info[index].info;
404 key = &cfg_cache->cfg_info[index].key;
405
406 if (info->ssid.len)
407 rt_kprintf("%-32.32s", &info->ssid.val[0]);
408 else
409 rt_kprintf("%-32.32s", " ");
410
411 if (key->len)
412 rt_kprintf("%-32.32s", &key->val[0]);
413 else
414 rt_kprintf("%-32.32s", " ");
415
416 rt_kprintf("%02x:%02x:%02x:%02x:%02x:%02x ",
417 info->bssid[0],
418 info->bssid[1],
419 info->bssid[2],
420 info->bssid[3],
421 info->bssid[4],
422 info->bssid[5]
423 );
424 switch (info->security)
425 {
426 case SECURITY_OPEN:
427 security = "OPEN";
428 break;
429 case SECURITY_WEP_PSK:
430 security = "WEP_PSK";
431 break;
432 case SECURITY_WEP_SHARED:
433 security = "WEP_SHARED";
434 break;
435 case SECURITY_WPA_TKIP_PSK:
436 security = "WPA_TKIP_PSK";
437 break;
438 case SECURITY_WPA_AES_PSK:
439 security = "WPA_AES_PSK";
440 break;
441 case SECURITY_WPA2_AES_PSK:
442 security = "WPA2_AES_PSK";
443 break;
444 case SECURITY_WPA2_TKIP_PSK:
445 security = "WPA2_TKIP_PSK";
446 break;
447 case SECURITY_WPA2_MIXED_PSK:
448 security = "WPA2_MIXED_PSK";
449 break;
450 case SECURITY_WPS_OPEN:
451 security = "WPS_OPEN";
452 break;
453 case SECURITY_WPS_SECURE:
454 security = "WPS_SECURE";
455 break;
456 default:
457 security = "UNKNOWN";
458 break;
459 }
460 rt_kprintf("%-14.14s ", security);
461 rt_kprintf("%3d \n", info->channel);
462 }
463 }
464