blob: cd2c38942b8badf7fc416103abfb476230853b10 [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/******************************************************************************
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 */
64dev_log_id log_id_cli;
65
66/* CLI logging for ONU discovery */
67dev_log_id log_id_cli_disc;
68#endif
69bcmcli_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) */
74static bcmbal_exit_cb user_exit_cb;
75static bcmos_task bal_cli_thread;
76
77static 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
87static 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 */
106static 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 */
127static 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 */
135static 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 *****************************************************************************/
148static 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 */
178static 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 */
222bcmos_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 */
244bcmos_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 */
256static 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 *****************************************************************************/
294bcmos_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, &current_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 *****************************************************************************/
391bcmos_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 */
407void 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? */
418bcmos_bool bcmbal_cli_is_terminated(void)
419{
420 return (current_session == NULL) || bcmcli_is_stopped(current_session);
421}
422
423/*@}*/