blob: 05f5b63cf1ff4cecf1c2a033c7adbc11b36b2a79 [file] [log] [blame]
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02001/* OpenBSC interface to quagga VTY */
2/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther0e7d0712011-04-18 17:15:53 +02003 * (C) 2009-2011 by Holger Hans Peter Freyther
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02004 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01007 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02009 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010014 * GNU Affero General Public License for more details.
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020015 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010016 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020018 *
19 */
20
21#include <stdlib.h>
Holger Hans Peter Freyther73b878a2010-12-25 00:33:40 +010022#include <limits.h>
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020023#include <unistd.h>
Holger Hans Peter Freytherb9708942013-07-27 19:42:35 +020024#include <time.h>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020025#include <inttypes.h>
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020026
Harald Welte4b037e42010-05-19 19:45:32 +020027#include <osmocom/vty/command.h>
28#include <osmocom/vty/buffer.h>
29#include <osmocom/vty/vty.h>
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020030
31#include <arpa/inet.h>
32
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010033#include <osmocom/core/linuxlist.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020034#include <osmocom/msc/gsm_data.h>
35#include <osmocom/msc/gsm_subscriber.h>
36#include <osmocom/msc/silent_call.h>
37#include <osmocom/msc/gsm_04_11.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010038#include <osmocom/gsm/gsm_utils.h>
39#include <osmocom/core/utils.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020040#include <osmocom/msc/db.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010041#include <osmocom/core/talloc.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020042#include <osmocom/msc/signal.h>
43#include <osmocom/msc/debug.h>
44#include <osmocom/msc/vty.h>
45#include <osmocom/msc/gsm_04_80.h>
46#include <osmocom/msc/gsm_04_14.h>
Harald Welted35038d2018-01-25 00:07:33 +010047#include <osmocom/gsm/protocol/gsm_08_58.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020048#include <osmocom/msc/sms_queue.h>
49#include <osmocom/msc/mncc_int.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020050#include <osmocom/msc/vlr.h>
Harald Welte66a301e2018-01-24 16:48:17 +010051#include <osmocom/msc/transaction.h>
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020052
Holger Hans Peter Freyther6995f242014-12-28 18:54:32 +010053#include <osmocom/vty/logging.h>
54
Neels Hofmeyr90843962017-09-04 15:04:35 +020055#include <osmocom/msc/osmo_msc.h>
Harald Welte2483f1b2016-06-19 18:06:02 +020056
Harald Weltedcccb182010-05-16 20:52:23 +020057extern struct gsm_network *gsmnet_from_vty(struct vty *v);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020058
Harald Welte66a301e2018-01-24 16:48:17 +010059static void vty_conn_hdr(struct vty *vty)
60{
Harald Welte9199f8b2018-02-14 00:13:47 +010061 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
Harald Welte66a301e2018-01-24 16:48:17 +010062 VTY_NEWLINE);
63}
64
65static void vty_dump_one_conn(struct vty *vty, const struct gsm_subscriber_connection *conn)
66{
Harald Welte9199f8b2018-02-14 00:13:47 +010067 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
Harald Welte66a301e2018-01-24 16:48:17 +010068 conn->a.conn_id,
69 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
70 conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
71 conn->lac,
72 conn->use_count,
73 conn->use_tokens,
74 conn->received_cm_service_request ? 'C' : '-',
Harald Welte66a301e2018-01-24 16:48:17 +010075 conn->encr.alg_id,
76 conn->conn_fsm ? osmo_fsm_inst_state_name(conn->conn_fsm) : "-",
77 VTY_NEWLINE);
78}
79
80DEFUN(show_msc_conn, show_msc_conn_cmd,
81 "show connection", SHOW_STR "Subscriber Connections\n")
82{
83 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
84 struct gsm_subscriber_connection *conn;
85
86 vty_conn_hdr(vty);
87 llist_for_each_entry(conn, &gsmnet->subscr_conns, entry)
88 vty_dump_one_conn(vty, conn);
89
90 return CMD_SUCCESS;
91}
92
93static void vty_trans_hdr(struct vty *vty)
94{
95 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
96 VTY_NEWLINE);
97}
98
99static const char *get_trans_proto_str(const struct gsm_trans *trans)
100{
101 static char buf[256];
102
103 switch (trans->protocol) {
104 case GSM48_PDISC_CC:
105 snprintf(buf, sizeof(buf), "%s %4u %4u",
106 gsm48_cc_state_name(trans->cc.state),
107 trans->cc.Tcurrent,
108 trans->cc.T308_second);
109 break;
110 case GSM48_PDISC_SMS:
111 snprintf(buf, sizeof(buf), "%s %s",
112 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
113 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
114 break;
115 default:
116 buf[0] = '\0';
117 break;
118 }
119
120 return buf;
121}
122
123static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
124{
125 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
126 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
127 trans->conn ? trans->conn->a.conn_id : 0,
128 gsm48_pdisc_name(trans->protocol),
129 trans->transaction_id,
130 trans->callref,
131 get_trans_proto_str(trans), VTY_NEWLINE);
132}
133
134DEFUN(show_msc_transaction, show_msc_transaction_cmd,
135 "show transaction", SHOW_STR "Transactions\n")
136{
137 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
138 struct gsm_trans *trans;
139
140 vty_trans_hdr(vty);
141 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
142 vty_dump_one_trans(vty, trans);
143
144 return CMD_SUCCESS;
145}
146
147
148
Harald Welte2483f1b2016-06-19 18:06:02 +0200149static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100150{
Harald Welte66a301e2018-01-24 16:48:17 +0100151 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
152 struct gsm_trans *trans;
Holger Hans Peter Freytherc9dbe3c2015-08-04 13:18:47 +0200153 int reqs;
Holger Hans Peter Freytherc9dbe3c2015-08-04 13:18:47 +0200154 struct llist_head *entry;
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100155
Harald Welte2483f1b2016-06-19 18:06:02 +0200156 if (strlen(vsub->name))
157 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
158 if (strlen(vsub->msisdn))
159 vty_out(vty, " Extension: %s%s", vsub->msisdn,
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100160 VTY_NEWLINE);
Holger Hans Peter Freyther3d76e442010-12-25 16:40:54 +0100161 vty_out(vty, " LAC: %d/0x%x%s",
Harald Welte2483f1b2016-06-19 18:06:02 +0200162 vsub->lac, vsub->lac, VTY_NEWLINE);
163 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
164 if (vsub->tmsi != GSM_RESERVED_TMSI)
165 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
166 VTY_NEWLINE);
167 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
168 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100169 VTY_NEWLINE);
170
Harald Welte2483f1b2016-06-19 18:06:02 +0200171#if 0
172 /* TODO: add this to vlr_subscr? */
173 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
174 struct gsm_auth_info *i = &vsub->auth_info;
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100175 vty_out(vty, " A3A8 algorithm id: %d%s",
Harald Welte2483f1b2016-06-19 18:06:02 +0200176 i->auth_algo, VTY_NEWLINE);
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100177 vty_out(vty, " A3A8 Ki: %s%s",
Harald Welte2483f1b2016-06-19 18:06:02 +0200178 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100179 VTY_NEWLINE);
180 }
Harald Welte2483f1b2016-06-19 18:06:02 +0200181#endif
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100182
Harald Welte2483f1b2016-06-19 18:06:02 +0200183 if (vsub->last_tuple) {
184 struct gsm_auth_tuple *t = vsub->last_tuple;
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100185 vty_out(vty, " A3A8 last tuple (used %d times):%s",
Harald Welte2483f1b2016-06-19 18:06:02 +0200186 t->use_count, VTY_NEWLINE);
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100187 vty_out(vty, " seq # : %d%s",
Harald Welte2483f1b2016-06-19 18:06:02 +0200188 t->key_seq, VTY_NEWLINE);
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100189 vty_out(vty, " RAND : %s%s",
Harald Welte2483f1b2016-06-19 18:06:02 +0200190 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100191 VTY_NEWLINE);
192 vty_out(vty, " SRES : %s%s",
Harald Welte2483f1b2016-06-19 18:06:02 +0200193 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100194 VTY_NEWLINE);
195 vty_out(vty, " Kc : %s%s",
Harald Welte2483f1b2016-06-19 18:06:02 +0200196 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100197 VTY_NEWLINE);
198 }
Holger Hans Peter Freytherb9708942013-07-27 19:42:35 +0200199
Holger Hans Peter Freytherc9dbe3c2015-08-04 13:18:47 +0200200 reqs = 0;
Harald Welte2483f1b2016-06-19 18:06:02 +0200201 llist_for_each(entry, &vsub->cs.requests)
Holger Hans Peter Freytherc9dbe3c2015-08-04 13:18:47 +0200202 reqs += 1;
Harald Welte2483f1b2016-06-19 18:06:02 +0200203 vty_out(vty, " Paging: %s paging for %d requests%s",
204 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
205 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
Harald Welte66a301e2018-01-24 16:48:17 +0100206
207 /* Connection */
208 if (vsub->msc_conn_ref) {
209 struct gsm_subscriber_connection *conn = vsub->msc_conn_ref;
210 vty_conn_hdr(vty);
211 vty_dump_one_conn(vty, conn);
212 }
213
214 /* Transactions */
215 vty_trans_hdr(vty);
216 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
217 if (trans->vsub != vsub)
218 continue;
219 vty_dump_one_trans(vty, trans);
220 }
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100221}
222
223
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200224/* Subscriber */
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200225DEFUN(show_subscr_cache,
226 show_subscr_cache_cmd,
227 "show subscriber cache",
Harald Weltecfaabbb2012-08-16 23:23:50 +0200228 SHOW_STR "Show information about subscribers\n"
229 "Display contents of subscriber cache\n")
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200230{
Harald Welte2483f1b2016-06-19 18:06:02 +0200231 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
232 struct vlr_subscr *vsub;
233 int count = 0;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200234
Harald Welte2483f1b2016-06-19 18:06:02 +0200235 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
236 if (++count > 100) {
237 vty_out(vty, "%% More than %d subscribers in cache,"
238 " stopping here.%s", count-1, VTY_NEWLINE);
239 break;
240 }
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200241 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Harald Welte2483f1b2016-06-19 18:06:02 +0200242 subscr_dump_full_vty(vty, vsub);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200243 }
244
245 return CMD_SUCCESS;
246}
247
248DEFUN(sms_send_pend,
249 sms_send_pend_cmd,
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100250 "sms send pending",
Neels Hofmeyrd1fdefe2016-04-01 02:17:24 +0200251 "SMS related commands\n" "SMS Sending related commands\n"
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100252 "Send all pending SMS")
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200253{
Harald Weltedcccb182010-05-16 20:52:23 +0200254 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200255 struct gsm_sms *sms;
Harald Welte2483f1b2016-06-19 18:06:02 +0200256 unsigned long long sms_id = 0;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200257
258 while (1) {
Harald Welte2483f1b2016-06-19 18:06:02 +0200259 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200260 if (!sms)
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100261 break;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200262
Harald Welte2483f1b2016-06-19 18:06:02 +0200263 if (sms->receiver)
264 gsm411_send_sms_subscr(sms->receiver, sms);
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100265
Harald Welte2483f1b2016-06-19 18:06:02 +0200266 sms_id = sms->id + 1;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200267 }
268
269 return CMD_SUCCESS;
270}
271
Stefan Sperling87cba1f2018-01-22 17:05:37 +0100272
273DEFUN(sms_delete_expired,
274 sms_delete_expired_cmd,
275 "sms delete expired",
276 "SMS related commands\n" "SMS Database related commands\n"
277 "Delete all expired SMS")
278{
279 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
280 struct gsm_sms *sms;
281 unsigned long long sms_id = 0;
282 long long num_deleted = 0;
283
284 while (1) {
285 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
286 if (!sms)
287 break;
288
289 /* Skip SMS which are currently queued for sending. */
290 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
291 continue;
292
293 /* Expiration check is performed by the DB layer. */
294 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
295 num_deleted++;
296
297 sms_id = sms->id + 1;
298 }
299
300 if (num_deleted == 0) {
301 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
302 return CMD_WARNING;
303 }
304
305 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
306 return CMD_SUCCESS;
307}
308
309
Harald Welte2483f1b2016-06-19 18:06:02 +0200310static int _send_sms_str(struct vlr_subscr *receiver,
311 struct vlr_subscr *sender,
312 char *str, uint8_t tp_pid)
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200313{
Harald Welte2483f1b2016-06-19 18:06:02 +0200314 struct gsm_network *net = receiver->vlr->user_ctx;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200315 struct gsm_sms *sms;
316
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100317 sms = sms_from_text(receiver, sender, 0, str);
Harald Welte793a1352009-11-05 15:51:17 +0900318 sms->protocol_id = tp_pid;
Nico Golde59502362010-06-29 20:13:06 +0200319
Holger Hans Peter Freyther445e6152010-12-25 15:57:34 +0100320 /* store in database for the queue */
321 if (db_sms_store(sms) != 0) {
Holger Hans Peter Freythereff409492012-11-10 19:46:58 +0100322 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
Holger Hans Peter Freyther445e6152010-12-25 15:57:34 +0100323 sms_free(sms);
324 return CMD_WARNING;
Nico Golde59502362010-06-29 20:13:06 +0200325 }
Neels Hofmeyr1e918c32016-05-09 21:48:53 +0200326 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200327
Holger Hans Peter Freyther445e6152010-12-25 15:57:34 +0100328 sms_free(sms);
Harald Welte2483f1b2016-06-19 18:06:02 +0200329 sms_queue_trigger(net->sms_queue);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200330 return CMD_SUCCESS;
331}
332
Harald Welte2483f1b2016-06-19 18:06:02 +0200333static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
334 const char *type,
335 const char *id)
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200336{
Harald Welte2483f1b2016-06-19 18:06:02 +0200337 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
338 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
339 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
340 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
Harald Welte98f9c752009-11-14 08:00:53 +0100341 else if (!strcmp(type, "tmsi"))
Harald Welte2483f1b2016-06-19 18:06:02 +0200342 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
Harald Welte98f9c752009-11-14 08:00:53 +0100343
344 return NULL;
345}
Neels Hofmeyr11010b12018-03-09 16:59:08 +0100346#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
Harald Welte28326062010-05-14 20:05:17 +0200347#define SUBSCR_HELP "Operations on a Subscriber\n" \
Neels Hofmeyr11010b12018-03-09 16:59:08 +0100348 "Identify subscriber by MSISDN (phone number)\n" \
349 "Legacy alias for 'msisdn'\n" \
Neels Hofmeyrd1fdefe2016-04-01 02:17:24 +0200350 "Identify subscriber by IMSI\n" \
351 "Identify subscriber by TMSI\n" \
352 "Identify subscriber by database ID\n" \
Harald Welte28326062010-05-14 20:05:17 +0200353 "Identifier for the subscriber\n"
Harald Welte98f9c752009-11-14 08:00:53 +0100354
Harald Welteb4a84e12010-05-27 10:44:58 +0200355DEFUN(show_subscr,
356 show_subscr_cmd,
357 "show subscriber " SUBSCR_TYPES " ID",
358 SHOW_STR SUBSCR_HELP)
359{
360 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte2483f1b2016-06-19 18:06:02 +0200361 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
362 argv[1]);
Harald Welteb4a84e12010-05-27 10:44:58 +0200363
Harald Welte2483f1b2016-06-19 18:06:02 +0200364 if (!vsub) {
Harald Welteb4a84e12010-05-27 10:44:58 +0200365 vty_out(vty, "%% No subscriber found for %s %s%s",
366 argv[0], argv[1], VTY_NEWLINE);
367 return CMD_WARNING;
368 }
369
Harald Welte2483f1b2016-06-19 18:06:02 +0200370 subscr_dump_full_vty(vty, vsub);
Harald Welteb4a84e12010-05-27 10:44:58 +0200371
Harald Welte2483f1b2016-06-19 18:06:02 +0200372 vlr_subscr_put(vsub);
Harald Welteb4a84e12010-05-27 10:44:58 +0200373
374 return CMD_SUCCESS;
375}
376
Alexander Chemerisbd6d40f2013-10-04 23:54:17 +0200377DEFUN(subscriber_create,
378 subscriber_create_cmd,
379 "subscriber create imsi ID",
380 "Operations on a Subscriber\n" \
381 "Create new subscriber\n" \
382 "Identify the subscriber by his IMSI\n" \
383 "Identifier for the subscriber\n")
384{
Harald Welte2483f1b2016-06-19 18:06:02 +0200385 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
386 VTY_NEWLINE);
387 return CMD_WARNING;
Alexander Chemerisbd6d40f2013-10-04 23:54:17 +0200388}
389
Nico Goldeb62b1232011-02-22 17:54:47 +0100390DEFUN(subscriber_send_pending_sms,
391 subscriber_send_pending_sms_cmd,
Holger Hans Peter Freyther3217fa22012-07-20 23:55:08 +0200392 "subscriber " SUBSCR_TYPES " ID sms pending-send",
Nico Goldeb62b1232011-02-22 17:54:47 +0100393 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
394{
395 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte2483f1b2016-06-19 18:06:02 +0200396 struct vlr_subscr *vsub;
Nico Goldeb62b1232011-02-22 17:54:47 +0100397 struct gsm_sms *sms;
398
Harald Welte2483f1b2016-06-19 18:06:02 +0200399 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
400 if (!vsub) {
Holger Hans Peter Freyther9feef482013-07-04 20:34:46 +0200401 vty_out(vty, "%% No subscriber found for %s %s%s",
402 argv[0], argv[1], VTY_NEWLINE);
403 return CMD_WARNING;
404 }
405
Harald Welte2483f1b2016-06-19 18:06:02 +0200406 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
Nico Goldeb62b1232011-02-22 17:54:47 +0100407 if (sms)
408 gsm411_send_sms_subscr(sms->receiver, sms);
409
Harald Welte2483f1b2016-06-19 18:06:02 +0200410 vlr_subscr_put(vsub);
Nico Goldeb62b1232011-02-22 17:54:47 +0100411
412 return CMD_SUCCESS;
413}
414
Harald Welte98f9c752009-11-14 08:00:53 +0100415DEFUN(subscriber_send_sms,
416 subscriber_send_sms_cmd,
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100417 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +0100418 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
Harald Welte98f9c752009-11-14 08:00:53 +0100419{
Harald Weltedcccb182010-05-16 20:52:23 +0200420 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte2483f1b2016-06-19 18:06:02 +0200421 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
422 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
Harald Welte20474ad2010-05-16 19:28:32 +0200423 char *str;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200424 int rc;
425
Harald Welte2483f1b2016-06-19 18:06:02 +0200426 if (!vsub) {
Harald Welte20f98312009-11-14 10:11:45 +0100427 vty_out(vty, "%% No subscriber found for %s %s%s",
428 argv[0], argv[1], VTY_NEWLINE);
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100429 rc = CMD_WARNING;
430 goto err;
Harald Welte20f98312009-11-14 10:11:45 +0100431 }
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100432
433 if (!sender) {
434 vty_out(vty, "%% No sender found for %s %s%s",
435 argv[2], argv[3], VTY_NEWLINE);
436 rc = CMD_WARNING;
437 goto err;
438 }
439
440 str = argv_concat(argv, argc, 4);
Harald Welte2483f1b2016-06-19 18:06:02 +0200441 rc = _send_sms_str(vsub, sender, str, 0);
Harald Welte20474ad2010-05-16 19:28:32 +0200442 talloc_free(str);
Harald Welte793a1352009-11-05 15:51:17 +0900443
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100444err:
445 if (sender)
Harald Welte2483f1b2016-06-19 18:06:02 +0200446 vlr_subscr_put(sender);
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100447
Harald Welte2483f1b2016-06-19 18:06:02 +0200448 if (vsub)
449 vlr_subscr_put(vsub);
Harald Welteaf8c7b42009-11-14 10:10:54 +0100450
Harald Welte793a1352009-11-05 15:51:17 +0900451 return rc;
452}
453
Harald Welte98f9c752009-11-14 08:00:53 +0100454DEFUN(subscriber_silent_sms,
455 subscriber_silent_sms_cmd,
Harald Welte1011d5b2014-07-10 20:19:00 +0200456
457 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
458 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
Harald Welte793a1352009-11-05 15:51:17 +0900459{
Harald Weltedcccb182010-05-16 20:52:23 +0200460 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte2483f1b2016-06-19 18:06:02 +0200461 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
462 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
Harald Welte20474ad2010-05-16 19:28:32 +0200463 char *str;
Harald Welte793a1352009-11-05 15:51:17 +0900464 int rc;
465
Harald Welte2483f1b2016-06-19 18:06:02 +0200466 if (!vsub) {
Harald Welte20f98312009-11-14 10:11:45 +0100467 vty_out(vty, "%% No subscriber found for %s %s%s",
468 argv[0], argv[1], VTY_NEWLINE);
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100469 rc = CMD_WARNING;
470 goto err;
Harald Welte20f98312009-11-14 10:11:45 +0100471 }
Harald Welte793a1352009-11-05 15:51:17 +0900472
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100473 if (!sender) {
474 vty_out(vty, "%% No sender found for %s %s%s",
475 argv[2], argv[3], VTY_NEWLINE);
476 rc = CMD_WARNING;
477 goto err;
478 }
479
480 str = argv_concat(argv, argc, 4);
Harald Welte2483f1b2016-06-19 18:06:02 +0200481 rc = _send_sms_str(vsub, sender, str, 64);
Harald Welte20474ad2010-05-16 19:28:32 +0200482 talloc_free(str);
Harald Welte793a1352009-11-05 15:51:17 +0900483
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100484err:
485 if (sender)
Harald Welte2483f1b2016-06-19 18:06:02 +0200486 vlr_subscr_put(sender);
Sylvain Munaut01c13a32012-12-28 00:49:01 +0100487
Harald Welte2483f1b2016-06-19 18:06:02 +0200488 if (vsub)
489 vlr_subscr_put(vsub);
Harald Welteaf8c7b42009-11-14 10:10:54 +0100490
Harald Welte793a1352009-11-05 15:51:17 +0900491 return rc;
492}
493
Harald Welte28326062010-05-14 20:05:17 +0200494#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
495#define CHAN_TYPE_HELP \
496 "Any channel\n" \
497 "TCH/F channel\n" \
498 "Any TCH channel\n" \
499 "SDCCH channel\n"
500
Sylvain Munaut50480702010-01-02 14:29:43 +0100501DEFUN(subscriber_silent_call_start,
502 subscriber_silent_call_start_cmd,
Harald Welteb4a84e12010-05-27 10:44:58 +0200503 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
Harald Welte28326062010-05-14 20:05:17 +0200504 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
505 CHAN_TYPE_HELP)
Sylvain Munaut50480702010-01-02 14:29:43 +0100506{
Harald Weltedcccb182010-05-16 20:52:23 +0200507 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte2483f1b2016-06-19 18:06:02 +0200508 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut50480702010-01-02 14:29:43 +0100509 int rc, type;
510
Harald Welte2483f1b2016-06-19 18:06:02 +0200511 if (!vsub) {
Sylvain Munaut50480702010-01-02 14:29:43 +0100512 vty_out(vty, "%% No subscriber found for %s %s%s",
513 argv[0], argv[1], VTY_NEWLINE);
514 return CMD_WARNING;
515 }
516
517 if (!strcmp(argv[2], "tch/f"))
518 type = RSL_CHANNEED_TCH_F;
519 else if (!strcmp(argv[2], "tch/any"))
520 type = RSL_CHANNEED_TCH_ForH;
521 else if (!strcmp(argv[2], "sdcch"))
522 type = RSL_CHANNEED_SDCCH;
523 else
524 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
525
Harald Welte2483f1b2016-06-19 18:06:02 +0200526 rc = gsm_silent_call_start(vsub, vty, type);
Neels Hofmeyrd656dff2018-03-09 14:59:44 +0100527 switch (rc) {
528 case -ENODEV:
529 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
530 break;
531 default:
532 if (rc)
533 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
534 else
535 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
536 break;
Sylvain Munaut50480702010-01-02 14:29:43 +0100537 }
538
Harald Welte2483f1b2016-06-19 18:06:02 +0200539 vlr_subscr_put(vsub);
Neels Hofmeyrd656dff2018-03-09 14:59:44 +0100540 return rc ? CMD_WARNING : CMD_SUCCESS;
Sylvain Munaut50480702010-01-02 14:29:43 +0100541}
542
543DEFUN(subscriber_silent_call_stop,
544 subscriber_silent_call_stop_cmd,
Harald Welteb4a84e12010-05-27 10:44:58 +0200545 "subscriber " SUBSCR_TYPES " ID silent-call stop",
Harald Welte28326062010-05-14 20:05:17 +0200546 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
547 CHAN_TYPE_HELP)
Harald Weltea1482332009-11-14 10:08:40 +0100548{
Harald Weltedcccb182010-05-16 20:52:23 +0200549 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte2483f1b2016-06-19 18:06:02 +0200550 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Weltea1482332009-11-14 10:08:40 +0100551 int rc;
552
Harald Welte2483f1b2016-06-19 18:06:02 +0200553 if (!vsub) {
Harald Weltea1482332009-11-14 10:08:40 +0100554 vty_out(vty, "%% No subscriber found for %s %s%s",
Harald Welte20f98312009-11-14 10:11:45 +0100555 argv[0], argv[1], VTY_NEWLINE);
Harald Weltea1482332009-11-14 10:08:40 +0100556 return CMD_WARNING;
557 }
558
Harald Welte2483f1b2016-06-19 18:06:02 +0200559 rc = gsm_silent_call_stop(vsub);
Neels Hofmeyrd656dff2018-03-09 14:59:44 +0100560 switch (rc) {
561 case -ENODEV:
562 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
563 break;
564 case -ENOENT:
565 vty_out(vty, "%% Subscriber has no silent call active%s",
566 VTY_NEWLINE);
567 break;
568 default:
569 if (rc)
570 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
571 else
572 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
573 break;
Harald Weltea1482332009-11-14 10:08:40 +0100574 }
575
Harald Welte2483f1b2016-06-19 18:06:02 +0200576 vlr_subscr_put(vsub);
Neels Hofmeyrd656dff2018-03-09 14:59:44 +0100577 return rc ? CMD_WARNING : CMD_SUCCESS;
Harald Weltea1482332009-11-14 10:08:40 +0100578}
579
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800580DEFUN(subscriber_ussd_notify,
581 subscriber_ussd_notify_cmd,
Holger Hans Peter Freythere731e1d2010-07-27 18:27:46 +0800582 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
Harald Weltecfaabbb2012-08-16 23:23:50 +0200583 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +0200584 "Alerting Level 0\n"
585 "Alerting Level 1\n"
586 "Alerting Level 2\n"
587 "Text of USSD message to send\n")
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800588{
589 char *text;
590 struct gsm_subscriber_connection *conn;
591 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte2483f1b2016-06-19 18:06:02 +0200592 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Holger Hans Peter Freythere731e1d2010-07-27 18:27:46 +0800593 int level;
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800594
Harald Welte2483f1b2016-06-19 18:06:02 +0200595 if (!vsub) {
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800596 vty_out(vty, "%% No subscriber found for %s %s%s",
597 argv[0], argv[1], VTY_NEWLINE);
598 return CMD_WARNING;
599 }
600
Holger Hans Peter Freythere731e1d2010-07-27 18:27:46 +0800601 level = atoi(argv[2]);
602 text = argv_concat(argv, argc, 3);
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800603 if (!text) {
Harald Welte2483f1b2016-06-19 18:06:02 +0200604 vlr_subscr_put(vsub);
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800605 return CMD_WARNING;
606 }
607
Harald Welte2483f1b2016-06-19 18:06:02 +0200608 conn = connection_for_subscr(vsub);
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800609 if (!conn) {
610 vty_out(vty, "%% An active connection is required for %s %s%s",
611 argv[0], argv[1], VTY_NEWLINE);
Harald Welte2483f1b2016-06-19 18:06:02 +0200612 vlr_subscr_put(vsub);
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800613 talloc_free(text);
614 return CMD_WARNING;
615 }
616
Neels Hofmeyr43273c62016-05-10 12:50:31 +0200617 msc_send_ussd_notify(conn, level, text);
618 msc_send_ussd_release_complete(conn);
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800619
Harald Welte2483f1b2016-06-19 18:06:02 +0200620 vlr_subscr_put(vsub);
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +0800621 talloc_free(text);
622 return CMD_SUCCESS;
623}
624
Neels Hofmeyr596ef652018-03-09 15:05:29 +0100625DEFUN(subscriber_paging,
626 subscriber_paging_cmd,
627 "subscriber " SUBSCR_TYPES " ID paging",
628 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
629{
630 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
631 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
632 struct subscr_request *req;
633
634 if (!vsub) {
635 vty_out(vty, "%% No subscriber found for %s %s%s",
636 argv[0], argv[1], VTY_NEWLINE);
637 return CMD_WARNING;
638 }
639
640 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
641 if (req)
642 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
643 else
644 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
645
646 vlr_subscr_put(vsub);
647 return req ? CMD_SUCCESS : CMD_WARNING;
648}
649
Harald Welte94307772017-06-12 01:52:27 +0200650static int loop_by_char(uint8_t ch)
651{
652 switch (ch) {
653 case 'a':
654 return GSM414_LOOP_A;
655 case 'b':
656 return GSM414_LOOP_B;
657 case 'c':
658 return GSM414_LOOP_C;
659 case 'd':
660 return GSM414_LOOP_D;
661 case 'e':
662 return GSM414_LOOP_E;
663 case 'f':
664 return GSM414_LOOP_F;
665 case 'i':
666 return GSM414_LOOP_I;
667 }
668 return -1;
669}
670
671DEFUN(subscriber_mstest_close,
672 subscriber_mstest_close_cmd,
673 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
674 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
675 "Close a TCH Loop inside the MS\n"
676 "Loop Type A\n"
677 "Loop Type B\n"
678 "Loop Type C\n"
679 "Loop Type D\n"
680 "Loop Type E\n"
681 "Loop Type F\n"
682 "Loop Type I\n")
683{
684 struct gsm_subscriber_connection *conn;
685 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
686 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
687 const char *loop_str;
688 int loop_mode;
689
690 if (!vsub) {
691 vty_out(vty, "%% No subscriber found for %s %s%s",
692 argv[0], argv[1], VTY_NEWLINE);
693 return CMD_WARNING;
694 }
695
696 loop_str = argv[2];
697 loop_mode = loop_by_char(loop_str[0]);
698
699 conn = connection_for_subscr(vsub);
700 if (!conn) {
701 vty_out(vty, "%% An active connection is required for %s %s%s",
702 argv[0], argv[1], VTY_NEWLINE);
703 vlr_subscr_put(vsub);
704 return CMD_WARNING;
705 }
706
707 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
708
709 return CMD_SUCCESS;
710}
711
712DEFUN(subscriber_mstest_open,
713 subscriber_mstest_open_cmd,
714 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
715 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
716 "Open a TCH Loop inside the MS\n")
717{
718 struct gsm_subscriber_connection *conn;
719 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
720 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
721
722 if (!vsub) {
723 vty_out(vty, "%% No subscriber found for %s %s%s",
724 argv[0], argv[1], VTY_NEWLINE);
725 return CMD_WARNING;
726 }
727
728 conn = connection_for_subscr(vsub);
729 if (!conn) {
730 vty_out(vty, "%% An active connection is required for %s %s%s",
731 argv[0], argv[1], VTY_NEWLINE);
732 vlr_subscr_put(vsub);
733 return CMD_WARNING;
734 }
735
736 gsm0414_tx_open_loop_cmd(conn);
737
738 return CMD_SUCCESS;
739}
740
Keithd32b6d12017-01-18 17:09:33 +0100741DEFUN(ena_subscr_expire,
742 ena_subscr_expire_cmd,
743 "subscriber " SUBSCR_TYPES " ID expire",
744 SUBSCR_HELP "Expire the subscriber Now\n")
745{
Keithd32b6d12017-01-18 17:09:33 +0100746 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte2483f1b2016-06-19 18:06:02 +0200747 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
748 argv[1]);
Keithd32b6d12017-01-18 17:09:33 +0100749
Harald Welte2483f1b2016-06-19 18:06:02 +0200750 if (!vsub) {
Keithd32b6d12017-01-18 17:09:33 +0100751 vty_out(vty, "%% No subscriber found for %s %s%s",
752 argv[0], argv[1], VTY_NEWLINE);
753 return CMD_WARNING;
754 }
755
Maxdcc193d2017-12-27 19:34:15 +0100756 if (vlr_subscr_expire(vsub))
Harald Welte2483f1b2016-06-19 18:06:02 +0200757 vty_out(vty, "%% VLR released subscriber %s%s",
758 vlr_subscr_name(vsub), VTY_NEWLINE);
Keithd32b6d12017-01-18 17:09:33 +0100759
Harald Welte2483f1b2016-06-19 18:06:02 +0200760 if (vsub->use_count > 1)
761 vty_out(vty, "%% Subscriber %s is still in use,"
762 " should be released soon%s",
763 vlr_subscr_name(vsub), VTY_NEWLINE);
764
765 vlr_subscr_put(vsub);
Keithd32b6d12017-01-18 17:09:33 +0100766 return CMD_SUCCESS;
767}
768
Harald Weltea1482332009-11-14 10:08:40 +0100769static int scall_cbfn(unsigned int subsys, unsigned int signal,
770 void *handler_data, void *signal_data)
771{
772 struct scall_signal_data *sigdata = signal_data;
773 struct vty *vty = sigdata->data;
774
775 switch (signal) {
776 case S_SCALL_SUCCESS:
Neels Hofmeyre2f24d52017-05-08 15:12:20 +0200777 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
Harald Weltea1482332009-11-14 10:08:40 +0100778 break;
779 case S_SCALL_EXPIRED:
780 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
781 break;
782 }
783 return 0;
784}
785
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200786DEFUN(show_stats,
787 show_stats_cmd,
788 "show statistics",
789 SHOW_STR "Display network statistics\n")
790{
Harald Weltedcccb182010-05-16 20:52:23 +0200791 struct gsm_network *net = gsmnet_from_vty(vty);
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200792
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200793 vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s",
Alexander Couzensb847a212016-08-02 11:34:11 +0200794 net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
795 net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
796 net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +0200797 VTY_NEWLINE);
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200798 vty_out(vty, "IMSI Detach Indications : %lu%s",
Alexander Couzensb847a212016-08-02 11:34:11 +0200799 net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +0200800 VTY_NEWLINE);
Neels Hofmeyr36891a72016-05-09 13:18:03 +0200801 vty_out(vty, "Location Updating Results: %lu completed, %lu failed%s",
802 net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
803 net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +0200804 VTY_NEWLINE);
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200805 vty_out(vty, "SMS MO : %lu submitted, %lu no receiver%s",
Alexander Couzensb847a212016-08-02 11:34:11 +0200806 net->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
807 net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +0200808 VTY_NEWLINE);
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200809 vty_out(vty, "SMS MT : %lu delivered, %lu no memory, %lu other error%s",
Alexander Couzensb847a212016-08-02 11:34:11 +0200810 net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
811 net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
812 net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +0200813 VTY_NEWLINE);
Harald Weltea29e43a2010-12-24 16:06:33 +0100814 vty_out(vty, "MO Calls : %lu setup, %lu connect ack%s",
Alexander Couzensb847a212016-08-02 11:34:11 +0200815 net->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
816 net->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +0200817 VTY_NEWLINE);
Harald Weltea29e43a2010-12-24 16:06:33 +0100818 vty_out(vty, "MT Calls : %lu setup, %lu connect%s",
Alexander Couzensb847a212016-08-02 11:34:11 +0200819 net->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
820 net->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +0200821 VTY_NEWLINE);
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200822 return CMD_SUCCESS;
823}
824
Holger Hans Peter Freyther81c0e252010-12-25 14:08:00 +0100825DEFUN(show_smsqueue,
826 show_smsqueue_cmd,
827 "show sms-queue",
828 SHOW_STR "Display SMSqueue statistics\n")
829{
830 struct gsm_network *net = gsmnet_from_vty(vty);
831
832 sms_queue_stats(net->sms_queue, vty);
833 return CMD_SUCCESS;
834}
835
Holger Hans Peter Freyther7a0e1662010-12-25 14:15:32 +0100836DEFUN(smsqueue_trigger,
837 smsqueue_trigger_cmd,
838 "sms-queue trigger",
839 "SMS Queue\n" "Trigger sending messages\n")
840{
841 struct gsm_network *net = gsmnet_from_vty(vty);
842
843 sms_queue_trigger(net->sms_queue);
844 return CMD_SUCCESS;
845}
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200846
Holger Hans Peter Freyther3c6f6c22010-12-25 14:25:12 +0100847DEFUN(smsqueue_max,
848 smsqueue_max_cmd,
849 "sms-queue max-pending <1-500>",
Holger Hans Peter Freyther3217fa22012-07-20 23:55:08 +0200850 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
Holger Hans Peter Freyther3c6f6c22010-12-25 14:25:12 +0100851{
852 struct gsm_network *net = gsmnet_from_vty(vty);
853
854 sms_queue_set_max_pending(net->sms_queue, atoi(argv[0]));
855 return CMD_SUCCESS;
856}
857
Holger Hans Peter Freyther4dcc5e52010-12-25 14:38:30 +0100858DEFUN(smsqueue_clear,
859 smsqueue_clear_cmd,
860 "sms-queue clear",
861 "SMS Queue\n" "Clear the queue of pending SMS\n")
862{
863 struct gsm_network *net = gsmnet_from_vty(vty);
864
865 sms_queue_clear(net->sms_queue);
866 return CMD_SUCCESS;
867}
868
Holger Hans Peter Freyther994dcbb2010-12-25 14:50:50 +0100869DEFUN(smsqueue_fail,
870 smsqueue_fail_cmd,
871 "sms-queue max-failure <1-500>",
Holger Hans Peter Freyther3217fa22012-07-20 23:55:08 +0200872 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
Holger Hans Peter Freyther994dcbb2010-12-25 14:50:50 +0100873{
874 struct gsm_network *net = gsmnet_from_vty(vty);
875
876 sms_queue_set_max_failure(net->sms_queue, atoi(argv[0]));
877 return CMD_SUCCESS;
878}
879
Harald Welteab386e62011-09-01 18:18:43 +0200880
881DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
882 "mncc-int", "Configure internal MNCC handler")
883{
884 vty->node = MNCC_INT_NODE;
885
886 return CMD_SUCCESS;
887}
888
889static struct cmd_node mncc_int_node = {
890 MNCC_INT_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200891 "%s(config-mncc-int)# ",
Harald Welteab386e62011-09-01 18:18:43 +0200892 1,
893};
894
895static const struct value_string tchf_codec_names[] = {
896 { GSM48_CMODE_SPEECH_V1, "fr" },
897 { GSM48_CMODE_SPEECH_EFR, "efr" },
898 { GSM48_CMODE_SPEECH_AMR, "amr" },
899 { 0, NULL }
900};
901
902static const struct value_string tchh_codec_names[] = {
903 { GSM48_CMODE_SPEECH_V1, "hr" },
904 { GSM48_CMODE_SPEECH_AMR, "amr" },
905 { 0, NULL }
906};
907
908static int config_write_mncc_int(struct vty *vty)
909{
910 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
911 vty_out(vty, " default-codec tch-f %s%s",
912 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
913 VTY_NEWLINE);
914 vty_out(vty, " default-codec tch-h %s%s",
915 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
916 VTY_NEWLINE);
917
918 return CMD_SUCCESS;
919}
920
921DEFUN(mnccint_def_codec_f,
922 mnccint_def_codec_f_cmd,
923 "default-codec tch-f (fr|efr|amr)",
924 "Set default codec\n" "Codec for TCH/F\n"
925 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
926{
927 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
928
929 return CMD_SUCCESS;
930}
931
932DEFUN(mnccint_def_codec_h,
933 mnccint_def_codec_h_cmd,
934 "default-codec tch-h (hr|amr)",
935 "Set default codec\n" "Codec for TCH/H\n"
936 "Half-Rate\n" "Adaptive Multi-Rate\n")
937{
938 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
939
940 return CMD_SUCCESS;
941}
942
Holger Hans Peter Freyther6995f242014-12-28 18:54:32 +0100943
944DEFUN(logging_fltr_imsi,
945 logging_fltr_imsi_cmd,
946 "logging filter imsi IMSI",
947 LOGGING_STR FILTER_STR
948 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
949{
Harald Welte2483f1b2016-06-19 18:06:02 +0200950 struct vlr_subscr *vlr_subscr;
Holger Hans Peter Freyther6995f242014-12-28 18:54:32 +0100951 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
952 struct log_target *tgt = osmo_log_vty2tgt(vty);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +0100953 const char *imsi = argv[0];
Holger Hans Peter Freyther6995f242014-12-28 18:54:32 +0100954
955 if (!tgt)
956 return CMD_WARNING;
957
Harald Welte2483f1b2016-06-19 18:06:02 +0200958 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +0100959
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200960 if (!vlr_subscr) {
Holger Hans Peter Freyther6995f242014-12-28 18:54:32 +0100961 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
962 argv[0], VTY_NEWLINE);
963 return CMD_WARNING;
964 }
965
Harald Welte2483f1b2016-06-19 18:06:02 +0200966 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Holger Hans Peter Freyther6995f242014-12-28 18:54:32 +0100967 return CMD_SUCCESS;
968}
Holger Hans Peter Freyther925c57f2015-01-27 10:58:29 +0100969
Harald Welte2483f1b2016-06-19 18:06:02 +0200970static struct cmd_node hlr_node = {
971 HLR_NODE,
972 "%s(config-hlr)# ",
973 1,
974};
975
976DEFUN(cfg_hlr, cfg_hlr_cmd,
977 "hlr", "Configure connection to the HLR")
978{
979 vty->node = HLR_NODE;
980 return CMD_SUCCESS;
981}
982
983DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
984 "Remote GSUP address of the HLR\n"
985 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
986{
987 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
988 talloc_free((void*)gsmnet->gsup_server_addr_str);
989 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
990 return CMD_SUCCESS;
991}
992
993DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
994 "Remote GSUP port of the HLR\n"
995 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
996{
997 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
998 gsmnet->gsup_server_port = atoi(argv[0]);
999 return CMD_SUCCESS;
1000}
1001
1002static int config_write_hlr(struct vty *vty)
1003{
1004 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1005
1006 vty_out(vty, "hlr%s", VTY_NEWLINE);
1007 vty_out(vty, " remote-ip %s%s",
1008 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1009 vty_out(vty, " remote-port %u%s",
1010 gsmnet->gsup_server_port, VTY_NEWLINE);
1011 return CMD_SUCCESS;
1012}
1013
Harald Weltedcccb182010-05-16 20:52:23 +02001014int bsc_vty_init_extra(void)
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02001015{
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001016 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
Harald Weltea1482332009-11-14 10:08:40 +01001017
Harald Welteb4d5b172010-05-12 16:10:35 +00001018 install_element_ve(&show_subscr_cmd);
1019 install_element_ve(&show_subscr_cache_cmd);
Harald Welte66a301e2018-01-24 16:48:17 +01001020 install_element_ve(&show_msc_conn_cmd);
1021 install_element_ve(&show_msc_transaction_cmd);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02001022
Harald Welteb4d5b172010-05-12 16:10:35 +00001023 install_element_ve(&sms_send_pend_cmd);
Stefan Sperling87cba1f2018-01-22 17:05:37 +01001024 install_element_ve(&sms_delete_expired_cmd);
Harald Welte98f9c752009-11-14 08:00:53 +01001025
Alexander Chemerisbd6d40f2013-10-04 23:54:17 +02001026 install_element_ve(&subscriber_create_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00001027 install_element_ve(&subscriber_send_sms_cmd);
1028 install_element_ve(&subscriber_silent_sms_cmd);
1029 install_element_ve(&subscriber_silent_call_start_cmd);
1030 install_element_ve(&subscriber_silent_call_stop_cmd);
Holger Hans Peter Freytherdaf75342010-07-26 20:01:07 +08001031 install_element_ve(&subscriber_ussd_notify_cmd);
Harald Welte94307772017-06-12 01:52:27 +02001032 install_element_ve(&subscriber_mstest_close_cmd);
1033 install_element_ve(&subscriber_mstest_open_cmd);
Neels Hofmeyr596ef652018-03-09 15:05:29 +01001034 install_element_ve(&subscriber_paging_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00001035 install_element_ve(&show_stats_cmd);
Holger Hans Peter Freyther81c0e252010-12-25 14:08:00 +01001036 install_element_ve(&show_smsqueue_cmd);
Holger Hans Peter Freyther6995f242014-12-28 18:54:32 +01001037 install_element_ve(&logging_fltr_imsi_cmd);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02001038
Keithd32b6d12017-01-18 17:09:33 +01001039 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
Holger Hans Peter Freyther7a0e1662010-12-25 14:15:32 +01001040 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
Holger Hans Peter Freyther3c6f6c22010-12-25 14:25:12 +01001041 install_element(ENABLE_NODE, &smsqueue_max_cmd);
Holger Hans Peter Freyther4dcc5e52010-12-25 14:38:30 +01001042 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
Holger Hans Peter Freyther994dcbb2010-12-25 14:50:50 +01001043 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
Nico Goldeb62b1232011-02-22 17:54:47 +01001044 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02001045
Harald Welteab386e62011-09-01 18:18:43 +02001046 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1047 install_node(&mncc_int_node, config_write_mncc_int);
Harald Welteab386e62011-09-01 18:18:43 +02001048 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1049 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1050
Holger Hans Peter Freyther6995f242014-12-28 18:54:32 +01001051 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
Harald Welteb02fc1e2013-02-12 11:15:49 +01001052
Harald Welte2483f1b2016-06-19 18:06:02 +02001053 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1054 install_node(&hlr_node, config_write_hlr);
1055 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1056 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Holger Hans Peter Freyther925c57f2015-01-27 10:58:29 +01001057
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02001058 return 0;
1059}