summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2017-02-20 17:22:56 +0100
committerMax <msuraev@sysmocom.de>2017-03-06 13:58:04 +0100
commit9cacb6f74b73f90d79aa53f707124cceee19f8af (patch)
tree2a990d86bc53fffaf25f1d5a9cbe668515f53c43
parent372868baa37010625eb66f3c03677cac743cec5b (diff)
CTRL: add enable/disable packet service cmds
Add commands to enable/disable Packet Service for a given IMSI. Changes are synced to DB and propagated at runtime to SGSN (in case of disable command). Change-Id: I23163ce8667292443ed61cb15c928357dba4b4be Related: OS#1645
-rw-r--r--src/ctrl.c43
-rw-r--r--src/gsup_server.c8
-rw-r--r--src/gsup_server.h10
-rw-r--r--src/hlr.c11
-rw-r--r--src/luop.c13
-rw-r--r--src/luop.h1
6 files changed, 79 insertions, 7 deletions
diff --git a/src/ctrl.c b/src/ctrl.c
index a167171..81de961 100644
--- a/src/ctrl.c
+++ b/src/ctrl.c
@@ -33,6 +33,47 @@
#include "luop.h"
#include "ctrl.h"
+static int handle_cmd_ps(struct hlr *ctx, struct ctrl_cmd *cmd, bool enable)
+{
+ struct lu_operation *luop = NULL;
+ struct osmo_gsup_conn *co;
+
+ if (db_subscr_get(ctx->dbc, cmd->value, NULL) < 0) {
+ cmd->reply = "Subscriber Unknown in HLR";
+ return CTRL_CMD_ERROR;
+ }
+
+ if (db_subscr_ps(ctx->dbc, cmd->value, enable) < 0) {
+ cmd->reply = "Error updating DB";
+ return CTRL_CMD_ERROR;
+ }
+
+ /* FIXME: only send to single SGSN where latest update for IMSI came from */
+ if (!enable) {
+ llist_for_each_entry(co, &ctx->gs->clients, list) {
+ luop = lu_op_alloc_conn(co);
+ lu_op_fill_subscr(luop, ctx->dbc, cmd->value);
+ lu_op_tx_del_subscr_data(luop);
+ }
+ }
+
+ cmd->reply = "OK";
+
+ return CTRL_CMD_REPLY;
+}
+
+CTRL_CMD_DEFINE_WO_NOVRF(enable_ps, "enable-ps");
+static int set_enable_ps(struct ctrl_cmd *cmd, void *data)
+{
+ return handle_cmd_ps(data, cmd, true);
+}
+
+CTRL_CMD_DEFINE_WO_NOVRF(disable_ps, "disable-ps");
+static int set_disable_ps(struct ctrl_cmd *cmd, void *data)
+{
+ return handle_cmd_ps(data, cmd, false);
+}
+
CTRL_CMD_DEFINE_WO_NOVRF(status_ps, "status-ps");
static int set_status_ps(struct ctrl_cmd *cmd, void *data)
{
@@ -57,6 +98,8 @@ int hlr_ctrl_cmds_install()
{
int rc = 0;
+ rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_enable_ps);
+ rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_disable_ps);
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_status_ps);
return rc;
diff --git a/src/gsup_server.c b/src/gsup_server.c
index ea51f7d..d431637 100644
--- a/src/gsup_server.c
+++ b/src/gsup_server.c
@@ -245,9 +245,9 @@ failed:
}
struct osmo_gsup_server *
-osmo_gsup_server_create(void *ctx, const char *ip_addr,
- uint16_t tcp_port,
- osmo_gsup_read_cb_t read_cb)
+osmo_gsup_server_create(void *ctx, const char *ip_addr, uint16_t tcp_port,
+ osmo_gsup_read_cb_t read_cb,
+ struct llist_head *lu_op_lst)
{
struct osmo_gsup_server *gsups;
int rc;
@@ -272,6 +272,8 @@ osmo_gsup_server_create(void *ctx, const char *ip_addr,
if (rc < 0)
goto failed;
+ gsups->luop = lu_op_lst;
+
return gsups;
failed:
diff --git a/src/gsup_server.h b/src/gsup_server.h
index 484a0d7..885fe52 100644
--- a/src/gsup_server.h
+++ b/src/gsup_server.h
@@ -14,6 +14,9 @@ struct osmo_gsup_server {
/* list of osmo_gsup_conn */
struct llist_head clients;
+ /* lu_operations list */
+ struct llist_head *luop;
+
struct ipa_server_link *link;
osmo_gsup_read_cb_t read_cb;
struct llist_head routes;
@@ -36,9 +39,10 @@ int osmo_gsup_conn_ccm_get(const struct osmo_gsup_conn *clnt, uint8_t **addr,
uint8_t tag);
struct osmo_gsup_server *osmo_gsup_server_create(void *ctx,
- const char *ip_addr,
- uint16_t tcp_port,
- osmo_gsup_read_cb_t read_cb);
+ const char *ip_addr,
+ uint16_t tcp_port,
+ osmo_gsup_read_cb_t read_cb,
+ struct llist_head *lu_op_lst);
void osmo_gsup_server_destroy(struct osmo_gsup_server *gsups);
diff --git a/src/hlr.c b/src/hlr.c
index 95a565e..00a6459 100644
--- a/src/hlr.c
+++ b/src/hlr.c
@@ -260,6 +260,14 @@ static int read_cb(struct osmo_gsup_conn *conn, struct msgb *msg)
rx_purge_ms_req(conn, &gsup);
break;
/* responses to requests sent by us */
+ case OSMO_GSUP_MSGT_DELETE_DATA_ERROR:
+ LOGP(DMAIN, LOGL_ERROR, "Error while deleting subscriber data "
+ "for IMSI %s\n", gsup.imsi);
+ break;
+ case OSMO_GSUP_MSGT_DELETE_DATA_RESULT:
+ LOGP(DMAIN, LOGL_ERROR, "Deleting subscriber data for IMSI %s\n",
+ gsup.imsi);
+ break;
case OSMO_GSUP_MSGT_INSERT_DATA_ERROR:
case OSMO_GSUP_MSGT_INSERT_DATA_RESULT:
case OSMO_GSUP_MSGT_LOCATION_CANCEL_ERROR:
@@ -456,7 +464,8 @@ int main(int argc, char **argv)
exit(1);
}
- g_hlr->gs = osmo_gsup_server_create(hlr_ctx, NULL, 2222, read_cb);
+ g_hlr->gs = osmo_gsup_server_create(hlr_ctx, NULL, 2222, read_cb,
+ &g_lu_ops);
if (!g_hlr->gs) {
LOGP(DMAIN, LOGL_FATAL, "Error starting GSUP server\n");
exit(1);
diff --git a/src/luop.c b/src/luop.c
index ecf31b4..937c02c 100644
--- a/src/luop.c
+++ b/src/luop.c
@@ -266,3 +266,16 @@ void lu_op_tx_insert_subscr_data(struct lu_operation *luop)
lu_op_statechg(luop, LU_S_ISD_SENT);
osmo_timer_schedule(&luop->timer, ISD_TIMEOUT_SECS, 0);
}
+
+/*! Transmit Delete Subscriber Data to new VLR/SGSN */
+void lu_op_tx_del_subscr_data(struct lu_operation *luop)
+{
+ struct osmo_gsup_message gsup;
+
+ fill_gsup_msg(&gsup, luop, OSMO_GSUP_MSGT_DELETE_DATA_REQUEST);
+
+ gsup.cn_domain = OSMO_GSUP_CN_DOMAIN_PS;
+
+ /* Send ISD to new VLR/SGSN */
+ _luop_tx_gsup(luop, &gsup);
+}
diff --git a/src/luop.h b/src/luop.h
index 7e2fbb0..ab1bc24 100644
--- a/src/luop.h
+++ b/src/luop.h
@@ -78,3 +78,4 @@ void lu_op_tx_error(struct lu_operation *luop, enum gsm48_gmm_cause cause);
void lu_op_tx_ack(struct lu_operation *luop);
void lu_op_tx_cancel_old(struct lu_operation *luop);
void lu_op_tx_insert_subscr_data(struct lu_operation *luop);
+void lu_op_tx_del_subscr_data(struct lu_operation *luop);