11bd4fe43Sopenharmony_ci/* 21bd4fe43Sopenharmony_ci * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 31bd4fe43Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 41bd4fe43Sopenharmony_ci * you may not use this file except in compliance with the License. 51bd4fe43Sopenharmony_ci * You may obtain a copy of the License at 61bd4fe43Sopenharmony_ci * 71bd4fe43Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 81bd4fe43Sopenharmony_ci * 91bd4fe43Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 101bd4fe43Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 111bd4fe43Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 121bd4fe43Sopenharmony_ci * See the License for the specific language governing permissions and 131bd4fe43Sopenharmony_ci * limitations under the License. 141bd4fe43Sopenharmony_ci */ 151bd4fe43Sopenharmony_ci 161bd4fe43Sopenharmony_ci#include <hi_stdlib.h> 171bd4fe43Sopenharmony_ci#include <at.h> 181bd4fe43Sopenharmony_ci#include <at_cmd.h> 191bd4fe43Sopenharmony_ci#include <at_parse.h> 201bd4fe43Sopenharmony_ci#include "hi_config.h" 211bd4fe43Sopenharmony_ci 221bd4fe43Sopenharmony_ci#include "stdio.h" 231bd4fe43Sopenharmony_ci#include "string.h" 241bd4fe43Sopenharmony_ci#include "malloc.h" 251bd4fe43Sopenharmony_ci#include "stdarg.h" 261bd4fe43Sopenharmony_ci#include "securec.h" 271bd4fe43Sopenharmony_ci 281bd4fe43Sopenharmony_ci#ifdef __cplusplus 291bd4fe43Sopenharmony_ci#if __cplusplus 301bd4fe43Sopenharmony_ciextern "C" { 311bd4fe43Sopenharmony_ci#endif 321bd4fe43Sopenharmony_ci#endif 331bd4fe43Sopenharmony_ci 341bd4fe43Sopenharmony_ci#define AT_SSID_MAX_LEN 32 351bd4fe43Sopenharmony_ci 361bd4fe43Sopenharmony_ciat_cmd_ctrl g_at_ctrl = { 371bd4fe43Sopenharmony_ci .at_state = AT_IDLE, 381bd4fe43Sopenharmony_ci .send_len = 0, 391bd4fe43Sopenharmony_ci .trans_len = 0, 401bd4fe43Sopenharmony_ci .is_first_recv_data = HI_TRUE, 411bd4fe43Sopenharmony_ci .is_first_over_data = HI_TRUE, 421bd4fe43Sopenharmony_ci .is_recv_end_char_flag = 0, 431bd4fe43Sopenharmony_ci}; 441bd4fe43Sopenharmony_ci 451bd4fe43Sopenharmony_cihi_u32 at_cmd_excute(const at_cmd_func *cmd_func, at_cmd_attr *cmd_parsed) 461bd4fe43Sopenharmony_ci{ 471bd4fe43Sopenharmony_ci hi_u32 ret; 481bd4fe43Sopenharmony_ci 491bd4fe43Sopenharmony_ci if (cmd_func == HI_NULL || cmd_parsed == HI_NULL) { 501bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 511bd4fe43Sopenharmony_ci } 521bd4fe43Sopenharmony_ci 531bd4fe43Sopenharmony_ci if (cmd_parsed->at_cmd_type == AT_CMD_TYPE_TEST) { 541bd4fe43Sopenharmony_ci if (cmd_func->at_test_cmd) { 551bd4fe43Sopenharmony_ci ret = cmd_func->at_test_cmd((hi_s32)cmd_parsed->at_param_cnt, 561bd4fe43Sopenharmony_ci (const hi_char **)&cmd_parsed->param_array[0]); 571bd4fe43Sopenharmony_ci } else { 581bd4fe43Sopenharmony_ci at_printf("COMMAND TYPE NOT SUPPORT!\r\n"); 591bd4fe43Sopenharmony_ci ret = HI_ERR_FAILURE; 601bd4fe43Sopenharmony_ci at_printf("err at %s line: %d\n", __FUNCTION__, __LINE__); 611bd4fe43Sopenharmony_ci } 621bd4fe43Sopenharmony_ci } else if (cmd_parsed->at_cmd_type == AT_CMD_TYPE_QUERY) { 631bd4fe43Sopenharmony_ci if (cmd_func->at_query_cmd) { 641bd4fe43Sopenharmony_ci ret = cmd_func->at_query_cmd((hi_s32)cmd_parsed->at_param_cnt, 651bd4fe43Sopenharmony_ci (const hi_char **)&cmd_parsed->param_array[0]); 661bd4fe43Sopenharmony_ci } else { 671bd4fe43Sopenharmony_ci at_printf("COMMAND TYPE NOT SUPPORT!\r\n"); 681bd4fe43Sopenharmony_ci ret = HI_ERR_FAILURE; 691bd4fe43Sopenharmony_ci at_printf("err at %s line: %d\n", __FUNCTION__, __LINE__); 701bd4fe43Sopenharmony_ci } 711bd4fe43Sopenharmony_ci } else if (cmd_parsed->at_cmd_type == AT_CMD_TYPE_SETUP) { 721bd4fe43Sopenharmony_ci if (cmd_func->at_setup_cmd) { 731bd4fe43Sopenharmony_ci ret = cmd_func->at_setup_cmd((hi_s32)cmd_parsed->at_param_cnt, 741bd4fe43Sopenharmony_ci (const hi_char **)&cmd_parsed->param_array[0]); 751bd4fe43Sopenharmony_ci } else { 761bd4fe43Sopenharmony_ci at_printf("COMMAND TYPE NOT SUPPORT!\r\n"); 771bd4fe43Sopenharmony_ci ret = HI_ERR_FAILURE; 781bd4fe43Sopenharmony_ci at_printf("err at %s line: %d\n", __FUNCTION__, __LINE__); 791bd4fe43Sopenharmony_ci } 801bd4fe43Sopenharmony_ci } else if (cmd_parsed->at_cmd_type == AT_CMD_TYPE_EXE) { 811bd4fe43Sopenharmony_ci if (cmd_func->at_exe_cmd) { 821bd4fe43Sopenharmony_ci ret = cmd_func->at_exe_cmd((hi_s32)cmd_parsed->at_param_cnt, 831bd4fe43Sopenharmony_ci (const hi_char **)&cmd_parsed->param_array[0]); 841bd4fe43Sopenharmony_ci } else { 851bd4fe43Sopenharmony_ci at_printf("COMMAND TYPE NOT SUPPORT!\r\n"); 861bd4fe43Sopenharmony_ci ret = HI_ERR_FAILURE; 871bd4fe43Sopenharmony_ci at_printf("err at %s line: %d\n", __FUNCTION__, __LINE__); 881bd4fe43Sopenharmony_ci } 891bd4fe43Sopenharmony_ci } else { 901bd4fe43Sopenharmony_ci at_printf("COMMAND TYPE NOT SUPPORT!\r\n"); 911bd4fe43Sopenharmony_ci ret = HI_ERR_FAILURE; 921bd4fe43Sopenharmony_ci at_printf("err at %s line: %d\n", __FUNCTION__, __LINE__); 931bd4fe43Sopenharmony_ci } 941bd4fe43Sopenharmony_ci 951bd4fe43Sopenharmony_ci return ret; 961bd4fe43Sopenharmony_ci} 971bd4fe43Sopenharmony_ci 981bd4fe43Sopenharmony_cistatic hi_void at_get_cmd_name(hi_char *cmd_line, at_cmd_attr *cmd_parsed) 991bd4fe43Sopenharmony_ci{ 1001bd4fe43Sopenharmony_ci hi_s8 n = 0; 1011bd4fe43Sopenharmony_ci 1021bd4fe43Sopenharmony_ci for (hi_u8 i = AT_CMD_MAX_LEN; i > 0; i--) { 1031bd4fe43Sopenharmony_ci if ((*cmd_line == '\0') || (*cmd_line == '=') || (*cmd_line == '?')) { 1041bd4fe43Sopenharmony_ci cmd_parsed->at_cmd_len = n; 1051bd4fe43Sopenharmony_ci return; 1061bd4fe43Sopenharmony_ci } else { 1071bd4fe43Sopenharmony_ci cmd_parsed->cmd_name[n] = *cmd_line; 1081bd4fe43Sopenharmony_ci cmd_line++; 1091bd4fe43Sopenharmony_ci n++; 1101bd4fe43Sopenharmony_ci } 1111bd4fe43Sopenharmony_ci } 1121bd4fe43Sopenharmony_ci 1131bd4fe43Sopenharmony_ci cmd_parsed->at_cmd_len = -1; 1141bd4fe43Sopenharmony_ci memset_s(cmd_parsed->cmd_name, AT_CMD_MAX_LEN, 0, AT_CMD_MAX_LEN); 1151bd4fe43Sopenharmony_ci} 1161bd4fe43Sopenharmony_ci 1171bd4fe43Sopenharmony_cihi_u32 at_func_process(hi_char *out_cmd_line, at_cmd_attr *cmd_parsed) 1181bd4fe43Sopenharmony_ci{ 1191bd4fe43Sopenharmony_ci hi_u32 ret; 1201bd4fe43Sopenharmony_ci at_cmd_func *cmd_func = HI_NULL; 1211bd4fe43Sopenharmony_ci at_get_cmd_name(out_cmd_line, cmd_parsed); 1221bd4fe43Sopenharmony_ci if (cmd_parsed->at_cmd_len != (-1)) { 1231bd4fe43Sopenharmony_ci cmd_func = at_find_proc_func(cmd_parsed); 1241bd4fe43Sopenharmony_ci } 1251bd4fe43Sopenharmony_ci 1261bd4fe43Sopenharmony_ci if (cmd_func != HI_NULL) { 1271bd4fe43Sopenharmony_ci ret = at_cmd_parse(out_cmd_line, cmd_parsed); 1281bd4fe43Sopenharmony_ci if (ret != HI_ERR_SUCCESS) { 1291bd4fe43Sopenharmony_ci at_printf("%s line: %d PARSE CMD FAIL!\r\n", __FUNCTION__, __LINE__); 1301bd4fe43Sopenharmony_ci return ret; 1311bd4fe43Sopenharmony_ci } 1321bd4fe43Sopenharmony_ci 1331bd4fe43Sopenharmony_ci ret = at_cmd_excute(cmd_func, cmd_parsed); 1341bd4fe43Sopenharmony_ci } else { 1351bd4fe43Sopenharmony_ci ret = HI_ERR_FAILURE; 1361bd4fe43Sopenharmony_ci at_printf("%s line: %d COMMAND NOT SUPPORT!\r\n", __FUNCTION__, __LINE__); 1371bd4fe43Sopenharmony_ci } 1381bd4fe43Sopenharmony_ci 1391bd4fe43Sopenharmony_ci return ret; 1401bd4fe43Sopenharmony_ci} 1411bd4fe43Sopenharmony_ci 1421bd4fe43Sopenharmony_cihi_u32 at_cmd_process(const hi_char *at_cmd_line) 1431bd4fe43Sopenharmony_ci{ 1441bd4fe43Sopenharmony_ci hi_u32 at_cmd_line_len; 1451bd4fe43Sopenharmony_ci hi_char *out_cmd_line = HI_NULL; 1461bd4fe43Sopenharmony_ci at_cmd_attr cmd_parsed = {0}; 1471bd4fe43Sopenharmony_ci hi_u32 ret; 1481bd4fe43Sopenharmony_ci 1491bd4fe43Sopenharmony_ci AT_ENTER; 1501bd4fe43Sopenharmony_ci if (at_cmd_line == HI_NULL) { 1511bd4fe43Sopenharmony_ci at_printf("INVALID NULL CMD!\r\n"); 1521bd4fe43Sopenharmony_ci AT_RESPONSE_ERROR; 1531bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 1541bd4fe43Sopenharmony_ci } 1551bd4fe43Sopenharmony_ci 1561bd4fe43Sopenharmony_ci at_cmd_line_len = (hi_u32)strlen(at_cmd_line) + 1; 1571bd4fe43Sopenharmony_ci out_cmd_line = (hi_char *)hi_malloc(HI_MOD_ID_SAL_DFX, at_cmd_line_len); 1581bd4fe43Sopenharmony_ci if (out_cmd_line == HI_NULL) { 1591bd4fe43Sopenharmony_ci at_printf("%s line%d NO ENOUGH MEMORY!\r\n", __FUNCTION__, __LINE__); 1601bd4fe43Sopenharmony_ci AT_RESPONSE_ERROR; 1611bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 1621bd4fe43Sopenharmony_ci } 1631bd4fe43Sopenharmony_ci memset_s(out_cmd_line, at_cmd_line_len, 0, at_cmd_line_len); 1641bd4fe43Sopenharmony_ci 1651bd4fe43Sopenharmony_ci ret = (hi_u32)strncpy_s(out_cmd_line, at_cmd_line_len, at_cmd_line, at_cmd_line_len - 1); 1661bd4fe43Sopenharmony_ci if (ret != EOK) { 1671bd4fe43Sopenharmony_ci at_printf("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret); 1681bd4fe43Sopenharmony_ci AT_RESPONSE_ERROR; 1691bd4fe43Sopenharmony_ci hi_free(HI_MOD_ID_SAL_DFX, out_cmd_line); 1701bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 1711bd4fe43Sopenharmony_ci } 1721bd4fe43Sopenharmony_ci out_cmd_line[at_cmd_line_len - 1] = '\0'; 1731bd4fe43Sopenharmony_ci 1741bd4fe43Sopenharmony_ci ret = at_func_process(out_cmd_line, &cmd_parsed); 1751bd4fe43Sopenharmony_ci if (ret != HI_ERR_SUCCESS && ret != HI_ERR_RECVING) { 1761bd4fe43Sopenharmony_ci at_printf("err at %s line: %d\n", __FUNCTION__, __LINE__); 1771bd4fe43Sopenharmony_ci AT_RESPONSE_ERROR; 1781bd4fe43Sopenharmony_ci } else if (ret == HI_ERR_RECVING) { 1791bd4fe43Sopenharmony_ci g_at_ctrl.at_state = AT_DATA_RECVING; 1801bd4fe43Sopenharmony_ci } else { 1811bd4fe43Sopenharmony_ci g_at_ctrl.at_state = AT_IDLE; 1821bd4fe43Sopenharmony_ci } 1831bd4fe43Sopenharmony_ci 1841bd4fe43Sopenharmony_ci hi_free(HI_MOD_ID_SAL_DFX, out_cmd_line); 1851bd4fe43Sopenharmony_ci out_cmd_line = HI_NULL; 1861bd4fe43Sopenharmony_ci 1871bd4fe43Sopenharmony_ci return ret; 1881bd4fe43Sopenharmony_ci} 1891bd4fe43Sopenharmony_ci 1901bd4fe43Sopenharmony_cihi_u32 at_param_null_check(hi_s32 argc, const hi_char **argv) 1911bd4fe43Sopenharmony_ci{ 1921bd4fe43Sopenharmony_ci for (hi_s32 i = 0; i < argc; i++) { 1931bd4fe43Sopenharmony_ci if (argv[i] == HI_NULL) { 1941bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 1951bd4fe43Sopenharmony_ci } 1961bd4fe43Sopenharmony_ci } 1971bd4fe43Sopenharmony_ci return HI_ERR_SUCCESS; 1981bd4fe43Sopenharmony_ci} 1991bd4fe43Sopenharmony_ci 2001bd4fe43Sopenharmony_cihi_u32 integer_check(const hi_char *val) 2011bd4fe43Sopenharmony_ci{ 2021bd4fe43Sopenharmony_ci hi_u32 len; 2031bd4fe43Sopenharmony_ci hi_u32 i; 2041bd4fe43Sopenharmony_ci hi_char *buf = (hi_char *)val; 2051bd4fe43Sopenharmony_ci if (buf == HI_NULL) { 2061bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 2071bd4fe43Sopenharmony_ci } 2081bd4fe43Sopenharmony_ci len = strlen(buf); 2091bd4fe43Sopenharmony_ci if ((*buf == '0') && (len != 1)) { 2101bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 2111bd4fe43Sopenharmony_ci } 2121bd4fe43Sopenharmony_ci for (i = 0; i < len; i++) { 2131bd4fe43Sopenharmony_ci if ((*buf < '0') || (*buf > '9')) { 2141bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 2151bd4fe43Sopenharmony_ci } 2161bd4fe43Sopenharmony_ci buf++; 2171bd4fe43Sopenharmony_ci } 2181bd4fe43Sopenharmony_ci return HI_ERR_SUCCESS; 2191bd4fe43Sopenharmony_ci} 2201bd4fe43Sopenharmony_ci 2211bd4fe43Sopenharmony_cistatic hi_u32 at_check_mac_elem(const hi_char elem) 2221bd4fe43Sopenharmony_ci{ 2231bd4fe43Sopenharmony_ci if (elem >= '0' && elem <= '9') { 2241bd4fe43Sopenharmony_ci return HI_ERR_SUCCESS; 2251bd4fe43Sopenharmony_ci } else if (elem >= 'A' && elem <= 'F') { 2261bd4fe43Sopenharmony_ci return HI_ERR_SUCCESS; 2271bd4fe43Sopenharmony_ci } else if (elem >= 'a' && elem <= 'f') { 2281bd4fe43Sopenharmony_ci return HI_ERR_SUCCESS; 2291bd4fe43Sopenharmony_ci } else if (elem == ':') { 2301bd4fe43Sopenharmony_ci return HI_ERR_SUCCESS; 2311bd4fe43Sopenharmony_ci } 2321bd4fe43Sopenharmony_ci 2331bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 2341bd4fe43Sopenharmony_ci} 2351bd4fe43Sopenharmony_ci 2361bd4fe43Sopenharmony_cihi_u32 cmd_strtoaddr(const hi_char *param, hi_uchar *mac_addr, hi_u32 addr_len) 2371bd4fe43Sopenharmony_ci{ 2381bd4fe43Sopenharmony_ci hi_u32 cnt; 2391bd4fe43Sopenharmony_ci hi_char *tmp1 = (hi_char *)param; 2401bd4fe43Sopenharmony_ci hi_char *tmp2 = NULL; 2411bd4fe43Sopenharmony_ci hi_char *tmp3 = NULL; 2421bd4fe43Sopenharmony_ci 2431bd4fe43Sopenharmony_ci for (cnt = 0; cnt < 17; cnt++) { /* 17 */ 2441bd4fe43Sopenharmony_ci if (at_check_mac_elem(param[cnt]) != HI_ERR_SUCCESS) { 2451bd4fe43Sopenharmony_ci return HI_ERR_FAILURE; 2461bd4fe43Sopenharmony_ci } 2471bd4fe43Sopenharmony_ci } 2481bd4fe43Sopenharmony_ci 2491bd4fe43Sopenharmony_ci for (cnt = 0; cnt < (addr_len - 1); cnt++) { 2501bd4fe43Sopenharmony_ci tmp2 = (char*)strsep(&tmp1, ":"); 2511bd4fe43Sopenharmony_ci if (tmp2 == NULL) { 2521bd4fe43Sopenharmony_ci return HI_ERR_APP_INVALID_PARAMETER; 2531bd4fe43Sopenharmony_ci } 2541bd4fe43Sopenharmony_ci mac_addr[cnt] = (hi_uchar)strtoul(tmp2, &tmp3, 16); /* 16 */ 2551bd4fe43Sopenharmony_ci } 2561bd4fe43Sopenharmony_ci 2571bd4fe43Sopenharmony_ci if (tmp1 == NULL) { 2581bd4fe43Sopenharmony_ci return HI_ERR_APP_INVALID_PARAMETER; 2591bd4fe43Sopenharmony_ci } 2601bd4fe43Sopenharmony_ci mac_addr[cnt] = (hi_uchar)strtoul(tmp1, &tmp3, 16); /* 16 */ 2611bd4fe43Sopenharmony_ci return HI_ERR_SUCCESS; 2621bd4fe43Sopenharmony_ci} 2631bd4fe43Sopenharmony_ci 2641bd4fe43Sopenharmony_cichar *at_strrchr(const char *src, int c) 2651bd4fe43Sopenharmony_ci{ 2661bd4fe43Sopenharmony_ci return strrchr(src, c); 2671bd4fe43Sopenharmony_ci} 2681bd4fe43Sopenharmony_ci 2691bd4fe43Sopenharmony_civoid *at_malloc(size_t size) 2701bd4fe43Sopenharmony_ci{ 2711bd4fe43Sopenharmony_ci if (size > 4096) { /* max alloc mem 4096 */ 2721bd4fe43Sopenharmony_ci return NULL; 2731bd4fe43Sopenharmony_ci } 2741bd4fe43Sopenharmony_ci void *ptr = malloc(size); 2751bd4fe43Sopenharmony_ci return ptr; 2761bd4fe43Sopenharmony_ci} 2771bd4fe43Sopenharmony_ci 2781bd4fe43Sopenharmony_civoid at_free(char *ptr) 2791bd4fe43Sopenharmony_ci{ 2801bd4fe43Sopenharmony_ci if (ptr) { 2811bd4fe43Sopenharmony_ci free(ptr); 2821bd4fe43Sopenharmony_ci } 2831bd4fe43Sopenharmony_ci} 2841bd4fe43Sopenharmony_ci 2851bd4fe43Sopenharmony_cisize_t at_strlen(const char *src) 2861bd4fe43Sopenharmony_ci{ 2871bd4fe43Sopenharmony_ci return strlen(src); 2881bd4fe43Sopenharmony_ci} 2891bd4fe43Sopenharmony_ci 2901bd4fe43Sopenharmony_ciint at_pading(char *str, size_t size, const char *format, ...) 2911bd4fe43Sopenharmony_ci{ 2921bd4fe43Sopenharmony_ci va_list ap = NULL; 2931bd4fe43Sopenharmony_ci int ret; 2941bd4fe43Sopenharmony_ci 2951bd4fe43Sopenharmony_ci va_start(ap, format); 2961bd4fe43Sopenharmony_ci ret = vsnprintf_s(str, AT_SSID_MAX_LEN * 4 + 1, size, format, ap); /* 4 length */ 2971bd4fe43Sopenharmony_ci va_end(ap); 2981bd4fe43Sopenharmony_ci if (size > 0) { 2991bd4fe43Sopenharmony_ci str[size - 1] = '\0'; 3001bd4fe43Sopenharmony_ci } 3011bd4fe43Sopenharmony_ci return ret; 3021bd4fe43Sopenharmony_ci} 3031bd4fe43Sopenharmony_ci 3041bd4fe43Sopenharmony_cichar* at_dup_binstr(const char *src, size_t len) 3051bd4fe43Sopenharmony_ci{ 3061bd4fe43Sopenharmony_ci char *res = NULL; 3071bd4fe43Sopenharmony_ci int ret; 3081bd4fe43Sopenharmony_ci 3091bd4fe43Sopenharmony_ci if (src == NULL) { 3101bd4fe43Sopenharmony_ci return NULL; 3111bd4fe43Sopenharmony_ci } 3121bd4fe43Sopenharmony_ci res = at_malloc(len + 1); 3131bd4fe43Sopenharmony_ci if (res == NULL) { 3141bd4fe43Sopenharmony_ci return NULL; 3151bd4fe43Sopenharmony_ci } 3161bd4fe43Sopenharmony_ci ret = memcpy_s(res, len, src, len); 3171bd4fe43Sopenharmony_ci if (ret != EOK) { 3181bd4fe43Sopenharmony_ci at_free(res); 3191bd4fe43Sopenharmony_ci res = NULL; 3201bd4fe43Sopenharmony_ci return NULL; 3211bd4fe43Sopenharmony_ci } 3221bd4fe43Sopenharmony_ci res[len] = '\0'; 3231bd4fe43Sopenharmony_ci 3241bd4fe43Sopenharmony_ci return res; 3251bd4fe43Sopenharmony_ci} 3261bd4fe43Sopenharmony_ci 3271bd4fe43Sopenharmony_cistatic int at_hex2num(char c) 3281bd4fe43Sopenharmony_ci{ 3291bd4fe43Sopenharmony_ci if (c >= '0' && c <= '9') { 3301bd4fe43Sopenharmony_ci return c - '0'; 3311bd4fe43Sopenharmony_ci } 3321bd4fe43Sopenharmony_ci if (c >= 'a' && c <= 'f') { 3331bd4fe43Sopenharmony_ci return c - 'a' + 10; /* add 10 */ 3341bd4fe43Sopenharmony_ci } 3351bd4fe43Sopenharmony_ci if (c >= 'A' && c <= 'F') { 3361bd4fe43Sopenharmony_ci return c - 'A' + 10; /* add 10 */ 3371bd4fe43Sopenharmony_ci } 3381bd4fe43Sopenharmony_ci return -1; 3391bd4fe43Sopenharmony_ci} 3401bd4fe43Sopenharmony_ci 3411bd4fe43Sopenharmony_ciint at_hex2byte(const char *hex) 3421bd4fe43Sopenharmony_ci{ 3431bd4fe43Sopenharmony_ci int a, b; 3441bd4fe43Sopenharmony_ci a = at_hex2num(*hex++); 3451bd4fe43Sopenharmony_ci if (a < 0) { 3461bd4fe43Sopenharmony_ci return -1; 3471bd4fe43Sopenharmony_ci } 3481bd4fe43Sopenharmony_ci b = at_hex2num(*hex++); 3491bd4fe43Sopenharmony_ci if (b < 0) { 3501bd4fe43Sopenharmony_ci return -1; 3511bd4fe43Sopenharmony_ci } 3521bd4fe43Sopenharmony_ci return ((hi_u32)a << 4) | (hi_u32)b; /* 4 */ 3531bd4fe43Sopenharmony_ci} 3541bd4fe43Sopenharmony_ci 3551bd4fe43Sopenharmony_ci/** 3561bd4fe43Sopenharmony_ci * at_hexstr2bin - Convert ASCII hex string into binary data 3571bd4fe43Sopenharmony_ci * @hex: ASCII hex string (e.g., "01ab") 3581bd4fe43Sopenharmony_ci * @buf: Buffer for the binary data 3591bd4fe43Sopenharmony_ci * @len: Length of the text to convert in bytes (of buf); hex will be double 3601bd4fe43Sopenharmony_ci * this size 3611bd4fe43Sopenharmony_ci * Returns: 0 on success, -1 on failure (invalid hex string) 3621bd4fe43Sopenharmony_ci */ 3631bd4fe43Sopenharmony_ciint at_hexstr2bin(const char *hex, hi_u8 *buf, size_t len) 3641bd4fe43Sopenharmony_ci{ 3651bd4fe43Sopenharmony_ci size_t i; 3661bd4fe43Sopenharmony_ci const char *ipos = hex; 3671bd4fe43Sopenharmony_ci hi_u8 *opos = buf; 3681bd4fe43Sopenharmony_ci 3691bd4fe43Sopenharmony_ci for (i = 0; i < len; i++) { 3701bd4fe43Sopenharmony_ci int a = at_hex2byte(ipos); 3711bd4fe43Sopenharmony_ci if (a < 0) { 3721bd4fe43Sopenharmony_ci return -1; 3731bd4fe43Sopenharmony_ci } 3741bd4fe43Sopenharmony_ci *opos++ = a; 3751bd4fe43Sopenharmony_ci ipos += 2; /* add 2 */ 3761bd4fe43Sopenharmony_ci } 3771bd4fe43Sopenharmony_ci return 0; 3781bd4fe43Sopenharmony_ci} 3791bd4fe43Sopenharmony_ci 3801bd4fe43Sopenharmony_civoid at_printf_encode(char *txt, size_t maxlen, const hi_u8 *data, size_t len) 3811bd4fe43Sopenharmony_ci{ 3821bd4fe43Sopenharmony_ci char *end = txt + maxlen; 3831bd4fe43Sopenharmony_ci size_t i; 3841bd4fe43Sopenharmony_ci 3851bd4fe43Sopenharmony_ci for (i = 0; i < len; i++) { 3861bd4fe43Sopenharmony_ci if (txt + 4 >= end) { /* add 4 */ 3871bd4fe43Sopenharmony_ci break; 3881bd4fe43Sopenharmony_ci } 3891bd4fe43Sopenharmony_ci 3901bd4fe43Sopenharmony_ci switch (data[i]) { 3911bd4fe43Sopenharmony_ci case '\"': 3921bd4fe43Sopenharmony_ci *txt++ = '\\'; 3931bd4fe43Sopenharmony_ci *txt++ = '\"'; 3941bd4fe43Sopenharmony_ci break; 3951bd4fe43Sopenharmony_ci case '\\': 3961bd4fe43Sopenharmony_ci *txt++ = '\\'; 3971bd4fe43Sopenharmony_ci *txt++ = '\\'; 3981bd4fe43Sopenharmony_ci break; 3991bd4fe43Sopenharmony_ci case '\033': 4001bd4fe43Sopenharmony_ci *txt++ = '\\'; 4011bd4fe43Sopenharmony_ci *txt++ = 'e'; 4021bd4fe43Sopenharmony_ci break; 4031bd4fe43Sopenharmony_ci case '\n': 4041bd4fe43Sopenharmony_ci *txt++ = '\\'; 4051bd4fe43Sopenharmony_ci *txt++ = 'n'; 4061bd4fe43Sopenharmony_ci break; 4071bd4fe43Sopenharmony_ci case '\r': 4081bd4fe43Sopenharmony_ci *txt++ = '\\'; 4091bd4fe43Sopenharmony_ci *txt++ = 'r'; 4101bd4fe43Sopenharmony_ci break; 4111bd4fe43Sopenharmony_ci case '\t': 4121bd4fe43Sopenharmony_ci *txt++ = '\\'; 4131bd4fe43Sopenharmony_ci *txt++ = 't'; 4141bd4fe43Sopenharmony_ci break; 4151bd4fe43Sopenharmony_ci default: 4161bd4fe43Sopenharmony_ci if (data[i] >= 32 && data[i] <= 126) { /* range [32,126] */ 4171bd4fe43Sopenharmony_ci *txt++ = data[i]; 4181bd4fe43Sopenharmony_ci } else { 4191bd4fe43Sopenharmony_ci txt += at_pading(txt, end - txt, "\\x%02x", data[i]); 4201bd4fe43Sopenharmony_ci } 4211bd4fe43Sopenharmony_ci break; 4221bd4fe43Sopenharmony_ci } 4231bd4fe43Sopenharmony_ci } 4241bd4fe43Sopenharmony_ci 4251bd4fe43Sopenharmony_ci *txt = '\0'; 4261bd4fe43Sopenharmony_ci} 4271bd4fe43Sopenharmony_ci 4281bd4fe43Sopenharmony_cihi_void at_printf_decode_slash(hi_u8 *buf, const char **str_pos, size_t *str_len) 4291bd4fe43Sopenharmony_ci{ 4301bd4fe43Sopenharmony_ci const char *pos = *str_pos; 4311bd4fe43Sopenharmony_ci size_t len = *str_len; 4321bd4fe43Sopenharmony_ci int val; 4331bd4fe43Sopenharmony_ci 4341bd4fe43Sopenharmony_ci pos++; 4351bd4fe43Sopenharmony_ci switch (*pos) { 4361bd4fe43Sopenharmony_ci case '\\': 4371bd4fe43Sopenharmony_ci buf[len++] = '\\'; 4381bd4fe43Sopenharmony_ci pos++; 4391bd4fe43Sopenharmony_ci break; 4401bd4fe43Sopenharmony_ci case '"': 4411bd4fe43Sopenharmony_ci buf[len++] = '"'; 4421bd4fe43Sopenharmony_ci pos++; 4431bd4fe43Sopenharmony_ci break; 4441bd4fe43Sopenharmony_ci case 'n': 4451bd4fe43Sopenharmony_ci buf[len++] = '\n'; 4461bd4fe43Sopenharmony_ci pos++; 4471bd4fe43Sopenharmony_ci break; 4481bd4fe43Sopenharmony_ci case 'r': 4491bd4fe43Sopenharmony_ci buf[len++] = '\r'; 4501bd4fe43Sopenharmony_ci pos++; 4511bd4fe43Sopenharmony_ci break; 4521bd4fe43Sopenharmony_ci case 't': 4531bd4fe43Sopenharmony_ci buf[len++] = '\t'; 4541bd4fe43Sopenharmony_ci pos++; 4551bd4fe43Sopenharmony_ci break; 4561bd4fe43Sopenharmony_ci case 'e': 4571bd4fe43Sopenharmony_ci buf[len++] = '\033'; 4581bd4fe43Sopenharmony_ci pos++; 4591bd4fe43Sopenharmony_ci break; 4601bd4fe43Sopenharmony_ci case 'x': 4611bd4fe43Sopenharmony_ci pos++; 4621bd4fe43Sopenharmony_ci val = at_hex2byte(pos); 4631bd4fe43Sopenharmony_ci if (val < 0) { 4641bd4fe43Sopenharmony_ci val = at_hex2num(*pos); 4651bd4fe43Sopenharmony_ci if (val < 0) { 4661bd4fe43Sopenharmony_ci break; 4671bd4fe43Sopenharmony_ci } 4681bd4fe43Sopenharmony_ci buf[len++] = val; 4691bd4fe43Sopenharmony_ci pos++; 4701bd4fe43Sopenharmony_ci } else { 4711bd4fe43Sopenharmony_ci buf[len++] = val; 4721bd4fe43Sopenharmony_ci pos += 2; /* add 2 */ 4731bd4fe43Sopenharmony_ci } 4741bd4fe43Sopenharmony_ci break; 4751bd4fe43Sopenharmony_ci case '0': 4761bd4fe43Sopenharmony_ci case '1': 4771bd4fe43Sopenharmony_ci case '2': 4781bd4fe43Sopenharmony_ci case '3': 4791bd4fe43Sopenharmony_ci case '4': 4801bd4fe43Sopenharmony_ci case '5': 4811bd4fe43Sopenharmony_ci case '6': 4821bd4fe43Sopenharmony_ci case '7': 4831bd4fe43Sopenharmony_ci val = *pos++ - '0'; 4841bd4fe43Sopenharmony_ci if (*pos >= '0' && *pos <= '7') { 4851bd4fe43Sopenharmony_ci val = val * 8 + (*pos++ - '0'); /* 8 */ 4861bd4fe43Sopenharmony_ci } 4871bd4fe43Sopenharmony_ci if (*pos >= '0' && *pos <= '7') { 4881bd4fe43Sopenharmony_ci val = val * 8 + (*pos++ - '0'); /* 8 */ 4891bd4fe43Sopenharmony_ci } 4901bd4fe43Sopenharmony_ci buf[len++] = val; 4911bd4fe43Sopenharmony_ci break; 4921bd4fe43Sopenharmony_ci default: 4931bd4fe43Sopenharmony_ci break; 4941bd4fe43Sopenharmony_ci } 4951bd4fe43Sopenharmony_ci 4961bd4fe43Sopenharmony_ci *str_pos = pos; 4971bd4fe43Sopenharmony_ci *str_len = len; 4981bd4fe43Sopenharmony_ci} 4991bd4fe43Sopenharmony_ci 5001bd4fe43Sopenharmony_cisize_t at_printf_decode(hi_u8 *buf, size_t maxlen, const char *str) 5011bd4fe43Sopenharmony_ci{ 5021bd4fe43Sopenharmony_ci const char *pos = str; 5031bd4fe43Sopenharmony_ci size_t len = 0; 5041bd4fe43Sopenharmony_ci 5051bd4fe43Sopenharmony_ci while (*pos) { 5061bd4fe43Sopenharmony_ci if (len + 1 >= maxlen) { 5071bd4fe43Sopenharmony_ci break; 5081bd4fe43Sopenharmony_ci } 5091bd4fe43Sopenharmony_ci switch (*pos) { 5101bd4fe43Sopenharmony_ci case '\\': 5111bd4fe43Sopenharmony_ci at_printf_decode_slash(buf, &pos, &len); 5121bd4fe43Sopenharmony_ci break; 5131bd4fe43Sopenharmony_ci default: 5141bd4fe43Sopenharmony_ci buf[len++] = *pos++; 5151bd4fe43Sopenharmony_ci break; 5161bd4fe43Sopenharmony_ci } 5171bd4fe43Sopenharmony_ci } 5181bd4fe43Sopenharmony_ci if (maxlen > len) { 5191bd4fe43Sopenharmony_ci buf[len] = '\0'; 5201bd4fe43Sopenharmony_ci } 5211bd4fe43Sopenharmony_ci 5221bd4fe43Sopenharmony_ci return len; 5231bd4fe43Sopenharmony_ci} 5241bd4fe43Sopenharmony_ci 5251bd4fe43Sopenharmony_cichar* at_parse_string_normal(const char *value, size_t *len) 5261bd4fe43Sopenharmony_ci{ 5271bd4fe43Sopenharmony_ci const char *pos = NULL; 5281bd4fe43Sopenharmony_ci char *str = NULL; 5291bd4fe43Sopenharmony_ci 5301bd4fe43Sopenharmony_ci value++; 5311bd4fe43Sopenharmony_ci pos = at_strrchr(value, '"'); 5321bd4fe43Sopenharmony_ci if (pos == NULL || pos[1] != '\0') { 5331bd4fe43Sopenharmony_ci return NULL; 5341bd4fe43Sopenharmony_ci } 5351bd4fe43Sopenharmony_ci *len = pos - value; 5361bd4fe43Sopenharmony_ci str = at_dup_binstr(value, *len); 5371bd4fe43Sopenharmony_ci if (str == NULL) { 5381bd4fe43Sopenharmony_ci return NULL; 5391bd4fe43Sopenharmony_ci } 5401bd4fe43Sopenharmony_ci return str; 5411bd4fe43Sopenharmony_ci} 5421bd4fe43Sopenharmony_ci 5431bd4fe43Sopenharmony_cichar* at_parse_string_with_p(const char *value, size_t *len) 5441bd4fe43Sopenharmony_ci{ 5451bd4fe43Sopenharmony_ci const char *pos = NULL; 5461bd4fe43Sopenharmony_ci char *tstr = NULL; 5471bd4fe43Sopenharmony_ci char *str = NULL; 5481bd4fe43Sopenharmony_ci size_t tlen; 5491bd4fe43Sopenharmony_ci 5501bd4fe43Sopenharmony_ci value += 2; /* add 2 */ 5511bd4fe43Sopenharmony_ci pos = at_strrchr(value, '"'); 5521bd4fe43Sopenharmony_ci if (pos == NULL || pos[1] != '\0') { 5531bd4fe43Sopenharmony_ci return NULL; 5541bd4fe43Sopenharmony_ci } 5551bd4fe43Sopenharmony_ci tlen = pos - value; 5561bd4fe43Sopenharmony_ci tstr = at_dup_binstr(value, tlen); 5571bd4fe43Sopenharmony_ci if (tstr == NULL) { 5581bd4fe43Sopenharmony_ci return NULL; 5591bd4fe43Sopenharmony_ci } 5601bd4fe43Sopenharmony_ci 5611bd4fe43Sopenharmony_ci str = at_malloc(tlen + 1); 5621bd4fe43Sopenharmony_ci if (str == NULL) { 5631bd4fe43Sopenharmony_ci at_free(tstr); 5641bd4fe43Sopenharmony_ci return NULL; 5651bd4fe43Sopenharmony_ci } 5661bd4fe43Sopenharmony_ci 5671bd4fe43Sopenharmony_ci *len = at_printf_decode((hi_u8 *) str, tlen + 1, tstr); 5681bd4fe43Sopenharmony_ci at_free(tstr); 5691bd4fe43Sopenharmony_ci 5701bd4fe43Sopenharmony_ci return str; 5711bd4fe43Sopenharmony_ci} 5721bd4fe43Sopenharmony_ci 5731bd4fe43Sopenharmony_cichar* at_parse_string_other(const char *value, size_t *len) 5741bd4fe43Sopenharmony_ci{ 5751bd4fe43Sopenharmony_ci hi_u8 *str = NULL; 5761bd4fe43Sopenharmony_ci size_t tlen; 5771bd4fe43Sopenharmony_ci size_t hlen = at_strlen(value); 5781bd4fe43Sopenharmony_ci if (hlen & 1) { 5791bd4fe43Sopenharmony_ci return NULL; 5801bd4fe43Sopenharmony_ci } 5811bd4fe43Sopenharmony_ci tlen = hlen / 2; /* 2 */ 5821bd4fe43Sopenharmony_ci str = at_malloc(tlen + 1); 5831bd4fe43Sopenharmony_ci if (str == NULL) { 5841bd4fe43Sopenharmony_ci return NULL; 5851bd4fe43Sopenharmony_ci } 5861bd4fe43Sopenharmony_ci if (at_hexstr2bin(value, str, tlen)) { 5871bd4fe43Sopenharmony_ci at_free((char*)str); 5881bd4fe43Sopenharmony_ci return NULL; 5891bd4fe43Sopenharmony_ci } 5901bd4fe43Sopenharmony_ci str[tlen] = '\0'; 5911bd4fe43Sopenharmony_ci *len = tlen; 5921bd4fe43Sopenharmony_ci return (char *) str; 5931bd4fe43Sopenharmony_ci} 5941bd4fe43Sopenharmony_ci 5951bd4fe43Sopenharmony_ci 5961bd4fe43Sopenharmony_cichar* at_parse_string(const char *value, size_t *len) 5971bd4fe43Sopenharmony_ci{ 5981bd4fe43Sopenharmony_ci if (len == HI_NULL) { 5991bd4fe43Sopenharmony_ci return HI_NULL; 6001bd4fe43Sopenharmony_ci } 6011bd4fe43Sopenharmony_ci if (*value == '"') { 6021bd4fe43Sopenharmony_ci return at_parse_string_normal(value, len); 6031bd4fe43Sopenharmony_ci } else if (*value == 'P' && value[1] == '"') { 6041bd4fe43Sopenharmony_ci return at_parse_string_with_p(value, len); 6051bd4fe43Sopenharmony_ci } else { 6061bd4fe43Sopenharmony_ci return at_parse_string_other(value, len); 6071bd4fe43Sopenharmony_ci } 6081bd4fe43Sopenharmony_ci} 6091bd4fe43Sopenharmony_ci 6101bd4fe43Sopenharmony_ci/** 6111bd4fe43Sopenharmony_ci * at_ssid_txt - Convert SSID to a printable string 6121bd4fe43Sopenharmony_ci * @ssid: SSID (32-octet string) 6131bd4fe43Sopenharmony_ci * @ssid_len: Length of ssid in octets 6141bd4fe43Sopenharmony_ci * Returns: Pointer to a printable string 6151bd4fe43Sopenharmony_ci * 6161bd4fe43Sopenharmony_ci * This function can be used to convert SSIDs into printable form. In most 6171bd4fe43Sopenharmony_ci * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard 6181bd4fe43Sopenharmony_ci * does not limit the used character set, so anything could be used in an SSID. 6191bd4fe43Sopenharmony_ci * 6201bd4fe43Sopenharmony_ci * This function uses a static buffer, so only one call can be used at the 6211bd4fe43Sopenharmony_ci * time, i.e., this is not re-entrant and the returned buffer must be used 6221bd4fe43Sopenharmony_ci * before calling this again. 6231bd4fe43Sopenharmony_ci */ 6241bd4fe43Sopenharmony_ciconst char* at_ssid_txt(const hi_u8 *ssid, size_t ssid_len) 6251bd4fe43Sopenharmony_ci{ 6261bd4fe43Sopenharmony_ci static char ssid_txt[AT_SSID_MAX_LEN * 4 + 1]; /* 4 */ 6271bd4fe43Sopenharmony_ci 6281bd4fe43Sopenharmony_ci if (ssid == NULL) { 6291bd4fe43Sopenharmony_ci ssid_txt[0] = '\0'; 6301bd4fe43Sopenharmony_ci return ssid_txt; 6311bd4fe43Sopenharmony_ci } 6321bd4fe43Sopenharmony_ci 6331bd4fe43Sopenharmony_ci at_printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); 6341bd4fe43Sopenharmony_ci return ssid_txt; 6351bd4fe43Sopenharmony_ci} 6361bd4fe43Sopenharmony_ci 6371bd4fe43Sopenharmony_ci#ifdef __cplusplus 6381bd4fe43Sopenharmony_ci#if __cplusplus 6391bd4fe43Sopenharmony_ci } 6401bd4fe43Sopenharmony_ci#endif 6411bd4fe43Sopenharmony_ci#endif 642