1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License. \n
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License. *
25 * Description: At plt function \n
26 */
27
28 #include <string.h>
29
30 #include "gpio.h"
31 #include "pinctrl.h"
32 #include "pinctrl_porting.h"
33 #include "watchdog.h"
34 #ifdef CONFIG_MIDDLEWARE_SUPPORT_FTM
35 #include "factory.h"
36 #endif
37 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
38 #include "factory.h"
39 #include "sfc.h"
40 #include "xo_trim_porting.h"
41 #endif
42 #ifdef CONFIG_DRIVER_SUPPORT_TSENSOR
43 #include "tsensor.h"
44 #endif
45 #if defined(ENABLE_LOW_POWER) && (ENABLE_LOW_POWER == YES)
46 #include "idle_config.h"
47 #endif
48 #include "at_cmd.h"
49 #include "at_utils.h"
50 #include "at_plt_cmd_register.h"
51 #include "at_plt_cmd_table.h"
52 #include "debug_print.h"
53 #include "time64.h"
54 #include "version_porting.h"
55 #include "hal_reboot.h"
56 #include "at_plt.h"
57
58 #ifdef CONFIG_MIDDLEWARE_SUPPORT_NV
59 #include "nv.h"
60 #endif
61 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
62 #include "upg_porting.h"
63 #include "upg_ab.h"
64 #endif
65 #include "efuse.h"
66 #include "efuse_porting.h"
67 #ifdef CONFIG_DFX_SUPPORT_PRINT
68 #include "dfx_print.h"
69 #endif
70 #ifdef CONFIG_SUPPORT_CRASHINFO_SAVE_TO_FLASH
71 #include "exception.h"
72 #endif
73
74 #define CONVERT_HALF 2
at_plt_convert_bin_to_dec(td_s32 pbin)75 static td_s32 at_plt_convert_bin_to_dec(td_s32 pbin)
76 {
77 td_s32 result = 0;
78 td_s32 temp = pbin;
79
80 while (temp != 0) {
81 result += temp % CONVERT_HALF;
82 temp /= CONVERT_HALF;
83 }
84
85 return result;
86 }
87
at_plt_check_mac_elem(TD_CONST td_char elem)88 TD_PRV td_u32 at_plt_check_mac_elem(TD_CONST td_char elem)
89 {
90 if (elem >= '0' && elem <= '9') {
91 return EXT_ERR_SUCCESS;
92 } else if (elem >= 'A' && elem <= 'F') {
93 return EXT_ERR_SUCCESS;
94 } else if (elem >= 'a' && elem <= 'f') {
95 return EXT_ERR_SUCCESS;
96 } else if (elem == ':') {
97 return EXT_ERR_SUCCESS;
98 }
99
100 return EXT_ERR_FAILURE;
101 }
102
at_plt_cmd_strtoaddr(TD_CONST td_char * param,td_uchar * mac_addr,td_u32 addr_len)103 static td_u32 at_plt_cmd_strtoaddr(TD_CONST td_char *param, td_uchar *mac_addr, td_u32 addr_len)
104 {
105 td_u32 cnt;
106 td_char *tmp1 = (td_char *)param;
107 td_char *tmp2 = TD_NULL;
108 td_char *tmp3 = TD_NULL;
109
110 for (cnt = 0; cnt < 17; cnt++) { /* 17 */
111 if (at_plt_check_mac_elem(param[cnt]) != EXT_ERR_SUCCESS) {
112 return EXT_ERR_FAILURE;
113 }
114 }
115
116 for (cnt = 0; cnt < (addr_len - 1); cnt++) {
117 tmp2 = (char*)strsep(&tmp1, ":");
118 if (tmp2 == TD_NULL) {
119 return EXT_ERR_AT_INVALID_PARAMETER;
120 }
121 mac_addr[cnt] = (td_uchar)strtoul(tmp2, &tmp3, 16); /* 16 */
122 }
123
124 if (tmp1 == TD_NULL) {
125 return EXT_ERR_AT_INVALID_PARAMETER;
126 }
127 mac_addr[cnt] = (td_uchar)strtoul(tmp1, &tmp3, 16); /* 16 */
128 return EXT_ERR_SUCCESS;
129 }
130
131 #ifdef CONFIG_MIDDLEWARE_SUPPORT_NV
132 #define AT_PLT_NV_WRITE_MAX_LENGTH 1024
133 typedef enum {
134 PLT_NV_ATTR_NORMAL = 0,
135 PLT_NV_ATTR_PERMANENT = 1,
136 PLT_NV_ATTR_ENCRYPTED = 2,
137 PLT_NV_ATTR_NON_UPGRADE = 4
138 } plt_nv_attr;
139 STATIC uint32_t plt_nv_get_value(const nvwrite_args_t *args, uint8_t *value);
140 #endif
141 #define DATE_BASE_YEAR 1900
142 #define leap_year(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
143 static const int32_t g_mon_lengths[2][12] = { /* 2: 2 Column,Contains leap year; 12: 12 months */
144 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
145 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
146 };
147
148 #define AT_PLT_FUNC_NUM (sizeof(at_plt_cmd_parse_table) / sizeof(at_plt_cmd_parse_table[0]))
149
los_at_plt_cmd_register(void)150 void los_at_plt_cmd_register(void)
151 {
152 print_str("los_at_plt_cmd_register EXCUTE\r\n");
153 uapi_at_plt_register_cmd(at_plt_cmd_parse_table, AT_PLT_FUNC_NUM);
154 }
155
plt_nv_read(const nvread_args_t * args)156 at_ret_t plt_nv_read(const nvread_args_t *args)
157 {
158 #ifdef CONFIG_MIDDLEWARE_SUPPORT_NV
159 uint16_t nv_value_length = 0;
160 uint8_t nv_value[AT_PLT_NV_WRITE_MAX_LENGTH] = {0};
161 nv_key_attr_t nv_attr = {0};
162 errcode_t ret = uapi_nv_read_with_attr((uint16_t)args->key_id, AT_PLT_NV_WRITE_MAX_LENGTH, &nv_value_length,
163 nv_value, &nv_attr);
164 if (ret != ERRCODE_SUCC) {
165 print_str("plt_nv_read failed, ret = [0x%x]\r\n", ret);
166 return ret;
167 }
168 if (nv_attr.permanent == true) {
169 print_str("NV[0x%x] is permanent\r\n", args->key_id);
170 }
171 if (nv_attr.encrypted == true) {
172 print_str("NV[0x%x] is encrypted\r\n", args->key_id);
173 }
174 if (nv_attr.non_upgrade == true) {
175 print_str("NV[0x%x] is non_upgrade\r\n", args->key_id);
176 }
177 for (int i = 0; i < nv_value_length; i++) {
178 print_str("nv_value[%d] = [0x%x]\r\n", i, nv_value[i]);
179 }
180 #else
181 unused(args);
182 #endif
183 return AT_RET_OK;
184 }
185
186 #ifdef CONFIG_MIDDLEWARE_SUPPORT_NV
plt_nv_get_value(const nvwrite_args_t * args,uint8_t * value)187 STATIC uint32_t plt_nv_get_value(const nvwrite_args_t *args, uint8_t *value)
188 {
189 errno_t ret;
190 td_u8 *tmp = TD_NULL;
191 tmp = (td_u8 *)malloc(args->length);
192 if (tmp == TD_NULL) {
193 free(tmp);
194 return AT_RET_SYNTAX_ERROR;
195 }
196
197 at_str_to_hex((char *)(args->value), args->length + args->length, tmp); /* 2:偏移2个字符 */
198 ret = memcpy_s(value, AT_PLT_NV_WRITE_MAX_LENGTH + 1, tmp, args->length + 1);
199 free(tmp);
200 if (ret != EOK) {
201 return EXT_ERR_MEMCPYS_FAIL;
202 }
203 return EXT_ERR_SUCCESS;
204 }
205 #endif
plt_nv_write(const nvwrite_args_t * args)206 at_ret_t plt_nv_write(const nvwrite_args_t *args)
207 {
208 #ifdef CONFIG_MIDDLEWARE_SUPPORT_NV
209 if (args->length == 0) {
210 return AT_RET_CMD_PARA_ERROR;
211 }
212 uint8_t write_value[AT_PLT_NV_WRITE_MAX_LENGTH] = {0};
213 if (plt_nv_get_value(args, write_value) != EXT_ERR_SUCCESS) {
214 return AT_RET_CMD_PARA_ERROR;
215 }
216 nv_key_attr_t nv_attr = {0};
217 switch (args->attr) {
218 case PLT_NV_ATTR_PERMANENT:
219 nv_attr.permanent = 1;
220 break;
221 case PLT_NV_ATTR_ENCRYPTED:
222 nv_attr.encrypted = 1;
223 break;
224 case PLT_NV_ATTR_NON_UPGRADE:
225 nv_attr.non_upgrade = 1;
226 break;
227 default:
228 break;
229 }
230 errcode_t ret = uapi_nv_write_with_attr((uint16_t)args->key_id, write_value, (uint16_t)args->length, &nv_attr,
231 NULL);
232 if (ret != ERRCODE_SUCC) {
233 print_str("plt_nv_write failed, ret = [0x%x]\r\n", ret);
234 return ret;
235 }
236 for (uint32_t i = 0; i < args->length; i++) {
237 print_str("nv_value[%d] = [0x%x]\r\n", i, write_value[i]);
238 }
239 #else
240 unused(args);
241 #endif
242 return AT_RET_OK;
243 }
244
245 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
246 #define UPG_AB_REGION_CFG_ADDR 0x3FF000
247 #define UPG_AB_REGION_CFG_SIZE 0x1000
248 #define UPG_AB_CONFIG_CHECK 0x70746C6C
249 typedef struct {
250 uint32_t check_num; /* check number */
251 uint32_t run_region; /* run region */
252 } upg_ab_config_t;
253 #endif
upg_ab_set_run_region(const absetrun_args_t * args)254 at_ret_t upg_ab_set_run_region(const absetrun_args_t *args)
255 {
256 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
257 errcode_t ret = ws63_upg_init();
258 if (ret != ERRCODE_SUCC && ret != ERRCODE_UPG_ALREADY_INIT) {
259 print_str("ab upg set run region init failed, ret : 0x%x\r\n", ret);
260 }
261 upg_ab_config_t config = {0};
262 ret = upg_flash_read(UPG_AB_REGION_CFG_ADDR, sizeof(upg_ab_config_t), (uint8_t *)&config);
263 if (ret != ERRCODE_SUCC || config.check_num != UPG_AB_CONFIG_CHECK) {
264 print_str("ab upg set run region read failed, ret : 0x%x\r\n", ret);
265 return AT_RET_PROGRESS_BLOCK;
266 }
267 config.run_region = args->run_region;
268 ret = upg_flash_write(UPG_AB_REGION_CFG_ADDR, sizeof(upg_ab_config_t), (const uint8_t *)&config, true);
269 if (ret != ERRCODE_SUCC) {
270 print_str("ab upg set run region write failed, ret : 0x%x\r\n", ret);
271 return ret;
272 }
273 #else
274 unused(args);
275 #endif
276 return AT_RET_OK;
277 }
278
279 #define MAC_ADDR_EFUSE 0
280 #define MAC_ADDR_NV 1
281 #define SLE_MAC_ADDR 2
282 #define SET_EFUSE_MAC_PARAM_CNT 2
283 #ifndef WIFI_MAC_LEN
284 #define WIFI_MAC_LEN 6
285 #endif
286
287 /*****************************************************************************
288 功能描述 :设置efuse mac地址
289 *****************************************************************************/
set_efuse_mac_addr(const efusemac_args_t * args)290 at_ret_t set_efuse_mac_addr(const efusemac_args_t *args)
291 {
292 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
293 td_uchar mac_addr[WIFI_MAC_LEN] = {0};
294
295 if (argc != SET_EFUSE_MAC_PARAM_CNT || strlen((const char *)args->mac_addr) != 17) { /* 17 mac string len */
296 return AT_RET_SYNTAX_ERROR;
297 }
298
299 td_u32 ret = at_plt_cmd_strtoaddr((const char *)args->mac_addr, mac_addr, WIFI_MAC_LEN);
300 if (ret != EXT_ERR_SUCCESS) {
301 return AT_RET_SYNTAX_ERROR;
302 }
303 if ((mac_addr[0] & 0x1) == 0x1) {
304 osal_printk("set mac error: multicast mac addr not aviable!!\r\n");
305 return AT_RET_SYNTAX_ERROR;
306 }
307 switch (args->mac_type) {
308 case MAC_ADDR_EFUSE:
309 ret = efuse_write_mac(mac_addr, WIFI_MAC_LEN);
310 if (ret != ERRCODE_SUCC) {
311 osal_printk("SET EFUSE MAC ERROR, ret : 0x%x\r\n", ret);
312 return AT_RET_CMD_PARA_ERROR;
313 }
314 break;
315 case SLE_MAC_ADDR:
316 ret = efuse_write_sle_mac(mac_addr, WIFI_MAC_LEN);
317 if (ret != ERRCODE_SUCC) {
318 osal_printk("SET SLE EFUSE MAC ERROR, ret : 0x%x\r\n", ret);
319 return AT_RET_CMD_PARA_ERROR;
320 }
321 break;
322 case MAC_ADDR_NV:
323 #if defined(CONFIG_MIDDLEWARE_SUPPORT_NV)
324 ret = uapi_nv_write(NV_ID_SYSTEM_FACTORY_MAC, mac_addr, WIFI_MAC_LEN);
325 if (ret != ERRCODE_SUCC) {
326 osal_printk("SET NV MAC ERROR, ret : 0x%x\r\n", ret);
327 return AT_RET_CMD_PARA_ERROR;
328 }
329 #else
330 return AT_RET_CMD_PARA_ERROR;
331 #endif
332 break;
333 default:
334 return AT_RET_CMD_PARA_ERROR;
335 break;
336 }
337
338 osal_printk("OK\r\n");
339 return AT_RET_OK;
340 }
341
342 /*****************************************************************************
343 功能描述 :获取efuse mac地址
344 *****************************************************************************/
get_efuse_mac_addr(void)345 at_ret_t get_efuse_mac_addr(void)
346 {
347 td_uchar mac_addr[WIFI_MAC_LEN] = {0};
348 td_uchar null_mac_addr[WIFI_MAC_LEN] = {0};
349 td_uchar efuse_left_count = 0;
350 errcode_t ret;
351
352 #if defined(CONFIG_MIDDLEWARE_SUPPORT_NV)
353 uint16_t nv_mac_length;
354 ret = uapi_nv_read(NV_ID_SYSTEM_FACTORY_MAC, WIFI_MAC_LEN, &nv_mac_length, mac_addr);
355 if (ret != ERRCODE_SUCC || nv_mac_length != WIFI_MAC_LEN) {
356 osal_printk("GET NV MAC ERROR, ret : 0x%x\r\n", ret);
357 }
358 osal_printk("+EFUSEMAC: NV MAC " EXT_AT_MACSTR "\r\n", ext_at_mac2str(mac_addr));
359 #endif
360 ret = efuse_read_mac(mac_addr, WIFI_MAC_LEN, &efuse_left_count);
361 if (ret == ERRCODE_SUCC) {
362 osal_printk("+EFUSEMAC: EFUSE MAC " EXT_AT_MACSTR "\r\n", ext_at_mac2str(mac_addr));
363 } else {
364 osal_printk("+EFUSEMAC: EFUSE MAC " EXT_AT_MACSTR "\r\n", ext_at_mac2str(null_mac_addr));
365 }
366 osal_printk("+EFUSEMAC: Efuse mac chance(s) left: %d times.\r\n", efuse_left_count);
367
368 ret = efuse_read_sle_mac(mac_addr, WIFI_MAC_LEN);
369 if (ret == ERRCODE_SUCC) {
370 osal_printk("+EFUSEMAC: EFUSE SLE MAC " EXT_AT_MACSTR "\r\n", ext_at_mac2str(mac_addr));
371 } else {
372 osal_printk("+EFUSEMAC: EFUSE SLE MAC " EXT_AT_MACSTR "\r\n", ext_at_mac2str(null_mac_addr));
373 }
374 osal_printk("OK\r\n");
375
376 return AT_RET_OK;
377 }
378
379 #define BOOT_PORTING_RESET_REG 0x40002110
380 #define BOOT_PORTING_RESET_VALUE 0x4
381
plt_reboot(void)382 at_ret_t plt_reboot(void)
383 {
384 hal_reboot_chip();
385 return AT_RET_OK;
386 }
387
at_query_ver_cmd(void)388 at_ret_t at_query_ver_cmd(void)
389 {
390 print_version();
391 return AT_RET_OK;
392 }
393
at_query_tsensor_temp(void)394 at_ret_t at_query_tsensor_temp(void)
395 {
396 #ifdef CONFIG_DRIVER_SUPPORT_TSENSOR
397 td_u32 ret;
398 td_u32 i;
399 td_s8 temp = 0;
400
401 for (i = 0; i < 3; i++) { /* loop 3 times */
402 ret = uapi_tsensor_get_current_temp(&temp);
403 if (ret == EXT_ERR_SUCCESS) {
404 break;
405 }
406 }
407
408 if (ret != EXT_ERR_SUCCESS) {
409 osal_printk("+RDTEMP:ret0x%x.\r\n", ret);
410 return ret;
411 }
412
413 osal_printk("+RDTEMP:%d\r\n", temp);
414 #endif
415 return AT_RET_OK;
416 }
417
418 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
get_rf_cmu_pll_param(const td_s16 * high_temp,const td_s16 * low_temp,const td_s16 * compesation)419 static td_u32 get_rf_cmu_pll_param(const td_s16 *high_temp, const td_s16 *low_temp, const td_s16 *compesation)
420 {
421 unused(high_temp);
422 unused(low_temp);
423 unused(compesation);
424 cmu_xo_trim_temp_comp_print();
425 return EXT_ERR_SUCCESS;
426 }
427 #endif
428
at_query_xtal_compesation(void)429 at_ret_t at_query_xtal_compesation(void)
430 {
431 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
432 td_u32 ret;
433 td_s16 high_temp_threshold = 0;
434 td_s16 low_temp_threshold = 0;
435 td_s16 pll_compesation = 0;
436
437 ret = get_rf_cmu_pll_param(&high_temp_threshold, &low_temp_threshold, &pll_compesation);
438 if (ret != EXT_ERR_SUCCESS) {
439 return ret;
440 }
441
442 osal_printk("+XTALCOM:%d,%d,%d\r\n", high_temp_threshold, low_temp_threshold, pll_compesation);
443 #endif
444
445 return AT_RET_OK;
446 }
447
at_factory_erase(void)448 at_ret_t at_factory_erase(void)
449 {
450 #ifdef CONFIG_MIDDLEWARE_SUPPORT_FTM
451 errcode_t ret;
452 mfg_factory_config_t factory_mode_cfg;
453
454 memset_s(&factory_mode_cfg, sizeof(factory_mode_cfg), 0, sizeof(factory_mode_cfg));
455 ret = mfg_flash_read((uint8_t *)(&factory_mode_cfg), sizeof(mfg_factory_config_t));
456 if (ret != EXT_ERR_SUCCESS) {
457 return ret;
458 }
459 if (factory_mode_cfg.factory_mode != 0x0) {
460 osal_printk("factory mode, can not erase\r\n");
461 return AT_RET_SYNTAX_ERROR;
462 }
463 ret = mfg_flash_erase();
464 if (ret != EXT_ERR_SUCCESS) {
465 osal_printk("at_factory_erase:: uapi_flash_erase failed, ret :%x\r\n", ret);
466 return ret;
467 }
468 /* set normal mode after erase factory. inorder to let start success after reboot. */
469 factory_mode_cfg.factory_mode = 0x0;
470 factory_mode_cfg.factory_valid = MFG_FACTORY_INVALID;
471 ret = mfg_flash_write((const uint8_t *)(&factory_mode_cfg), sizeof(factory_mode_cfg));
472 if (ret != EXT_ERR_SUCCESS) {
473 return ret;
474 }
475 osal_printk("+FTMERASE:erase addr:0x%x, size:0x%x OK.\r\n", factory_mode_cfg.factory_addr_start,
476 factory_mode_cfg.factory_size);
477 #endif
478
479 return AT_RET_OK;
480 }
481
at_factory_mode_read(void)482 at_ret_t at_factory_mode_read(void)
483 {
484 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
485 osal_printk("factory mode\r\n");
486 #else
487 osal_printk("non_factory mode\r\n");
488 #endif
489 return AT_RET_OK;
490 }
491
492 #ifdef CONFIG_MIDDLEWARE_SUPPORT_FTM
493
at_setup_factory_mode_switch(td_s32 argc,const factory_mode_args_t * args)494 static td_u32 at_setup_factory_mode_switch(td_s32 argc, const factory_mode_args_t *args)
495 {
496 errcode_t ret;
497 mfg_factory_config_t factory_mode_cfg;
498 mfg_region_config_t img_info;
499 osal_printk("+FTM SWITCH: start\r\n");
500
501 if (argc != 1) {
502 return AT_RET_SYNTAX_ERROR;
503 }
504
505 /* switch_mode:0 normal_mode; switch_mode:1 factory_test_mode */
506 td_u8 switch_mode = (td_u8)(args->para1);
507 if (switch_mode != 0x0 && switch_mode != 0x1) {
508 return AT_RET_SYNTAX_ERROR;
509 }
510
511 memset_s(&factory_mode_cfg, sizeof(factory_mode_cfg), 0, sizeof(factory_mode_cfg));
512 memset_s(&img_info, sizeof(img_info), 0, sizeof(img_info));
513 ret = mfg_get_region_config(&img_info);
514 if (ret != ERRCODE_SUCC) {
515 return ret;
516 }
517
518 ret = mfg_flash_read((uint8_t *)(&factory_mode_cfg), sizeof(mfg_factory_config_t));
519 if (ret != ERRCODE_SUCC) {
520 osal_printk("at_setup_factory_mode_switch:: read failed, ret :%x ", ret);
521 return ERRCODE_FAIL;
522 }
523
524 ret = mfg_factory_mode_switch(img_info, switch_mode, &factory_mode_cfg);
525 if (ret != ERRCODE_SUCC) {
526 osal_printk("at_setup_factory_mode_switch:: mfg_factory_mode_switch failed, ret :%x ", ret);
527 return ERRCODE_FAIL;
528 }
529
530 ret = mfg_flash_write((const uint8_t *)(&factory_mode_cfg), sizeof(factory_mode_cfg));
531 if (ret != ERRCODE_SUCC) {
532 osal_printk("ftm config init write failed, ret :%x ", ret);
533 return ERRCODE_FAIL;
534 }
535 osal_printk("FTM SWTICH:0x%x, size:0x%x OK.\r\n", factory_mode_cfg.factory_addr_switch,
536 factory_mode_cfg.factory_switch_size);
537 return AT_RET_OK;
538 }
539 #endif
540
at_factory_mode_switch(const factory_mode_args_t * args)541 at_ret_t at_factory_mode_switch(const factory_mode_args_t *args)
542 {
543 #ifdef CONFIG_MIDDLEWARE_SUPPORT_FTM
544 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
545 if (at_setup_factory_mode_switch(argc, args) != AT_RET_OK) {
546 return AT_RET_SYNTAX_ERROR;
547 }
548 #else
549 unused(args);
550 #endif
551
552 return AT_RET_OK;
553 }
554
555 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
556 // start of at cmd: uart log level
557
at_setup_loglevel_cmd(td_s32 argc,const loglevel_args_t * args)558 static td_u32 at_setup_loglevel_cmd(td_s32 argc, const loglevel_args_t *args)
559 {
560 #ifdef CONFIG_DFX_SUPPORT_PRINT
561 td_u8 log_level;
562
563 if (argc == 0) { /* argc 0 */
564 osal_printk("+LOGL:%u\r\n", dfx_print_get_level());
565 return AT_RET_OK;
566 }
567 if (argc != 1) { /* argc 1 */
568 return AT_RET_SYNTAX_ERROR;
569 }
570
571 log_level = (td_u8)(args->para1);
572 if (log_level >= DFX_PRINT_LEVEL_MAX) {
573 return AT_RET_SYNTAX_ERROR;
574 }
575
576 dfx_print_set_level(log_level);
577 osal_printk("+LOGL:%d\r\n", log_level);
578 #else
579 unused(argc);
580 unused(args);
581 #endif
582 return AT_RET_OK;
583 }
584 #endif
585
at_get_log_level(void)586 at_ret_t at_get_log_level(void)
587 {
588 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
589 if (at_setup_loglevel_cmd(0, NULL) != AT_RET_OK) {
590 return AT_RET_SYNTAX_ERROR;
591 }
592 #endif
593 return AT_RET_OK;
594 }
595
at_set_log_level(const loglevel_args_t * args)596 at_ret_t at_set_log_level(const loglevel_args_t *args)
597 {
598 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
599 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
600 if (at_setup_loglevel_cmd(argc, args) != AT_RET_OK) {
601 return AT_RET_SYNTAX_ERROR;
602 }
603 #else
604 unused(args);
605 #endif
606
607 return AT_RET_OK;
608 }
609
610 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
611 #define UAPI_MAX_SLEEP_MODE 2
612
613 td_u8 g_sleep_mode;
614
uapi_set_sleep_mode(td_u8 sleep_mode)615 static errcode_t uapi_set_sleep_mode(td_u8 sleep_mode)
616 {
617 g_sleep_mode = sleep_mode;
618 #if defined(ENABLE_LOW_POWER) && (ENABLE_LOW_POWER == YES)
619 bool open_pm = (g_sleep_mode == 0) ? false : true;
620 idle_set_open_pm(open_pm);
621 #endif
622 return ERRCODE_SUCC;
623 }
624
uapi_get_sleep_mode(td_void)625 static td_u8 uapi_get_sleep_mode(td_void)
626 {
627 return g_sleep_mode;
628 }
629
at_setup_sleepmode_cmd(td_s32 argc,const sleepmode_args_t * args)630 static td_u32 at_setup_sleepmode_cmd(td_s32 argc, const sleepmode_args_t *args)
631 {
632 td_u8 sleep_mode;
633 td_u32 ret;
634
635 if (argc != 1) { /* argc 2 */
636 osal_printk("+SLP:%d\r\n", uapi_get_sleep_mode());
637 return AT_RET_OK;
638 }
639
640 sleep_mode = (td_u8)(args->para1);
641 if (sleep_mode > UAPI_MAX_SLEEP_MODE) {
642 return AT_RET_SYNTAX_ERROR;
643 }
644
645 ret = uapi_set_sleep_mode(sleep_mode);
646 if (ret != EXT_ERR_SUCCESS) {
647 return AT_RET_SYNTAX_ERROR;
648 }
649 osal_printk("+SLP:%d\r\n", sleep_mode);
650
651 return AT_RET_OK;
652 }
653 #endif
654
at_get_sleep_mode(void)655 at_ret_t at_get_sleep_mode(void)
656 {
657 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
658 if (at_setup_sleepmode_cmd(0, NULL) != AT_RET_OK) {
659 return AT_RET_SYNTAX_ERROR;
660 }
661 #endif
662 return AT_RET_OK;
663 }
664
at_set_sleep_mode(const sleepmode_args_t * args)665 at_ret_t at_set_sleep_mode(const sleepmode_args_t *args)
666 {
667 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
668 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
669 if (at_setup_sleepmode_cmd(argc, args) != AT_RET_OK) {
670 return AT_RET_SYNTAX_ERROR;
671 }
672 #else
673 unused(args);
674 #endif
675
676 return AT_RET_OK;
677 }
678
679 #define UAPI_UART_PORT_MAX 2
680 #define UAPI_UART_PORT_NUM 3
681
at_set_uart_port(const uartport_args_t * args)682 at_ret_t at_set_uart_port(const uartport_args_t *args)
683 {
684 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
685 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
686
687 osal_printk("+SETUART :%d\r\n", argc);
688 if (argc != UAPI_UART_PORT_NUM) { /* argc 3 */
689 return AT_RET_SYNTAX_ERROR;
690 }
691
692 if (args->para1 > UAPI_UART_PORT_MAX) {
693 return AT_RET_SYNTAX_ERROR;
694 }
695
696 if (args->para2 > UAPI_UART_PORT_MAX) {
697 return AT_RET_SYNTAX_ERROR;
698 }
699
700 if (args->para3 > UAPI_UART_PORT_MAX) {
701 return AT_RET_SYNTAX_ERROR;
702 }
703 osal_printk("+SETUART:%d,%d,%d\r\n", args->para1, args->para2, args->para3);
704 #else
705 unused(args);
706 #endif
707
708 return AT_RET_OK;
709 }
710
711 // gpio ops
712 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
at_setup_gpiodir_cmd(td_s32 argc,const gpiodir_args_t * args)713 static td_u32 at_setup_gpiodir_cmd(td_s32 argc, const gpiodir_args_t *args)
714 {
715 pin_t io_num;
716 gpio_direction_t io_dir;
717 pin_mode_t io_mode;
718 td_u32 ret;
719
720 if (argc != 2) { /* argc 2 */
721 return AT_RET_SYNTAX_ERROR;
722 }
723
724 io_num = (pin_t)(args->para1);
725 if (io_num > PIN_NONE) {
726 osal_printk("+RDGPIO:invalid io,%d\r\n", io_num);
727 return AT_RET_SYNTAX_ERROR;
728 }
729
730 io_mode = uapi_pin_get_mode(io_num);
731 if (io_mode != 0) {
732 return ERRCODE_PIN_INVALID_PARAMETER;
733 }
734
735 io_dir = (gpio_direction_t)(args->para2);
736 if (io_dir > GPIO_DIRECTION_OUTPUT) {
737 return AT_RET_SYNTAX_ERROR;
738 }
739
740 ret = uapi_gpio_set_dir((pin_t)io_num, io_dir);
741 if (ret != EXT_ERR_SUCCESS) {
742 return AT_RET_SYNTAX_ERROR;
743 }
744 osal_printk("+GPIODIR:%d,%d\r\n", io_num, io_dir);
745
746 return AT_RET_OK;
747 }
748 #endif
749
at_set_gpio_dir(const gpiodir_args_t * args)750 at_ret_t at_set_gpio_dir(const gpiodir_args_t *args)
751 {
752 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
753 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
754 if (at_setup_gpiodir_cmd(argc, args) != AT_RET_OK) {
755 return AT_RET_SYNTAX_ERROR;
756 }
757 #else
758 unused(args);
759 #endif
760
761 return AT_RET_OK;
762 }
763
764 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
at_setup_iogetmode_cmd(td_s32 argc,const getiomode_args_t * args)765 static td_u32 at_setup_iogetmode_cmd(td_s32 argc, const getiomode_args_t *args)
766 {
767 pin_t io_num;
768 pin_mode_t io_mode;
769 pin_pull_t io_pull_stat; /* record io_pull */
770 pin_drive_strength_t io_capalibity; /* record io_driver_strength */
771
772 if (argc != 1) {
773 return AT_RET_SYNTAX_ERROR;
774 }
775
776 io_num = (pin_t)(args->para1);
777 if (io_num > PIN_NONE) {
778 osal_printk("+GETIOMODE:invalid io,%d\r\n", io_num);
779 return AT_RET_SYNTAX_ERROR;
780 }
781
782 io_mode = uapi_pin_get_mode(io_num);
783 if (io_mode >= PIN_MODE_MAX) {
784 return AT_RET_SYNTAX_ERROR;
785 }
786
787 io_pull_stat = uapi_pin_get_pull(io_num);
788 if (io_pull_stat > PIN_PULL_MAX) { /* HAL_PIO_PULL_MAX */
789 return AT_RET_SYNTAX_ERROR;
790 }
791
792 io_capalibity = uapi_pin_get_ds(io_num);
793 if (io_capalibity > PIN_DS_MAX) {
794 return AT_RET_SYNTAX_ERROR;
795 }
796
797 osal_printk("+GETIOMODE:%d,%d,%d,%d\r\n", io_num, io_mode, io_pull_stat, io_capalibity);
798 return AT_RET_OK;
799 }
800 #endif
801
at_get_iomode(const getiomode_args_t * args)802 at_ret_t at_get_iomode(const getiomode_args_t *args)
803 {
804 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
805 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
806 if (at_setup_iogetmode_cmd(argc, args) != AT_RET_OK) {
807 return AT_RET_SYNTAX_ERROR;
808 }
809 #else
810 unused(args);
811 #endif
812
813 return AT_RET_OK;
814 }
815
816 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
at_setup_iosetmode_cmd(td_s32 argc,const setiomode_args_t * args)817 static td_u32 at_setup_iosetmode_cmd(td_s32 argc, const setiomode_args_t *args)
818 {
819 pin_t io_num;
820 pin_mode_t io_mode;
821 pin_pull_t io_pull_stat; /* record io_pull */
822 pin_drive_strength_t io_capalibity; /* record io_driver_strength */
823 td_u32 ret;
824
825 if (argc < 3 || argc > 4) { /* argc 3/4 */
826 return AT_RET_SYNTAX_ERROR;
827 }
828
829 io_num = (pin_t)(args->para1);
830 if (io_num > PIN_NONE) {
831 return AT_RET_SYNTAX_ERROR;
832 }
833
834 io_mode = (pin_mode_t)(args->para2);
835 if (io_mode >= PIN_MODE_MAX) {
836 return AT_RET_SYNTAX_ERROR;
837 }
838
839 io_pull_stat = (pin_pull_t)(args->para3); /* argc 2 */
840 if (io_pull_stat >= PIN_PULL_MAX) { /* HAL_PIO_PULL_MAX */
841 return AT_RET_SYNTAX_ERROR;
842 }
843
844 if (argc == 3) { /* argc 3 */
845 io_capalibity = PIN_DS_MAX - 1;
846 } else {
847 io_capalibity = (pin_drive_strength_t)(args->para4); /* argc 3 */
848 }
849
850 ret = uapi_pin_set_mode(io_num, io_mode);
851 if (ret != EXT_ERR_SUCCESS) {
852 return AT_RET_CMD_ATTR_NOT_ALLOW;
853 }
854
855 ret = uapi_pin_get_pull(io_num);
856 if (ret != PIN_PULL_MAX) {
857 ret = uapi_pin_set_pull(io_num, io_pull_stat);
858 if (ret != EXT_ERR_SUCCESS) {
859 return AT_RET_CMD_ATTR_NOT_ALLOW;
860 }
861 }
862
863 ret = uapi_pin_get_ds(io_num);
864 if (ret != PIN_DS_MAX) {
865 ret = uapi_pin_set_ds(io_num, io_capalibity);
866 if (ret != EXT_ERR_SUCCESS) {
867 return AT_RET_CMD_ATTR_NOT_ALLOW;
868 }
869 }
870
871 osal_printk("+SETIOMODE:%d,%d,%d,%d\r\n", io_num, io_mode, io_pull_stat, io_capalibity);
872 return AT_RET_OK;
873 }
874 #endif
875
at_set_iomode(const setiomode_args_t * args)876 at_ret_t at_set_iomode(const setiomode_args_t *args)
877 {
878 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
879 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
880 if (at_setup_iosetmode_cmd(argc, args) != AT_RET_OK) {
881 return AT_RET_SYNTAX_ERROR;
882 }
883 #else
884 unused(args);
885 #endif
886
887 return AT_RET_OK;
888 }
889
890 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
at_setup_gpiowt_cmd(td_s32 argc,const wrgpio_args_t * args)891 static td_u32 at_setup_gpiowt_cmd(td_s32 argc, const wrgpio_args_t *args)
892 {
893 pin_t io_num;
894 gpio_level_t io_level;
895 pin_mode_t io_mode;
896 gpio_direction_t io_dir = GPIO_DIRECTION_OUTPUT;
897 td_u32 ret;
898
899 if (argc != 2) { /* argc 2 */
900 return AT_RET_SYNTAX_ERROR;
901 }
902
903 io_num = (pin_t)(args->para1);
904 if (io_num > PIN_NONE) {
905 return AT_RET_SYNTAX_ERROR;
906 }
907
908 io_level = (gpio_level_t)(args->para2);
909 if (io_level > GPIO_LEVEL_HIGH) {
910 return AT_RET_SYNTAX_ERROR;
911 }
912
913 io_mode = uapi_pin_get_mode(io_num);
914 if (io_mode >= PIN_MODE_MAX) {
915 return AT_RET_SYNTAX_ERROR;
916 }
917
918 io_dir = uapi_gpio_get_dir(io_num);
919 if (io_dir != GPIO_DIRECTION_OUTPUT) {
920 return AT_RET_SYNTAX_ERROR;
921 }
922
923 ret = uapi_gpio_set_val((pin_t)io_num, io_level);
924 if (ret != EXT_ERR_SUCCESS) {
925 return AT_RET_SYNTAX_ERROR;
926 }
927 osal_printk("+WRGPIO:%d,%d,%d\r\n", io_num, io_dir, io_level);
928
929 return EXT_ERR_SUCCESS;
930 }
931 #endif
932
at_wrgpio(const wrgpio_args_t * args)933 at_ret_t at_wrgpio(const wrgpio_args_t *args)
934 {
935 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
936 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
937 if (at_setup_gpiowt_cmd(argc, args) != AT_RET_OK) {
938 return AT_RET_SYNTAX_ERROR;
939 }
940 #else
941 unused(args);
942 #endif
943
944 return AT_RET_OK;
945 }
946
947 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
at_setup_gpiord_cmd(td_s32 argc,const rdgpio_args_t * args)948 static td_u32 at_setup_gpiord_cmd(td_s32 argc, const rdgpio_args_t *args)
949 {
950 pin_t io_num;
951 gpio_level_t io_level;
952 pin_mode_t io_mode;
953 gpio_direction_t io_dir;
954
955 if (argc != 1) {
956 return AT_RET_SYNTAX_ERROR;
957 }
958
959 io_num = (pin_t)(args->para1);
960 if (io_num > PIN_NONE) {
961 return AT_RET_SYNTAX_ERROR;
962 }
963
964 io_mode = uapi_pin_get_mode(io_num);
965 if (io_mode >= PIN_MODE_MAX) {
966 return AT_RET_SYNTAX_ERROR;
967 }
968
969 io_dir = uapi_gpio_get_dir(io_num);
970
971 io_level = uapi_gpio_get_val((pin_t)io_num);
972
973 osal_printk("+RDGPIO:%d,%d,%d\r\n", io_num, io_dir, io_level);
974
975 return EXT_ERR_SUCCESS;
976 }
977 #endif
978
at_rdgpio(const rdgpio_args_t * args)979 at_ret_t at_rdgpio(const rdgpio_args_t *args)
980 {
981 #ifdef CONFIG_DRIVER_SUPPORT_GPIO
982 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
983 if (at_setup_gpiord_cmd(argc, args) != AT_RET_OK) {
984 return AT_RET_SYNTAX_ERROR;
985 }
986 #else
987 unused(args);
988 #endif
989
990 return AT_RET_OK;
991 }
992
cmd_set_pm(const pm_args_t * args)993 at_ret_t cmd_set_pm(const pm_args_t *args)
994 {
995 unused(args);
996 #if defined(ENABLE_LOW_POWER) && (ENABLE_LOW_POWER == YES)
997 bool open_pm = (args->para1 == 0) ? false : true;
998 idle_set_open_pm(open_pm);
999 #endif
1000 return AT_RET_OK;
1001 }
1002
1003 // at help dump cmd lists
at_help(void)1004 at_ret_t at_help(void)
1005 {
1006 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1007 td_u32 i;
1008 td_u32 cnt = at_cmd_get_entry_total();
1009 td_u32 total = 0;
1010 at_cmd_entry_t *cmd_entry = NULL;
1011 at_cmd_entry_t **cmd_tbl = (at_cmd_entry_t **)malloc(sizeof(at_cmd_entry_t *) * cnt);
1012
1013 if (cmd_tbl == TD_NULL) {
1014 return AT_RET_MALLOC_ERROR;
1015 }
1016 if (at_cmd_get_all_entrys((const at_cmd_entry_t **)cmd_tbl, cnt) != cnt) {
1017 free(cmd_tbl);
1018 return AT_RET_MEM_API_ERROR;
1019 }
1020 osal_printk("+HELP:cmd cnt:%d\r\n", cnt);
1021 for (i = 0; i < cnt; ++i) {
1022 cmd_entry = (at_cmd_entry_t *)cmd_tbl[i];
1023 osal_printk("AT+%-28s ", cmd_entry->name);
1024 total++;
1025 if (total % 3 == 0) { /* 3 entrys per newline */
1026 osal_printk("\r\n");
1027 }
1028 }
1029 free(cmd_tbl);
1030 #endif
1031 return AT_RET_OK;
1032 }
1033
1034 // dump last system crash info
at_get_dump(void)1035 at_ret_t at_get_dump(void)
1036 {
1037 #ifdef CONFIG_SUPPORT_CRASHINFO_SAVE_TO_FLASH
1038 bool hascrashinfo = crashinfo_status_get();
1039 if (hascrashinfo == false) {
1040 osal_printk("No crash dump found!\r\n");
1041 return AT_RET_OK;
1042 }
1043 crashinfo_dump();
1044 #else
1045 osal_printk("No crash dump found!\r\n");
1046 #endif
1047 return AT_RET_OK;
1048 }
1049 // reboot system
at_exe_reset_cmd(void)1050 at_ret_t at_exe_reset_cmd(void)
1051 {
1052 uapi_watchdog_disable();
1053 /* Wait for 3000 us until the AT print is complete. */
1054 // call LOS_TaskDelay to wait
1055 plt_reboot();
1056 return AT_RET_OK;
1057 }
1058
at_set_reset_cmd(const reboot_args_t * args)1059 at_ret_t at_set_reset_cmd(const reboot_args_t *args)
1060 {
1061 UINT32 delay;
1062
1063 uapi_watchdog_disable();
1064
1065 delay = strtoul(args->delay_time,NULL, 10);
1066 osal_printk("OK %d \r\n", delay);
1067 LOS_TaskDelay(delay);
1068
1069 plt_reboot();
1070 return AT_RET_OK;
1071 }
1072
at_copy_tm(struct tm * dest_tm,const struct tm * src_tm)1073 static void at_copy_tm(struct tm *dest_tm, const struct tm *src_tm)
1074 {
1075 if (src_tm == NULL) {
1076 (void)memset_s(dest_tm, sizeof(struct tm), 0, sizeof(struct tm));
1077 } else {
1078 dest_tm->tm_sec = src_tm->tm_sec;
1079 dest_tm->tm_min = src_tm->tm_min;
1080 dest_tm->tm_hour = src_tm->tm_hour;
1081 dest_tm->tm_mday = src_tm->tm_mday;
1082 dest_tm->tm_mon = src_tm->tm_mon;
1083 dest_tm->tm_year = src_tm->tm_year;
1084 dest_tm->tm_wday = src_tm->tm_wday;
1085 dest_tm->tm_yday = src_tm->tm_yday;
1086 dest_tm->tm_isdst = src_tm->tm_isdst;
1087 dest_tm->tm_gmtoff = src_tm->tm_gmtoff;
1088 dest_tm->tm_zone = src_tm->tm_zone;
1089 }
1090 }
1091
at_str_to_tm(const char * str,struct tm * tm)1092 static at_ret_t at_str_to_tm(const char *str, struct tm *tm)
1093 {
1094 CHAR *ret = NULL;
1095 size_t para_len = strlen(str);
1096 if (para_len == 8) { /* 8:Time format string length, such as hh:mm:ss or yyyymmdd */
1097 if (str[2] == ':') { /* 2:Index of Eigenvalues */
1098 ret = strptime(str, "%H:%M:%S", tm);
1099 } else {
1100 ret = strptime(str, "%Y%m%d", tm);
1101 }
1102 } else if (para_len == 10) { /* 10:Time format string length,such as yyyy/mm/dd */
1103 ret = strptime(str, "%Y/%m/%d", tm);
1104 } else if (para_len == 5) { /* 5:Time format string length,such as hh:mm or mm/dd */
1105 if (str[2] == ':') { /* 2:Index of Eigenvalues */
1106 ret = strptime(str, "%H:%M", tm);
1107 } else if (str[2] == '/') { /* 2:Index of Eigenvalues */
1108 ret = strptime(str, "%m/%d", tm);
1109 }
1110 } else if (para_len == 7) { /* 7:Time format string length,such as yyyy/mm */
1111 if (str[4] == '/') { /* 4:Index of Eigenvalues */
1112 ret = strptime(str, "%Y/%m", tm);
1113 }
1114 }
1115
1116 if (tm->tm_year < 70) { /* 70:the year is starting in 1970,tm_year must be greater than 70 */
1117 osal_printk("\nUsage: date -s set system time range from 1970.\n");
1118 return AT_RET_SYNTAX_ERROR;
1119 }
1120
1121 if (tm->tm_mday > g_mon_lengths[(INT32)leap_year(tm->tm_year + DATE_BASE_YEAR)][tm->tm_mon]) {
1122 return AT_RET_SYNTAX_ERROR;
1123 }
1124
1125 if ((tm->tm_sec < 0) || (tm->tm_sec > 59)) { /* Seconds (0-59), leap seconds shall not be used when set time. */
1126 return AT_RET_SYNTAX_ERROR;
1127 }
1128 return (ret == NULL) ? AT_RET_SYNTAX_ERROR : AT_RET_OK;
1129 }
1130
at_date_cmd(void)1131 at_ret_t at_date_cmd(void)
1132 {
1133 struct timeval64 now_time = {0};
1134
1135 if (gettimeofday64(&now_time, NULL) != 0) {
1136 return AT_RET_SYNTAX_ERROR;
1137 }
1138 osal_printk("%s\n", ctime64(&now_time.tv_sec));
1139
1140 return AT_RET_OK;
1141 }
1142
at_date_set_cmd(const date_args_t * args)1143 at_ret_t at_date_set_cmd(const date_args_t *args)
1144 {
1145 struct tm tm = {0};
1146 struct timeval64 now_time = {0};
1147 struct timeval64 set_time = {0};
1148
1149 if (gettimeofday64(&now_time, NULL) != 0) {
1150 osal_printk("set_time failed...\n");
1151 return AT_RET_SYNTAX_ERROR;
1152 }
1153
1154 set_time.tv_usec = now_time.tv_usec;
1155 at_copy_tm(&tm, localtime64(&now_time.tv_sec));
1156
1157 if (at_str_to_tm(args->para1, &tm) != AT_RET_OK) {
1158 osal_printk("at_str_to_tm failed...\n");
1159 return AT_RET_SYNTAX_ERROR;
1160 }
1161
1162 set_time.tv_sec = mktime64(&tm);
1163 if (set_time.tv_sec == -1) {
1164 osal_printk("mktime failed...\n");
1165 return AT_RET_SYNTAX_ERROR;
1166 }
1167
1168 if (settimeofday64(&set_time, NULL) != 0) {
1169 osal_printk("settime failed...\n");
1170 return AT_RET_SYNTAX_ERROR;
1171 }
1172
1173 at_date_cmd();
1174
1175 return AT_RET_OK;
1176 }
1177
1178 #define EFUSE_MFG_FLAG_ID_1 161
1179 #define EFUSE_MFG_FLAG_ID_2 179
1180 #define EFUSE_MFG_FLAG_ID_3 197
1181 #define EFUSE_MFG_FLAG_BIT_POS 7
1182 #define EFUSE_GROUP_MAX 3
cmd_write_mfg_flag(void)1183 at_ret_t cmd_write_mfg_flag(void)
1184 {
1185 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1186 td_u8 id[EFUSE_GROUP_MAX] = {EFUSE_MFG_FLAG_ID_1, EFUSE_MFG_FLAG_ID_2, EFUSE_MFG_FLAG_ID_3};
1187 td_u8 index;
1188 td_u8 value = 0;
1189 bool writable = false;
1190
1191 for (index = 0; index < EFUSE_GROUP_MAX; ++index) {
1192 if (uapi_efuse_read_bit(&value, id[index], EFUSE_MFG_FLAG_BIT_POS) != AT_RET_OK) {
1193 return AT_RET_SYNTAX_ERROR;
1194 }
1195 if (value != 0) {
1196 continue;
1197 }
1198 if (uapi_efuse_write_bit(id[index], EFUSE_MFG_FLAG_BIT_POS) != AT_RET_OK) {
1199 return AT_RET_SYNTAX_ERROR;
1200 }
1201 writable = true;
1202 break;
1203 }
1204 if (writable == false) {
1205 osal_printk("mfg flag no remain left\r\n");
1206 return AT_RET_SYNTAX_ERROR;
1207 }
1208 #endif
1209 return AT_RET_OK;
1210 }
1211 #define DIE_ID_LENGTH 21
cmd_get_dieid(void)1212 at_ret_t cmd_get_dieid(void)
1213 {
1214 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1215 td_u32 index;
1216 td_u8 die_id[DIE_ID_LENGTH] = {0};
1217
1218 if (uapi_efuse_read_buffer(die_id, 0, sizeof(die_id)) != AT_RET_OK) {
1219 return AT_RET_SYNTAX_ERROR;
1220 }
1221 osal_printk("OK\r\n");
1222 osal_printk("CHIP_ID: 0x%02x\r\n", die_id[0]);
1223 osal_printk("DIE_ID: 0x: ", die_id[0]);
1224 for (index = 1; index < sizeof(die_id); ++index) {
1225 osal_printk("%02x", die_id[index]);
1226 }
1227 osal_printk("OK\r\n");
1228 #endif
1229 return AT_RET_OK;
1230 }
1231
cmd_set_customer_rsvd_efuse(const customer_rsvd_efuse_args_t * args)1232 at_ret_t cmd_set_customer_rsvd_efuse(const customer_rsvd_efuse_args_t *args)
1233 {
1234 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1235 td_s32 argc = at_plt_convert_bin_to_dec((td_s32)args->para_map);
1236 errcode_t ret;
1237 td_u8 key[CUSTOM_RESVED_EFUSE_BYTE_LEN];
1238 td_u32 len = 0;
1239 td_u8 tmp_data;
1240
1241 if (argc != 1) {
1242 return AT_RET_SYNTAX_ERROR;
1243 }
1244 if ((args->para1[0] != '0') && (args->para1[1] != 'x')) {
1245 return AT_RET_CMD_PARA_ERROR;
1246 }
1247
1248 len = strlen((char *)(args->para1 + 2)); /* 2:偏移2个字符 */
1249 if (len != CUSTOM_RESVED_EFUSE_BYTE_LEN * 2) { /* 2:乘2 */
1250 return AT_RET_CMD_PARA_ERROR;
1251 }
1252 memset_s(key, CUSTOM_RESVED_EFUSE_BYTE_LEN, 0, CUSTOM_RESVED_EFUSE_BYTE_LEN);
1253 at_str_to_hex((char *)(args->para1 + 2), len, key); /* 2:偏移2个字符 */
1254 for (td_u8 index = 0; index < (CUSTOM_RESVED_EFUSE_BYTE_LEN >> 1); index++) {
1255 tmp_data = key[index];
1256 key[index] = key[CUSTOM_RESVED_EFUSE_BYTE_LEN - 1 - index];
1257 key[CUSTOM_RESVED_EFUSE_BYTE_LEN - 1 - index] = tmp_data;
1258 }
1259 ret = efuse_write_customer_rsvd_efuse(key, CUSTOM_RESVED_EFUSE_BYTE_LEN);
1260 if (ret != ERRCODE_SUCC) {
1261 osal_printk("SET CUSTOMER RSVD EFUSE ERROR, ret : 0x%x\r\n", ret);
1262 return AT_RET_CMD_PARA_ERROR;
1263 }
1264 osal_printk("OK\r\n");
1265 #else
1266 unused(args);
1267 #endif
1268 return AT_RET_OK;
1269 }
1270
cmd_get_customer_rsvd_efuse(void)1271 at_ret_t cmd_get_customer_rsvd_efuse(void)
1272 {
1273 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1274 errcode_t ret;
1275 td_u8 key[CUSTOM_RESVED_EFUSE_BYTE_LEN];
1276 td_u32 index;
1277
1278 memset_s(key, CUSTOM_RESVED_EFUSE_BYTE_LEN, 0, CUSTOM_RESVED_EFUSE_BYTE_LEN);
1279 ret = efuse_read_item(EFUSE_CUSTOM_RESVED_ID, key, sizeof(key));
1280 if (ret != EXT_ERR_SUCCESS) {
1281 osal_printk("READ EFUSE CUSTOM RESVED ERROR, ret : 0x%x\r\n", ret);
1282 return AT_RET_SYNTAX_ERROR;
1283 }
1284 osal_printk("OK\r\n");
1285 osal_printk("RESERVED EFUSE:0x");
1286 for (index = sizeof(key); index > 0; index--) {
1287 osal_printk("%02x", key[index - 1]);
1288 }
1289 osal_printk("\r\n");
1290 #endif
1291 return AT_RET_OK;
1292 }
1293
cmd_disable_ssi_jtag(void)1294 at_ret_t cmd_disable_ssi_jtag(void)
1295 {
1296 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1297 errcode_t ret;
1298
1299 ret = efuse_write_jtag_ssi();
1300 if (ret != ERRCODE_SUCC) {
1301 osal_printk("SET EFUSE SSI JTAG ERROR, ret : 0x%x\r\n", ret);
1302 return AT_RET_CMD_PARA_ERROR;
1303 }
1304 osal_printk("OK\r\n");
1305 #endif
1306 return AT_RET_OK;
1307 }
1308
cmd_get_ssi_jtag_status(void)1309 at_ret_t cmd_get_ssi_jtag_status(void)
1310 {
1311 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1312 errcode_t ret;
1313 td_u8 ssi_jtag = 0;
1314
1315 ret = efuse_read_jtag_ssi(&ssi_jtag, sizeof(ssi_jtag));
1316 if (ret != EXT_ERR_SUCCESS) {
1317 osal_printk("READ EFUSE SSI JTAG ERROR, ret : 0x%x\r\n", ret);
1318 return AT_RET_SYNTAX_ERROR;
1319 }
1320 osal_printk("OK\r\n");
1321 osal_printk("SSI JTAG: %d\r\n", ssi_jtag);
1322 #endif
1323 return AT_RET_OK;
1324 }
1325
cmd_set_hash_root_public_key(const pubkey_args_t * args)1326 at_ret_t cmd_set_hash_root_public_key(const pubkey_args_t *args)
1327 {
1328 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1329 errcode_t ret;
1330 td_u8 key[HASH_ROOT_PUBLIC_KEY_LEN];
1331 td_u32 len = 0;
1332
1333 if ((args->para1[0] != '0') && (args->para1[1] != 'x')) {
1334 return AT_RET_CMD_PARA_ERROR;
1335 }
1336
1337 len = strlen((char *)(args->para1 + 2)); /* 2:偏移2个字符 */
1338 if (len != HASH_ROOT_PUBLIC_KEY_LEN * 2) { /* 2:乘2 */
1339 return AT_RET_CMD_PARA_ERROR;
1340 }
1341 memset_s(key, sizeof(key), 0, sizeof(key));
1342 at_str_to_hex((char *)(args->para1 + 2), len, key); /* 2:偏移2个字符 */
1343 ret = efuse_write_hash_root_public_key(key, sizeof(key));
1344 if (ret != ERRCODE_SUCC) {
1345 osal_printk("SET EFUSE KEY ERROR, ret : 0x%x\r\n", ret);
1346 return AT_RET_CMD_PARA_ERROR;
1347 }
1348 osal_printk("OK\r\n");
1349 #else
1350 unused(args);
1351 #endif
1352 return AT_RET_OK;
1353 }
1354
cmd_get_hash_root_public_key(void)1355 at_ret_t cmd_get_hash_root_public_key(void)
1356 {
1357 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1358 errcode_t ret;
1359 td_u8 key[HASH_ROOT_PUBLIC_KEY_LEN];
1360 td_u32 index;
1361
1362 memset_s(key, sizeof(key), 0, sizeof(key));
1363 ret = efuse_read_hash_root_public_key(key, sizeof(key));
1364 if (ret != EXT_ERR_SUCCESS) {
1365 osal_printk("READ EFUSE HASH ROOT PUBLIC KEY ERROR, ret : 0x%x\r\n", ret);
1366 return AT_RET_SYNTAX_ERROR;
1367 }
1368 osal_printk("OK\r\n");
1369 osal_printk("KEY:");
1370 for (index = 0; index < sizeof(key); index++) {
1371 osal_printk("%02x", key[index]);
1372 }
1373 osal_printk("\r\n");
1374 #endif
1375 return AT_RET_OK;
1376 }
1377
cmd_sec_verify_enable(void)1378 at_ret_t cmd_sec_verify_enable(void)
1379 {
1380 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1381 errcode_t ret;
1382
1383 ret = efuse_write_sec_verify();
1384 if (ret != ERRCODE_SUCC) {
1385 osal_printk("SET EFUSE SEC VERIFY ERROR, ret : 0x%x\r\n", ret);
1386 return AT_RET_CMD_PARA_ERROR;
1387 }
1388 osal_printk("OK\r\n");
1389 #endif
1390 return AT_RET_OK;
1391 }
1392
cmd_get_sec_verify_status(void)1393 at_ret_t cmd_get_sec_verify_status(void)
1394 {
1395 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1396 errcode_t ret;
1397 td_u8 sec_verify = 0;
1398
1399 ret = efuse_read_sec_verify(&sec_verify, sizeof(sec_verify));
1400 if (ret != EXT_ERR_SUCCESS) {
1401 osal_printk("READ EFUSE SEC VERIFY ERROR, ret : 0x%x\r\n", ret);
1402 return AT_RET_SYNTAX_ERROR;
1403 }
1404 osal_printk("OK\r\n");
1405 osal_printk("SEC VERIFY: %d\r\n", sec_verify);
1406 #endif
1407 return AT_RET_OK;
1408 }
1409
plt_flash_read(const flashread_args_t * args)1410 at_ret_t plt_flash_read(const flashread_args_t *args)
1411 {
1412 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1413 errcode_t ret;
1414 td_u8 *data = TD_NULL;
1415 td_u32 index;
1416
1417 data = (td_u8 *)malloc(args->length);
1418 if (data == TD_NULL) {
1419 free(data);
1420 return AT_RET_SYNTAX_ERROR;
1421 }
1422 ret = plt_flash_read_data(args->addr, args->length, data);
1423 if (ret != EXT_ERR_SUCCESS) {
1424 free(data);
1425 osal_printk("plt_flash_read_data error, ret: 0x%x\r\n", ret);
1426 return AT_RET_SYNTAX_ERROR;
1427 }
1428 for (index = 0; index < (td_u32)args->length; ++index) {
1429 print_str("%x ", data[index]);
1430 }
1431 print_str("\r\n", data[index]);
1432 free(data);
1433 #else
1434 unused(args);
1435 #endif
1436 return AT_RET_OK;
1437 }
1438
1439 #define FLASH_DATA_MAX_LENGTH 3
plt_flash_write(const flashwrite_args_t * args)1440 at_ret_t plt_flash_write(const flashwrite_args_t *args)
1441 {
1442 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1443 errcode_t ret;
1444 td_u32 len = 0;
1445 td_u32 left = 0;
1446 td_u8 *data = TD_NULL;
1447
1448 len = strlen((char *)(args->data));
1449 if (len != (td_u32)(args->length * 2)) { /* 2:乘2 */
1450 return AT_RET_CMD_PARA_ERROR;
1451 }
1452 data = (td_u8 *)malloc(args->length);
1453 if (data == TD_NULL) {
1454 free(data);
1455 return AT_RET_SYNTAX_ERROR;
1456 }
1457 at_str_to_hex((char *)(args->data), len, data);
1458 ret = plt_flash_write_data(args->addr, args->length, data, &left);
1459 if (ret != EXT_ERR_SUCCESS) {
1460 free(data);
1461 osal_printk("plt_flash_write error, ret: 0x%x\r\n", ret);
1462 return AT_RET_SYNTAX_ERROR;
1463 }
1464 osal_printk("plt_flash_write left:%d\r\n", left);
1465 free(data);
1466 #else
1467 unused(args);
1468 #endif
1469 return AT_RET_OK;
1470 }
1471
save_license(const license_args_t * args)1472 at_ret_t save_license(const license_args_t *args)
1473 {
1474 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
1475 uint32_t value_length = 0;
1476 char *tmp = at_parse_string((char *)(args->license), &value_length);
1477 if (tmp == NULL) {
1478 return AT_RET_SYNTAX_ERROR;
1479 }
1480 partition_information_t info;
1481 errcode_t ret_val = uapi_partition_get_info(PARTITION_CUSTOMER_FACTORY, &info);
1482 if (ret_val != ERRCODE_SUCC || info.part_info.addr_info.size == 0) {
1483 return AT_RET_SYNTAX_ERROR;
1484 }
1485 ret_val = uapi_sfc_reg_erase(info.part_info.addr_info.addr, info.part_info.addr_info.size);
1486 if (ret_val != ERRCODE_SUCC) {
1487 return AT_RET_SYNTAX_ERROR;
1488 }
1489 ret_val = uapi_sfc_reg_write(info.part_info.addr_info.addr, (uint8_t *)tmp, value_length);
1490 if (ret_val != ERRCODE_SUCC) {
1491 return AT_RET_SYNTAX_ERROR;
1492 }
1493 #else
1494 unused(args);
1495 #endif
1496 return AT_RET_OK;
1497 }
1498