| /* |
| <:copyright-BRCM:2016:DUAL/GPL:standard |
| |
| Broadcom Proprietary and Confidential.(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. |
| |
| :> |
| */ |
| |
| #include <bcmos_system.h> |
| #include <bcmcli.h> |
| #include <bcmolt_api.h> |
| #include <bcmolt_model_types.h> |
| #include "bcmolt_user_appl_remote_logger_cli.h" |
| #include "bcmolt_user_appl_remote_logger.h" |
| #include "bcmolt_conv.h" |
| |
| #define BCMOLT_REMOTE_LOGGER_DEFAULT_POLLING_PERIOD_MS 5000 |
| #define BCMOLT_REMOTE_LOGGER_DEFAULT_SUBSEQUENT_DELAY_MS 5 |
| #define BCMOLT_REMOTE_LOGGER_DEFAULT_MAX_FILE_SIZE (200 * 1000000) |
| #define BCMOLT_REMOTE_LOGGER_DEFAULT_FILE_REACHED_BEHAVIOR "stop" |
| #define BCMOLT_REMOTE_LOGGER_DEFAULT_FILENAME "remote_log.txt" |
| |
| static bcmos_errno remote_logger_configure_log( |
| bcmolt_devid device, |
| const bcmolt_log_entry_key *key, |
| bcmolt_log_level log_level_save) |
| { |
| bcmolt_log_entry_cfg cfg; |
| BCMOLT_CFG_INIT(&cfg, log_entry, *key); |
| BCMOLT_CFG_PROP_SET(&cfg, log_entry, log_level_save, log_level_save); |
| BCMOLT_CFG_PROP_SET(&cfg, log_entry, log_level_print, BCMOLT_LOG_LEVEL_WARNING); |
| return bcmolt_cfg_set(device, &cfg.hdr); |
| } |
| |
| static bcmos_errno remote_logger_configure_logs(bcmolt_devid device) |
| { |
| bcmos_errno err; |
| bcmolt_msg_set *msg_set; |
| bcmolt_log_entry_cfg multi_cfg; |
| bcmolt_log_entry_key multi_key = { .log_id = 0 }; /* start from the first log ID */ |
| uint16_t i; |
| |
| /* allocate space for multi-get return */ |
| err = bcmolt_msg_set_alloc(BCMOLT_OBJ_ID_LOG_ENTRY, BCMOLT_MGT_GROUP_CFG, 50, &msg_set); |
| if (err != BCM_ERR_OK) |
| { |
| return err; |
| } |
| |
| /* initialize the multi-get config structure */ |
| BCMOLT_CFG_INIT(&multi_cfg, log_entry, multi_key); |
| BCMOLT_MSGSET_CFG_PROP_GET(msg_set, log_entry, log_level_save); |
| |
| do |
| { |
| /* call multi-get API */ |
| err = bcmolt_cfg_get_multi(device, &multi_cfg.hdr, BCMOLT_FILTER_FLAGS_NONE, msg_set); |
| if (err != BCM_ERR_OK) |
| { |
| break; |
| } |
| |
| /* for each log entry, reconfigure it to print only warning level and above to the screen (keeping current |
| * behavior for printing to RAM files) */ |
| for (i = 0; i < msg_set->num_instances; i++) |
| { |
| bcmolt_log_entry_cfg *cfg = (bcmolt_log_entry_cfg *)msg_set->msg[i]; |
| err = remote_logger_configure_log(device, &cfg->key, cfg->data.log_level_save); |
| if (err != BCM_ERR_OK) |
| { |
| break; |
| } |
| } |
| |
| /* update the key for next call */ |
| multi_cfg.key = *((bcmolt_log_entry_key *)msg_set->next_key); |
| |
| /* keep calling the function until we have retrieved all entries */ |
| } while (msg_set->more); |
| |
| bcmolt_msg_set_free(msg_set); |
| return err; |
| } |
| |
| static bcmos_errno remote_logger_cmd_start(bcmcli_session *session, const bcmcli_cmd_parm parms[], uint16_t n_parms) |
| { |
| bcmos_errno err; |
| |
| /* these parameters will always be non-NULL since they have default values */ |
| bcmolt_remote_logger_cfg cfg = |
| { |
| .max_file_size = bcmcli_find_named_parm(session, "max_file_size")->value.unumber, |
| .max_file_size_reached_behavior = (bcmolt_remote_logger_file_size_reached_behavior) |
| bcmcli_find_named_parm(session, "file_size_reached")->value.number, |
| .polling_period_ms = bcmcli_find_named_parm(session, "polling_period")->value.unumber, |
| .subsequent_delay_ms = bcmcli_find_named_parm(session, "subsequent_delay")->value.unumber, |
| }; |
| strncpy( |
| cfg.filename, |
| bcmcli_find_named_parm(session, "filename")->value.string, |
| BCMOLT_REMOTE_LOGGER_FILENAME_MAX_LEN - 1); /* leave room for terminator */ |
| |
| /* if the user requested, set all logs on the device to print warnings/errors only */ |
| if ((bcmos_bool)bcmcli_find_named_parm(session, "configure_logs")->value.number) |
| { |
| err = remote_logger_configure_logs(current_device); |
| if (err != BCM_ERR_OK) |
| { |
| return err; |
| } |
| bcmcli_session_print(session, "Reconfigured all log entries to print warning/error messages only\n"); |
| } |
| |
| err = bcmolt_remote_logger_appl_cfg_update(current_device, &cfg); |
| if (err != BCM_ERR_OK) |
| { |
| return err; |
| } |
| |
| err = bcmolt_remote_logger_appl_start(current_device); |
| if (err == BCM_ERR_OK) |
| { |
| bcmcli_session_print(session, "Remote logger application started\n"); |
| } |
| return err; |
| } |
| |
| static bcmos_errno remote_logger_cmd_stop(bcmcli_session *session, const bcmcli_cmd_parm parms[], uint16_t n_parms) |
| { |
| bcmos_errno err = bcmolt_remote_logger_appl_stop(current_device); |
| if (err == BCM_ERR_OK) |
| { |
| bcmcli_session_print(session, "Remote logger application stopped\n"); |
| } |
| return err; |
| } |
| |
| static bcmos_errno remote_logger_cmd_status(bcmcli_session *session, const bcmcli_cmd_parm parms[], uint16_t n_parms) |
| { |
| static int2str_t file_size_reached2str[] = |
| { |
| { BCMOLT_REMOTE_LOGGER_FILE_SIZE_REACHED_BEHAVIOR_STOP, "stop" }, |
| { BCMOLT_REMOTE_LOGGER_FILE_SIZE_REACHED_BEHAVIOR_CLEAR, "clear" }, |
| { -1 } |
| }; |
| |
| bcmos_errno err; |
| bcmolt_remote_logger_cfg cfg; |
| |
| if (bcmolt_remote_logger_appl_is_running(current_device)) |
| { |
| bcmcli_session_print(session, "Remote logger application is running\n"); |
| err = bcmolt_remote_logger_appl_cfg_get(current_device, &cfg); |
| if (err != BCM_ERR_OK) |
| { |
| return err; |
| } |
| |
| bcmcli_session_print(session, "filename=%s\n", cfg.filename); |
| bcmcli_session_print(session, "max_file_size=%u\n", cfg.max_file_size); |
| bcmcli_session_print( |
| session, |
| "file_size_reached=%s\n", |
| int2str(file_size_reached2str, cfg.max_file_size_reached_behavior)); |
| bcmcli_session_print(session, "polling_period=%u\n", cfg.polling_period_ms); |
| bcmcli_session_print(session, "subsequent_delay=%u\n", cfg.subsequent_delay_ms); |
| } |
| else |
| { |
| bcmcli_session_print(session, "Remote logger application is not running\n"); |
| } |
| |
| return BCM_ERR_OK; |
| } |
| |
| bcmos_errno bcmolt_remote_logger_appl_cli_init(bcmcli_entry *top_dir) |
| { |
| static bcmcli_enum_val file_size_reached_behavior_table[] = |
| { |
| { "stop", BCMOLT_REMOTE_LOGGER_FILE_SIZE_REACHED_BEHAVIOR_STOP }, |
| { "clear", BCMOLT_REMOTE_LOGGER_FILE_SIZE_REACHED_BEHAVIOR_CLEAR }, |
| BCMCLI_ENUM_LAST |
| }; |
| |
| bcmcli_entry *dir = bcmcli_dir_add( |
| top_dir, |
| "remote_logger", |
| "Periodically copy device log to local file", |
| BCMCLI_ACCESS_ADMIN, |
| NULL); |
| BCMOS_CHECK_RETURN_ERROR(!dir, BCM_ERR_NOMEM); |
| |
| BCMCLI_MAKE_CMD(dir, "start", "Start periodically copying device log to host", remote_logger_cmd_start, |
| BCMCLI_MAKE_PARM_DEFVAL( |
| "filename", |
| "Output file path", |
| BCMCLI_PARM_STRING, |
| BCMCLI_PARM_FLAG_OPTIONAL, |
| (long)BCMOLT_REMOTE_LOGGER_DEFAULT_FILENAME), |
| BCMCLI_MAKE_PARM_DEFVAL( |
| "max_file_size", |
| "Maximum output file size in bytes", |
| BCMCLI_PARM_UNUMBER, |
| BCMCLI_PARM_FLAG_OPTIONAL, |
| BCMOLT_REMOTE_LOGGER_DEFAULT_MAX_FILE_SIZE), |
| BCMCLI_MAKE_PARM_ENUM_DEFVAL( |
| "file_size_reached", |
| "Behavior when max file size is reached", |
| file_size_reached_behavior_table, |
| BCMCLI_PARM_FLAG_OPTIONAL, |
| BCMOLT_REMOTE_LOGGER_DEFAULT_FILE_REACHED_BEHAVIOR), |
| BCMCLI_MAKE_PARM_DEFVAL( |
| "polling_period", |
| "Polling period in ms", |
| BCMCLI_PARM_UNUMBER, |
| BCMCLI_PARM_FLAG_OPTIONAL, |
| BCMOLT_REMOTE_LOGGER_DEFAULT_POLLING_PERIOD_MS), |
| BCMCLI_MAKE_PARM_DEFVAL( |
| "subsequent_delay", |
| "Delay between repeated API calls in ms", |
| BCMCLI_PARM_UNUMBER, |
| BCMCLI_PARM_FLAG_OPTIONAL, |
| BCMOLT_REMOTE_LOGGER_DEFAULT_SUBSEQUENT_DELAY_MS), |
| BCMCLI_MAKE_PARM_ENUM_DEFVAL( |
| "configure_logs", |
| "Configure all device logs to print error/warning only", |
| bcmcli_enum_bool_table, |
| BCMCLI_PARM_FLAG_OPTIONAL, |
| "yes")); |
| |
| BCMCLI_MAKE_CMD_NOPARM(dir, "stop", "Stop periodically copying device log to host", remote_logger_cmd_stop); |
| |
| BCMCLI_MAKE_CMD_NOPARM(dir, "status", "Show status / configuration parameters", remote_logger_cmd_status); |
| |
| return BCM_ERR_OK; |
| } |