| // Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #define _GNU_SOURCE |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <wchar.h> |
| #include <signal.h> |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #include <sys/stat.h> |
| #include <sys/socket.h> |
| #include <sys/time.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| #include <assert.h> |
| #include <math.h> |
| #include <zlib.h> |
| |
| #include "cm.h" |
| #include "profilestring.h" |
| #include "param.h" |
| #include "sem.h" |
| |
| extern int get_first_odev(void); |
| extern int cm_odev_cnt; |
| extern char *StatusStr[8]; |
| extern char *ConnStatusStr[8]; |
| static sem_t hci_data_sem[MAX_DEV]; |
| |
| typedef struct hci_data_s { |
| char data[HCI_MAX_PACKET]; |
| int len; |
| } hci_data_t; |
| static hci_data_t hci_data[MAX_DEV]; |
| |
| #define NO_CM_CMD (-2) |
| #define EXIT_CM_CMD (-100) |
| |
| #define KEY_auth_pkm_enable "auth_pkm_enable" |
| #define KEY_eap_type "eap_type" |
| #define KEY_eap_tls_use_nvram_info "eap_tls_use_nvram_info" |
| #define KEY_eap_tls_userid "eap_tls_userid" |
| #define KEY_eap_tls_userpasswd "eap_tls_userpasswd" |
| #define KEY_eap_tls_anonyid "eap_tls_anonyid" |
| #define KEY_eap_tls_privateKeyPwd "eap_tls_pri_passwd" |
| #define KEY_eap_tls_fragsize "eap_tls_fragsize" |
| #define KEY_eap_tls_delimiter_enable "eap_tls_delimiter_enable" |
| #define KEY_eap_tls_resumption_disable "eap_tls_resumption_disable" |
| #define KEY_eap_tls_cr801_enable "eap_tls_cr801_enable" |
| #define KEY_eap_tls_decoration "eap_tls_decoration" |
| #define KEY_eap_tls_sessionticket_disable "eap_tls_sessionticket_disable" |
| #define KEY_eap_tls_dev_cert_null "eap_tls_dev_cert_null" |
| #define KEY_eap_tls_ca_cert_null "eap_tls_ca_cert_null" |
| #define KEY_eap_tls_use_nvram_cert "eap_tls_use_nvram_cert" |
| #define KEY_eap_tls_wm_serv_root "eap_tls_wm_serv_root" |
| #define KEY_eap_tls_serv_root_ca1 "eap_tls_serv_root_ca1" |
| #define KEY_eap_tls_serv_root_ca2 "eap_tls_serv_root_ca2" |
| #define KEY_eap_tls_serv_root_ca3 "eap_tls_serv_root_ca3" |
| #define KEY_eap_tls_wm_dev_root "eap_tls_wm_dev_root" |
| #define KEY_eap_tls_dev_root_ca1 "eap_tls_dev_root_ca1" |
| #define KEY_eap_tls_dev_sub_ca "eap_tls_dev_sub_ca" |
| #define KEY_eap_tls_dev_cert "eap_tls_dev_cert" |
| #define KEY_eap_tls_dev_cert_key "eap_tls_dev_cert_key" |
| |
| #define desc_eap_tls_wm_serv_root "wimax server root" |
| #define desc_eap_tls_serv_root_ca1 "server root ca1" |
| #define desc_eap_tls_serv_root_ca2 "server root ca2" |
| #define desc_eap_tls_serv_root_ca3 "server root ca3" |
| #define desc_eap_tls_wm_dev_root "wimax device root" |
| #define desc_eap_tls_dev_root_ca1 "device root ca1" |
| #define desc_eap_tls_dev_sub_ca "device sub ca" |
| #define desc_eap_tls_dev_cert "device cert" |
| #define desc_eap_tls_dev_cert_key "device cert private key" |
| |
| dev_conf_t default_dev_conf; |
| WIMAX_API_PROFILE_INFO profile_list[MAX_PROFILE_LIST]; |
| int profile_list_cnt; |
| |
| typedef int cmd_fun(int argc, char *argv[]); |
| |
| typedef struct cmd_s { |
| const char *cmd; |
| const char *desc; |
| const char *param; |
| cmd_fun *func; |
| |
| } cmd_t; |
| |
| #define DEVIATION_CNT 10 |
| |
| typedef struct deviation_s { |
| float value[DEVIATION_CNT]; |
| int cnt; |
| |
| } deviation_t; |
| |
| typedef struct dev_info_s { |
| deviation_t cinr1; |
| deviation_t cinr2; |
| deviation_t rssi1; |
| deviation_t rssi2; |
| |
| } dev_info_t; |
| |
| static dev_info_t dev_info[MAX_DEV]; |
| |
| |
| static int cm_uicc_power(int dev_idx, int on); |
| static void print_cmd_usage(const char *cmd); |
| static void print_cmd_list(const char *cmd); |
| static int do_cmd(char *cmd_line, int len); |
| |
| static __inline bool __is_delimiter(char ch) |
| { |
| return (ch == ' '); |
| } |
| |
| static __inline bool __is_binder(char ch) |
| { |
| return (ch == '"'); |
| } |
| |
| static void __get_token_arg(char *cmd_line, int *argc, char *argv[]) |
| { |
| int found_arg = 1, |
| bind_on = 0; |
| int argn = 0; |
| |
| while (*cmd_line) { |
| if (*cmd_line == '\n') { |
| *cmd_line = '\0'; |
| break; |
| } |
| if (0 == bind_on && __is_delimiter(*cmd_line)) { |
| found_arg = 1; |
| *cmd_line = '\0'; |
| } |
| else if (__is_binder(*cmd_line)) { |
| bind_on ^= 1; |
| *cmd_line = '\0'; |
| } |
| else if (found_arg) { |
| argv[argn++] = cmd_line; |
| found_arg = 0; |
| } |
| |
| cmd_line++; |
| } |
| |
| *argc = argn; |
| } |
| |
| static int find_device_conf(const char *mac) |
| { |
| char section[256]; |
| int tmp; |
| |
| assert(mac); |
| |
| sprintf(section, "device-%s", mac); |
| |
| if (get_profile_section(section, (char *)&tmp, 1, CONF_FILE)) |
| return 1; |
| else |
| return 0; |
| } |
| |
| void load_device_conf(dev_conf_t *conf, const char *mac) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| char section[256]; |
| char str[256]; |
| |
| memset(conf, 0, sizeof(*conf)); |
| |
| if (!mac) { |
| memset(conf->mac_str, 0, sizeof(conf->mac_str)); |
| mac = "default"; |
| } |
| else |
| memcpy(conf->mac_str, mac, sizeof(conf->mac_str)); |
| sprintf(section, "device-%s", mac); |
| |
| get_profile_string(section, KEY_auth_pkm_enable, "n", str, sizeof(str), CONF_FILE); |
| if (!strcasecmp(str, "n")) |
| conf->eapp.type = GCT_WIMAX_NO_EAP; |
| else { |
| get_profile_string(section, KEY_eap_type, "TTLS_MSCHAPV2", |
| str, sizeof(str), CONF_FILE); |
| strcpy(conf->type_str, str); |
| if (!strcasecmp(str, "AKA")) |
| conf->eapp.type = GCT_WIMAX_EAP_AKA; |
| else if (!strcasecmp(str, "TLS")) |
| conf->eapp.type = GCT_WIMAX_EAP_TLS; |
| else if (!strcasecmp(str, "TTLS_MD5")) |
| conf->eapp.type = GCT_WIMAX_EAP_TTLS_MD5; |
| else if (!strcasecmp(str, "TTLS_MSCHAPV2")) |
| conf->eapp.type = GCT_WIMAX_EAP_TTLS_MSCHAPV2; |
| else if (!strcasecmp(str, "TTLS_CHAP")) |
| conf->eapp.type = GCT_WIMAX_EAP_TTLS_CHAP; |
| } |
| get_profile_string(section, KEY_eap_tls_use_nvram_info, "n", str, |
| sizeof(str), CONF_FILE); |
| if (!strcasecmp(str, "y")) |
| conf->eapp.useNvramParam = 1; |
| else { |
| conf->eapp.useNvramParam = 0; |
| |
| get_profile_string(section, KEY_eap_tls_userid, "", |
| (char *) conf->eapp.userId, sizeof(conf->eapp.userId), CONF_FILE); |
| get_profile_string(section, KEY_eap_tls_userpasswd, "", |
| (char *) conf->eapp.userIdPwd, sizeof(conf->eapp.userIdPwd), CONF_FILE); |
| get_profile_string(section, KEY_eap_tls_anonyid, "", |
| (char *) conf->eapp.anonymousId, sizeof(conf->eapp.anonymousId), CONF_FILE); |
| get_profile_string(section, KEY_eap_tls_privateKeyPwd, "", |
| (char *) conf->eapp.privateKeyPwd, sizeof(conf->eapp.privateKeyPwd), CONF_FILE); |
| } |
| |
| get_profile_string(section, KEY_eap_tls_fragsize, "1300", |
| str, sizeof(str), CONF_FILE); |
| conf->eapp.fragSize = atoi(str); |
| |
| get_profile_string(section, KEY_eap_tls_delimiter_enable, "n", |
| str, sizeof(str), CONF_FILE); |
| if (!strcasecmp(str, "y")) |
| conf->eapp.useDelimiter = 1; |
| else |
| conf->eapp.useDelimiter = 0; |
| |
| get_profile_string(section, KEY_eap_tls_resumption_disable, "n", |
| str, sizeof(str), CONF_FILE); |
| if (!strcasecmp(str, "y")) |
| conf->eapp.disableResumption = 1; |
| else |
| conf->eapp.disableResumption = 0; |
| |
| get_profile_string(section, KEY_eap_tls_cr801_enable, "n", |
| str, sizeof(str), CONF_FILE); |
| if (!strcasecmp(str, "y")) |
| conf->eapp.cr801Enable = 1; |
| else |
| conf->eapp.cr801Enable = 0; |
| |
| get_profile_string(section, KEY_eap_tls_decoration, "", |
| (char *) conf->eapp.decoration, sizeof(conf->eapp.decoration), CONF_FILE); |
| |
| get_profile_string(section, KEY_eap_tls_sessionticket_disable, "n", |
| str, sizeof(str), CONF_FILE); |
| if (!strcasecmp(str, "y")) |
| conf->eapp.disableSessionTicket = 1; |
| else |
| conf->eapp.disableSessionTicket = 0; |
| |
| get_profile_string(section, KEY_eap_tls_dev_cert_null, "n", |
| str, sizeof(str), CONF_FILE); |
| if (!strcasecmp(str, "y")) |
| conf->eapp.devCertNULL = 1; |
| else |
| conf->eapp.devCertNULL = 0; |
| |
| get_profile_string(section, KEY_eap_tls_ca_cert_null, "n", |
| str, sizeof(str), CONF_FILE); |
| if (!strcasecmp(str, "y")) |
| conf->eapp.caCertNULL = 1; |
| else |
| conf->eapp.caCertNULL = 0; |
| |
| conf->eapp.logEnable = pconf->eap_log_enable; |
| } |
| |
| static void print_device_conf(dev_conf_t *conf) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| const char *type; |
| |
| cm_printf("--------------- Begin loaded configurations ---------------\n"); |
| |
| cm_printf("[common]\n"); |
| cm_printf("Log path: %s\n", pconf->log_path); |
| cm_printf("Log level: %d\n", pconf->log_level); |
| cm_printf("EAP log: %s\n", pconf->eap_log_enable ? "enabled" : "disabled"); |
| cm_printf("Embedded EAP: %s\n", pconf->embedded_eap_enable ? "enabled" : "disabled"); |
| cm_printf("OMA-DM: %s\n", pconf->oma_dm_enable ? "enabled" : "disabled"); |
| cm_printf("Non-volatile path: %s\n", pconf->nonvolatile_dir); |
| cm_printf("Default script file: %s\n", pconf->run_script_file); |
| cm_printf("Auto connection: %s\n", pconf->auto_connect_enable ? "enabled" : "disabled"); |
| if (pconf->auto_connect_enable) |
| cm_printf("Auto connection retry count: %u\n", pconf->auto_connect_retry_count); |
| cm_printf("Auto selecting profile index: %d\n", pconf->auto_select_profile_index); |
| cm_printf("Unknown network auto connection: %s\n", |
| pconf->unknown_net_auto_connect_enable ? "enabled" : "disabled"); |
| cm_printf("IP allocation timeout: %d sec.\n", pconf->ip_allocation_timeout_sec); |
| cm_printf("Disconnect on ip failure: %s\n", |
| pconf->disconnct_on_ip_failure ? "enabled" : "disabled"); |
| cm_printf("\n"); |
| |
| if (!conf->mac_str[0]) |
| cm_printf("[device-default]\n"); |
| else |
| cm_printf("[device-%s]\n", conf->mac_str); |
| |
| if (conf->eapp.type == GCT_WIMAX_NO_EAP) |
| cm_printf("AUTH PKM: disabled\n"); |
| else { |
| cm_printf("AUTH PKM: enabled\n"); |
| cm_printf("EAP type: %s\n", conf->type_str); |
| if (conf->eapp.type >= GCT_WIMAX_EAP_TLS && |
| conf->eapp.type <= GCT_WIMAX_EAP_TTLS_CHAP) { |
| if (conf->eapp.useNvramParam) |
| cm_printf("NVRAM parameter for TLS/TTLS enabled\n"); |
| |
| if (conf->eapp.type != GCT_WIMAX_EAP_TLS) { |
| type = "TTLS"; |
| if (!conf->eapp.useNvramParam) { |
| cm_printf("%s user id: %s\n", type, conf->eapp.userId); |
| cm_printf("%s user passwd: %s\n", type, conf->eapp.userIdPwd); |
| } |
| } |
| else |
| type = "TLS"; |
| |
| if (!conf->eapp.useNvramParam) { |
| cm_printf("%s anonymous id: %s\n", type, conf->eapp.anonymousId); |
| cm_printf("%s private key passwd: %s\n", type, conf->eapp.privateKeyPwd); |
| } |
| cm_printf("%s frag size: %d\n", type, conf->eapp.fragSize); |
| cm_printf("%s delimiter: %s\n", type, |
| conf->eapp.useDelimiter ? "enabled" : "disabled"); |
| cm_printf("%s null dev cert: %s\n", type, |
| conf->eapp.devCertNULL ? "enabled" : "disabled"); |
| cm_printf("%s null ca cert: %s\n", type, |
| conf->eapp.caCertNULL ? "enabled" : "disabled"); |
| cm_printf("%s resumption: %s\n", type, |
| conf->eapp.disableResumption ? "disabled" : "enabled"); |
| cm_printf("%s cr801: %s\n", type, |
| conf->eapp.cr801Enable ? "enabled" : "disabled"); |
| cm_printf("%s decoration: %s\n", type, conf->eapp.decoration); |
| cm_printf("%s session-ticket: %s\n", type, |
| conf->eapp.disableSessionTicket ? "disabled" : "enabled"); |
| } |
| } |
| |
| cm_printf("---------------- End loaded configurations ----------------\n"); |
| } |
| |
| int setup_device_conf(GDEV_ID *ID, const unsigned char *mac) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| dev_conf_t *conf = &cm_dev_conf[ID->deviceIndex]; |
| char mac_str[32]; |
| |
| memset(conf, 0, sizeof(*conf)); |
| |
| assert(mac); |
| |
| sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", |
| mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
| |
| if (find_device_conf(mac_str)) |
| load_device_conf(conf, mac_str); |
| else |
| memcpy(conf, &default_dev_conf, sizeof(dev_conf_t)); |
| |
| print_device_conf(conf); |
| if (conf->eapp.type != GCT_WIMAX_NO_EAP) { |
| if (pconf->api_mode != GCT_WIMAX_API_PRIVILEGE_READ_ONLY) { |
| if (GAPI_SetEap(ID, &conf->eapp) != GCT_API_RET_SUCCESS) { |
| cm_printf("Auth configuration failure\n"); |
| return -1; |
| } |
| } |
| } |
| |
| if (GAPI_GetCapability(ID, &conf->cap) != GCT_API_RET_SUCCESS) { |
| conf->cap = 0; |
| cm_printf("Getting capability failure\n"); |
| return -1; |
| } |
| if (pconf->api_mode != GCT_WIMAX_API_PRIVILEGE_READ_ONLY) { |
| if (CAP_EEAP_AKA_ENABLED(ID->deviceIndex)) |
| cm_uicc_power(ID->deviceIndex, 1); |
| } |
| return ID->deviceIndex; |
| } |
| |
| static int send_print_string(GDEV_ID_P pID, void *buf, int len) |
| { |
| char hci_buf[HCI_MAX_PACKET]; |
| hci_t *hci = (hci_t *) hci_buf; |
| |
| if (len > (HCI_MAX_PACKET-HCI_HEADER_SIZE)) |
| len = HCI_MAX_PACKET-HCI_HEADER_SIZE; |
| |
| hci->cmd_evt = _H2B(WIMAX_CLI_CMD); |
| hci->length = _H2B(len); |
| memcpy(hci->data, buf, len); |
| |
| len += HCI_HEADER_SIZE; |
| |
| if (GAPI_WriteHCIPacket(pID, hci_buf, len) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write HCI failure\n"); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| static int cmd_get_dev_list(int argc, char *argv[]) |
| { |
| WIMAX_API_HW_DEVICE_ID list[256]; |
| UINT32 cnt = 256; |
| int i; |
| |
| if (GAPI_GetListDevice(cm_api_handle, list, &cnt) != GCT_API_RET_SUCCESS) { |
| cm_printf("Get device list failure\n"); |
| return -1; |
| } |
| |
| if (cnt) { |
| cm_printf("[Device index] [Device name]\n"); |
| for (i = 0; i < (int) cnt; i++) { |
| cm_printf(" %3d%14S\n", |
| list[i].deviceIndex, (wchar_t *)list[i].deviceName); |
| } |
| return list[0].deviceIndex; |
| } |
| else |
| cm_printf("Not found device\n"); |
| return 0; |
| } |
| |
| static int cmd_get_status(int argc, char *argv[]) |
| { |
| WIMAX_API_DEVICE_STATUS nDevStatus = 0; |
| WIMAX_API_CONNECTION_PROGRESS_INFO nConnectionInfo = 0; |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| if (argc == 1) |
| ID.deviceIndex = DEFAULT_DEVICE; |
| else |
| ID.deviceIndex = atoi(argv[1]); |
| |
| if (GAPI_GetDeviceStatus(&ID, &nDevStatus, &nConnectionInfo) == GCT_API_RET_SUCCESS) { |
| cm_printf("device[%d] status [%s]\n", ID.deviceIndex, StatusStr[nDevStatus]); |
| if (nDevStatus == WIMAX_API_DEVICE_STATUS_Connecting) |
| cm_printf("Connection status [%s]\n", ConnStatusStr[nConnectionInfo]); |
| } |
| else |
| cm_printf("Get device status failure\n"); |
| return ID.deviceIndex; |
| } |
| |
| static int cm_rf_up(int dev_idx) |
| { |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx; |
| |
| if (GAPI_CmdControlPowerManagement(&ID, WIMAX_API_RF_ON) != GCT_API_RET_SUCCESS) { |
| cm_eprintf("device[%d] rf up failure\n", ID.deviceIndex); |
| return -1; |
| } |
| return dev_idx; |
| } |
| |
| static int cmd_rf_up(int argc, char *argv[]) |
| { |
| int dev_idx; |
| |
| if (argc == 1) |
| dev_idx = DEFAULT_DEVICE; |
| else |
| dev_idx = atoi(argv[1]); |
| |
| return cm_rf_up(dev_idx); |
| } |
| |
| static int cmd_rf_down(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| if (argc == 1) |
| ID.deviceIndex = DEFAULT_DEVICE; |
| else |
| ID.deviceIndex = atoi(argv[1]); |
| |
| if (GAPI_CmdControlPowerManagement(&ID, WIMAX_API_RF_OFF) != GCT_API_RET_SUCCESS) { |
| cm_printf("device[%d] rf down failure\n", ID.deviceIndex); |
| return -1; |
| } |
| return ID.deviceIndex; |
| } |
| |
| static int cm_get_profile_list(int dev_idx) |
| { |
| GDEV_ID ID; |
| int i; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx; |
| |
| profile_list_cnt = _numof_array(profile_list); |
| if (GAPI_GetSelectProfileList(&ID, profile_list, (UINT32 *) &profile_list_cnt) |
| != GCT_API_RET_SUCCESS) { |
| cm_printf("Get profile failure\n"); |
| return -1; |
| } |
| |
| cm_printf("[Profile-Index] [Profile-ID] [Profile-Name]\n"); |
| for (i = 0; i < profile_list_cnt; i++) { |
| cm_printf("%14d %08X %S\n", |
| i, (int)profile_list[i].profileID, (wchar_t *)profile_list[i].profileName); |
| } |
| |
| return profile_list_cnt; |
| } |
| |
| static int cmd_get_profile_list(int argc, char *argv[]) |
| { |
| int dev_idx; |
| |
| if (argc == 1) |
| dev_idx = DEFAULT_DEVICE; |
| else |
| dev_idx = atoi(argv[1]); |
| |
| if (cm_get_profile_list(dev_idx) < 0) |
| return -1; |
| |
| return dev_idx; |
| } |
| |
| static int cm_set_profile(int dev_idx, int profile_idx) |
| { |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx; |
| |
| if (profile_idx >= profile_list_cnt) |
| cm_eprintf("index[%d] is invalid\n", profile_idx); |
| else { |
| if (GAPI_SetProfile(&ID, profile_list[profile_idx].profileID) |
| != GCT_API_RET_SUCCESS ) { |
| cm_eprintf("Set profile failure\n"); |
| return -1; |
| } |
| } |
| |
| return 0; |
| } |
| |
| static int cmd_set_profile(int argc, char *argv[]) |
| { |
| int dev_idx, profile_idx; |
| |
| if (argc < 2) { |
| cm_printf("Invalid parameter.\n"); |
| return -1; |
| } |
| |
| if (argc == 2) |
| dev_idx = DEFAULT_DEVICE; |
| else |
| dev_idx = atoi(argv[2]); |
| profile_idx = atoi(argv[1]); |
| |
| return cm_set_profile(dev_idx, profile_idx); |
| } |
| |
| static int cm_get_net_list(int dev_idx, WIMAX_API_NSP_INFO_P list, int *list_cnt) |
| { |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx; |
| |
| if (GAPI_GetNetworkList(&ID, list, (UINT32 *) list_cnt) |
| != GCT_API_RET_SUCCESS) { |
| cm_eprintf("Get network list failure\n"); |
| return -1; |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static void cm_print_net_list(WIMAX_API_NSP_INFO_P list, int list_cnt) |
| { |
| int i; |
| |
| cm_printf("[NSP-Name] [NSP-ID] [RSSI] [CINR]\n"); |
| for (i = 0; i < list_cnt; i++) { |
| cm_printf("%9S %06X %6d %6d\n", |
| (wchar_t *) list[i].NSPName, |
| (int) list[i].NSPid, |
| (int) list[i].RSSI-123, |
| (int) list[i].CINR-10); |
| } |
| } |
| |
| static int cmd_get_net_list(int argc, char *argv[]) |
| { |
| WIMAX_API_NSP_INFO nsp[MAX_NETWORK_LIST]; |
| int dev_idx; |
| int list_cnt = MAX_NETWORK_LIST; |
| |
| if (argc == 1) |
| dev_idx = DEFAULT_DEVICE; |
| else |
| dev_idx = atoi(argv[1]); |
| |
| if (cm_get_net_list(dev_idx, nsp, &list_cnt) < 0) |
| return -1; |
| |
| cm_print_net_list(nsp, list_cnt); |
| |
| return dev_idx; |
| } |
| |
| static int cmd_get_neighbor_list(int argc, char *argv[]) |
| { |
| GCT_API_NEIGHBOR_LIST Neighbor[64], *n; |
| GDEV_ID ID; |
| UINT32 list_cnt = _numof_array(Neighbor), i; |
| |
| ID.apiHandle = cm_api_handle; |
| if (argc == 1) |
| ID.deviceIndex = DEFAULT_DEVICE; |
| else |
| ID.deviceIndex = atoi(argv[1]); |
| |
| if (GAPI_GetNeighborList(&ID, Neighbor, &list_cnt) |
| != GCT_API_RET_SUCCESS) { |
| cm_printf("Get neighbor list failure\n"); |
| return -1; |
| } |
| |
| if (!list_cnt) { |
| cm_printf("Not found neighbor!!\n"); |
| goto out; |
| } |
| |
| n = Neighbor; |
| cm_printf("[Frequency] [Preamble] [CINR] [RSSI] [BSID]\n"); |
| for (i = 0; i < list_cnt; i++, n++) { |
| cm_printf(" %9d %3d %4d %4d %02x%02x%02x:%02x%02x%02x\n", |
| (int)n->frequency, n->preamble, (s8)n->cinr-10, (s8)n->rssi-123, |
| n->bsId[0], n->bsId[1], n->bsId[2], |
| n->bsId[3], n->bsId[4], n->bsId[5]); |
| } |
| |
| out: |
| return ID.deviceIndex; |
| } |
| |
| static int combine_level(int dev_idx, int c0, int c1) |
| { |
| dev_conf_t *conf = &cm_dev_conf[dev_idx]; |
| int max, diff, offset; |
| |
| if (c0 > c1) { |
| max = c0; |
| diff = c0 - c1; |
| } |
| else { |
| max = c1; |
| diff = c1 - c0; |
| } |
| |
| if (conf->fw_mac_version < 0x01090104/*1.9.1.4*/) { |
| /*floor*/ |
| if (diff >= 6) offset = 0; |
| else if (diff >= 3) offset = 1; |
| else if (diff >= 1) offset = 2; |
| else offset = 3; |
| } |
| else { |
| /*round*/ |
| if (diff >= 10) offset = 0; |
| else if (diff >= 4) offset = 1; |
| else if (diff >= 2) offset = 2; |
| else offset = 3; |
| } |
| |
| max += offset; |
| |
| return max; |
| } |
| |
| static float calc_deviation(float *fArr, int cnt) |
| { |
| float sum, dsum, avg; |
| int i; |
| |
| if (cnt <= 0) |
| return 0; |
| if (cnt > DEVIATION_CNT) |
| cnt = DEVIATION_CNT; |
| |
| sum = 0; |
| for (i = 0; i < cnt; i++) |
| sum += fArr[i]; |
| avg = sum/cnt; |
| |
| for (i = dsum = 0; i < cnt; i++) |
| dsum += (fArr[i]-avg)*(fArr[i]-avg); |
| |
| return (float) sqrt(dsum/cnt); |
| } |
| |
| static const char *fec_string(int fec) |
| { |
| #define _T(s) s |
| const char *str; |
| |
| switch(fec) { |
| case 0: |
| str = _T("QPSK(CC) 1/2"); |
| break; |
| case 1: |
| str = _T("QPSK(CC) 3/4"); |
| break; |
| case 2: |
| str = _T("16-QAM(CC) 1/2"); |
| break; |
| case 3: |
| str = _T("16-QAM(CC) 3/4"); |
| break; |
| case 4: |
| str = _T("64-QAM(CC) 1/2"); |
| break; |
| case 5: |
| str = _T("64-QAM(CC) 2/3"); |
| break; |
| case 6: |
| str = _T("64-QAM(CC) 3/4"); |
| break; |
| case 7: |
| str = _T("QPSK(BTC) 1/2"); |
| break; |
| case 8: |
| str = _T("QPSK(BTC) 3/4 or 2/3"); |
| break; |
| case 9: |
| str = _T("16-QAM(BTC) 3/5"); |
| break; |
| case 10: |
| str = _T("16-QAM(BTC) 4/5"); |
| break; |
| case 11: |
| str = _T("64-QAM(BTC) 2/3 or 5/8"); |
| break; |
| case 12: |
| str = _T("64-QAM(BTC) 5/6 or 4/5"); |
| break; |
| case 13: |
| str = _T("QPSK(CTC) 1/2"); |
| break; |
| /*case 14: |
| str = _T("Reserved"); |
| break;*/ |
| case 15: |
| str = _T("QPSK(CTC) 3/4"); |
| break; |
| case 16: |
| str = _T("16-QAM(CTC) 1/2"); |
| break; |
| case 17: |
| str = _T("16-QAM(CTC) 3/4"); |
| break; |
| case 18: |
| str = _T("64-QAM(CTC) 1/2"); |
| break; |
| case 19: |
| str = _T("64-QAM(CTC) 2/3"); |
| break; |
| case 20: |
| str = _T("64-QAM(CTC) 3/4"); |
| break; |
| case 21: |
| str = _T("64-QAM(CTC) 5/6"); |
| break; |
| case 22: |
| str = _T("QPSK(ZT CC) 1/2"); |
| break; |
| case 23: |
| str = _T("QPSK(ZT CC) 3/4"); |
| break; |
| case 24: |
| str = _T("16-QAM(ZT CC) 1/2"); |
| break; |
| case 25: |
| str = _T("16-QAM(ZT CC) 3/4"); |
| break; |
| case 26: |
| str = _T("64-QAM(ZT CC) 1/2"); |
| break; |
| case 27: |
| str = _T("64-QAM(ZT CC) 2/3"); |
| break; |
| case 28: |
| str = _T("64-QAM(ZT CC) 3/4"); |
| break; |
| case 29: |
| str = _T("QPSK(LDPC) 1/2"); |
| break; |
| case 30: |
| str = _T("QPSK(LDPC) 2/3 A code"); |
| break; |
| case 31: |
| str = _T("QPSK(LDPC) 3/4 A code"); |
| break; |
| case 32: |
| str = _T("16-QAM(LDPC) 1/2"); |
| break; |
| case 33: |
| str = _T("16-QAM(LDPC) 2/3 A code"); |
| break; |
| case 34: |
| str = _T("16-QAM(LDPC) 3/4 A code"); |
| break; |
| case 35: |
| str = _T("64-QAM(LDPC) 1/2"); |
| break; |
| case 36: |
| str = _T("64-QAM(LDPC) 2/3 A code"); |
| break; |
| case 37: |
| str = _T("64-QAM(LDPC) 3/4 A code"); |
| break; |
| case 38: |
| str = _T("QPSK(LDPC) 2/3 B code"); |
| break; |
| case 39: |
| str = _T("QPSK(LDPC) 3/4 B code"); |
| break; |
| case 40: |
| str = _T("16-QAM(LDPC) 2/3 B code"); |
| break; |
| case 41: |
| str = _T("16-QAM(LDPC) 3/4 B code"); |
| break; |
| case 42: |
| str = _T("64-QAM(LDPC) 2/3 B code"); |
| break; |
| case 43: |
| str = _T("64-QAM(LDPC) 3/4 B code"); |
| break; |
| case 44: |
| str = _T("QPSK(CC with optional interleaver) 1/2"); |
| break; |
| case 45: |
| str = _T("QPSK(CC with optional interleaver) 3/4"); |
| break; |
| case 46: |
| str = _T("16-QAM(CC with optional interleaver) 1/2"); |
| break; |
| case 47: |
| str = _T("16-QAM(CC with optional interleaver) 3/4"); |
| break; |
| case 48: |
| str = _T("64-QAM(CC with optional interleaver) 2/3"); |
| break; |
| case 49: |
| str = _T("64-QAM(CC with optional interleaver) 3/4"); |
| break; |
| case 50: |
| str = _T("QPSK(LDPC) 5/6"); |
| break; |
| case 51: |
| str = _T("16-QAM(LDPC) 5/6"); |
| break; |
| case 52: |
| str = _T("64-QAM(LDPC) 5/6"); |
| break; |
| default: |
| str = _T("Unknown"); |
| break; |
| } |
| |
| return str; |
| } |
| |
| static int refresh_rf_info(GDEV_ID *ID) |
| { |
| static int last_recv_PERErrorCount; |
| static int last_recv_PERReceiveCount; |
| static int base_PERErrorCount; |
| static int base_PERReceiveCount; |
| |
| dev_info_t *di = &dev_info[ID->deviceIndex]; |
| GCT_API_RF_INFORM rf_info; |
| s8 cinr1, cinr2, rssi1, rssi2; |
| float per; |
| |
| if (GAPI_GetRFInform(ID, &rf_info) != GCT_API_RET_SUCCESS) { |
| cm_printf("Get rf info fail\n"); |
| return -1; |
| } |
| |
| cinr1 = (s8) rf_info.CINR-10; |
| cinr2 = (s8) rf_info.CINR2-10; |
| rssi1 = (s8) rf_info.RSSI-123; |
| rssi2 = (s8) rf_info.RSSI2-123; |
| |
| cm_printf("[RF Information]\n"); |
| |
| cm_printf("BSID: %02X %02X %02X %02X %02X %02X\n", |
| rf_info.bsId[0], rf_info.bsId[1], rf_info.bsId[2], |
| rf_info.bsId[3], rf_info.bsId[4], rf_info.bsId[5]); |
| cm_printf("UL PermBase: %d\n", rf_info.ULPermBase); |
| cm_printf("DL PermBase: %d\n", rf_info.DLPermBase); |
| cm_printf("Current preamble index: %d\n", rf_info.CurrentPreambleIndex); |
| cm_printf("Previous preamble index: %d\n", rf_info.PreviousPreambleIndex); |
| cm_printf("HO count: %d\n", rf_info.HandOverCount); |
| cm_printf("HO fail count: %d\n", rf_info.HandOverFailCount); |
| cm_printf("Resync count: %d\n", rf_info.ResyncCount); |
| cm_printf("HO signal latency: %d\n", rf_info.HoSignalLatency); |
| cm_printf("Combined CINR: %d\n", combine_level(ID->deviceIndex, cinr1, cinr2)); |
| cm_printf("CINR: %d\n", cinr1); |
| cm_printf("CINR deviation: %.4f\n", calc_deviation(di->cinr1.value, ++di->cinr1.cnt)); |
| cm_printf("CINR2: %d\n", cinr2); |
| cm_printf("CINR2 deviation: %.4f\n", calc_deviation(di->cinr2.value, ++di->cinr2.cnt)); |
| cm_printf("Combined RSSI: %d\n", combine_level(ID->deviceIndex, rssi1, rssi2)); |
| cm_printf("RSSI: %d\n", rssi1); |
| cm_printf("RSSI deviation: %.4f\n", calc_deviation(di->rssi1.value, ++di->rssi1.cnt)); |
| cm_printf("RSSI2: %d\n", rssi2); |
| cm_printf("RSSI2 deviation: %.4f\n", calc_deviation(di->rssi2.value, ++di->rssi2.cnt)); |
| |
| if (rf_info.nPERReceiveCount) { |
| last_recv_PERErrorCount = rf_info.nPERErrorCount; |
| last_recv_PERReceiveCount = rf_info.nPERReceiveCount; |
| if (base_PERErrorCount > last_recv_PERErrorCount) |
| base_PERErrorCount = last_recv_PERErrorCount; |
| if (base_PERReceiveCount > last_recv_PERReceiveCount) |
| base_PERReceiveCount = last_recv_PERReceiveCount; |
| |
| if (last_recv_PERReceiveCount-base_PERReceiveCount) { |
| per = ((float)last_recv_PERErrorCount-(float)base_PERErrorCount)/ |
| ((float)last_recv_PERReceiveCount-(float)base_PERReceiveCount); |
| } else |
| per = 0; |
| |
| cm_printf("PER: %.6f [%d/%d]\n", per, |
| last_recv_PERErrorCount-base_PERErrorCount, |
| last_recv_PERReceiveCount-base_PERReceiveCount); |
| } |
| else |
| cm_printf("PER: --\n"); |
| |
| cm_printf("Power control mode: %d\n", rf_info.PowerControlMode); |
| cm_printf("Tx power: %d\n", (s8) (rf_info.TxPower/2-84)); |
| cm_printf("Tx power maximum: %d\n", (s8) (rf_info.TxPowerMax/2-84)); |
| cm_printf("Tx power headroom: %d\n", (s8)rf_info.TxPowerMax-(s8)rf_info.TxPower); |
| cm_printf("UL burst data FEC scheme: %s\n", fec_string(rf_info.ULBurstDataFECScheme)); |
| cm_printf("DL burst data FEC scheme: %s\n", fec_string(rf_info.DLBurstDataFECScheme)); |
| cm_printf("UL burst data UIUC: %02d\n", rf_info.ULBurstDataUIUC); |
| cm_printf("DL burst data DIUC: %02d\n", rf_info.DLBurstDataDIUC); |
| cm_printf("Frequency: %d\n", (int)rf_info.Frequency); |
| |
| return 0; |
| } |
| |
| static int cmd_get_link_status(int argc, char *argv[]) |
| { |
| WIMAX_API_LINK_STATUS_INFO LinkStatus; |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| if (argc == 1) |
| ID.deviceIndex = DEFAULT_DEVICE; |
| else |
| ID.deviceIndex = atoi(argv[1]); |
| |
| if (GAPI_GetLinkStatus(&ID, &LinkStatus) != GCT_API_RET_SUCCESS) { |
| cm_printf("Get link status fail\n"); |
| return -1; |
| } |
| |
| cm_printf("[RSSI] [CINR] [TX-PWR] [NAP-ID]\n"); |
| cm_printf("%5d %6d %8d %02X%02X%02X\n", |
| LinkStatus.RSSI-123, |
| LinkStatus.CINR-10, |
| (s8) (LinkStatus.txPWR/2-84), |
| LinkStatus.bsId[0], LinkStatus.bsId[1], LinkStatus.bsId[2]); |
| |
| return refresh_rf_info(&ID); |
| } |
| |
| static int cm_connect_net(int dev_idx, WIMAX_API_WSTRING nsp_name, |
| WIMAX_API_PROFILE_ID profileID) |
| { |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx; |
| dev_conf_t *conf = &cm_dev_conf[dev_idx]; |
| |
| wcscpy((wchar_t*)conf->nsp_name16_before, (wchar_t*)conf->nsp_name16_current); |
| |
| if (GAPI_CmdConnectToNetwork(&ID, nsp_name, profileID) != GCT_API_RET_SUCCESS) { |
| cm_eprintf("Connect failure\n"); |
| return -1; |
| } |
| |
| wcscpy((wchar_t*)conf->nsp_name16_current, (wchar_t*)nsp_name); |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_connect_net(int argc, char *argv[]) |
| { |
| u16 nsp_name16[MAX_SIZE_OF_NSP_NAME]; |
| int dev_idx = DEFAULT_DEVICE; |
| WIMAX_API_PROFILE_ID profileID = 0; |
| |
| if (argc < 2 && argc > 4) { |
| cm_eprintf("Invalid parameter.\n"); |
| return -1; |
| } |
| |
| if (argc > 2) { |
| if (strlen(argv[2]) <= 1) |
| dev_idx = atoi(argv[2]); |
| else { |
| profileID = strtoul(argv[2], NULL, 16); |
| if (argc == 4) |
| dev_idx = atoi(argv[3]); |
| } |
| } |
| mbstowcs((wchar_t*)nsp_name16, argv[1], strlen(argv[1])+1); |
| |
| return cm_connect_net(dev_idx, (WIMAX_API_WSTRING)nsp_name16, profileID); |
| } |
| |
| void cm_enable_auto_connet(int enable, int dev_idx) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| pconf->auto_connect_enable = enable; |
| if (enable) |
| cm_request_auto_connection(dev_idx); |
| } |
| |
| static int cmd_auto_connect_net(int argc, char *argv[]) |
| { |
| int dev_idx = DEFAULT_DEVICE; |
| int enable = 0; |
| |
| if (argc < 2) { |
| invalid_param: |
| cm_eprintf("Invalid parameter\n"); |
| return -1; |
| } |
| if (!strcasecmp(argv[1], "on")) |
| enable = 1; |
| else if (strcasecmp(argv[1], "off")) |
| goto invalid_param; |
| |
| if (argc > 2) |
| dev_idx = atoi(argv[1]); |
| |
| cm_enable_auto_connet(enable, dev_idx); |
| return dev_idx; |
| } |
| |
| static WIMAX_API_NSP_INFO_P select_nsp(WIMAX_API_NSP_INFO_P nsp, int nsp_cnt) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| WIMAX_API_NSP_INFO_P mnsp; |
| WIMAX_API_NSP_INFO_P home, partner, rpartner; |
| UINT8 cinr = 0; |
| int i; |
| |
| mnsp = nsp; |
| rpartner = partner = home = NULL; |
| for (i = 0; i < nsp_cnt; i++, nsp++) { |
| switch (nsp->networkType) { |
| case WIMAX_API_HOME: |
| if (!home) |
| home = nsp; |
| break; |
| case WIMAX_API_PARTNER: |
| if (!partner) |
| partner = nsp; |
| break; |
| case WIMAX_API_ROAMING_PARTNER: |
| if (!rpartner) |
| rpartner = nsp; |
| break; |
| case WIMAX_API_UNKNOWN: |
| if (nsp->CINR > cinr) { |
| cinr = nsp->CINR; |
| mnsp = nsp; |
| } |
| break; |
| default: |
| cm_printf("Unknown Network Type"); |
| break; |
| } |
| } |
| |
| if (home != NULL) { |
| cm_printf("HOME Operator %S is selected\n", (wchar_t *)home->NSPName); |
| return home; |
| } |
| if (partner != NULL) { |
| cm_printf("CAPL Operator %S is selected\n", (wchar_t *)partner->NSPName); |
| return partner; |
| } |
| if (rpartner != NULL) { |
| cm_printf("RAPL Operator %S is selected\n", (wchar_t *)rpartner->NSPName); |
| return rpartner; |
| } |
| |
| if (pconf->unknown_net_auto_connect_enable) { |
| cm_printf("No known network is found, Selecting NSP with better CINR\n"); |
| return mnsp; |
| } |
| else { |
| cm_printf("No known network is not selected!\n"); |
| return NULL; |
| } |
| } |
| |
| int cm_profiling_rf_up(int dev_idx) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| int profile_idx = pconf->auto_select_profile_index; |
| int ret; |
| |
| if ((ret = cm_get_profile_list(dev_idx)) <= 0) { |
| cm_printf("There is no proile!\n"); |
| goto out; |
| } |
| |
| cm_printf("Profile index is %d\n", profile_idx); |
| if ((ret = cm_set_profile(dev_idx, profile_idx)) < 0) |
| goto out; |
| |
| if ((ret = cm_rf_up(dev_idx)) < 0) |
| goto out; |
| out: |
| return ret; |
| } |
| |
| int cm_auto_connect(int dev_idx) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| WIMAX_API_NSP_INFO nsp[MAX_NETWORK_LIST], *selected_nsp = NULL; |
| WIMAX_API_PROFILE_ID profileID = 0; |
| int list_cnt, waiting_timeout_sec = NETWORK_LIST_TIMEOUT_SEC; |
| unsigned connect_retries = pconf->auto_connect_retry_count; |
| GDEV_ID ID; |
| WIMAX_API_DEVICE_STATUS DeviceStatus; |
| WIMAX_API_CONNECTION_PROGRESS_INFO ConnectionProgressInfo; |
| cm_msg_cb_t *msg_cb; |
| time_t start_time, cur_time; |
| int ret = -1; |
| |
| msg_cb = &pconf->auto_conn_msg; |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx; |
| |
| if (waiting_timeout_sec == 0) |
| waiting_timeout_sec = 1; |
| if (connect_retries == 0) |
| connect_retries = 1; |
| |
| if (GAPI_GetDeviceStatus(&ID, &DeviceStatus, &ConnectionProgressInfo) |
| != GCT_API_RET_SUCCESS) { |
| cm_eprintf("GAPI_GetDeviceStatus Failure\n"); |
| goto out; |
| } |
| |
| if (DeviceStatus == WIMAX_API_DEVICE_STATUS_Connecting || |
| DeviceStatus == WIMAX_API_DEVICE_STATUS_Data_Connected) { |
| cm_eprintf("DeviceStatus is not connectable state(%d)\n\n", DeviceStatus); |
| goto out; |
| } |
| |
| if (cm_profiling_rf_up(dev_idx) <= 0) |
| goto out; |
| |
| get_net_list: |
| time(&start_time); |
| do { |
| sleep(1); |
| if (!pconf->auto_connect_enable) |
| goto out; |
| list_cnt = MAX_NETWORK_LIST; |
| if (cm_get_net_list(dev_idx, nsp, &list_cnt) < 0) |
| goto out; |
| time(&cur_time); |
| if (list_cnt == 0) |
| cm_printf("network list=%d (elapsed %dsec.)\n", |
| list_cnt, (unsigned)cur_time-(unsigned)start_time); |
| if (list_cnt) { |
| cm_print_net_list(nsp, list_cnt); |
| if ((selected_nsp = select_nsp(nsp, list_cnt))) |
| goto connect; |
| } |
| } while (--waiting_timeout_sec); |
| |
| if (waiting_timeout_sec == 0) { |
| cm_eprintf("There is no scan list\n"); |
| goto out; |
| } |
| connect: |
| if (selected_nsp && pconf->auto_connect_enable) { |
| cm_printf("Connect to %S\n", (wchar_t *) selected_nsp->NSPName); |
| if (cm_connect_net(dev_idx, selected_nsp->NSPName, profileID) < 0) { |
| if (--connect_retries) |
| goto get_net_list; |
| ret = -1; |
| } |
| ret = 0; |
| } |
| out: |
| cm_printf("Auto connect done\n"); |
| return ret; |
| } |
| |
| int cm_disconnect_net(int dev_idx) |
| { |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx; |
| |
| if (GAPI_CmdDisconnectFromNetwork(&ID) != GCT_API_RET_SUCCESS) { |
| cm_printf("Disconnect failure\n"); |
| return -1; |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_disconnect_net(int argc, char *argv[]) |
| { |
| int dev_idx; |
| |
| if (argc == 1) |
| dev_idx = DEFAULT_DEVICE; |
| else |
| dev_idx = atoi(argv[1]); |
| |
| return cm_disconnect_net(dev_idx); |
| } |
| |
| static int cmd_set_autoscan_interval(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int interval_sec; |
| |
| if (argc < 2) { |
| cm_printf("Command usage: %s interval(second)\n", argv[0]); |
| return -1; |
| } |
| |
| interval_sec = atoi(argv[1]); |
| |
| ID.apiHandle = cm_api_handle; |
| if (argc == 2) |
| ID.deviceIndex = DEFAULT_DEVICE; |
| else |
| ID.deviceIndex = atoi(argv[1]); |
| |
| if (GAPI_SetScanInterval(&ID, interval_sec) != GCT_API_RET_SUCCESS) { |
| cm_printf("Setting Scan-Interval failure!\n"); |
| return -1; |
| } |
| else |
| cm_printf("Set autoscan interval(%d second)\n", interval_sec); |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_scan(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int scan_mode; |
| GCT_API_SCAN_TYPE type; |
| #define WIDE_SCAN 0 |
| #define ALL_SUBS_SCAN 1 |
| #define CURR_SUBS_SCAN 2 |
| const char *scan_type = NULL; |
| |
| if (argc < 2 || (scan_mode = atoi(argv[1])) > CURR_SUBS_SCAN) { |
| cm_printf("Command usage: %s scan-mode\n" |
| " scan-mode 0: wide scan\n" |
| " scan-mode 1: all subscriptions scan\n" |
| " scan-mode 2: current subscription scan\n", argv[0]); |
| return -1; |
| } |
| |
| ID.apiHandle = cm_api_handle; |
| if (argc == 2) |
| ID.deviceIndex = DEFAULT_DEVICE; |
| else |
| ID.deviceIndex = atoi(argv[2]); |
| |
| if (scan_mode == WIDE_SCAN) { |
| type = GCT_API_SCAN_WIDE; |
| scan_type = "wide"; |
| } |
| else if (scan_mode == ALL_SUBS_SCAN) { |
| type = GCT_API_SCAN_ALL_SUBSCRIPTIONS; |
| scan_type = "all subscriptions"; |
| } |
| else { |
| type = GCT_API_SCAN_CURR_SUBSCRIPTION; |
| scan_type = "current subscription"; |
| } |
| |
| if (GAPI_NetworkSearchScan(&ID, type) != GCT_API_RET_SUCCESS) { |
| cm_printf("Scaning network failure\n"); |
| return -1; |
| } |
| else |
| cm_printf("Request %s scan!\n", scan_type); |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_auth(int argc, char *argv[]) |
| { |
| cm_printf("This command is not used no more.\n"); |
| cm_printf("Authentication will be automatically set according to cm.conf configuration.\n"); |
| return 0; |
| } |
| |
| static int cmd_delete_cert(int argc, char *argv[]) |
| { |
| cm_printf("%s: not supported!\n", __func__); |
| return -1; |
| } |
| |
| static int cmd_get_cert_status(int argc, char *argv[]) |
| { |
| cm_printf("%s: not supported!\n", __func__); |
| return -1; |
| } |
| |
| static int cmd_get_cert_mask(int argc, char *argv[]) |
| { |
| cm_printf("%s: not supported!\n", __func__); |
| return -1; |
| } |
| |
| static int cmd_set_cert_mask(int argc, char *argv[]) |
| { |
| cm_printf("%s: not supported!\n", __func__); |
| return -1; |
| } |
| |
| static int cmd_get_cert_info(int argc, char *argv[]) |
| { |
| cm_printf("%s: not supported!\n", __func__); |
| return -1; |
| } |
| |
| static int cmd_debug_level(int argc, char *argv[]) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| int level, prev_level; |
| |
| if (argc < 2) { |
| cm_printf("Invalid parameter.\n"); |
| return -1; |
| } |
| |
| level = atoi(argv[1]); |
| |
| if (GAPI_SetDebugLevel(cm_api_handle, level, &prev_level) != GCT_API_RET_SUCCESS) { |
| cm_printf("Debug level failure\n"); |
| return -1; |
| } |
| if (level != GAPI_LOG_FLUSH_LEVEL) |
| pconf->log_level = level; |
| return get_first_odev(); |
| } |
| |
| static int cmd_help(int argc, char *argv[]) |
| { |
| if (argc == 2) |
| print_cmd_list(argv[1]); |
| else |
| print_cmd_list(NULL); |
| return 0; |
| } |
| |
| static void request_dm_prompt(void) |
| { |
| GDEV_ID ID; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = get_first_odev(); |
| |
| if (ID.deviceIndex) |
| send_print_string(&ID, "\n", 1); |
| } |
| |
| static void do_shell(const char *shell) |
| { |
| #define DISABLE_SIGINT |
| pid_t pid; |
| int status, i; |
| #if defined(DISABLE_SIGINT) |
| struct sigaction act, oldact; |
| |
| memset(&act, 0, sizeof(act)); |
| act.sa_handler = SIG_IGN; |
| sigaction(SIGINT, &act, &oldact); |
| #endif |
| |
| pid = fork(); |
| if (pid == 0) { |
| /*Close all FDs*/ |
| for (i = 3; i < 64; i++) |
| close(i); |
| #if defined(DISABLE_SIGINT) |
| sigaction(SIGINT, &oldact, NULL); |
| #endif |
| /* Invokes a shell */ |
| execl(shell, shell, NULL); |
| cm_eprintf("execl failed\n"); |
| exit(1); |
| } |
| else if (pid != -1) { |
| waitpid(pid, &status, 0); |
| #if defined(DISABLE_SIGINT) |
| sigaction(SIGINT, &oldact, NULL); |
| #endif |
| if ((!WIFEXITED(status) || WEXITSTATUS(status))) |
| cm_printf("waitpid: status=%d\n", WEXITSTATUS(status)); |
| request_dm_prompt(); |
| } |
| else |
| cm_eprintf("fork failed\n"); |
| } |
| |
| static int cmd_shell(int argc, char *argv[]) |
| { |
| #define MY_SHELL "/bin/sh" |
| |
| do_shell(MY_SHELL); |
| return 0; |
| } |
| |
| static int cmd_exit(int argc, char *argv[]) |
| { |
| return EXIT_CM_CMD; |
| } |
| |
| static void cmd_init_event(int dev_idx) |
| { |
| sem_init(&hci_data_sem[dev_idx], 0); |
| } |
| |
| static char *cmd_wait_event(int dev_idx, unsigned short event, int second, int *len) |
| { |
| int ret; |
| |
| ret = sem_timedwait(&hci_data_sem[dev_idx], second); |
| if (ret) { |
| cm_printf("Event(0x%04X) time out(%d)\n", event, ret); |
| return NULL; |
| } |
| |
| if (len) |
| *len = hci_data[dev_idx].len; |
| return hci_data[dev_idx].data; |
| } |
| |
| void cmd_signal_event(int dev_idx, unsigned short event, char *data, int len) |
| { |
| memcpy(hci_data[dev_idx].data, data, len); |
| hci_data[dev_idx].len = len; |
| sem_signal(&hci_data_sem[dev_idx]); |
| } |
| |
| #define HCI_FILE_BUF_CHUNK 1024 |
| |
| static int check_file_arg(int argc, char *file) |
| { |
| if (argc < 3) { |
| cm_printf("Invalid parameter.\n"); |
| return -1; |
| } |
| |
| if (file && access(file, 0)) { |
| cm_printf("%s is not found\n", file); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int cm_read_fw_file(GDEV_ID_P pID, char *host_file, char *target_file) |
| { |
| int dev_idx = pID->deviceIndex; |
| char hci_buf[HCI_MAX_PACKET]; |
| hci_t *hci = (hci_t *) hci_buf; |
| int hci_length; |
| hci_file_response_t *rsp; |
| hci_file_read_t *p = (hci_file_read_t *) hci->data; |
| int len; |
| unsigned offset = 0; |
| int fd, ret = -1; |
| |
| if ((fd = open(host_file, O_CREAT|O_WRONLY|O_TRUNC, 0644)) < 0) { |
| cm_printf("Open failed, %s, %s(%d)\n", host_file, strerror(errno), errno); |
| return -1; |
| } |
| |
| hci->cmd_evt = _H2B(WIMAX_READ_FILE); |
| strcpy(p->path, target_file); |
| hci_length = HCI_HEADER_SIZE + sizeof(hci_file_read_t) + strlen(p->path) + 1; |
| hci->length = _H2B(hci_length-HCI_HEADER_SIZE); |
| |
| cmd_init_event(dev_idx); |
| |
| while (1) { |
| p->offset = _DH2B(offset); |
| |
| if (GAPI_WriteHCIPacket(pID, hci_buf, hci_length) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write HCI failed! (Reading %s)\n", target_file); |
| goto out; |
| } |
| |
| rsp = (hci_file_response_t *) cmd_wait_event(dev_idx, WIMAX_FILE_RESULT, 5, NULL); |
| if (!rsp) |
| break; |
| |
| ret = _DB2H(rsp->result); |
| if (!ret) |
| break; |
| if (ret < 0) { |
| cm_printf("Read file failed(%d)\n", ret); |
| break; |
| } |
| len = write(fd, file_response_data(rsp), ret); |
| if (len <= 0) { |
| cm_printf("Write failed, %s, %s(%d)\n", host_file, strerror(errno), errno); |
| ret = -1; |
| break; |
| } |
| offset += ret; |
| if (len < ret) |
| lseek(fd, offset, SEEK_SET); |
| } |
| |
| if (!ret) |
| cm_printf("\t%s <= %s\n", host_file, target_file); |
| out: |
| close(fd); |
| return pID->deviceIndex; |
| } |
| |
| static int cmd_read_file(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| char *host_file = argv[1]; |
| char *target_file = argv[2]; |
| |
| if (check_file_arg(argc, NULL) < 0) |
| return -1; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = (argc == 4 ? atoi(argv[3]) : DEFAULT_DEVICE); |
| |
| return cm_read_fw_file(&ID, host_file, target_file); |
| } |
| |
| static int cmd_write_file(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int dev_idx; |
| char hci_buf[HCI_MAX_PACKET]; |
| hci_t *hci = (hci_t *) hci_buf; |
| int fix_length, hci_length; |
| hci_file_response_t *rsp; |
| hci_file_write_t *p = (hci_file_write_t *) hci->data; |
| char *buf; |
| int buf_size = HCI_FILE_BUF_CHUNK; |
| int len; |
| unsigned offset = 0, total; |
| char *host_file = argv[1]; |
| char *target_file = argv[2]; |
| int fd, ret = -1; |
| |
| if (check_file_arg(argc, host_file) < 0) |
| return -1; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx = (argc == 4 ? atoi(argv[3]) : DEFAULT_DEVICE); |
| |
| if ((fd = open(host_file, O_RDONLY)) < 0) { |
| cm_printf("Open failed, %s, %s(%d)\n", host_file, strerror(errno), errno); |
| return -1; |
| } |
| |
| total = lseek(fd, 0, SEEK_END); |
| lseek(fd, 0, SEEK_SET); |
| |
| hci->cmd_evt = _H2B(WIMAX_WRITE_FILE); |
| strcpy(p->path, target_file); |
| p->path_len = strlen(p->path) + 1; |
| fix_length = sizeof(hci_file_write_t) + p->path_len; |
| buf = hci_file_data(p); |
| p->path_len = _H2B(p->path_len); |
| |
| cmd_init_event(dev_idx); |
| |
| while ((len = read(fd, buf, buf_size)) > 0) { |
| p->offset = _DH2B(offset); |
| hci->length = _H2B(fix_length + len); |
| hci_length = HCI_HEADER_SIZE + fix_length + len; |
| |
| if (GAPI_WriteHCIPacket(&ID, hci_buf, hci_length) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write-HCI failed\n"); |
| goto out; |
| } |
| |
| rsp = (hci_file_response_t *) cmd_wait_event(dev_idx, WIMAX_FILE_RESULT, 5, NULL); |
| if (!rsp) |
| break; |
| |
| ret = _DB2H(rsp->result); |
| if (!ret) |
| break; |
| if (ret < 0) { |
| cm_printf("Write-file failed(%d)\n", ret); |
| break; |
| } |
| offset += ret; |
| if (len > ret) |
| lseek(fd, offset, SEEK_SET); |
| } |
| |
| if (len < 0) |
| cm_printf("Read failed, %s, %s(%d)\n", host_file, strerror(errno), errno); |
| else { |
| /*Notify EOF*/ |
| p->offset = _DH2B(EOF_OFFSET); |
| hci->length = _H2B(fix_length); |
| hci_length = HCI_HEADER_SIZE + fix_length; |
| |
| if (GAPI_WriteHCIPacket(&ID, hci_buf, hci_length) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write-HCI failed\n"); |
| return -1; |
| } |
| |
| rsp = (hci_file_response_t *) cmd_wait_event(dev_idx, WIMAX_FILE_RESULT, 5, NULL); |
| if (rsp) { |
| ret = _DB2H(rsp->result); |
| if (ret < 0) |
| cm_printf("Write-file failed(%d)\n", ret); |
| } |
| |
| if (total == offset) |
| cm_printf("\t%s => %s\n", host_file, target_file); |
| else |
| cm_printf("\tWrite-file mismatch(%d!=%d)\n", total, offset); |
| } |
| out: |
| close(fd); |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_delete_file(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int dev_idx; |
| char hci_buf[HCI_MAX_PACKET]; |
| hci_t *hci = (hci_t *) hci_buf; |
| int hci_length; |
| hci_file_response_t *rsp; |
| hci_file_delete_t *p = (hci_file_delete_t *) hci->data; |
| char *target_file = argv[1]; |
| int path_len; |
| int ret = -1; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx = (argc == 4 ? atoi(argv[3]) : DEFAULT_DEVICE); |
| |
| hci->cmd_evt = _H2B(WIMAX_DELETE_FILE); |
| strcpy(p->path, target_file); |
| path_len = strlen(p->path) + 1; |
| hci_length = sizeof(hci_file_delete_t) + path_len; |
| hci->length = _H2B(hci_length); |
| hci_length +=HCI_HEADER_SIZE; |
| |
| cmd_init_event(dev_idx); |
| |
| if (GAPI_WriteHCIPacket(&ID, hci_buf, hci_length) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write-HCI failed\n"); |
| return -1; |
| } |
| |
| rsp = (hci_file_response_t *) cmd_wait_event(dev_idx, WIMAX_FILE_RESULT, 5, NULL); |
| if (rsp) { |
| ret = _DB2H(rsp->result); |
| if (ret < 0) |
| cm_printf("Delete-file failed(%d)\n", ret); |
| else |
| cm_printf("\t%s deleted\n", target_file); |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static int read_image(GDEV_ID_P pID, int type, const char *file) |
| { |
| cm_printf("%s: not supported!\n", __func__); |
| return -1; |
| } |
| |
| static int cmd_read_image(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int type; |
| char *file; |
| int ret; |
| |
| type = strtoul(argv[1], NULL, 0); |
| file = argv[2]; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = (argc == 4 ? atoi(argv[3]) : DEFAULT_DEVICE); |
| |
| switch (type) { |
| case DLIMG_BL_EEPROM: |
| case DLIMG_OMA_XML: |
| case DLIMG_DEV_CERT: |
| case DLIMG_CERT1_U: |
| case DLIMG_CERT1_L: |
| case DLIMG_CERT2_U: |
| case DLIMG_CERT_BIG: |
| break; |
| default: |
| cm_printf("0x%x is unknown type\n", type); |
| return 0; |
| break; |
| } |
| |
| ret = read_image(&ID, type, file); |
| if (ret >= 0) |
| ret = ID.deviceIndex; |
| return ret; |
| } |
| |
| static int cmd_write_image(int argc, char *argv[]) |
| { |
| cm_printf("%s: not supported!\n", __func__); |
| return -1; |
| } |
| |
| static int control_image(GDEV_ID_P pID, int type, int cmd, void *buffer, int length) |
| { |
| int dev_idx = pID->deviceIndex; |
| char hci_buf[HCI_MAX_PACKET]; |
| hci_t *hci = (hci_t *) hci_buf; |
| int hci_length; |
| int data_len = 0, len; |
| hci_image_cmd_t *p = (hci_image_cmd_t *) hci->data; |
| hci_image_cmd_result_t *rsp; |
| int ret = 0; |
| |
| hci->cmd_evt = _H2B(WIMAX_IMAGE_CMD); |
| hci_length = sizeof(*p); |
| hci->length = _H2B(hci_length); |
| p->cmd = _H2B(cmd); |
| p->type = _H2B(type); |
| |
| cm_dprintf("cmd=%d, type=0x%x\n", cmd, type); |
| |
| hci_length += HCI_HEADER_SIZE; |
| if (GAPI_WriteHCIPacket(pID, hci_buf, hci_length) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write-HCI failed\n"); |
| ret = -1; |
| goto out; |
| } |
| |
| rsp = (hci_image_cmd_result_t *) cmd_wait_event(dev_idx, WIMAX_IMAGE_CMD_STATUS, |
| 3, &data_len); |
| if (!rsp) { |
| ret = -1; |
| goto out; |
| } |
| |
| ret = _DB2H(rsp->status); |
| if (ret) { |
| if (cmd == ICMD_GET_SIZE) { |
| if (buffer) |
| memcpy(buffer, &rsp->status, sizeof(rsp->status)); |
| ret = 0; |
| } |
| else { |
| cm_printf("Image result failed(%d)\n", ret); |
| ret = -1; |
| goto out; |
| } |
| } |
| else if ((len = data_len-sizeof(hci_image_cmd_result_t))) { |
| if (len > length) { |
| cm_eprintf("Buffer length is too small(%d)\n", length); |
| ret = -1; |
| } |
| else if (buffer) |
| memcpy(buffer, rsp->data, len); |
| } |
| out: |
| return ret; |
| } |
| |
| static int cmd_control_image(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int type, cmd; |
| char buffer[16]; |
| int ret; |
| |
| if (argc < 3) { |
| cm_eprintf("Invalid parameter\n"); |
| return 0; |
| } |
| |
| type = strtoul(argv[1], NULL, 0); |
| cmd = strtoul(argv[2], NULL, 0); |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = (argc == 4 ? atoi(argv[3]) : DEFAULT_DEVICE); |
| |
| switch (type) { |
| case DLIMG_DEV_CERT: |
| case DLIMG_CERT1_U: |
| case DLIMG_CERT1_L: |
| case DLIMG_CERT2_U: |
| case DLIMG_EAP_PARAM: |
| case DLIMG_CERT_BIG: |
| break; |
| default: |
| cm_printf("0x%x is unknown type\n", type); |
| goto out; |
| } |
| |
| if (cmd == ICMD_INVALIDATE) { |
| cm_printf("0x%x will be deleted! Are you sure (y/n) ? ", type); |
| if (!fgets(buffer, sizeof(buffer), stdin)) { |
| cm_eprintf("fgets error: %s(%d)\n", strerror(errno), errno); |
| goto out; |
| } |
| if (buffer[0] != 'y') |
| goto out; |
| } |
| |
| ret = control_image(&ID, type, cmd, buffer, sizeof(buffer)); |
| if (!ret) { |
| switch (cmd) { |
| case ICMD_INVALIDATE: |
| cm_printf("Type(0x%x) Deleted!\n", type); |
| break; |
| case ICMD_GET_SIZE: |
| cm_printf("Type(0x%x) Size: %u.\n", type, _U82U32(buffer)); |
| break; |
| case ICMD_GET_CRC32: |
| cm_printf("Type(0x%x) CRC32: 0x%x.\n", type, _U82U32(buffer)); |
| break; |
| } |
| } |
| out: |
| return ID.deviceIndex; |
| } |
| |
| static int read_param_block(GDEV_ID_P pID, void *buf, int offset, int length) |
| { |
| int dev_idx = pID->deviceIndex; |
| char hci_buf[HCI_MAX_PACKET]; |
| hci_t *hci = (hci_t *) hci_buf; |
| int hci_length; |
| int data_len = 0; |
| hci_image_payload_t *p = (hci_image_payload_t *) hci->data; |
| int ret = 0; |
| |
| cmd_init_event(dev_idx); |
| |
| hci->cmd_evt = _H2B(WIMAX_UL_IMAGE); |
| hci->length = _H2B(sizeof(*p)); |
| hci_length = HCI_HEADER_SIZE + sizeof(*p); |
| p->type = _H2B(DLIMG_CFG); |
| p->offset = _DH2B(offset); |
| |
| if (GAPI_WriteHCIPacket(pID, hci_buf, hci_length) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write-HCI failed\n"); |
| ret = -1; |
| goto out; |
| } |
| |
| p = (hci_image_payload_t *) cmd_wait_event(dev_idx, WIMAX_UL_IMAGE_RESULT, 5, &data_len); |
| if (!p) { |
| ret = -1; |
| goto out; |
| } |
| |
| if (data_len != sizeof(hci_image_payload_t)+length) { |
| cm_printf("Length mismatch(%d!=%d)\n", data_len, length); |
| ret = -1; |
| goto out; |
| } |
| |
| memcpy(buf, p->data, data_len); |
| |
| out: |
| return ret; |
| } |
| |
| static int write_param_block(GDEV_ID_P pID, void *buf, int offset, int length) |
| { |
| int dev_idx = pID->deviceIndex; |
| char hci_buf[HCI_MAX_PACKET]; |
| hci_t *hci = (hci_t *) hci_buf; |
| int hci_length; |
| int data_len = 0; |
| hci_image_payload_t *p = (hci_image_payload_t *) hci->data; |
| hci_image_response_t *rsp; |
| int ret = 0; |
| |
| cmd_init_event(dev_idx); |
| |
| hci->cmd_evt = _H2B(WIMAX_DL_IMAGE); |
| hci_length = sizeof(*p) + length; |
| hci->length = _H2B(hci_length); |
| p->type = _H2B(DLIMG_CFG); |
| p->offset = _DH2B(offset); |
| memcpy(p->data, buf, length); |
| |
| hci_length += HCI_HEADER_SIZE; |
| if (GAPI_WriteHCIPacket(pID, hci_buf, hci_length) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write-HCI failed\n"); |
| ret = -1; |
| goto out; |
| } |
| |
| rsp = (hci_image_response_t *) cmd_wait_event(dev_idx, WIMAX_DL_IMAGE_STATUS, 5, &data_len); |
| if (!rsp) { |
| ret = -1; |
| goto out; |
| } |
| |
| ret = _DB2H(rsp->result); |
| if (ret) { |
| cm_printf("Image result failed(%d)\n", ret); |
| ret = -1; |
| goto out; |
| } |
| |
| out: |
| return ret; |
| } |
| |
| static const char nv_param_usage[] = "<operation> [opeion]" |
| "\n <operation>" |
| "\n w.info Write NV info block parameters to NVRAM." |
| "\n v.info Print NV info block parameters." |
| "\n [options]" |
| "\n macaddr [6 bytes hex digits (Mac Address)]"; |
| |
| static int is_valid_mac(char *mac) |
| { |
| return (!(mac[0] & 0x1) |
| && (mac[0] | mac[1] | mac[2] | mac[3] | mac[4] | mac[5]) |
| ); |
| } |
| |
| static int cmd_nv_param(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| char buf[HCI_MAX_PACKET]; |
| char *operation = argv[1]; |
| char *param = argv[2]; |
| char *value = argv[3]; |
| int is_invalid_block = 0; |
| int i, ret = -1; |
| |
| if (argc < 2) |
| return -1; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = 1; /*Support for only single device.*/ |
| |
| if (!strcasecmp(operation, "w.info") || !strcasecmp(operation, "v.info")) { |
| struct wb_info_block_v2 *info = (struct wb_info_block_v2 *) buf; |
| ret = read_param_block(&ID, buf, WB_INFO_BLOCK_OFFSET_V2, sizeof(*info)); |
| if (ret < 0) |
| goto out; |
| |
| if (_H2B(info->magic) != MAGIC || info->version != MAP_VERSION_V2) |
| is_invalid_block = 1; |
| |
| if (!strcasecmp(operation, "v.info")) { |
| if (is_invalid_block) { |
| cm_printf("Info block is invalid(MAGIC:0x%04X, Version:%d)\n", |
| _H2B(info->magic), info->version); |
| goto out; |
| } |
| if (!strcasecmp(param, "macaddr")) { |
| unsigned char *p = info->mac_address; |
| cm_printf("%02X:%02X:%02X:%02X:%02X:%02X\n", p[0], p[1], p[2], p[3], p[4], p[5]); |
| goto out; |
| } |
| goto err; |
| } |
| else if (!strcasecmp(operation, "w.info")) { |
| if (is_invalid_block) { |
| memset(info, 0, sizeof(*info)); |
| info->magic = _H2B(MAGIC); |
| info->version = MAP_VERSION_V2; |
| } |
| |
| if (!strcasecmp(param, "macaddr")) { |
| char mac[6], ch[3] = {0}; |
| |
| if (strlen(value) != 12) |
| goto err; |
| |
| for (i = 0; i < 6; i++) { |
| memcpy(ch, value + 2 * i, 2); |
| mac[i] = strtoul(ch, NULL, 16); |
| } |
| if (!is_valid_mac(mac)) { |
| cm_printf("Invalid MAC address\n"); |
| goto out; |
| } |
| memcpy((char *) info->mac_address, mac, 6); |
| } |
| else |
| goto err; |
| |
| ret = write_param_block(&ID, buf, WB_INFO_BLOCK_OFFSET_V2, sizeof(*info)); |
| if (!ret) |
| cm_printf("Writing is success!\n"); |
| goto out; |
| } |
| } |
| |
| err: |
| print_cmd_usage(argv[0]); |
| |
| out: |
| return ret; |
| } |
| |
| static int run_script(int dev_idx, const char *scr_file) |
| { |
| #define IS_COMMENT(ch) ((ch)=='#' || (ch)=='\n') |
| GDEV_ID ID; |
| char file[256]; |
| FILE *fp; |
| char buf[1024]; |
| int ret, readn; |
| |
| if (strstr(scr_file, ".scr")) |
| strcpy(file, scr_file); |
| else |
| sprintf(file, "%s.scr", scr_file); |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = dev_idx; |
| |
| if (!(fp = fopen(file, "rt"))) { |
| cm_eprintf("fopen(%s) failed!\n", file); |
| return -1; |
| } |
| |
| cm_printf("Begin script(%s)\n", file); |
| |
| while (fgets(buf, sizeof(buf), fp)) { |
| readn = strlen(buf); |
| if (IS_COMMENT(*buf)) |
| continue; |
| cm_printf("%s", buf); |
| if ((ret = do_cmd(buf, readn)) == NO_CM_CMD) |
| ret = send_print_string(&ID, buf, readn); |
| } |
| cm_printf("End script(%s)\n", file); |
| |
| fclose(fp); |
| return ret; |
| } |
| |
| static int cmd_script(int argc, char *argv[]) |
| { |
| int ret, dev_idx; |
| |
| dev_idx = (argc == 3 ? atoi(argv[2]) : DEFAULT_DEVICE); |
| ret = run_script(dev_idx, argv[1]); |
| return ret; |
| } |
| |
| static int cmd_date(int argc, char *argv[]) |
| { |
| cm_printf("NOW: %s\n", cm_get_cur_date()); |
| return 1; |
| } |
| |
| static int cmd_sleep(int argc, char *argv[]) |
| { |
| int second; |
| |
| second = (argc == 2 ? atoi(argv[1]) : 1); |
| cm_printf("Sleep %d...\n", second); |
| sleep(second); |
| |
| return 1; |
| } |
| |
| #define MALLOC_CHECK |
| #if defined(MALLOC_CHECK) |
| #include <malloc.h> |
| static void malloc_check(void) |
| { |
| static struct mallinfo mem_info_st; |
| struct mallinfo mem_info; |
| |
| mem_info = mallinfo(); |
| |
| if (!memcmp(&mem_info_st, &mem_info, sizeof(struct mallinfo))) { |
| cm_printf("#malloc status has not been chagned#\n"); |
| } |
| else { |
| memcpy(&mem_info_st, &mem_info, sizeof(struct mallinfo)); |
| cm_printf("(%d) This is the total size of memory allocated with sbrk by malloc, in bytes.\n", mem_info.arena); |
| cm_printf("(%d) This is the number of chunks not in use.\n", mem_info.ordblks); |
| cm_printf("(%d) This field is unused.\n", mem_info.smblks); |
| cm_printf("(%d) This is the total number of chunks allocated with mmap.\n", mem_info.hblks); |
| cm_printf("(%d) This is the total size of memory allocated with mmap, in bytes.\n", mem_info.hblkhd); |
| cm_printf("(%d) This field is unused.\n", mem_info.usmblks); |
| cm_printf("(%d) This field is unused.\n", mem_info.fsmblks); |
| } |
| cm_printf("(%d) This is the total size of memory occupied by chunks handed out by malloc.\n", mem_info.uordblks); |
| cm_printf("(%d) This is the total size of memory occupied by free (not in use) chunks.\n", mem_info.fordblks); |
| cm_printf("(%d) This is the size of the top-most releasable chunk that normally borders the end of the heap.\n", mem_info.keepcost); |
| } |
| #endif |
| |
| static int cmd_chk(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int ret; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| #if defined(MALLOC_CHECK) |
| malloc_check(); |
| #endif |
| |
| return ret; |
| } |
| |
| static int cmd_test(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int ret; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_get_statistics(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| WIMAX_API_CONNECTION_STAT stat; |
| int ret; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| if (GAPI_GetStatistics(&ID, &stat) == GCT_API_RET_SUCCESS) { |
| cm_printf("\tTotal Rx Byte: %u\n", stat.totalRxByte); |
| cm_printf("\tTotal Tx Byte: %u\n", stat.totalTxByte); |
| cm_printf("\tTotal Rx Packets: %u\n", stat.totalRxPackets); |
| cm_printf("\tTotal Tx Packets: %u\n", stat.totalTxPackets); |
| } |
| else |
| cm_eprintf("GAPI_GetStatistics failed\n"); |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cm_uicc_power(int dev_idx, int on) |
| { |
| GDEV_ID ID; |
| char hci_buf[HCI_MAX_PACKET]; |
| hci_t *hci = (hci_t *) hci_buf; |
| int len; |
| |
| ID.apiHandle = cm_api_handle; |
| ID.deviceIndex = dev_idx; |
| |
| hci->cmd_evt = _H2B(WIMAX_UICC_CMD); |
| len = HCI_HEADER_SIZE; |
| |
| if (on) { |
| hci->data[0] = UICC_CMD_POWER_UP; |
| len += 1; |
| cm_printf("uicc on\n"); |
| } |
| else { |
| hci->data[0] = UICC_CMD_POWER_DOWN; |
| len += 1; |
| cm_printf("uicc off\n"); |
| } |
| hci->length = _H2B(len-HCI_HEADER_SIZE); |
| |
| if (GAPI_WriteHCIPacket(&ID, hci_buf, HCI_HEADER_SIZE+len) != GCT_API_RET_SUCCESS) { |
| cm_printf("Write HCI failure\n"); |
| return -1; |
| } |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_uicc(int argc, char *argv[]) |
| { |
| int dev_idx; |
| int ret = -1; |
| |
| dev_idx = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| if (!strcmp(argv[1], "on")) |
| ret = cm_uicc_power(DEFAULT_DEVICE, 1); |
| else if (!strcmp(argv[1], "off")) |
| ret = cm_uicc_power(DEFAULT_DEVICE, 0); |
| else { |
| cm_eprintf("Not supported command: %s\n", argv[1]); |
| ret = -1; |
| } |
| return ret; |
| } |
| |
| #if defined(CONFIG_DM_INTERFACE) |
| static int cmd_dmif(int argc, char *argv[]) |
| { |
| cm_common_conf_t *pconf = &cm_common_conf; |
| GDEV_ID ID; |
| WIMAX_API_PROFILE_INFO profile; |
| int ret, enabled = 0, profile_cnt = 1; |
| |
| if (argc < 2) { |
| invalid_param: |
| cm_printf("Invalid parameter\n"); |
| return -1; |
| } |
| |
| if (pconf->api_mode == GCT_WIMAX_API_PRIVILEGE_READ_ONLY) { |
| cm_eprintf("Permission denied\n"); |
| return -1; |
| } |
| |
| if (!strcasecmp(argv[1], "on")) |
| enabled = 1; |
| else if (strcasecmp(argv[1], "off")) |
| goto invalid_param; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 3? atoi(argv[2]) : DEFAULT_DEVICE); |
| |
| if (enabled) { |
| if (pconf->dm_interface_enable) { |
| cm_printf("DM Interface has been enabled already!\n"); |
| goto out; |
| } |
| if (dmif_init() < 0) { |
| ret = -1; |
| goto out; |
| } |
| pconf->dm_interface_enable = 1; |
| |
| if (GAPI_CmdControlPowerManagement(&ID, WIMAX_API_RF_ON) != GCT_API_RET_SUCCESS) { |
| cm_printf("device[%d] rf up failure\n", ID.deviceIndex); |
| ret = -1; |
| goto out; |
| } |
| |
| if (GAPI_GetSelectProfileList(&ID, &profile, (UINT32 *) &profile_cnt) |
| != GCT_API_RET_SUCCESS) { |
| cm_printf("Get profile failure\n"); |
| ret = -1; |
| goto out; |
| } |
| |
| if (GAPI_SetProfile(&ID, profile.profileID) != GCT_API_RET_SUCCESS ) { |
| cm_printf("Set profile failure\n"); |
| ret = -1; |
| goto out; |
| } |
| } |
| else { |
| pconf->dm_interface_enable = 0; |
| if (dmif_deinit() < 0) |
| ret = -1; |
| } |
| out: |
| return ret; |
| } |
| #endif |
| |
| #if defined(CONFIG_ENABLE_SERVICE_FLOW) |
| #include <arpa/inet.h> |
| static int cmd_gsf(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| WIMAX_API_DEVICE_STATUS DeviceStatus; |
| WIMAX_API_CONNECTION_PROGRESS_INFO ConnectionProgressInfo; |
| WIMAX_SERVICE_FLOW *pServiceFlow; |
| WIMAX_CLFR_RULE *pCrRule; |
| WIMAX_PHS_RULE *pPhsRule; |
| int count; |
| int ret; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| if (GAPI_GetDeviceStatus(&ID, &DeviceStatus, &ConnectionProgressInfo) |
| != GCT_API_RET_SUCCESS) { |
| cm_eprintf("GAPI_GetDeviceStatus Failure\n"); |
| return -1; |
| } |
| |
| if (DeviceStatus != WIMAX_API_DEVICE_STATUS_Data_Connected) { |
| cm_eprintf("DeviceStatus is not connected state(%d)\n", DeviceStatus); |
| return 0; |
| } |
| |
| // Enumerate service flow |
| ret = GAPI_BeginSFRead(&ID); |
| if (GCT_API_RET_SUCCESS != ret) { |
| cm_printf("Failed to GAPI_BeginSFRead=%d\n",ret); |
| } |
| |
| pServiceFlow = NULL; |
| pCrRule = NULL; |
| pPhsRule = NULL; |
| count = 0; |
| while ( GCT_API_RET_SUCCESS == (ret = GAPI_GetNextSF(&ID, pServiceFlow, 2, &pServiceFlow)) && pServiceFlow ) |
| { |
| cm_printf("SFID=0x%08x\n", ntohl(pServiceFlow->param.SFID)); |
| |
| while ( GCT_API_RET_SUCCESS == (ret = GAPI_GetNextClfrRule(&ID, pServiceFlow, pCrRule, &pCrRule)) && pCrRule ) |
| { |
| cm_printf("\tClfrIndex=%d\n", ntohs(pCrRule->PacketClassifierRuleIndex)); |
| } |
| |
| while ( GCT_API_RET_SUCCESS == (ret = GAPI_GetNextPHSRule(&ID, pServiceFlow, pPhsRule, &pPhsRule)) && pPhsRule ) |
| { |
| cm_printf("\tPHSI=%d\n", pPhsRule->PHSI); |
| } |
| |
| count++; |
| } |
| |
| if (!count) { |
| cm_printf("Service Flow does not exist.\n"); |
| } |
| else { |
| cm_printf("Service Flow count=[%d]\n", count); |
| } |
| |
| ret = GAPI_EndSFRead(&ID); |
| if (GCT_API_RET_SUCCESS != ret) { |
| cm_printf("Failed to GAPI_EndSFRead=%d\n",ret); |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_dsa_test(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| WIMAX_API_DEVICE_STATUS DeviceStatus; |
| WIMAX_API_CONNECTION_PROGRESS_INFO ConnectionProgressInfo; |
| WIMAX_SF_PARAM lSfParam; |
| WIMAX_CLFR_RULE lCrRule; |
| WIMAX_PHS_RULE lPhsRule; |
| int ret; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| if (GAPI_GetDeviceStatus(&ID, &DeviceStatus, &ConnectionProgressInfo) |
| != GCT_API_RET_SUCCESS) { |
| cm_eprintf("GAPI_GetDeviceStatus Failure\n"); |
| return -1; |
| } |
| |
| if (DeviceStatus != WIMAX_API_DEVICE_STATUS_Data_Connected) { |
| cm_eprintf("DeviceStatus is not connected state(%d)\n", DeviceStatus); |
| return -1; |
| } |
| |
| // DSA Test |
| unsigned char phsmdat[3] = {0x00,0x0f,0xf0}; |
| unsigned char phsf[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x59, 0xc0, 0xa8, 0x01, 0xfd}; |
| |
| lSfParam = sf_param_init; |
| lCrRule = classifier_rule_init; |
| lPhsRule = phs_rule_init; |
| |
| lSfParam.DL = 0; /* Uplink service flow */ |
| lSfParam.TrafficPriority = 1; |
| lSfParam.QosParamSetType = 7; |
| lSfParam.MaxSustainedTrafficRate = 88000; |
| lSfParam.MinReservedTrafficRate = 88000; |
| lSfParam.ULGrantSchedulingType = UL_SCHED_TYPE_ertPS; |
| lSfParam.RequestTransmissionPolicy = 0x02; |
| lSfParam.ToleratedJitter = 20; |
| lSfParam.MaxLatency = 60; |
| lSfParam.TypeOfDataDeliveryServices = DATA_SERVICE_UGS; |
| lSfParam.UnsolicitedGrantInterval = 20; |
| |
| lSfParam.CSSpecification = 1; |
| lSfParam.ARQEnable = 0; |
| lSfParam.HARQServiceFlows = 1; |
| lSfParam.PDUSNExtendedSubheaderForHARQReordering = 2; |
| lSfParam.FSNSize = 1; |
| |
| /* Classifier rule: UDP packets with destination port 5001 */ |
| lCrRule.ClassifierRulePriority = 1; |
| lCrRule.Protocol = 17; |
| lCrRule.ProtocolDestPort.low = 0; |
| lCrRule.ProtocolDestPort.high = 65535; |
| lCrRule.IPv4MaskedDestAddress.address.s_addr = inet_addr("192.168.1.253"); |
| lCrRule.IPv4MaskedDestAddress.mask.s_addr = inet_addr("255.255.255.255"); |
| |
| lPhsRule.PHSI = 1; |
| lPhsRule.PHSS = 20; |
| |
| memcpy(lPhsRule.PHSM, phsmdat, 3); |
| memcpy(lPhsRule.PHSF, phsf, 20); |
| |
| lPhsRule.PHSV = 1; |
| |
| ret = GAPI_CmdAddSF(&ID, &lSfParam, &lCrRule, &lPhsRule); |
| if (GCT_API_RET_SUCCESS != ret) { |
| cm_printf("Failed to GAPI_CmdAddSF=%d\n",ret); |
| } |
| else { |
| cm_printf("Success! GAPI_CmdAddSF, SFID=0x%08x\n", ntohl(lSfParam.SFID)); |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_dsc_test(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| WIMAX_API_DEVICE_STATUS DeviceStatus; |
| WIMAX_API_CONNECTION_PROGRESS_INFO ConnectionProgressInfo; |
| WIMAX_SERVICE_FLOW *sfp; |
| uint32_t sfid; |
| int ret; |
| |
| if (argc < 2) { |
| cm_eprintf("Invalid parameter\n"); |
| return 0; |
| } |
| |
| sfid = strtoul(argv[1], NULL, 16); |
| sfid = htonl(sfid); |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 3 ? atoi(argv[2]) : DEFAULT_DEVICE); |
| |
| if (GAPI_GetDeviceStatus(&ID, &DeviceStatus, &ConnectionProgressInfo) |
| != GCT_API_RET_SUCCESS) { |
| cm_eprintf("GAPI_GetDeviceStatus Failure\n"); |
| return -1; |
| } |
| |
| if (DeviceStatus != WIMAX_API_DEVICE_STATUS_Data_Connected) { |
| cm_eprintf("DeviceStatus is not connected state(%d)\n", DeviceStatus); |
| return -1; |
| } |
| |
| // DSC Test |
| ret = GAPI_GetServiceFlow(&ID, sfid, &sfp); |
| if (GCT_API_RET_SUCCESS != ret) { |
| cm_printf("Failed to GAPI_GetServiceFlow=%d\n",ret); |
| } |
| |
| if (sfp) { |
| sfp->param.MaxSustainedTrafficRate = 100000; |
| sfp->param.MinReservedTrafficRate = 100000; |
| |
| sfp->classification_rule[0].Protocol = 1; /* ICMP */ |
| |
| ret = GAPI_CmdChangeSF(&ID, &sfp->param, |
| DSC_ADD_CLASSIFIER, &sfp->classification_rule[0], |
| DSC_NOP_PHS, NULL); |
| |
| if (GCT_API_RET_SUCCESS != ret) { |
| cm_printf("Failed to GAPI_CmdChangeSF=%d\n",ret); |
| } |
| else { |
| cm_printf("Success! GAPI_CmdChangeSF\n"); |
| } |
| } else { |
| cm_printf("Not found Service Flow\n"); |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_dsd_test(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| WIMAX_API_DEVICE_STATUS DeviceStatus; |
| WIMAX_API_CONNECTION_PROGRESS_INFO ConnectionProgressInfo; |
| WIMAX_SERVICE_FLOW *sfp; |
| uint32_t sfid; |
| int ret; |
| |
| if (argc < 2) { |
| cm_eprintf("Invalid parameter\n"); |
| return 0; |
| } |
| |
| sfid = strtoul(argv[1], NULL, 16); |
| sfid = htonl(sfid); |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 3 ? atoi(argv[2]) : DEFAULT_DEVICE); |
| |
| if (GAPI_GetDeviceStatus(&ID, &DeviceStatus, &ConnectionProgressInfo) |
| != GCT_API_RET_SUCCESS) { |
| cm_eprintf("GAPI_GetDeviceStatus Failure\n"); |
| return -1; |
| } |
| |
| if (DeviceStatus != WIMAX_API_DEVICE_STATUS_Data_Connected) { |
| cm_eprintf("DeviceStatus is not connected state(%d)\n", DeviceStatus); |
| return -1; |
| } |
| |
| // DSD Test |
| ret = GAPI_GetServiceFlow(&ID, sfid, &sfp); |
| if (GCT_API_RET_SUCCESS != ret) { |
| cm_printf("Failed to GAPI_GetServiceFlow=%d\n",ret); |
| } |
| |
| if (sfp) { |
| ret = GAPI_CmdDeleteSF(&ID, &sfp->param); |
| if (GCT_API_RET_SUCCESS != ret) { |
| cm_printf("Failed to GAPI_CmdDeleteSF=%d\n",ret); |
| } |
| else { |
| cm_printf("Success! GAPI_CmdDeleteSF\n"); |
| } |
| } else { |
| cm_printf("Not found service flow\n"); |
| } |
| |
| return ID.deviceIndex; |
| } |
| #endif // CONFIG_ENABLE_SERVICE_FLOW |
| |
| static int cmd_command_mac_state(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int type; |
| int ret; |
| |
| if (argc < 2) { |
| cm_printf("Invalid parameter.\n"); |
| return -1; |
| } |
| |
| type = atoi(argv[1]); |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 3 ? atoi(argv[2]) : DEFAULT_DEVICE); |
| |
| if(GAPI_CmdMACState(&ID, type) |
| != GCT_API_RET_SUCCESS) { |
| cm_printf("Failed to GAPI_CmdMACState=%d\n",ret); |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_set_idle_mode_timeout(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| int timeoutSec; |
| int ret; |
| |
| if (argc < 2) { |
| cm_printf("Invalid parameter.\n"); |
| return -1; |
| } |
| |
| timeoutSec = atoi(argv[1]); |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 3 ? atoi(argv[2]) : DEFAULT_DEVICE); |
| |
| if(GAPI_SetIdleModeTimeout(&ID, timeoutSec) |
| != GCT_API_RET_SUCCESS) { |
| cm_printf("Failed to GAPI_SetIdleModeTimeout=%d\n",ret); |
| } |
| |
| return ID.deviceIndex; |
| |
| } |
| |
| static int cmd_get_phy_mac_basic(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| GCT_API_MAC_PHY_MAC_BASIC phy_mac_basic; |
| int ret; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| if(GAPI_GetPHY_MAC_Basic(&ID, &phy_mac_basic) |
| == GCT_API_RET_SUCCESS) { |
| |
| cm_printf("[PHY/MAC Basic]\n"); |
| cm_printf("FrameNumber: %u\n", phy_mac_basic.frame_number); |
| cm_printf("FCH: %u\n", phy_mac_basic.fch); |
| cm_printf("TTG: %u\n", phy_mac_basic.ttg); |
| cm_printf("RTG: %u\n", phy_mac_basic.rtg); |
| cm_printf("NumDlSymbol: %u\n", phy_mac_basic.num_dl_symbol); |
| cm_printf("NumUlSymbol: %u\n", phy_mac_basic.num_ul_symbol); |
| cm_printf("CurrentPI: %u\n", phy_mac_basic.current_pi); |
| cm_printf("PerviousPI: %u\n", phy_mac_basic.previous_pi); |
| cm_printf("UlPermBase: %u\n", phy_mac_basic.ul_perm_base); |
| cm_printf("MAC State: %u\n", phy_mac_basic.mac_state); |
| cm_printf("BSID: 0x%02x%02x%02x%02x%02x%02x\n", |
| phy_mac_basic.bsid[0], phy_mac_basic.bsid[1], phy_mac_basic.bsid[2], |
| phy_mac_basic.bsid[3], phy_mac_basic.bsid[4], phy_mac_basic.bsid[5]); |
| cm_printf("ulTime: %d\n", phy_mac_basic.ul_time); |
| cm_printf("Frequency: %u\n", phy_mac_basic.frequency); |
| cm_printf("Bandwidth: %u\n", phy_mac_basic.bandwidth); |
| cm_printf("TimeActive: %u\n", phy_mac_basic.time_active); |
| cm_printf("TimeSleep: %u\n", phy_mac_basic.time_sleep); |
| cm_printf("TimeIdle: %u\n", phy_mac_basic.time_idle); |
| cm_printf("BasicCID: %u\n", phy_mac_basic.basic_cid); |
| cm_printf("PrimaryCID: %u\n", phy_mac_basic.primary_cid); |
| |
| } else { |
| cm_printf("Failed to GAPI_GetPHY_MAC_Basic=%d\n",ret); |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_get_phy_mcs(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| GCT_API_MAC_PHY_MCS phy_mcs; |
| int i, j, k; |
| int ret; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| if(GAPI_GetPHY_MCS(&ID, &phy_mcs) |
| == GCT_API_RET_SUCCESS) { |
| |
| cm_printf("[PHY MCS: DL]\n"); |
| cm_printf("[OFDMA_FEC] [REPETITION] [MIMO] [num_burst] [num_burst_err] [len_pdu] [num_pdu]\n"); |
| |
| for (i = 0 ; i < OFDMA_FEC_MODE_CNT ; i++) |
| { |
| for (j = 0 ; j < REPETITION_CODING_CNT ; j++) |
| { |
| for (k = 0 ; k < MIMO_TYPE_CNT ; k++) |
| { |
| if (phy_mcs.dl_used[i][j][k]) |
| { |
| cm_printf("%10d %12d %6d %11u %15u %9u %9u\n", |
| i, j, k, |
| phy_mcs.dl[i][j][k].num_burst, phy_mcs.dl[i][j][k].num_burst_error, phy_mcs.dl[i][j][k].len_pdu, phy_mcs.dl[i][j][k].num_pdu); |
| } |
| } |
| } |
| } |
| |
| cm_printf("[PHY MCS: UL]\n"); |
| cm_printf("[OFDMA_FEC] [REPETITION] [MIMO] [num_burst] [num_burst_err] [len_pdu] [num_pdu]\n"); |
| |
| for (i = 0 ; i < OFDMA_FEC_MODE_CNT ; i++) |
| { |
| for (j = 0 ; j < REPETITION_CODING_CNT ; j++) |
| { |
| for (k = 0 ; k < MIMO_TYPE_CNT ; k++) |
| { |
| if (phy_mcs.ul_used[i][j][k]) |
| { |
| cm_printf("%10d %12d %6d %11u %15u %9u %9u\n", |
| i, j, k, |
| phy_mcs.ul[i][j][k].num_burst, phy_mcs.ul[i][j][k].num_burst_error, phy_mcs.ul[i][j][k].len_pdu, phy_mcs.ul[i][j][k].num_pdu); |
| } |
| } |
| } |
| } |
| |
| } else { |
| cm_printf("Failed to GAPI_GetPHY_MCS=%d\n",ret); |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static int cmd_get_phy_cinr_rssi(int argc, char *argv[]) |
| { |
| GDEV_ID ID; |
| GCT_API_MAC_PHY_CINR_RSSI phy_cinr_rssi; |
| int ret; |
| |
| ID.apiHandle = cm_api_handle; |
| ret = ID.deviceIndex = (argc == 2 ? atoi(argv[1]) : DEFAULT_DEVICE); |
| |
| if(GAPI_GetPHY_CINR_RSSI(&ID, &phy_cinr_rssi) |
| == GCT_API_RET_SUCCESS) { |
| |
| cm_printf("[PHY CINR/RSSI]\n"); |
| cm_printf("CINR-mean: %d\n", phy_cinr_rssi.cinr_mean); |
| cm_printf("CINR-std-dev: %d\n", phy_cinr_rssi.cinr_std_dev); |
| cm_printf("RSSI-mean: %d\n", phy_cinr_rssi.rssi_mean); |
| cm_printf("RSSI-std-dev: %d\n", phy_cinr_rssi.rssi_std_dev); |
| cm_printf("CINR_A_mean: %d\n", phy_cinr_rssi.cinr_a_mean); |
| cm_printf("CINR_B_mean: %d\n", phy_cinr_rssi.cinr_b_mean); |
| cm_printf("CINR-main: %d\n", phy_cinr_rssi.cinr_main); |
| cm_printf("CINR-diversity: %d\n", phy_cinr_rssi.cinr_diversity); |
| cm_printf("RSSI-main: %d\n", phy_cinr_rssi.rssi_main); |
| cm_printf("RSSI-diversity: %d\n", phy_cinr_rssi.rssi_diversity); |
| cm_printf("Preamble CINR(reuse3): %d\n", phy_cinr_rssi.preamble_cinr_reuse3); |
| cm_printf("Preamble CINR(reuse1): %d\n", phy_cinr_rssi.preamble_cinr_reuse1); |
| |
| } else { |
| cm_printf("Failed to GAPI_GetPHY_CINR_RSSI=%d\n",ret); |
| } |
| |
| return ID.deviceIndex; |
| } |
| |
| static cmd_t cmd_list[] = { |
| {"cm_gdl", "It shows device list", NULL, cmd_get_dev_list}, |
| {"cm_gs", "It shows the current WiMax state", "[device index: default 1]", |
| cmd_get_status}, |
| {"cm_ru", "RF up.", "[device index: default 1]", cmd_rf_up}, |
| {"cm_rd", "RF down.", "[device index: default 1]", cmd_rf_down}, |
| {"cm_gl", "Get link status.", "[device index: default 1]", cmd_get_link_status}, |
| {"cm_gp", "Get profile list.", "[device index: default 1]", cmd_get_profile_list}, |
| {"cm_sp", "Set profile.", "profile-index [device index: default 1]", cmd_set_profile}, |
| {"cm_gnl", "It shows network list.", "[device index: default 1]", cmd_get_net_list}, |
| {"cm_gnbl", "It shows neighbor list.", "[device index: default 1]", |
| cmd_get_neighbor_list}, |
| {"cm_cn", "It connects to network", "[profile-ID] [device index: default 1]", |
| cmd_connect_net}, |
| {"cm_auto_cn", "Auto connection on/off", "on|off [device index: default 1]", |
| cmd_auto_connect_net}, |
| {"cm_dn", "It disconnects from network", "[device index: default 1]", |
| cmd_disconnect_net}, |
| {"cm_scit", "Set scan interval(second)", "interval [device index: default 1]", |
| cmd_set_autoscan_interval}, |
| {"cm_scan", "It scan network", "scan-mode [device index: default 1]" |
| "\n scan-mode 0: wide scan" |
| "\n scan-mode 1: all subscriptions scan" |
| "\n scan-mode 2: current subscription scan", |
| cmd_scan}, |
| {"cm_auth", "This command is not used no more.", NULL, cmd_auth}, |
| {"cm_dc", "Delete Cert.", "cert-index", cmd_delete_cert}, |
| {"cm_gcs", "Get Cert.'s status", NULL, cmd_get_cert_status}, |
| {"cm_gcm", "Get Cert.'s mask", NULL, cmd_get_cert_mask}, |
| {"cm_scm", "Set Cert.'s mask.", "cert-mask", cmd_set_cert_mask}, |
| {"cm_gci", "Get Cert.'s information.", NULL, cmd_get_cert_info}, |
| {"cm_sd", "Set debug level.", "level", cmd_debug_level}, |
| {"cm_rfile", "Read file.", "host-file target-file [device index: default 1]", |
| cmd_read_file}, |
| {"cm_wfile", "Write file.", "host-file target-file [device index: default 1]", |
| cmd_write_file}, |
| {"cm_dfile", "Delete file.", "target-file [device index: default 1]", |
| cmd_delete_file}, |
| {"cm_rimg", "Read image.", "type image-path [device index: default 1]" |
| "\n type 7: EEPROM Bootloader (All bootloader block: 12KB)" |
| "\n type 0x100: oma-xml" |
| "\n type 0x101: device Cert(private-key should be merged)" |
| "\n type 0x102: server root CA" |
| "\n type 0x103: sub CA #1" |
| "\n type 0x104: sub CA #2" |
| "\n type 0x106: combined CA", |
| cmd_read_image}, |
| {"cm_wimg", "Write image.", "type image-path [device index: default 1]" |
| "\n type 0: kernel" |
| "\n type 1: filesystem" |
| "\n type 7: EEPROM Bootloader" |
| "\n type 0x100: oma-xml" |
| "\n type 0x101: device Cert(private-key should be merged)" |
| "\n type 0x102: server root CA" |
| "\n type 0x103: sub CA #1" |
| "\n type 0x104: sub CA #2" |
| "\n type 0x106: combined CA", |
| cmd_write_image}, |
| {"cm_cimg", "Control image.", "type command [device index: default 1]" |
| "\n type 0x101: device Cert(private-key should be merged)" |
| "\n type 0x102: server root CA" |
| "\n type 0x103: sub CA #1" |
| "\n type 0x104: sub CA #2" |
| "\n type 0x105: eap parameter" |
| "\n type 0x106: combined CA" |
| "\n command 0: delete image" |
| "\n command 1: get size of image" |
| "\n command 2: get crc32 of image", |
| cmd_control_image}, |
| {"cm_nv", "Read/Write NV parameters.", nv_param_usage, cmd_nv_param}, |
| {"cm_scr", "Run script", "script-file [device index: default 1]", cmd_script}, |
| {"cm_date", "Print current time", NULL, cmd_date}, |
| {"cm_sleep", "Sleep function for script test", NULL, cmd_sleep}, |
| {"cm_chk", "Check cm status", NULL, cmd_chk}, |
| {"cm_test", "Test function", NULL, cmd_test}, |
| {"cm_gst", "Get statistics", NULL, cmd_get_statistics}, |
| {"cm_uicc", "UICC Test function", "on|off [device index: default 1]", cmd_uicc}, |
| {"cm_macst", "Command MAC State", "type [device index: default 1]" |
| "\n type 0: Enter Sleep Mode" |
| "\n type 1: Exit Sleep Mode" |
| "\n type 2: Enter Idle Mode" |
| "\n type 3: Exit Idle Mode", |
| cmd_command_mac_state}, |
| {"cm_idletm", "Set Idle Mode Timeout", "timeout-sec [device index: default 1]", cmd_set_idle_mode_timeout}, |
| {"cm_gpmac", "Get PHY MAC Basic status", "[device index: default 1]", cmd_get_phy_mac_basic}, |
| {"cm_gpmcs", "Get PHY MCS status", "[device index: default 1]", cmd_get_phy_mcs}, |
| {"cm_gpcinr", "Get PHY CINR/RSSI", "[device index: default 1]", cmd_get_phy_cinr_rssi}, |
| #if defined(CONFIG_DM_INTERFACE) |
| {"cm_dmif", "DM interface on/off", "on/off", cmd_dmif}, |
| #endif |
| #if defined(CONFIG_ENABLE_SERVICE_FLOW) |
| {"cm_gsf", "Get current service flow list", "[device index: default 1]", cmd_gsf}, |
| {"cm_dsa_test", "Service Flow DSA Test function", "[device index: default 1]", cmd_dsa_test}, |
| {"cm_dsc_test", "Service Flow DSC Test function", "sfid [device index: default 1]", cmd_dsc_test}, |
| {"cm_dsd_test", "Service Flow DSD Test function", "sfid [device index: default 1]", cmd_dsd_test}, |
| #endif // CONFIG_ENABLE_SERVICE_FLOW |
| {"shell", "Execute shell prompt", NULL, cmd_shell}, |
| {"cm_exit", "Exit CM.", NULL, cmd_exit}, |
| {"cm_help", "Print command list.", NULL, cmd_help}, |
| {NULL, NULL, NULL, NULL} |
| }; |
| |
| static void print_cmd(cmd_t *cmd) |
| { |
| cm_printf("%s: %s\n", cmd->cmd, cmd->desc ? cmd->desc : ""); |
| cm_printf(" =>%s %s\n", cmd->cmd, cmd->param ? cmd->param : ""); |
| } |
| |
| static void print_cmd_usage(const char *cmd) |
| { |
| cmd_t *list = cmd_list; |
| |
| while (list->cmd) { |
| if (!strcmp(list->cmd, cmd)) { |
| print_cmd(list); |
| return; |
| } |
| list++; |
| } |
| } |
| |
| static void print_cmd_list(const char *cmd) |
| { |
| cmd_t *list = cmd_list; |
| |
| if (!cmd) |
| cm_printf("----------------------[ Command list ]----------------------\n"); |
| else |
| cm_printf("------------------------------------------------------------\n"); |
| |
| while (list->cmd) { |
| if (!cmd || !strcmp(cmd, list->cmd)) { |
| print_cmd(list); |
| if (cmd) |
| break; |
| } |
| list++; |
| } |
| cm_printf("------------------------------------------------------------\n"); |
| } |
| |
| static int do_cmd(char *cmd_line, int len) |
| { |
| char buf[1024]; |
| cmd_t *list = cmd_list; |
| int argc; |
| char *argv[16]; |
| |
| memcpy(buf, cmd_line, len); |
| __get_token_arg(buf, &argc, argv); |
| |
| if (argc) { |
| while (list->cmd) { |
| if (!strcmp(list->cmd, argv[0])) { |
| return list->func(argc, argv); |
| } |
| list++; |
| } |
| } |
| |
| return NO_CM_CMD; |
| } |
| |
| static int is_foreground_process(void) |
| { |
| if (tcgetpgrp(STDIN_FILENO) == getpgrp()) |
| return 1; |
| else |
| return 0; |
| } |
| |
| void cmd_run(void) |
| { |
| GDEV_ID ID; |
| cm_common_conf_t *pconf = &cm_common_conf; |
| char buf[1024]; |
| int readn, ret; |
| GCT_API_RET gret = 0; |
| |
| ID.apiHandle = cm_api_handle; |
| |
| if (pconf->run_script_file[0] && !access(pconf->run_script_file, 0)) |
| run_script(DEFAULT_DEVICE, pconf->run_script_file); |
| |
| if (!isatty(STDIN_FILENO) || !is_foreground_process()) { |
| cm_printf("Background!\n"); |
| while (1); |
| } |
| |
| while (fgets(buf, sizeof(buf), stdin)) { |
| readn = strlen(buf); |
| ret = do_cmd(buf, readn); |
| if (ret == EXIT_CM_CMD) |
| break; |
| if (cm_odev_cnt) { |
| if (ret == NO_CM_CMD || ret > 0) { |
| if (ret == NO_CM_CMD) { |
| if (!(ret = get_first_odev())) |
| continue; |
| } |
| else |
| readn = 1; |
| buf[readn-1] = '\n'; |
| ID.deviceIndex = ret; |
| gret = send_print_string(&ID, buf, readn); |
| } |
| } |
| } |
| } |