blob: cd2c38942b8badf7fc416103abfb476230853b10 [file] [log] [blame]
/******************************************************************************
*
* <:copyright-BRCM:2016:DUAL/GPL:standard
*
* Copyright (c) 2016 Broadcom
* All Rights Reserved
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed
* to you under the terms of the GNU General Public License version 2
* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
* with the following added to such license:
*
* As a special exception, the copyright holders of this software give
* you permission to link this software with independent modules, and
* to copy and distribute the resulting executable under terms of your
* choice, provided that you also meet, for each linked independent
* module, the terms and conditions of the license of that module.
* An independent module is a module which is not derived from this
* software. The special exception does not apply to any modifications
* of the software.
*
* Not withstanding the above, under no circumstances may you combine
* this software in any way with any other Broadcom software provided
* under a license other than the GPL, without Broadcom's express prior
* written consent.
*
* :>
*
*****************************************************************************/
/**
* @file bal_cli.c
* @brief Sample CLI which is used to exercise the BAL Public API
*
*/
/*@{*/
#include <bcmos_system.h>
#include <bal_common.h>
#include <bal_core.h>
#include <bal_api.h>
#include <bal_api_cli.h>
#include <bcmos_cli.h>
#include <rsc_mgr_cli.h>
#include <bal_switch_acc_term.h>
#include <bal_mac_util.h>
#include <bal_switch_util.h>
#include "bal_cli.h"
#ifdef OMCI_SVC
#include <omci_svc.h>
#include <omci_svc_cli.h>
#endif
#ifdef ENABLE_LOG
#include <bcm_dev_log.h>
/*
* CLI logging device ids
*/
dev_log_id log_id_cli;
/* CLI logging for ONU discovery */
dev_log_id log_id_cli_disc;
#endif
bcmcli_session *current_session;
/* user_exit_cb is only supported when BAL is built with a user application
* and run as a set of threads in that application (i.e. when bcmbal_init is
* called) */
static bcmbal_exit_cb user_exit_cb;
static bcmos_task bal_cli_thread;
static const char *bal_iwf_mode_to_str(bcmbal_iwf_mode iwf_mode)
{
static const char *str_table[BCMBAL_IWF_MODE__NUM_OF] =
{
[BCMBAL_IWF_MODE_DIRECT_MAPPING] = "direct_mapping",
[BCMBAL_IWF_MODE_PER_FLOW] = "per_flow",
};
return (iwf_mode >= BCMBAL_IWF_MODE__NUM_OF) ? "<unknown>" : str_table[iwf_mode];
}
static const char *bal_intf_maptable_to_str(bal_swapp_port_map_indx intf_maptable)
{
static const char *str_table[BAL_SWAPP_PORT_MAP__NUM_OF] =
{
[BAL_SWAPP_PORT_MAP_GPON] = "gpon",
[BAL_SWAPP_PORT_MAP_GPON_V3] = "gpon v3",
[BAL_SWAPP_PORT_MAP_EXP] = "exp",
[BAL_SWAPP_PORT_MAP_EXP2] = "exp 2",
[BAL_SWAPP_PORT_MAP_SVK4] = "svk4",
[BAL_SWAPP_PORT_MAP_EPON_TDMA] = "epon_tdma",
[BAL_SWAPP_PORT_MAP_EPON_1G] = "epon_1g",
[BAL_SWAPP_PORT_MAP_EPON_10G] = "epon_10g",
};
return (intf_maptable >= BAL_SWAPP_PORT_MAP__NUM_OF) ? "<unknown>" : str_table[intf_maptable];
}
/*
* show_confif CLI command handler
*/
static bcmos_errno bal_show_config_cmd(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nParms)
{
const bcmbal_config_params *bal_config = bcmbal_config_get();
bcmolt_devid device_id;
bcmcli_session_print(session, "interworking mode is : %s\n", bal_iwf_mode_to_str(bal_config->iwf_mode));
bcmcli_session_print(session, "switch interface mapping table is : %s\n", bal_intf_maptable_to_str(bal_config->intf_maptable));
bcmcli_session_print(session, "mac is %s loopback mode \n", bcmbal_is_mac_in_loopback() ? "IN" : "NOT IN");
bcmcli_session_print(session, "number of nni ports is : %d \n", bal_config->num_nni_ports);
bcmcli_session_print(session, "port for trapped packets is : %d \n", bal_config->trap_udp_port);
BCM_TOPO_FOR_EACH_DEV(device_id)
{
bcmcli_session_print(session, "pon mode of device %d is %s , number of pons is %d\n", device_id,
bcm_topo_dev_get_pon_mode_str(device_id),bcm_topo_dev_get_max_pon(device_id));
}
return BCM_ERR_OK;
}
/* "quit" CLI command handler */
static int _cmd_quit(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
{
bcmcli_stop(sess);
bcmcli_session_print(sess, "BAL core CLI terminated by 'Quit' command\n");
return 0;
}
/* "sleep" CLI command handler */
static bcmos_errno _cmd_sleep(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nParms)
{
bcmos_usleep(parm[0].value.unumber);
return BCM_ERR_OK;
}
/*****************************************************************************/
/**
* @brief A function to initialize the BAL core debug CLI
*
* @returns BCM_ERR_OK
*
*****************************************************************************/
static bcmos_errno bal_debug_init(void)
{
bcmcli_entry *dir;
dir = bcmcli_dir_add(NULL, "debug", "BAL core debug CLI", BCMCLI_ACCESS_ADMIN, NULL);
/* Add the resource manager debug CLI */
rsc_mgr_cli_init(dir);
mac_util_cli_init(dir);
/* Add the switch util debug CLI */
sw_util_cli_init(dir);
#ifdef OMCI_SVC
if (!omci_svc_is_loopback())
omci_svc_cli_init(dir);
#endif
BCMCLI_MAKE_CMD(dir, "sleep", "Sleep for a specified number of usec", _cmd_sleep,
BCMCLI_MAKE_PARM("time to sleep (microseconds)", "time to sleep (microseconds)", BCMCLI_PARM_UDECIMAL, 0));
BCMCLI_MAKE_CMD_NOPARM(dir, "show_config", "show bal configuration", bal_show_config_cmd);
/* Add os CLI */
bcmos_cli_init(dir);
return BCM_ERR_OK;
}
/** BAL Indication callback handler */
static void api_ind_cb_handler(bcmbal_obj *obj)
{
if((BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL == obj->obj_type) &&
(BCMBAL_SUB_ID_UNKNOWN == ((bcmbal_subscriber_terminal_cfg *)obj)->key.sub_term_id))
{
bcmbal_serial_number *p_serial_number =
&(((bcmbal_subscriber_terminal_cfg *)obj)->data.serial_number);
BCM_LOG(DEBUG, log_id_cli_disc, "Discovered ONU serial number "
"%2X%2X%2X%2X%1X%1X%1X%1X%1X%1X%1X%1X "
"on PON %d\n",
p_serial_number->vendor_id[0],
p_serial_number->vendor_id[1],
p_serial_number->vendor_id[2],
p_serial_number->vendor_id[3],
p_serial_number->vendor_specific[0]>>4 & 0x0f,
p_serial_number->vendor_specific[0] & 0x0f,
p_serial_number->vendor_specific[1]>>4 & 0x0f,
p_serial_number->vendor_specific[1] & 0x0f,
p_serial_number->vendor_specific[2]>>4 & 0x0f,
p_serial_number->vendor_specific[2] & 0x0f,
p_serial_number->vendor_specific[3]>>4 & 0x0f,
p_serial_number->vendor_specific[3] & 0x0f,
((bcmbal_subscriber_terminal_cfg *)obj)->key.intf_id);
}
else
{
char obj_key_str[256];
bal_obj_key_str_get(obj, obj_key_str);
BCM_LOG(INFO, log_id_cli,
"Processing CLI API \'%s\' IND callback (status is %s), (key is %s)\n",
bcmbal_objtype_str(obj->obj_type),
bcmos_strerror(obj->status),
obj_key_str);
}
return;
}
/* Execute CLI script */
bcmos_errno bcmbal_cli_exec_script(const char *filename)
{
char buf[1024];
FILE *f;
f = fopen(filename, "r");
if (!f)
{
printf("Can't open file %s for reading\n", filename);
return BCM_ERR_PARM;
}
while (!bcmcli_is_stopped(current_session) && !feof(f) &&
fgets(buf, sizeof(buf)-1, f))
{
bcmcli_print(current_session, "%s", buf);
bcmcli_parse(current_session, buf);
}
fclose(f);
return BCM_ERR_OK;
}
/* Execute init CLI script if any */
bcmos_errno bcmbal_cli_exec_init_script(void)
{
bcmos_errno ret = BCM_ERR_OK;
const char *init_script = bcmbal_config_get()->init_script;
if (init_script)
ret = bcmbal_cli_exec_script(init_script);
return ret;
}
/* CLI thread handler */
static int _bal_cli_thread_handler(long data)
{
char init_string[]="\n";
bcmcli_session *sess = current_session;
/* Switch to interactive mode if not stopped in the init script */
if (!bcmcli_is_stopped(sess))
{
/* Force a CLI command prompt
*
* The string passed into the parse function
* must be modifiable, so a string constant like
* bcmcli_parse(current_session, "\n") will not
* work.
*/
bcmcli_parse(sess, init_string);
/* Process user input until EOF or quit command */
bcmcli_driver(sess);
};
BCM_LOG(INFO, log_id_core, "BAL CLI terminated\n");
/* call the user's exit callback, if any */
if(user_exit_cb) (*user_exit_cb)();
current_session = NULL;
bcmcli_session_close(sess);
return 0;
}
/*****************************************************************************/
/**
* @brief This function initializes the BAL CLI
*
* @returns BCM_ERR_OK on success, other bcmos_errno codes otherwise
*
*****************************************************************************/
bcmos_errno bcmbal_cli_init(bcmbal_exit_cb exit_cb)
{
const bcmbal_config_params *bal_config = bcmbal_config_get();
bcmcli_session_parm mon_session_parm = {};
bcmos_task_parm bal_cli_task_p = {};
bcmcli_entry *dir;
bcmos_errno ret;
bcmbal_cb_cfg cb_cfg = {};
mon_session_parm.access_right = bal_config->access;
mon_session_parm.line_edit_mode = bal_config->edit_mode;
#ifdef ENABLE_LOG
/*
* Initialize the logging context
*/
log_id_cli = bcm_dev_log_id_register("CLI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
BUG_ON(log_id_cli == DEV_LOG_INVALID_ID);
log_id_cli_disc = bcm_dev_log_id_register("CLI_DISC", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
BUG_ON(log_id_cli_disc == DEV_LOG_INVALID_ID);
#endif
do
{
ret = bcmcli_session_open(&mon_session_parm, &current_session);
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_cli, "Can't open CLI session\n");
break;
}
{
cb_cfg.obj_type = BCMBAL_OBJ_ID_ANY;
cb_cfg.ind_cb_hdlr = (f_bcmbal_ind_handler )api_ind_cb_handler;
bcmbal_subscribe_ind(&cb_cfg);
}
/* Initialize the bal api cli UI */
if(NULL == (dir = bcmcli_dir_add(NULL, "bal", "BAL API access", BCMCLI_ACCESS_ADMIN, NULL)))
{
BCM_LOG(ERROR, log_id_cli, "Could not initialize the BAL API CLI hierarchy\n");
break;
}
ret = bcmbal_apicli_add_commands(current_session, dir);
if (ret != BCM_ERR_OK)
{
BCM_LOG(ERROR, log_id_cli, "Could not initialize the BAL CLI: %s\n", bcmos_strerror(ret));
break;
}
/* Initialize the bal "debug" CLI */
ret = bal_debug_init();
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_core, "Error initializing the bal debug cli\n");
break;
}
#ifdef ENABLE_LOG
/* Add logger CLI */
bcm_dev_log_cli_init(NULL);
#endif
/* Add "quit" command at the top level */
BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", _cmd_quit);
/* Record the user's choice of callback function on our exit (may be NULL!) */
user_exit_cb = exit_cb;
/* Create BAL CLI thread */
bal_cli_task_p.name = "bal_cli_thread";
bal_cli_task_p.handler = _bal_cli_thread_handler;
bal_cli_task_p.priority = TASK_PRIORITY_CLI;
ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
if (BCM_ERR_OK != ret)
{
bcmos_printf("Couldn't create BAL CLI thread\n");
return ret;
}
} while(0);
return ret;
}
/*****************************************************************************/
/**
* @brief This function un-initializes the BAL CLI
*
* @returns BCM_ERR_OK
*
*****************************************************************************/
bcmos_errno bcmbal_cli_finish(void)
{
if (!current_session)
return BCM_ERR_OK;
bcmbal_cli_stop();
bcmos_task_destroy(&bal_cli_thread);
bcmbal_api_finish();
return BCM_ERR_OK;
}
/* Stop CLI */
void bcmbal_cli_stop(void)
{
if (current_session)
{
bcmcli_stop(current_session);
while (current_session)
bcmos_usleep(10000);
}
}
/* Is CLI terminated? */
bcmos_bool bcmbal_cli_is_terminated(void)
{
return (current_session == NULL) || bcmcli_is_stopped(current_session);
}
/*@}*/