nitb/ctrl: Implement a command to list all active subscribers
This is only useful for small networks. List the IMSI and MSISDN of all active subscribers. Fixes: SYS#266
This commit is contained in:
parent
2d99eeb7f2
commit
d883db027b
|
@ -47,6 +47,7 @@ int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char *imei);
|
||||||
int db_subscriber_delete(struct gsm_subscriber *subscriber);
|
int db_subscriber_delete(struct gsm_subscriber *subscriber);
|
||||||
int db_sync_equipment(struct gsm_equipment *equip);
|
int db_sync_equipment(struct gsm_equipment *equip);
|
||||||
int db_subscriber_update(struct gsm_subscriber *subscriber);
|
int db_subscriber_update(struct gsm_subscriber *subscriber);
|
||||||
|
int db_subscriber_list_active(void (*list_cb)(struct gsm_subscriber*,void*), void*);
|
||||||
|
|
||||||
/* auth info */
|
/* auth info */
|
||||||
int db_get_authinfo_for_subscr(struct gsm_auth_info *ainfo,
|
int db_get_authinfo_for_subscr(struct gsm_auth_info *ainfo,
|
||||||
|
|
|
@ -140,11 +140,40 @@ static int set_subscriber_delete(struct ctrl_cmd *cmd, void *data)
|
||||||
}
|
}
|
||||||
CTRL_CMD_DEFINE(subscriber_delete, "subscriber-delete-v1");
|
CTRL_CMD_DEFINE(subscriber_delete, "subscriber-delete-v1");
|
||||||
|
|
||||||
|
static int verify_subscriber_list(struct ctrl_cmd *cmd, const char *value, void *d)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_subscriber_list(struct ctrl_cmd *cmd, void *d)
|
||||||
|
{
|
||||||
|
cmd->reply = "Get only attribute";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_cb(struct gsm_subscriber *subscr, void *d)
|
||||||
|
{
|
||||||
|
char **data = (char **) d;
|
||||||
|
*data = talloc_asprintf_append(*data, "%s,%s\n",
|
||||||
|
subscr->imsi, subscr->extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_subscriber_list(struct ctrl_cmd *cmd, void *d)
|
||||||
|
{
|
||||||
|
cmd->reply = talloc_strdup(cmd, "");
|
||||||
|
|
||||||
|
db_subscriber_list_active(list_cb, &cmd->reply);
|
||||||
|
printf("%s\n", cmd->reply);
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
CTRL_CMD_DEFINE(subscriber_list, "subscriber-list-active-v1");
|
||||||
|
|
||||||
int msc_ctrl_cmds_install(void)
|
int msc_ctrl_cmds_install(void)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_modify);
|
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_modify);
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_delete);
|
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_delete);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_list);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -902,6 +902,39 @@ int db_subscriber_delete(struct gsm_subscriber *subscr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all the authorized and non-expired subscribers. The callback will
|
||||||
|
* be called one by one. The subscr argument is not fully initialize and
|
||||||
|
* subscr_get/subscr_put must not be called. The passed in pointer will be
|
||||||
|
* deleted after the callback by the database call.
|
||||||
|
*/
|
||||||
|
int db_subscriber_list_active(void (*cb)(struct gsm_subscriber*,void*), void *closure)
|
||||||
|
{
|
||||||
|
dbi_result result;
|
||||||
|
|
||||||
|
result = dbi_conn_queryf(conn,
|
||||||
|
"SELECT * from Subscriber WHERE LAC != 0 AND authorized = 1");
|
||||||
|
if (!result) {
|
||||||
|
LOGP(DDB, LOGL_ERROR, "Failed to list active subscribers\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dbi_result_next_row(result)) {
|
||||||
|
struct gsm_subscriber *subscr;
|
||||||
|
|
||||||
|
subscr = subscr_alloc();
|
||||||
|
subscr->id = dbi_result_get_ulonglong(result, "id");
|
||||||
|
db_set_from_query(subscr, result);
|
||||||
|
cb(subscr, closure);
|
||||||
|
OSMO_ASSERT(subscr->use_count == 1);
|
||||||
|
llist_del(&subscr->entry);
|
||||||
|
talloc_free(subscr);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbi_result_free(result);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int db_sync_equipment(struct gsm_equipment *equip)
|
int db_sync_equipment(struct gsm_equipment *equip)
|
||||||
{
|
{
|
||||||
dbi_result result;
|
dbi_result result;
|
||||||
|
|
|
@ -341,6 +341,13 @@ class TestCtrlNITB(TestCtrlBase):
|
||||||
self.assertEquals(r['mtype'], 'ERROR')
|
self.assertEquals(r['mtype'], 'ERROR')
|
||||||
self.assertEquals(r['error'], 'Failed to find subscriber')
|
self.assertEquals(r['error'], 'Failed to find subscriber')
|
||||||
|
|
||||||
|
def testSubscriberList(self):
|
||||||
|
# TODO. Add command to mark a subscriber as active
|
||||||
|
r = self.do_get('subscriber-list-active-v1')
|
||||||
|
self.assertEquals(r['mtype'], 'GET_REPLY')
|
||||||
|
self.assertEquals(r['var'], 'subscriber-list-active-v1')
|
||||||
|
self.assertEquals(r['value'], None)
|
||||||
|
|
||||||
class TestCtrlNAT(TestCtrlBase):
|
class TestCtrlNAT(TestCtrlBase):
|
||||||
|
|
||||||
def ctrl_command(self):
|
def ctrl_command(self):
|
||||||
|
|
Loading…
Reference in New Issue