aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/vty_interface_layer3.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/vty_interface_layer3.c')
-rw-r--r--openbsc/src/vty_interface_layer3.c128
1 files changed, 104 insertions, 24 deletions
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index 032e16fc4..4cc08c2da 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -1,5 +1,6 @@
/* OpenBSC interface to quagga VTY */
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009 by Holger Hans Peter Freyther
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -31,12 +32,14 @@
#include <openbsc/linuxlist.h>
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_subscriber.h>
+#include <openbsc/silent_call.h>
#include <openbsc/gsm_04_11.h>
#include <openbsc/e1_input.h>
#include <openbsc/abis_nm.h>
#include <openbsc/gsm_utils.h>
#include <openbsc/db.h>
#include <openbsc/talloc.h>
+#include <openbsc/signal.h>
/* forward declarations */
void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr);
@@ -54,7 +57,6 @@ static int dummy_config_write(struct vty *v)
return CMD_SUCCESS;
}
-
static struct buffer *argv_to_buffer(int argc, const char *argv[], int base)
{
struct buffer *b = buffer_new(1024);
@@ -88,6 +90,7 @@ DEFUN(cfg_subscr,
return CMD_WARNING;
}
+ /* vty_go_parent should put this subscriber */
vty->index = subscr;
vty->node = SUBSCR_NODE;
@@ -112,6 +115,7 @@ DEFUN(show_subscr,
return CMD_WARNING;
}
subscr_dump_vty(vty, subscr);
+ subscr_put(subscr);
return CMD_SUCCESS;
}
@@ -191,57 +195,111 @@ struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, const char *text)
}
static int _send_sms_buffer(struct gsm_subscriber *receiver,
- struct buffer *b)
+ struct buffer *b, u_int8_t tp_pid)
{
struct gsm_sms *sms;
sms = sms_from_text(receiver, buffer_getstr(b));
-
+ sms->protocol_id = tp_pid;
gsm411_send_sms_subscr(receiver, sms);
return CMD_SUCCESS;
}
-DEFUN(sms_send_ext,
- sms_send_ext_cmd,
- "sms send extension EXTEN .LINE",
- "Send a message to a subscriber identified by EXTEN")
+static struct gsm_subscriber *get_subscr_by_argv(const char *type,
+ const char *id)
+{
+ if (!strcmp(type, "extension"))
+ return subscr_get_by_extension(gsmnet, id);
+ else if (!strcmp(type, "imsi"))
+ return subscr_get_by_imsi(gsmnet, id);
+ else if (!strcmp(type, "tmsi"))
+ return subscr_get_by_tmsi(gsmnet, atoi(id));
+ else if (!strcmp(type, "id"))
+ return subscr_get_by_id(gsmnet, atoi(id));
+
+ return NULL;
+}
+#define SUBSCR_TYPES "(extension|imsi|tmsi|id)"
+
+DEFUN(subscriber_send_sms,
+ subscriber_send_sms_cmd,
+ "subscriber " SUBSCR_TYPES " EXTEN sms send .LINE",
+ "Select subscriber based on extension")
{
- struct gsm_subscriber *receiver;
+ struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
struct buffer *b;
int rc;
- receiver = subscr_get_by_extension(gsmnet, argv[0]);
- if (!receiver)
+ if (!subscr) {
+ vty_out(vty, "%% No subscriber found for %s %s%s",
+ argv[0], argv[1], VTY_NEWLINE);
return CMD_WARNING;
-
- b = argv_to_buffer(argc, argv, 1);
- rc = _send_sms_buffer(receiver, b);
+ }
+ b = argv_to_buffer(argc, argv, 2);
+ rc = _send_sms_buffer(subscr, b, 0);
buffer_free(b);
+ subscr_put(subscr);
+
return rc;
}
-DEFUN(sms_send_imsi,
- sms_send_imsi_cmd,
- "sms send imsi IMSI .LINE",
- "Send a message to a subscriber identified by IMSI")
+DEFUN(subscriber_silent_sms,
+ subscriber_silent_sms_cmd,
+ "subscriber " SUBSCR_TYPES " EXTEN silent sms send .LINE",
+ "Select subscriber based on extension")
{
- struct gsm_subscriber *receiver;
+ struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
struct buffer *b;
int rc;
- receiver = subscr_get_by_imsi(gsmnet, argv[0]);
- if (!receiver)
+ if (!subscr) {
+ vty_out(vty, "%% No subscriber found for %s %s%s",
+ argv[0], argv[1], VTY_NEWLINE);
return CMD_WARNING;
+ }
- b = argv_to_buffer(argc, argv, 1);
- rc = _send_sms_buffer(receiver, b);
+ b = argv_to_buffer(argc, argv, 2);
+ rc = _send_sms_buffer(subscr, b, 64);
buffer_free(b);
+ subscr_put(subscr);
+
return rc;
}
+DEFUN(subscriber_silent_call,
+ subscriber_silent_call_cmd,
+ "subscriber " SUBSCR_TYPES " EXTEN silent call (start|stop)",
+ "Send a silent call to a subscriber")
+{
+ struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
+ int rc;
+
+ if (!subscr) {
+ vty_out(vty, "%% No subscriber found for %s %s%s",
+ argv[0], argv[1], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (!strcmp(argv[2], "start")) {
+ rc = gsm_silent_call_start(subscr, vty);
+ if (rc <= 0) {
+ vty_out(vty, "%% Subscriber not attached%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ } else {
+ rc = gsm_silent_call_stop(subscr);
+ if (rc < 0)
+ return CMD_WARNING;
+ }
+
+ subscr_put(subscr);
+
+ return CMD_SUCCESS;
+}
DEFUN(cfg_subscr_name,
cfg_subscr_name_cmd,
@@ -291,17 +349,39 @@ DEFUN(cfg_subscr_authorized,
return CMD_SUCCESS;
}
+static int scall_cbfn(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *signal_data)
+{
+ struct scall_signal_data *sigdata = signal_data;
+ struct vty *vty = sigdata->data;
+
+ switch (signal) {
+ case S_SCALL_SUCCESS:
+ vty_out(vty, "%% silent call on ARFCN %u timeslot %u%s",
+ sigdata->lchan->ts->trx->arfcn, sigdata->lchan->ts->nr,
+ VTY_NEWLINE);
+ break;
+ case S_SCALL_EXPIRED:
+ vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
+ break;
+ }
+ return 0;
+}
int bsc_vty_init_extra(struct gsm_network *net)
{
gsmnet = net;
+ register_signal_handler(SS_SCALL, scall_cbfn, NULL);
+
install_element(VIEW_NODE, &show_subscr_cmd);
install_element(VIEW_NODE, &show_subscr_cache_cmd);
install_element(VIEW_NODE, &sms_send_pend_cmd);
- install_element(VIEW_NODE, &sms_send_ext_cmd);
- install_element(VIEW_NODE, &sms_send_imsi_cmd);
+
+ install_element(VIEW_NODE, &subscriber_send_sms_cmd);
+ install_element(VIEW_NODE, &subscriber_silent_sms_cmd);
+ install_element(VIEW_NODE, &subscriber_silent_call_cmd);
install_element(CONFIG_NODE, &cfg_subscr_cmd);
install_node(&subscr_node, dummy_config_write);