| /****************************************************************************** |
| * |
| * <: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, ¤t_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); |
| } |
| |
| /*@}*/ |