Shad Ansari | 2f7f9be | 2017-06-07 13:34:53 -0700 | [diff] [blame^] | 1 | /****************************************************************************** |
| 2 | * |
| 3 | * <:copyright-BRCM:2016:DUAL/GPL:standard |
| 4 | * |
| 5 | * Copyright (c) 2016 Broadcom |
| 6 | * All Rights Reserved |
| 7 | * |
| 8 | * Unless you and Broadcom execute a separate written software license |
| 9 | * agreement governing use of this software, this software is licensed |
| 10 | * to you under the terms of the GNU General Public License version 2 |
| 11 | * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| 12 | * with the following added to such license: |
| 13 | * |
| 14 | * As a special exception, the copyright holders of this software give |
| 15 | * you permission to link this software with independent modules, and |
| 16 | * to copy and distribute the resulting executable under terms of your |
| 17 | * choice, provided that you also meet, for each linked independent |
| 18 | * module, the terms and conditions of the license of that module. |
| 19 | * An independent module is a module which is not derived from this |
| 20 | * software. The special exception does not apply to any modifications |
| 21 | * of the software. |
| 22 | * |
| 23 | * Not withstanding the above, under no circumstances may you combine |
| 24 | * this software in any way with any other Broadcom software provided |
| 25 | * under a license other than the GPL, without Broadcom's express prior |
| 26 | * written consent. |
| 27 | * |
| 28 | * :> |
| 29 | * |
| 30 | *****************************************************************************/ |
| 31 | |
| 32 | /** |
| 33 | * @file bal_cli.c |
| 34 | * @brief Sample CLI which is used to exercise the BAL Public API |
| 35 | * |
| 36 | */ |
| 37 | |
| 38 | /*@{*/ |
| 39 | |
| 40 | #include <bcmos_system.h> |
| 41 | |
| 42 | #include <bal_common.h> |
| 43 | |
| 44 | #include <bal_core.h> |
| 45 | #include <bal_api.h> |
| 46 | #include <bal_api_cli.h> |
| 47 | #include <bcmos_cli.h> |
| 48 | #include <rsc_mgr_cli.h> |
| 49 | #include <bal_switch_acc_term.h> |
| 50 | #include <bal_mac_util.h> |
| 51 | #include <bal_switch_util.h> |
| 52 | #include "bal_cli.h" |
| 53 | |
| 54 | #ifdef OMCI_SVC |
| 55 | #include <omci_svc.h> |
| 56 | #include <omci_svc_cli.h> |
| 57 | #endif |
| 58 | |
| 59 | #ifdef ENABLE_LOG |
| 60 | #include <bcm_dev_log.h> |
| 61 | /* |
| 62 | * CLI logging device ids |
| 63 | */ |
| 64 | dev_log_id log_id_cli; |
| 65 | |
| 66 | /* CLI logging for ONU discovery */ |
| 67 | dev_log_id log_id_cli_disc; |
| 68 | #endif |
| 69 | bcmcli_session *current_session; |
| 70 | |
| 71 | /* user_exit_cb is only supported when BAL is built with a user application |
| 72 | * and run as a set of threads in that application (i.e. when bcmbal_init is |
| 73 | * called) */ |
| 74 | static bcmbal_exit_cb user_exit_cb; |
| 75 | static bcmos_task bal_cli_thread; |
| 76 | |
| 77 | static const char *bal_iwf_mode_to_str(bcmbal_iwf_mode iwf_mode) |
| 78 | { |
| 79 | static const char *str_table[BCMBAL_IWF_MODE__NUM_OF] = |
| 80 | { |
| 81 | [BCMBAL_IWF_MODE_DIRECT_MAPPING] = "direct_mapping", |
| 82 | [BCMBAL_IWF_MODE_PER_FLOW] = "per_flow", |
| 83 | }; |
| 84 | return (iwf_mode >= BCMBAL_IWF_MODE__NUM_OF) ? "<unknown>" : str_table[iwf_mode]; |
| 85 | } |
| 86 | |
| 87 | static const char *bal_intf_maptable_to_str(bal_swapp_port_map_indx intf_maptable) |
| 88 | { |
| 89 | static const char *str_table[BAL_SWAPP_PORT_MAP__NUM_OF] = |
| 90 | { |
| 91 | [BAL_SWAPP_PORT_MAP_GPON] = "gpon", |
| 92 | [BAL_SWAPP_PORT_MAP_GPON_V3] = "gpon v3", |
| 93 | [BAL_SWAPP_PORT_MAP_EXP] = "exp", |
| 94 | [BAL_SWAPP_PORT_MAP_EXP2] = "exp 2", |
| 95 | [BAL_SWAPP_PORT_MAP_SVK4] = "svk4", |
| 96 | [BAL_SWAPP_PORT_MAP_EPON_TDMA] = "epon_tdma", |
| 97 | [BAL_SWAPP_PORT_MAP_EPON_1G] = "epon_1g", |
| 98 | [BAL_SWAPP_PORT_MAP_EPON_10G] = "epon_10g", |
| 99 | }; |
| 100 | return (intf_maptable >= BAL_SWAPP_PORT_MAP__NUM_OF) ? "<unknown>" : str_table[intf_maptable]; |
| 101 | } |
| 102 | |
| 103 | /* |
| 104 | * show_confif CLI command handler |
| 105 | */ |
| 106 | static bcmos_errno bal_show_config_cmd(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nParms) |
| 107 | { |
| 108 | const bcmbal_config_params *bal_config = bcmbal_config_get(); |
| 109 | bcmolt_devid device_id; |
| 110 | |
| 111 | bcmcli_session_print(session, "interworking mode is : %s\n", bal_iwf_mode_to_str(bal_config->iwf_mode)); |
| 112 | bcmcli_session_print(session, "switch interface mapping table is : %s\n", bal_intf_maptable_to_str(bal_config->intf_maptable)); |
| 113 | bcmcli_session_print(session, "mac is %s loopback mode \n", bcmbal_is_mac_in_loopback() ? "IN" : "NOT IN"); |
| 114 | bcmcli_session_print(session, "number of nni ports is : %d \n", bal_config->num_nni_ports); |
| 115 | bcmcli_session_print(session, "port for trapped packets is : %d \n", bal_config->trap_udp_port); |
| 116 | |
| 117 | BCM_TOPO_FOR_EACH_DEV(device_id) |
| 118 | { |
| 119 | bcmcli_session_print(session, "pon mode of device %d is %s , number of pons is %d\n", device_id, |
| 120 | bcm_topo_dev_get_pon_mode_str(device_id),bcm_topo_dev_get_max_pon(device_id)); |
| 121 | } |
| 122 | |
| 123 | return BCM_ERR_OK; |
| 124 | } |
| 125 | |
| 126 | /* "quit" CLI command handler */ |
| 127 | static int _cmd_quit(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms) |
| 128 | { |
| 129 | bcmcli_stop(sess); |
| 130 | bcmcli_session_print(sess, "BAL core CLI terminated by 'Quit' command\n"); |
| 131 | return 0; |
| 132 | } |
| 133 | |
| 134 | /* "sleep" CLI command handler */ |
| 135 | static bcmos_errno _cmd_sleep(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nParms) |
| 136 | { |
| 137 | bcmos_usleep(parm[0].value.unumber); |
| 138 | return BCM_ERR_OK; |
| 139 | } |
| 140 | |
| 141 | /*****************************************************************************/ |
| 142 | /** |
| 143 | * @brief A function to initialize the BAL core debug CLI |
| 144 | * |
| 145 | * @returns BCM_ERR_OK |
| 146 | * |
| 147 | *****************************************************************************/ |
| 148 | static bcmos_errno bal_debug_init(void) |
| 149 | { |
| 150 | bcmcli_entry *dir; |
| 151 | |
| 152 | dir = bcmcli_dir_add(NULL, "debug", "BAL core debug CLI", BCMCLI_ACCESS_ADMIN, NULL); |
| 153 | |
| 154 | /* Add the resource manager debug CLI */ |
| 155 | rsc_mgr_cli_init(dir); |
| 156 | mac_util_cli_init(dir); |
| 157 | |
| 158 | /* Add the switch util debug CLI */ |
| 159 | sw_util_cli_init(dir); |
| 160 | |
| 161 | #ifdef OMCI_SVC |
| 162 | if (!omci_svc_is_loopback()) |
| 163 | omci_svc_cli_init(dir); |
| 164 | #endif |
| 165 | |
| 166 | BCMCLI_MAKE_CMD(dir, "sleep", "Sleep for a specified number of usec", _cmd_sleep, |
| 167 | BCMCLI_MAKE_PARM("time to sleep (microseconds)", "time to sleep (microseconds)", BCMCLI_PARM_UDECIMAL, 0)); |
| 168 | |
| 169 | BCMCLI_MAKE_CMD_NOPARM(dir, "show_config", "show bal configuration", bal_show_config_cmd); |
| 170 | |
| 171 | /* Add os CLI */ |
| 172 | bcmos_cli_init(dir); |
| 173 | |
| 174 | return BCM_ERR_OK; |
| 175 | } |
| 176 | |
| 177 | /** BAL Indication callback handler */ |
| 178 | static void api_ind_cb_handler(bcmbal_obj *obj) |
| 179 | { |
| 180 | |
| 181 | if((BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL == obj->obj_type) && |
| 182 | (BCMBAL_SUB_ID_UNKNOWN == ((bcmbal_subscriber_terminal_cfg *)obj)->key.sub_term_id)) |
| 183 | { |
| 184 | bcmbal_serial_number *p_serial_number = |
| 185 | &(((bcmbal_subscriber_terminal_cfg *)obj)->data.serial_number); |
| 186 | |
| 187 | BCM_LOG(DEBUG, log_id_cli_disc, "Discovered ONU serial number " |
| 188 | "%2X%2X%2X%2X%1X%1X%1X%1X%1X%1X%1X%1X " |
| 189 | "on PON %d\n", |
| 190 | p_serial_number->vendor_id[0], |
| 191 | p_serial_number->vendor_id[1], |
| 192 | p_serial_number->vendor_id[2], |
| 193 | p_serial_number->vendor_id[3], |
| 194 | p_serial_number->vendor_specific[0]>>4 & 0x0f, |
| 195 | p_serial_number->vendor_specific[0] & 0x0f, |
| 196 | p_serial_number->vendor_specific[1]>>4 & 0x0f, |
| 197 | p_serial_number->vendor_specific[1] & 0x0f, |
| 198 | p_serial_number->vendor_specific[2]>>4 & 0x0f, |
| 199 | p_serial_number->vendor_specific[2] & 0x0f, |
| 200 | p_serial_number->vendor_specific[3]>>4 & 0x0f, |
| 201 | p_serial_number->vendor_specific[3] & 0x0f, |
| 202 | |
| 203 | ((bcmbal_subscriber_terminal_cfg *)obj)->key.intf_id); |
| 204 | } |
| 205 | else |
| 206 | { |
| 207 | char obj_key_str[256]; |
| 208 | |
| 209 | bal_obj_key_str_get(obj, obj_key_str); |
| 210 | |
| 211 | BCM_LOG(INFO, log_id_cli, |
| 212 | "Processing CLI API \'%s\' IND callback (status is %s), (key is %s)\n", |
| 213 | bcmbal_objtype_str(obj->obj_type), |
| 214 | bcmos_strerror(obj->status), |
| 215 | obj_key_str); |
| 216 | } |
| 217 | |
| 218 | return; |
| 219 | } |
| 220 | |
| 221 | /* Execute CLI script */ |
| 222 | bcmos_errno bcmbal_cli_exec_script(const char *filename) |
| 223 | { |
| 224 | char buf[1024]; |
| 225 | FILE *f; |
| 226 | |
| 227 | f = fopen(filename, "r"); |
| 228 | if (!f) |
| 229 | { |
| 230 | printf("Can't open file %s for reading\n", filename); |
| 231 | return BCM_ERR_PARM; |
| 232 | } |
| 233 | while (!bcmcli_is_stopped(current_session) && !feof(f) && |
| 234 | fgets(buf, sizeof(buf)-1, f)) |
| 235 | { |
| 236 | bcmcli_print(current_session, "%s", buf); |
| 237 | bcmcli_parse(current_session, buf); |
| 238 | } |
| 239 | fclose(f); |
| 240 | return BCM_ERR_OK; |
| 241 | } |
| 242 | |
| 243 | /* Execute init CLI script if any */ |
| 244 | bcmos_errno bcmbal_cli_exec_init_script(void) |
| 245 | { |
| 246 | bcmos_errno ret = BCM_ERR_OK; |
| 247 | const char *init_script = bcmbal_config_get()->init_script; |
| 248 | |
| 249 | if (init_script) |
| 250 | ret = bcmbal_cli_exec_script(init_script); |
| 251 | |
| 252 | return ret; |
| 253 | } |
| 254 | |
| 255 | /* CLI thread handler */ |
| 256 | static int _bal_cli_thread_handler(long data) |
| 257 | { |
| 258 | char init_string[]="\n"; |
| 259 | bcmcli_session *sess = current_session; |
| 260 | |
| 261 | /* Switch to interactive mode if not stopped in the init script */ |
| 262 | if (!bcmcli_is_stopped(sess)) |
| 263 | { |
| 264 | /* Force a CLI command prompt |
| 265 | * |
| 266 | * The string passed into the parse function |
| 267 | * must be modifiable, so a string constant like |
| 268 | * bcmcli_parse(current_session, "\n") will not |
| 269 | * work. |
| 270 | */ |
| 271 | bcmcli_parse(sess, init_string); |
| 272 | |
| 273 | /* Process user input until EOF or quit command */ |
| 274 | bcmcli_driver(sess); |
| 275 | }; |
| 276 | BCM_LOG(INFO, log_id_core, "BAL CLI terminated\n"); |
| 277 | |
| 278 | /* call the user's exit callback, if any */ |
| 279 | if(user_exit_cb) (*user_exit_cb)(); |
| 280 | |
| 281 | current_session = NULL; |
| 282 | bcmcli_session_close(sess); |
| 283 | |
| 284 | return 0; |
| 285 | } |
| 286 | |
| 287 | /*****************************************************************************/ |
| 288 | /** |
| 289 | * @brief This function initializes the BAL CLI |
| 290 | * |
| 291 | * @returns BCM_ERR_OK on success, other bcmos_errno codes otherwise |
| 292 | * |
| 293 | *****************************************************************************/ |
| 294 | bcmos_errno bcmbal_cli_init(bcmbal_exit_cb exit_cb) |
| 295 | { |
| 296 | const bcmbal_config_params *bal_config = bcmbal_config_get(); |
| 297 | bcmcli_session_parm mon_session_parm = {}; |
| 298 | bcmos_task_parm bal_cli_task_p = {}; |
| 299 | bcmcli_entry *dir; |
| 300 | bcmos_errno ret; |
| 301 | bcmbal_cb_cfg cb_cfg = {}; |
| 302 | |
| 303 | mon_session_parm.access_right = bal_config->access; |
| 304 | mon_session_parm.line_edit_mode = bal_config->edit_mode; |
| 305 | |
| 306 | #ifdef ENABLE_LOG |
| 307 | /* |
| 308 | * Initialize the logging context |
| 309 | */ |
| 310 | log_id_cli = bcm_dev_log_id_register("CLI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH); |
| 311 | BUG_ON(log_id_cli == DEV_LOG_INVALID_ID); |
| 312 | |
| 313 | log_id_cli_disc = bcm_dev_log_id_register("CLI_DISC", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH); |
| 314 | BUG_ON(log_id_cli_disc == DEV_LOG_INVALID_ID); |
| 315 | #endif |
| 316 | |
| 317 | do |
| 318 | { |
| 319 | ret = bcmcli_session_open(&mon_session_parm, ¤t_session); |
| 320 | if(BCM_ERR_OK != ret) |
| 321 | { |
| 322 | BCM_LOG(ERROR, log_id_cli, "Can't open CLI session\n"); |
| 323 | break; |
| 324 | } |
| 325 | |
| 326 | { |
| 327 | cb_cfg.obj_type = BCMBAL_OBJ_ID_ANY; |
| 328 | cb_cfg.ind_cb_hdlr = (f_bcmbal_ind_handler )api_ind_cb_handler; |
| 329 | |
| 330 | bcmbal_subscribe_ind(&cb_cfg); |
| 331 | } |
| 332 | |
| 333 | /* Initialize the bal api cli UI */ |
| 334 | if(NULL == (dir = bcmcli_dir_add(NULL, "bal", "BAL API access", BCMCLI_ACCESS_ADMIN, NULL))) |
| 335 | { |
| 336 | BCM_LOG(ERROR, log_id_cli, "Could not initialize the BAL API CLI hierarchy\n"); |
| 337 | break; |
| 338 | } |
| 339 | |
| 340 | ret = bcmbal_apicli_add_commands(current_session, dir); |
| 341 | if (ret != BCM_ERR_OK) |
| 342 | { |
| 343 | BCM_LOG(ERROR, log_id_cli, "Could not initialize the BAL CLI: %s\n", bcmos_strerror(ret)); |
| 344 | break; |
| 345 | } |
| 346 | |
| 347 | /* Initialize the bal "debug" CLI */ |
| 348 | ret = bal_debug_init(); |
| 349 | if(BCM_ERR_OK != ret) |
| 350 | { |
| 351 | BCM_LOG(ERROR, log_id_core, "Error initializing the bal debug cli\n"); |
| 352 | break; |
| 353 | } |
| 354 | |
| 355 | #ifdef ENABLE_LOG |
| 356 | /* Add logger CLI */ |
| 357 | bcm_dev_log_cli_init(NULL); |
| 358 | #endif |
| 359 | |
| 360 | /* Add "quit" command at the top level */ |
| 361 | BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", _cmd_quit); |
| 362 | |
| 363 | |
| 364 | /* Record the user's choice of callback function on our exit (may be NULL!) */ |
| 365 | user_exit_cb = exit_cb; |
| 366 | |
| 367 | /* Create BAL CLI thread */ |
| 368 | bal_cli_task_p.name = "bal_cli_thread"; |
| 369 | bal_cli_task_p.handler = _bal_cli_thread_handler; |
| 370 | bal_cli_task_p.priority = TASK_PRIORITY_CLI; |
| 371 | |
| 372 | ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p); |
| 373 | if (BCM_ERR_OK != ret) |
| 374 | { |
| 375 | bcmos_printf("Couldn't create BAL CLI thread\n"); |
| 376 | return ret; |
| 377 | } |
| 378 | |
| 379 | } while(0); |
| 380 | |
| 381 | return ret; |
| 382 | } |
| 383 | |
| 384 | /*****************************************************************************/ |
| 385 | /** |
| 386 | * @brief This function un-initializes the BAL CLI |
| 387 | * |
| 388 | * @returns BCM_ERR_OK |
| 389 | * |
| 390 | *****************************************************************************/ |
| 391 | bcmos_errno bcmbal_cli_finish(void) |
| 392 | { |
| 393 | if (!current_session) |
| 394 | return BCM_ERR_OK; |
| 395 | |
| 396 | bcmbal_cli_stop(); |
| 397 | |
| 398 | bcmos_task_destroy(&bal_cli_thread); |
| 399 | |
| 400 | bcmbal_api_finish(); |
| 401 | |
| 402 | return BCM_ERR_OK; |
| 403 | } |
| 404 | |
| 405 | |
| 406 | /* Stop CLI */ |
| 407 | void bcmbal_cli_stop(void) |
| 408 | { |
| 409 | if (current_session) |
| 410 | { |
| 411 | bcmcli_stop(current_session); |
| 412 | while (current_session) |
| 413 | bcmos_usleep(10000); |
| 414 | } |
| 415 | } |
| 416 | |
| 417 | /* Is CLI terminated? */ |
| 418 | bcmos_bool bcmbal_cli_is_terminated(void) |
| 419 | { |
| 420 | return (current_session == NULL) || bcmcli_is_stopped(current_session); |
| 421 | } |
| 422 | |
| 423 | /*@}*/ |