blob: 338fb11547118ec52aa62ccccfe9ee9a2c3e5ceb [file] [log] [blame]
Holger Hans Peter Freyther49f9e5b2014-03-23 16:25:16 +01001/* SNMP-like status interface. Look-up of BTS/TRX
2 *
3 * (C) 2010-2011 by Daniel Willmann <daniel@totalueberwachung.de>
4 * (C) 2010-2011 by On-Waves
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include <openbsc/control_if.h>
25#include <openbsc/debug.h>
26
27extern vector ctrl_node_vec;
28
29static int get_num(vector vline, int i, long *num)
30{
31 char *token, *tmp;
32
33 if (i >= vector_active(vline))
34 return 0;
35 token = vector_slot(vline, i);
36
37 errno = 0;
38 if (token[0] == '\0')
39 return 0;
40
41 *num = strtol(token, &tmp, 10);
42 if (tmp[0] != '\0' || errno != 0)
43 return 0;
44
45 return 1;
46}
47
48int bsc_ctrl_cmd_handle(struct ctrl_cmd *cmd, void *data)
49{
50 char *token, *request;
51 long num;
52 int i, j, ret, node;
53
54 struct gsm_network *net = data;
55 struct gsm_bts *bts = NULL;
56 struct gsm_bts_trx *trx = NULL;
57 struct gsm_bts_trx_ts *ts = NULL;
58 vector vline, cmdvec, cmds_vec;
59
60 ret = CTRL_CMD_ERROR;
61 cmd->reply = NULL;
62 node = CTRL_NODE_ROOT;
63 cmd->node = net;
64
65 request = talloc_strdup(tall_bsc_ctx, cmd->variable);
66 if (!request)
67 goto err;
68
69 for (i=0;i<strlen(request);i++) {
70 if (request[i] == '.')
71 request[i] = ' ';
72 }
73
74 vline = cmd_make_strvec(request);
75 talloc_free(request);
76 if (!vline) {
77 cmd->reply = "cmd_make_strvec failed.";
78 goto err;
79 }
80
81 for (i=0;i<vector_active(vline);i++) {
82 token = vector_slot(vline, i);
83 /* TODO: We need to make sure that the following chars are digits
84 * and/or use strtol to check if number conversion was successful
85 * Right now something like net.bts_stats will not work */
86 if (!strcmp(token, "bts")) {
87 if (!net)
88 goto err_missing;
89 i++;
90 if (!get_num(vline, i, &num))
91 goto err_index;
92
93 bts = gsm_bts_num(net, num);
94 if (!bts)
95 goto err_missing;
96 cmd->node = bts;
97 node = CTRL_NODE_BTS;
98 } else if (!strcmp(token, "trx")) {
99 if (!bts)
100 goto err_missing;
101 i++;
102 if (!get_num(vline, i, &num))
103 goto err_index;
104
105 trx = gsm_bts_trx_num(bts, num);
106 if (!trx)
107 goto err_missing;
108 cmd->node = trx;
109 node = CTRL_NODE_TRX;
110 } else if (!strcmp(token, "ts")) {
111 if (!trx)
112 goto err_missing;
113 i++;
114 if (!get_num(vline, i, &num))
115 goto err_index;
116
117 if ((num >= 0) && (num < TRX_NR_TS))
118 ts = &trx->ts[num];
119 if (!ts)
120 goto err_missing;
121 cmd->node = ts;
122 node = CTRL_NODE_TS;
123 } else {
124 /* If we're here the rest must be the command */
125 cmdvec = vector_init(vector_active(vline)-i);
126 for (j=i; j<vector_active(vline); j++) {
127 vector_set(cmdvec, vector_slot(vline, j));
128 }
129
130 /* Get the command vector of the right node */
131 cmds_vec = vector_lookup(ctrl_node_vec, node);
132
133 if (!cmds_vec) {
134 cmd->reply = "Command not found.";
135 vector_free(cmdvec);
136 break;
137 }
138
139 ret = ctrl_cmd_exec(cmdvec, cmd, cmds_vec, data);
140
141 vector_free(cmdvec);
142 break;
143 }
144
145 if (i+1 == vector_active(vline))
146 cmd->reply = "Command not present.";
147 }
148
149 cmd_free_strvec(vline);
150
151err:
152 if (!cmd->reply) {
153 LOGP(DCTRL, LOGL_ERROR, "cmd->reply has not been set.\n");
154 if (ret == CTRL_CMD_ERROR)
155 cmd->reply = "An error has occured.";
156 else
157 cmd->reply = "Command has been handled.";
158 }
159
160 if (ret == CTRL_CMD_ERROR)
161 cmd->type = CTRL_TYPE_ERROR;
162 return ret;
163
164err_missing:
165 cmd_free_strvec(vline);
166 cmd->type = CTRL_TYPE_ERROR;
167 cmd->reply = "Error while resolving object";
168 return ret;
169err_index:
170 cmd_free_strvec(vline);
171 cmd->type = CTRL_TYPE_ERROR;
172 cmd->reply = "Error while parsing the index.";
173 return ret;
174}
175
176struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net, uint16_t port)
177{
178 return controlif_setup(net, port, bsc_ctrl_cmd_handle);
179}