blob: c88e8de00a54ab26d37695c339d42697d7cc7b6d [file] [log] [blame]
Harald Welte51c82382011-02-12 14:44:16 +01001/* VTY interface for A-bis OM2000 */
2
3/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#include <stdlib.h>
23#include <unistd.h>
24#include <errno.h>
25#include <stdint.h>
26
27#include <arpa/inet.h>
28
29#include <openbsc/gsm_data.h>
30#include <osmocore/msgb.h>
31#include <osmocore/tlv.h>
32#include <osmocore/talloc.h>
33#include <openbsc/debug.h>
34#include <openbsc/signal.h>
35#include <openbsc/abis_om2000.h>
36#include <openbsc/vty.h>
37
38#include <osmocom/vty/vty.h>
39#include <osmocom/vty/command.h>
40#include <osmocom/vty/logging.h>
41#include <osmocom/vty/telnet_interface.h>
42
43extern struct gsm_network *bsc_gsmnet;
44
45static struct cmd_node om2k_node = {
46 OM2K_NODE,
Harald Welteb0ec9e32011-02-12 20:50:58 +010047 "%s(om2k)# ",
Harald Welte51c82382011-02-12 14:44:16 +010048 1,
49};
50
51struct oml_node_state {
52 struct gsm_bts *bts;
53 struct abis_om2k_mo mo;
54};
55
56static int dummy_config_write(struct vty *v)
57{
58 return CMD_SUCCESS;
59}
60
61/* FIXME: auto-generate those strings from the value_string lists */
62#define OM2K_OBJCLASS_VTY "(trxc|ts|tf|is|con|dp|cf|tx|rx)"
63#define OM2K_OBJCLASS_VTY_HELP "FIXME"
64
65DEFUN(om2k_class_inst, om2k_class_inst_cmd,
66 "bts <0-255> om2000 class " OM2K_OBJCLASS_VTY
67 " <0-255> <0-255> <0-255>",
68 "BTS related commands\n" "BTS Number\n"
69 "Manipulate the OM2000 managed objects\n"
70 "Object Class\n" OM2K_OBJCLASS_VTY_HELP
71 "BTS Number\n" "Associated SO Instance\n" "Instance Number\n")
72{
73 struct gsm_bts *bts;
74 struct oml_node_state *oms;
75 int bts_nr = atoi(argv[0]);
76
77 bts = gsm_bts_num(bsc_gsmnet, bts_nr);
78 if (!bts) {
79 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
80 return CMD_WARNING;
81 }
82
83 if (bts->type != GSM_BTS_TYPE_RBS2000) {
84 vty_out(vty, "%% BTS %d not an Ericsson RBS%s",
85 bts_nr, VTY_NEWLINE);
86 return CMD_WARNING;
87 }
88
89 oms = talloc_zero(tall_bsc_ctx, struct oml_node_state);
90 if (!oms)
91 return CMD_WARNING;
92
93 oms->bts = bts;
94 oms->mo.class = get_string_value(om2k_mo_class_short_vals, argv[1]);
95 oms->mo.bts = atoi(argv[2]);
96 oms->mo.assoc_so = atoi(argv[3]);
97 oms->mo.inst = atoi(argv[4]);
98
99 vty->index = oms;
100 vty->node = OM2K_NODE;
101
102 return CMD_SUCCESS;
103
104}
105
106DEFUN(om2k_classnum_inst, om2k_classnum_inst_cmd,
107 "bts <0-255> om2000 class <0-255> <0-255> <0-255> <0-255>",
108 "BTS related commands\n" "BTS Number\n"
109 "Manipulate the OML managed objects\n"
110 "Object Class\n" "Object Class\n"
111 "BTS Number\n" "Associated SO Instance\n" "Instance Number\n")
112{
113 struct gsm_bts *bts;
114 struct oml_node_state *oms;
115 int bts_nr = atoi(argv[0]);
116
117 bts = gsm_bts_num(bsc_gsmnet, bts_nr);
118 if (!bts) {
119 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
120 return CMD_WARNING;
121 }
122
123 oms = talloc_zero(tall_bsc_ctx, struct oml_node_state);
124 if (!oms)
125 return CMD_WARNING;
126
127 oms->bts = bts;
128 oms->mo.class = atoi(argv[1]);
129 oms->mo.bts = atoi(argv[2]);
130 oms->mo.assoc_so = atoi(argv[3]);
131 oms->mo.inst = atoi(argv[4]);
132
133 vty->index = oms;
134 vty->node = OM2K_NODE;
135
136 return CMD_SUCCESS;
137}
138
139DEFUN(om2k_reset, om2k_reset_cmd,
140 "reset-command",
141 "Reset the MO\n")
142{
143 struct oml_node_state *oms = vty->index;
144
145 abis_om2k_tx_reset_cmd(oms->bts, &oms->mo);
146 return CMD_SUCCESS;
147}
148
149DEFUN(om2k_start, om2k_start_cmd,
150 "start-request",
151 "Start the MO\n")
152{
153 struct oml_node_state *oms = vty->index;
154
155 abis_om2k_tx_start_req(oms->bts, &oms->mo);
156 return CMD_SUCCESS;
157}
158
159DEFUN(om2k_status, om2k_status_cmd,
160 "status-request",
161 "Get the MO Status\n")
162{
163 struct oml_node_state *oms = vty->index;
164
165 abis_om2k_tx_status_req(oms->bts, &oms->mo);
166 return CMD_SUCCESS;
167}
168
Harald Welte6fec79d2011-02-12 14:57:17 +0100169DEFUN(om2k_connect, om2k_connect_cmd,
170 "connect-command",
171 "Connect the MO\n")
172{
173 struct oml_node_state *oms = vty->index;
174
175 abis_om2k_tx_connect_cmd(oms->bts, &oms->mo);
176 return CMD_SUCCESS;
177}
178
179DEFUN(om2k_disconnect, om2k_disconnect_cmd,
180 "disconnect-command",
181 "Disconnect the MO\n")
182{
183 struct oml_node_state *oms = vty->index;
184
185 abis_om2k_tx_disconnect_cmd(oms->bts, &oms->mo);
186 return CMD_SUCCESS;
187}
188
Harald Welte0741ffe2011-02-12 18:48:53 +0100189DEFUN(om2k_enable, om2k_enable_cmd,
190 "enable-request",
191 "Enable the MO\n")
192{
193 struct oml_node_state *oms = vty->index;
194
195 abis_om2k_tx_enable_req(oms->bts, &oms->mo);
196 return CMD_SUCCESS;
197}
198
199DEFUN(om2k_disable, om2k_disable_cmd,
200 "disable-request",
201 "Disable the MO\n")
202{
203 struct oml_node_state *oms = vty->index;
204
205 abis_om2k_tx_disable_req(oms->bts, &oms->mo);
206 return CMD_SUCCESS;
207}
208
Harald Welte6fec79d2011-02-12 14:57:17 +0100209DEFUN(om2k_op_info, om2k_op_info_cmd,
210 "operational-info <0-1>",
211 "Set operational information\n")
212{
213 struct oml_node_state *oms = vty->index;
214 int oper = atoi(argv[0]);
215
216 abis_om2k_tx_op_info(oms->bts, &oms->mo, oper);
217 return CMD_SUCCESS;
218}
219
Harald Welte8024d8f2011-02-12 15:07:30 +0100220DEFUN(om2k_test, om2k_test_cmd,
221 "test-request",
222 "Test the MO\n")
223{
224 struct oml_node_state *oms = vty->index;
225
226 abis_om2k_tx_test_req(oms->bts, &oms->mo);
227 return CMD_SUCCESS;
228}
229
Harald Welte8bcb1a02011-02-12 20:23:40 +0100230static void om2k_fill_is_conn_grp(struct om2k_is_conn_grp *grp, uint16_t icp1,
231 uint16_t icp2, uint8_t cont_idx)
232{
233 grp->icp1 = htons(icp1);
234 grp->icp2 = htons(icp2);
235 grp->cont_idx = cont_idx;
236}
237
Harald Weltea8e6a652011-02-13 22:13:28 +0100238struct is_conn_group {
239 struct llist_head list;
240 uint16_t icp1;
241 uint16_t icp2;
242 uint8_t ci;
243};
244
245DEFUN(om2k_is_conn_list, om2k_is_conn_list_cmd,
246 "is-connection-list (add|del) <0-2047> <0-2047> <0-255>",
247 "Interface Switch Connnection List\n"
248 "Add to IS list\n" "Delete from IS list\n"
249 "ICP1\n" "ICP2\n" "Contiguity Index\n")
Harald Welte8bcb1a02011-02-12 20:23:40 +0100250{
251 struct oml_node_state *oms = vty->index;
Harald Weltea8e6a652011-02-13 22:13:28 +0100252 struct gsm_bts *bts = oms->bts;
253 uint16_t icp1 = atoi(argv[1]);
254 uint16_t icp2 = atoi(argv[2]);
255 uint8_t ci = atoi(argv[3]);
256 struct is_conn_group *grp, *grp2;
Harald Welte8bcb1a02011-02-12 20:23:40 +0100257
Harald Weltea8e6a652011-02-13 22:13:28 +0100258 if (!strcmp(argv[0], "add")) {
259 grp = talloc_zero(bts, struct is_conn_group);
260 grp->icp1 = icp1;
261 grp->icp2 = icp2;
262 grp->ci = ci;
263 llist_add(&grp->list, &bts->rbs2000.is.conn_groups);
264 } else {
265 llist_for_each_entry_safe(grp, grp2, &bts->rbs2000.is.conn_groups, list) {
266 if (grp->icp1 == icp1 && grp->icp2 == icp2
267 && grp->ci == ci) {
268 llist_del(&grp->list);
269 talloc_free(grp);
270 return CMD_SUCCESS;
271 }
272 }
273 vty_out(vty, "%% No matching IS Conn Group found!%s",
274 VTY_NEWLINE);
275 return CMD_WARNING;
276 }
Harald Welte8bcb1a02011-02-12 20:23:40 +0100277
Harald Weltea8e6a652011-02-13 22:13:28 +0100278 return CMD_SUCCESS;
279}
280
281
282DEFUN(om2k_is_conf_req, om2k_is_conf_req_cmd,
283 "is-conf-req",
284 "Send IS Configuration Request\n")
285{
286 struct oml_node_state *oms = vty->index;
287 struct gsm_bts *bts = oms->bts;
288 struct is_conn_group *grp;
289 unsigned int num_grps = 0, i = 0;
290 struct om2k_is_conn_grp *o2grps;
291
292 /* count number of groups in linked list */
293 llist_for_each_entry(grp, &bts->rbs2000.is.conn_groups, list)
294 num_grps++;
295
296 if (!num_grps) {
297 vty_out(vty, "%% No IS connection groups configured!%s",
298 VTY_NEWLINE);
299 return CMD_WARNING;
300 }
301
302 /* allocate buffer for oml group array */
303 o2grps = talloc_zero_array(bts, struct om2k_is_conn_grp, num_grps);
304
305 /* fill array with data from linked list */
306 llist_for_each_entry(grp, &bts->rbs2000.is.conn_groups, list)
307 om2k_fill_is_conn_grp(&o2grps[i++], grp->icp1, grp->icp2, grp->ci);
308
309 /* send the actual OML request */
310 abis_om2k_tx_is_conf_req(oms->bts, o2grps, num_grps);
311
312 talloc_free(o2grps);
313
Harald Welte8bcb1a02011-02-12 20:23:40 +0100314 return CMD_SUCCESS;
315}
Harald Welte6fec79d2011-02-12 14:57:17 +0100316
Harald Welte51c82382011-02-12 14:44:16 +0100317int abis_om2k_vty_init(void)
318{
319 install_element(ENABLE_NODE, &om2k_class_inst_cmd);
320 install_element(ENABLE_NODE, &om2k_classnum_inst_cmd);
321 install_node(&om2k_node, dummy_config_write);
322
323 install_default(OM2K_NODE);
324 install_element(OM2K_NODE, &ournode_exit_cmd);
325 install_element(OM2K_NODE, &om2k_reset_cmd);
326 install_element(OM2K_NODE, &om2k_start_cmd);
327 install_element(OM2K_NODE, &om2k_status_cmd);
Harald Welte6fec79d2011-02-12 14:57:17 +0100328 install_element(OM2K_NODE, &om2k_connect_cmd);
329 install_element(OM2K_NODE, &om2k_disconnect_cmd);
Harald Welte0741ffe2011-02-12 18:48:53 +0100330 install_element(OM2K_NODE, &om2k_enable_cmd);
331 install_element(OM2K_NODE, &om2k_disable_cmd);
Harald Welte6fec79d2011-02-12 14:57:17 +0100332 install_element(OM2K_NODE, &om2k_op_info_cmd);
Harald Welte8024d8f2011-02-12 15:07:30 +0100333 install_element(OM2K_NODE, &om2k_test_cmd);
Harald Welte8bcb1a02011-02-12 20:23:40 +0100334 install_element(OM2K_NODE, &om2k_is_conf_req_cmd);
Harald Weltea8e6a652011-02-13 22:13:28 +0100335 install_element(OM2K_NODE, &om2k_is_conn_list_cmd);
336
337 //install_element(BTS_NODE, &om2k_is_conn_list_cmd);
Harald Welte51c82382011-02-12 14:44:16 +0100338
339 return 0;
340}