blob: d75c1ca75e4d137d770c342795cb3a907bda2936 [file] [log] [blame]
// 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);
}
}
}
}