msc: Add and use gsm_subscriber_group

Currently every subcriber object directly refers to the gsm_network
which contains a flag shared by every related subscriber
(keep_subscr). This adds a dependency on gsm_network even if only the
function defined in gsm_subscriber_base.c are used.

This patch adds a new struct gsm_subscriber_group which contains the
keep_subscr flag and a back reference to the network object. The
latter is not dereferenced in gsm_subscriber_base.c, so it can safely
be set to NULL when only that part of the gsm_subscriber API is being
used. It also changes that API to use gsm_subscriber_group instead of
gsm_network parameters.

Since there are some places where a pointer to the gsm_network is
needed but where only a gsm_subscriber is available, a 'net' back
pointer is added to the group struct, too. Nevertheless subscr group
and network could be separated completely, but this is not the topic
of this commit.

Sponsored-by: On-Waves ehf
This commit is contained in:
Jacob Erlbeck
2014-12-03 09:28:24 +01:00
committed by Holger Hans Peter Freyther
parent dae1f64ba6
commit 1e30a28e51
24 changed files with 128 additions and 93 deletions

View File

@@ -14,6 +14,7 @@
#define OBSC_NM_W_ACK_CB(__msgb) (__msgb)->cb[3] #define OBSC_NM_W_ACK_CB(__msgb) (__msgb)->cb[3]
struct mncc_sock_state; struct mncc_sock_state;
struct gsm_subscriber_group;
#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3] #define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3]
@@ -277,7 +278,7 @@ struct gsm_network {
struct osmo_bsc_data *bsc_data; struct osmo_bsc_data *bsc_data;
/* subscriber related features */ /* subscriber related features */
int keep_subscr; struct gsm_subscriber_group *subscr_group;
struct gsm_sms_queue *sms_queue; struct gsm_sms_queue *sms_queue;
/* control interface */ /* control interface */

View File

@@ -20,6 +20,12 @@
struct vty; struct vty;
struct sgsn_mm_ctx; struct sgsn_mm_ctx;
struct gsm_subscriber_group {
struct gsm_network *net;
int keep_subscr;
};
struct gsm_equipment { struct gsm_equipment {
long long unsigned int id; long long unsigned int id;
char imei[GSM_IMEI_LENGTH]; char imei[GSM_IMEI_LENGTH];
@@ -33,7 +39,7 @@ struct gsm_equipment {
}; };
struct gsm_subscriber { struct gsm_subscriber {
struct gsm_network *net; struct gsm_subscriber_group *group;
long long unsigned int id; long long unsigned int id;
char imsi[GSM_IMSI_LENGTH]; char imsi[GSM_IMSI_LENGTH];
uint32_t tmsi; uint32_t tmsi;
@@ -77,25 +83,25 @@ enum gsm_subscriber_update_reason {
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr); struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr); struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_create_subscriber(struct gsm_network *net, struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
const char *imsi); const char *imsi);
struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net, struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_subscriber_group *sgrp,
uint32_t tmsi); uint32_t tmsi);
struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net, struct gsm_subscriber *subscr_get_by_imsi(struct gsm_subscriber_group *sgrp,
const char *imsi); const char *imsi);
struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net, struct gsm_subscriber *subscr_get_by_extension(struct gsm_subscriber_group *sgrp,
const char *ext); const char *ext);
struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net, struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp,
unsigned long long id); unsigned long long id);
struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net, struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
const char *imsi); const char *imsi);
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason); int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
void subscr_put_channel(struct gsm_subscriber *subscr); void subscr_put_channel(struct gsm_subscriber *subscr);
void subscr_get_channel(struct gsm_subscriber *subscr, void subscr_get_channel(struct gsm_subscriber *subscr,
int type, gsm_cbfn *cbfn, void *param); int type, gsm_cbfn *cbfn, void *param);
struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_network *net, struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
uint32_t tmsi); uint32_t tmsi);
struct gsm_subscriber *subscr_active_by_imsi(struct gsm_network *net, struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
const char *imsi); const char *imsi);
int subscr_pending_requests(struct gsm_subscriber *subscr); int subscr_pending_requests(struct gsm_subscriber *subscr);
@@ -105,9 +111,9 @@ int subscr_pending_kick(struct gsm_subscriber *subscr);
char *subscr_name(struct gsm_subscriber *subscr); char *subscr_name(struct gsm_subscriber *subscr);
int subscr_purge_inactive(struct gsm_network *net); int subscr_purge_inactive(struct gsm_subscriber_group *sgrp);
void subscr_update_from_db(struct gsm_subscriber *subscr); void subscr_update_from_db(struct gsm_subscriber *subscr);
void subscr_expire(struct gsm_network *net); void subscr_expire(struct gsm_subscriber_group *sgrp);
int subscr_update_expire_lu(struct gsm_subscriber *subscr, struct gsm_bts *bts); int subscr_update_expire_lu(struct gsm_subscriber *subscr, struct gsm_bts *bts);
/* internal */ /* internal */

View File

@@ -709,7 +709,7 @@ static int config_write_net(struct vty *vty)
vty_out(vty, " timer t3141 %u%s", gsmnet->T3141, VTY_NEWLINE); vty_out(vty, " timer t3141 %u%s", gsmnet->T3141, VTY_NEWLINE);
vty_out(vty, " dtx-used %u%s", gsmnet->dtx_enabled, VTY_NEWLINE); vty_out(vty, " dtx-used %u%s", gsmnet->dtx_enabled, VTY_NEWLINE);
vty_out(vty, " subscriber-keep-in-ram %d%s", vty_out(vty, " subscriber-keep-in-ram %d%s",
gsmnet->keep_subscr, VTY_NEWLINE); gsmnet->subscr_group->keep_subscr, VTY_NEWLINE);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@@ -1510,7 +1510,7 @@ DEFUN(cfg_net_subscr_keep,
"Delete unused subscribers\n" "Keep unused subscribers\n") "Delete unused subscribers\n" "Keep unused subscribers\n")
{ {
struct gsm_network *gsmnet = gsmnet_from_vty(vty); struct gsm_network *gsmnet = gsmnet_from_vty(vty);
gsmnet->keep_subscr = atoi(argv[0]); gsmnet->subscr_group->keep_subscr = atoi(argv[0]);
return CMD_SUCCESS; return CMD_SUCCESS;
} }

View File

@@ -436,7 +436,7 @@ static struct gsm_lchan* lchan_find(struct gsm_bts *bts, struct gsm_subscriber *
struct gsm_subscriber_connection *connection_for_subscr(struct gsm_subscriber *subscr) struct gsm_subscriber_connection *connection_for_subscr(struct gsm_subscriber *subscr)
{ {
struct gsm_bts *bts; struct gsm_bts *bts;
struct gsm_network *net = subscr->net; struct gsm_network *net = subscr->group->net;
struct gsm_lchan *lchan; struct gsm_lchan *lchan;
llist_for_each_entry(bts, &net->bts_list, list) { llist_for_each_entry(bts, &net->bts_list, list) {

View File

@@ -19,6 +19,7 @@
#include <openbsc/gsm_data.h> #include <openbsc/gsm_data.h>
#include <openbsc/osmo_msc_data.h> #include <openbsc/osmo_msc_data.h>
#include <openbsc/gsm_subscriber.h>
struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code, struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code,
int (*mncc_recv)(struct gsm_network *, struct msgb *)) int (*mncc_recv)(struct gsm_network *, struct msgb *))
@@ -35,10 +36,17 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
return NULL; return NULL;
} }
net->subscr_group = talloc_zero(net, struct gsm_subscriber_group);
if (!net->subscr_group) {
talloc_free(net);
return NULL;
}
/* Init back pointer */ /* Init back pointer */
net->bsc_data->auto_off_timeout = -1; net->bsc_data->auto_off_timeout = -1;
net->bsc_data->network = net; net->bsc_data->network = net;
INIT_LLIST_HEAD(&net->bsc_data->mscs); INIT_LLIST_HEAD(&net->bsc_data->mscs);
net->subscr_group->net = net;
net->country_code = country_code; net->country_code = country_code;
net->network_code = network_code; net->network_code = network_code;

View File

@@ -389,7 +389,7 @@ void paging_request_stop(struct gsm_bts *_bts, struct gsm_subscriber *subscr,
* location area of the _bts as reconfiguration of the * location area of the _bts as reconfiguration of the
* network is probably happening less often. * network is probably happening less often.
*/ */
bts = gsm_bts_by_lac(subscr->net, subscr->lac, bts); bts = gsm_bts_by_lac(subscr->group->net, subscr->lac, bts);
if (!bts) if (!bts)
break; break;

View File

@@ -91,18 +91,18 @@ struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr)
subscr->use_count--; subscr->use_count--;
DEBUGP(DREF, "subscr %s usage decreased usage to: %d\n", DEBUGP(DREF, "subscr %s usage decreased usage to: %d\n",
subscr->extension, subscr->use_count); subscr->extension, subscr->use_count);
if (subscr->use_count <= 0 && !subscr->net->keep_subscr) if (subscr->use_count <= 0 && !subscr->group->keep_subscr)
subscr_free(subscr); subscr_free(subscr);
return NULL; return NULL;
} }
struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net, struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
const char *imsi) const char *imsi)
{ {
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) { llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
if (strcmp(subscr->imsi, imsi) == 0 && subscr->net == net) if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
return subscr_get(subscr); return subscr_get(subscr);
} }
@@ -112,41 +112,43 @@ struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net,
strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH); strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH);
subscr->imsi[GSM_IMSI_LENGTH - 1] = '\0'; subscr->imsi[GSM_IMSI_LENGTH - 1] = '\0';
subscr->net = net; subscr->group = sgrp;
return subscr; return subscr;
} }
struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_network *net, uint32_t tmsi) struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
uint32_t tmsi)
{ {
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) { llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
if (subscr->tmsi == tmsi && subscr->net == net) if (subscr->tmsi == tmsi && subscr->group == sgrp)
return subscr_get(subscr); return subscr_get(subscr);
} }
return NULL; return NULL;
} }
struct gsm_subscriber *subscr_active_by_imsi(struct gsm_network *net, const char *imsi) struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
const char *imsi)
{ {
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) { llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
if (strcmp(subscr->imsi, imsi) == 0 && subscr->net == net) if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
return subscr_get(subscr); return subscr_get(subscr);
} }
return NULL; return NULL;
} }
int subscr_purge_inactive(struct gsm_network *net) int subscr_purge_inactive(struct gsm_subscriber_group *sgrp)
{ {
struct gsm_subscriber *subscr, *tmp; struct gsm_subscriber *subscr, *tmp;
int purged = 0; int purged = 0;
llist_for_each_entry_safe(subscr, tmp, subscr_bsc_active_subscribers(), entry) { llist_for_each_entry_safe(subscr, tmp, subscr_bsc_active_subscribers(), entry) {
if (subscr->net == net && subscr->use_count <= 0) { if (subscr->group == sgrp && subscr->use_count <= 0) {
subscr_free(subscr); subscr_free(subscr);
purged += 1; purged += 1;
} }

View File

@@ -67,9 +67,9 @@ static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
imsi = strtok_r(tmp, ",", &saveptr); imsi = strtok_r(tmp, ",", &saveptr);
msisdn = strtok_r(NULL, ",", &saveptr); msisdn = strtok_r(NULL, ",", &saveptr);
subscr = subscr_get_by_imsi(net, imsi); subscr = subscr_get_by_imsi(net->subscr_group, imsi);
if (!subscr) if (!subscr)
subscr = subscr_create_subscriber(net, imsi); subscr = subscr_create_subscriber(net->subscr_group, imsi);
if (!subscr) if (!subscr)
goto fail; goto fail;
@@ -118,7 +118,7 @@ static int set_subscriber_delete(struct ctrl_cmd *cmd, void *data)
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
struct gsm_network *net = cmd->node; struct gsm_network *net = cmd->node;
subscr = subscr_get_by_imsi(net, cmd->value); subscr = subscr_get_by_imsi(net->subscr_group, cmd->value);
if (!subscr) { if (!subscr) {
cmd->reply = "Failed to find subscriber"; cmd->reply = "Failed to find subscriber";
return CTRL_CMD_ERROR; return CTRL_CMD_ERROR;

View File

@@ -1470,7 +1470,7 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul
strncpy(sms->dst.addr, daddr, sizeof(sms->dst.addr)); strncpy(sms->dst.addr, daddr, sizeof(sms->dst.addr));
sms->dst.addr[sizeof(sms->dst.addr)-1] = '\0'; sms->dst.addr[sizeof(sms->dst.addr)-1] = '\0';
} }
sms->receiver = subscr_get_by_extension(net, sms->dst.addr); sms->receiver = subscr_get_by_extension(net->subscr_group, sms->dst.addr);
sms->src.npi = dbi_result_get_ulonglong(result, "src_npi"); sms->src.npi = dbi_result_get_ulonglong(result, "src_npi");
sms->src.ton = dbi_result_get_ulonglong(result, "src_ton"); sms->src.ton = dbi_result_get_ulonglong(result, "src_ton");
@@ -1597,7 +1597,7 @@ struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr)
return NULL; return NULL;
} }
sms = sms_from_result(subscr->net, result); sms = sms_from_result(subscr->group->net, result);
dbi_result_free(result); dbi_result_free(result);

View File

@@ -255,7 +255,7 @@ static int authorize_subscriber(struct gsm_loc_updating_operation *loc,
if (loc && (loc->waiting_for_imsi || loc->waiting_for_imei)) if (loc && (loc->waiting_for_imsi || loc->waiting_for_imei))
return 0; return 0;
switch (subscriber->net->auth_policy) { switch (subscriber->group->net->auth_policy) {
case GSM_AUTH_POLICY_CLOSED: case GSM_AUTH_POLICY_CLOSED:
return subscriber->authorized; return subscriber->authorized;
case GSM_AUTH_POLICY_TOKEN: case GSM_AUTH_POLICY_TOKEN:
@@ -498,9 +498,11 @@ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *ms
case GSM_MI_TYPE_IMSI: case GSM_MI_TYPE_IMSI:
/* look up subscriber based on IMSI, create if not found */ /* look up subscriber based on IMSI, create if not found */
if (!conn->subscr) { if (!conn->subscr) {
conn->subscr = subscr_get_by_imsi(net, mi_string); conn->subscr = subscr_get_by_imsi(net->subscr_group,
mi_string);
if (!conn->subscr) if (!conn->subscr)
conn->subscr = subscr_create_subscriber(net, mi_string); conn->subscr = subscr_create_subscriber(
net->subscr_group, mi_string);
} }
if (conn->loc_operation) if (conn->loc_operation)
conn->loc_operation->waiting_for_imsi = 0; conn->loc_operation->waiting_for_imsi = 0;
@@ -610,15 +612,16 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
conn->loc_operation->waiting_for_imei = 1; conn->loc_operation->waiting_for_imei = 1;
/* look up subscriber based on IMSI, create if not found */ /* look up subscriber based on IMSI, create if not found */
subscr = subscr_get_by_imsi(bts->network, mi_string); subscr = subscr_get_by_imsi(bts->network->subscr_group, mi_string);
if (!subscr) { if (!subscr) {
subscr = subscr_create_subscriber(bts->network, mi_string); subscr = subscr_create_subscriber(
bts->network->subscr_group, mi_string);
} }
break; break;
case GSM_MI_TYPE_TMSI: case GSM_MI_TYPE_TMSI:
DEBUGPC(DMM, "\n"); DEBUGPC(DMM, "\n");
/* look up the subscriber based on TMSI, request IMSI if it fails */ /* look up the subscriber based on TMSI, request IMSI if it fails */
subscr = subscr_get_by_tmsi(bts->network, subscr = subscr_get_by_tmsi(bts->network->subscr_group,
tmsi_from_string(mi_string)); tmsi_from_string(mi_string));
if (!subscr) { if (!subscr) {
/* send IDENTITY REQUEST message to get IMSI */ /* send IDENTITY REQUEST message to get IMSI */
@@ -948,7 +951,7 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
if (is_siemens_bts(bts)) if (is_siemens_bts(bts))
send_siemens_mrpci(msg->lchan, classmark2-1); send_siemens_mrpci(msg->lchan, classmark2-1);
subscr = subscr_get_by_tmsi(bts->network, subscr = subscr_get_by_tmsi(bts->network->subscr_group,
tmsi_from_string(mi_string)); tmsi_from_string(mi_string));
/* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */ /* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
@@ -995,12 +998,13 @@ static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, s
switch (mi_type) { switch (mi_type) {
case GSM_MI_TYPE_TMSI: case GSM_MI_TYPE_TMSI:
DEBUGPC(DMM, "\n"); DEBUGPC(DMM, "\n");
subscr = subscr_get_by_tmsi(bts->network, subscr = subscr_get_by_tmsi(bts->network->subscr_group,
tmsi_from_string(mi_string)); tmsi_from_string(mi_string));
break; break;
case GSM_MI_TYPE_IMSI: case GSM_MI_TYPE_IMSI:
DEBUGPC(DMM, "\n"); DEBUGPC(DMM, "\n");
subscr = subscr_get_by_imsi(bts->network, mi_string); subscr = subscr_get_by_imsi(bts->network->subscr_group,
mi_string);
break; break;
case GSM_MI_TYPE_IMEI: case GSM_MI_TYPE_IMEI:
case GSM_MI_TYPE_IMEISV: case GSM_MI_TYPE_IMEISV:
@@ -1145,11 +1149,12 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m
switch (mi_type) { switch (mi_type) {
case GSM_MI_TYPE_TMSI: case GSM_MI_TYPE_TMSI:
subscr = subscr_get_by_tmsi(bts->network, subscr = subscr_get_by_tmsi(bts->network->subscr_group,
tmsi_from_string(mi_string)); tmsi_from_string(mi_string));
break; break;
case GSM_MI_TYPE_IMSI: case GSM_MI_TYPE_IMSI:
subscr = subscr_get_by_imsi(bts->network, mi_string); subscr = subscr_get_by_imsi(bts->network->subscr_group,
mi_string);
break; break;
} }
@@ -3040,10 +3045,11 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
} }
/* New transaction due to setup, find subscriber */ /* New transaction due to setup, find subscriber */
if (data->called.number[0]) if (data->called.number[0])
subscr = subscr_get_by_extension(net, subscr = subscr_get_by_extension(net->subscr_group,
data->called.number); data->called.number);
else else
subscr = subscr_get_by_imsi(net, data->imsi); subscr = subscr_get_by_imsi(net->subscr_group,
data->imsi);
/* update the subscriber we deal with */ /* update the subscriber we deal with */
log_set_context(BSC_CTX_SUBSCR, subscr); log_set_context(BSC_CTX_SUBSCR, subscr);
@@ -3107,7 +3113,8 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc)); memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc));
/* Get a channel */ /* Get a channel */
trans->paging_request = talloc_zero(subscr->net, struct gsm_network*); trans->paging_request = talloc_zero(subscr->group->net,
struct gsm_network*);
if (!trans->paging_request) { if (!trans->paging_request) {
LOGP(DCC, LOGL_ERROR, "Failed to allocate paging token.\n"); LOGP(DCC, LOGL_ERROR, "Failed to allocate paging token.\n");
subscr_put(subscr); subscr_put(subscr);
@@ -3115,7 +3122,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
return 0; return 0;
} }
*trans->paging_request = subscr->net; *trans->paging_request = subscr->group->net;
subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, setup_trig_pag_evt, trans->paging_request); subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, setup_trig_pag_evt, trans->paging_request);
subscr_put(subscr); subscr_put(subscr);

View File

@@ -392,7 +392,8 @@ static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *m
send_signal(0, NULL, gsms, 0); send_signal(0, NULL, gsms, 0);
/* determine gsms->receiver based on dialled number */ /* determine gsms->receiver based on dialled number */
gsms->receiver = subscr_get_by_extension(conn->bts->network, gsms->dst.addr); gsms->receiver = subscr_get_by_extension(conn->bts->network->subscr_group,
gsms->dst.addr);
if (!gsms->receiver) { if (!gsms->receiver) {
#ifdef BUILD_SMPP #ifdef BUILD_SMPP
rc = smpp_try_deliver(gsms, conn); rc = smpp_try_deliver(gsms, conn);

View File

@@ -78,12 +78,12 @@ enum {
REQ_STATE_DISPATCHED, REQ_STATE_DISPATCHED,
}; };
static struct gsm_subscriber *get_subscriber(struct gsm_network *net, static struct gsm_subscriber *get_subscriber(struct gsm_subscriber_group *sgrp,
int type, const char *ident) int type, const char *ident)
{ {
struct gsm_subscriber *subscr = db_get_subscriber(type, ident); struct gsm_subscriber *subscr = db_get_subscriber(type, ident);
if (subscr) if (subscr)
subscr->net = net; subscr->group = sgrp;
return subscr; return subscr;
} }
@@ -199,12 +199,13 @@ static void subscr_send_paging_request(struct gsm_subscriber *subscr)
{ {
struct subscr_request *request; struct subscr_request *request;
int rc; int rc;
struct gsm_network *net = subscr->group->net;
assert(!llist_empty(&subscr->requests)); assert(!llist_empty(&subscr->requests));
request = (struct subscr_request *)subscr->requests.next; request = (struct subscr_request *)subscr->requests.next;
request->state = REQ_STATE_PAGED; request->state = REQ_STATE_PAGED;
rc = paging_request(subscr->net, subscr, request->channel_type, rc = paging_request(net, subscr, request->channel_type,
subscr_paging_cb, subscr); subscr_paging_cb, subscr);
/* paging failed, quit now */ /* paging failed, quit now */
@@ -275,16 +276,16 @@ void subscr_put_channel(struct gsm_subscriber *subscr)
subscr_send_paging_request(subscr); subscr_send_paging_request(subscr);
} }
struct gsm_subscriber *subscr_create_subscriber(struct gsm_network *net, struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
const char *imsi) const char *imsi)
{ {
struct gsm_subscriber *subscr = db_create_subscriber(imsi); struct gsm_subscriber *subscr = db_create_subscriber(imsi);
if (subscr) if (subscr)
subscr->net = net; subscr->group = sgrp;
return subscr; return subscr;
} }
struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net, struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_subscriber_group *sgrp,
uint32_t tmsi) uint32_t tmsi)
{ {
char tmsi_string[14]; char tmsi_string[14];
@@ -297,10 +298,10 @@ struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net,
} }
sprintf(tmsi_string, "%u", tmsi); sprintf(tmsi_string, "%u", tmsi);
return get_subscriber(net, GSM_SUBSCRIBER_TMSI, tmsi_string); return get_subscriber(sgrp, GSM_SUBSCRIBER_TMSI, tmsi_string);
} }
struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net, struct gsm_subscriber *subscr_get_by_imsi(struct gsm_subscriber_group *sgrp,
const char *imsi) const char *imsi)
{ {
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
@@ -310,10 +311,10 @@ struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net,
return subscr_get(subscr); return subscr_get(subscr);
} }
return get_subscriber(net, GSM_SUBSCRIBER_IMSI, imsi); return get_subscriber(sgrp, GSM_SUBSCRIBER_IMSI, imsi);
} }
struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net, struct gsm_subscriber *subscr_get_by_extension(struct gsm_subscriber_group *sgrp,
const char *ext) const char *ext)
{ {
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
@@ -323,10 +324,10 @@ struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net,
return subscr_get(subscr); return subscr_get(subscr);
} }
return get_subscriber(net, GSM_SUBSCRIBER_EXTENSION, ext); return get_subscriber(sgrp, GSM_SUBSCRIBER_EXTENSION, ext);
} }
struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net, struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp,
unsigned long long id) unsigned long long id)
{ {
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
@@ -338,7 +339,7 @@ struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net,
return subscr_get(subscr); return subscr_get(subscr);
} }
return get_subscriber(net, GSM_SUBSCRIBER_ID, buf); return get_subscriber(sgrp, GSM_SUBSCRIBER_ID, buf);
} }
int subscr_update_expire_lu(struct gsm_subscriber *s, struct gsm_bts *bts) int subscr_update_expire_lu(struct gsm_subscriber *s, struct gsm_bts *bts)
@@ -370,7 +371,7 @@ int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason)
/* FIXME: Migrate pending requests from one BSC to another */ /* FIXME: Migrate pending requests from one BSC to another */
switch (reason) { switch (reason) {
case GSM_SUBSCRIBER_UPDATE_ATTACHED: case GSM_SUBSCRIBER_UPDATE_ATTACHED:
s->net = bts->network; s->group = bts->network->subscr_group;
/* Indicate "attached to LAC" */ /* Indicate "attached to LAC" */
s->lac = bts->location_area_code; s->lac = bts->location_area_code;
@@ -412,7 +413,7 @@ void subscr_update_from_db(struct gsm_subscriber *sub)
static void subscr_expire_callback(void *data, long long unsigned int id) static void subscr_expire_callback(void *data, long long unsigned int id)
{ {
struct gsm_network *net = data; struct gsm_network *net = data;
struct gsm_subscriber *s = subscr_get_by_id(net, id); struct gsm_subscriber *s = subscr_get_by_id(net->subscr_group, id);
struct gsm_subscriber_connection *conn = connection_for_subscr(s); struct gsm_subscriber_connection *conn = connection_for_subscr(s);
/* /*
@@ -438,9 +439,9 @@ static void subscr_expire_callback(void *data, long long unsigned int id)
subscr_put(s); subscr_put(s);
} }
void subscr_expire(struct gsm_network *net) void subscr_expire(struct gsm_subscriber_group *sgrp)
{ {
db_subscriber_expire(net, subscr_expire_callback); db_subscriber_expire(sgrp->net, subscr_expire_callback);
} }
int subscr_pending_requests(struct gsm_subscriber *sub) int subscr_pending_requests(struct gsm_subscriber *sub)

View File

@@ -120,7 +120,7 @@ int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data, int type)
{ {
int rc; int rc;
rc = paging_request(subscr->net, subscr, type, rc = paging_request(subscr->group->net, subscr, type,
paging_cb_silent, data); paging_cb_silent, data);
return rc; return rc;
} }

View File

@@ -55,11 +55,11 @@ static struct gsm_subscriber *subscr_by_dst(struct gsm_network *net,
switch (npi) { switch (npi) {
case NPI_Land_Mobile_E212: case NPI_Land_Mobile_E212:
subscr = subscr_get_by_imsi(net, addr); subscr = subscr_get_by_imsi(net->subscr_group, addr);
break; break;
case NPI_ISDN_E163_E164: case NPI_ISDN_E163_E164:
case NPI_Private: case NPI_Private:
subscr = subscr_get_by_extension(net, addr); subscr = subscr_get_by_extension(net->subscr_group, addr);
break; break;
default: default:
LOGP(DSMPP, LOGL_NOTICE, "Unsupported NPI: %u\n", npi); LOGP(DSMPP, LOGL_NOTICE, "Unsupported NPI: %u\n", npi);

View File

@@ -135,7 +135,7 @@ static void sms_pending_resend(struct gsm_sms_pending *pending)
pending->resend = 1; pending->resend = 1;
smsq = pending->subscr->net->sms_queue; smsq = pending->subscr->group->net->sms_queue;
if (osmo_timer_pending(&smsq->resend_pending)) if (osmo_timer_pending(&smsq->resend_pending))
return; return;
@@ -149,7 +149,7 @@ static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error
LOGP(DLSMS, LOGL_NOTICE, "Sending SMS %llu failed %d times.\n", LOGP(DLSMS, LOGL_NOTICE, "Sending SMS %llu failed %d times.\n",
pending->sms_id, pending->failed_attempts); pending->sms_id, pending->failed_attempts);
smsq = pending->subscr->net->sms_queue; smsq = pending->subscr->group->net->sms_queue;
if (++pending->failed_attempts < smsq->max_fail) if (++pending->failed_attempts < smsq->max_fail)
return sms_pending_resend(pending); return sms_pending_resend(pending);
@@ -285,7 +285,7 @@ static void sms_submit_pending(void *_data)
*/ */
static void sms_send_next(struct gsm_subscriber *subscr) static void sms_send_next(struct gsm_subscriber *subscr)
{ {
struct gsm_sms_queue *smsq = subscr->net->sms_queue; struct gsm_sms_queue *smsq = subscr->group->net->sms_queue;
struct gsm_sms_pending *pending; struct gsm_sms_pending *pending;
struct gsm_sms *sms; struct gsm_sms *sms;
@@ -316,7 +316,7 @@ static void sms_send_next(struct gsm_subscriber *subscr)
no_pending_sms: no_pending_sms:
/* Try to send the SMS to avoid the queue being stuck */ /* Try to send the SMS to avoid the queue being stuck */
sms_submit_pending(subscr->net->sms_queue); sms_submit_pending(subscr->group->net->sms_queue);
} }
/* /*

View File

@@ -59,7 +59,7 @@ static int token_subscr_cb(unsigned int subsys, unsigned int signal,
if (signal != S_SUBSCR_ATTACHED) if (signal != S_SUBSCR_ATTACHED)
return 0; return 0;
if (subscr->net->auth_policy != GSM_AUTH_POLICY_TOKEN) if (subscr->group->net->auth_policy != GSM_AUTH_POLICY_TOKEN)
return 0; return 0;
if (subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT) { if (subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT) {
@@ -82,7 +82,7 @@ static int token_subscr_cb(unsigned int subsys, unsigned int signal,
/* FIXME: don't use ID 1 static */ /* FIXME: don't use ID 1 static */
sender = subscr_get_by_id(subscr->net, 1); sender = subscr_get_by_id(subscr->group, 1);
sms = sms_from_text(subscr, sender, 0, sms_str); sms = sms_from_text(subscr, sender, 0, sms_str);
@@ -136,7 +136,7 @@ static int token_sms_cb(unsigned int subsys, unsigned int signal,
return 0; return 0;
if (sms->receiver->net->auth_policy != GSM_AUTH_POLICY_TOKEN) if (sms->receiver->group->net->auth_policy != GSM_AUTH_POLICY_TOKEN)
return 0; return 0;

View File

@@ -66,7 +66,7 @@ struct gsm_trans *trans_alloc(struct gsm_subscriber *subscr,
uint32_t callref) uint32_t callref)
{ {
struct gsm_trans *trans; struct gsm_trans *trans;
struct gsm_network *net = subscr->net; struct gsm_network *net = subscr->group->net;
DEBUGP(DCC, "subscr=%p, net=%p\n", subscr, net); DEBUGP(DCC, "subscr=%p, net=%p\n", subscr, net);

View File

@@ -169,7 +169,7 @@ static int _send_sms_str(struct gsm_subscriber *receiver,
} }
sms_free(sms); sms_free(sms);
sms_queue_trigger(receiver->net->sms_queue); sms_queue_trigger(receiver->group->net->sms_queue);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@@ -178,13 +178,13 @@ static struct gsm_subscriber *get_subscr_by_argv(struct gsm_network *gsmnet,
const char *id) const char *id)
{ {
if (!strcmp(type, "extension")) if (!strcmp(type, "extension"))
return subscr_get_by_extension(gsmnet, id); return subscr_get_by_extension(gsmnet->subscr_group, id);
else if (!strcmp(type, "imsi")) else if (!strcmp(type, "imsi"))
return subscr_get_by_imsi(gsmnet, id); return subscr_get_by_imsi(gsmnet->subscr_group, id);
else if (!strcmp(type, "tmsi")) else if (!strcmp(type, "tmsi"))
return subscr_get_by_tmsi(gsmnet, atoi(id)); return subscr_get_by_tmsi(gsmnet->subscr_group, atoi(id));
else if (!strcmp(type, "id")) else if (!strcmp(type, "id"))
return subscr_get_by_id(gsmnet, atoi(id)); return subscr_get_by_id(gsmnet->subscr_group, atoi(id));
return NULL; return NULL;
} }
@@ -229,7 +229,7 @@ DEFUN(subscriber_create,
struct gsm_network *gsmnet = gsmnet_from_vty(vty); struct gsm_network *gsmnet = gsmnet_from_vty(vty);
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
subscr = subscr_create_subscriber(gsmnet, argv[0]); subscr = subscr_create_subscriber(gsmnet->subscr_group, argv[0]);
if (!subscr) { if (!subscr) {
vty_out(vty, "%% No subscriber created for IMSI %s%s", vty_out(vty, "%% No subscriber created for IMSI %s%s",
argv[0], VTY_NEWLINE); argv[0], VTY_NEWLINE);
@@ -779,7 +779,7 @@ DEFUN(subscriber_purge,
struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_network *net = gsmnet_from_vty(vty);
int purged; int purged;
purged = subscr_purge_inactive(net); purged = subscr_purge_inactive(net->subscr_group);
vty_out(vty, "%d subscriber(s) were purged.%s", purged, VTY_NEWLINE); vty_out(vty, "%d subscriber(s) were purged.%s", purged, VTY_NEWLINE);
return CMD_SUCCESS; return CMD_SUCCESS;
} }

View File

@@ -167,7 +167,7 @@ static int bssmap_handle_paging(struct osmo_msc_data *msc,
LOGP(DMSC, LOGL_ERROR, "eMLPP is not handled\n"); LOGP(DMSC, LOGL_ERROR, "eMLPP is not handled\n");
} }
subscr = subscr_get_or_create(msc->network, mi_string); subscr = subscr_get_or_create(msc->network->subscr_group, mi_string);
if (!subscr) { if (!subscr) {
LOGP(DMSC, LOGL_ERROR, "Failed to allocate a subscriber for %s\n", mi_string); LOGP(DMSC, LOGL_ERROR, "Failed to allocate a subscriber for %s\n", mi_string);
return -1; return -1;

View File

@@ -78,11 +78,12 @@ static struct gsm_subscriber *extract_sub(struct gsm_subscriber_connection *conn
switch (mi_type) { switch (mi_type) {
case GSM_MI_TYPE_TMSI: case GSM_MI_TYPE_TMSI:
subscr = subscr_active_by_tmsi(conn->bts->network, subscr = subscr_active_by_tmsi(conn->bts->network->subscr_group,
tmsi_from_string(mi_string)); tmsi_from_string(mi_string));
break; break;
case GSM_MI_TYPE_IMSI: case GSM_MI_TYPE_IMSI:
subscr = subscr_active_by_imsi(conn->bts->network, mi_string); subscr = subscr_active_by_imsi(conn->bts->network->subscr_group,
mi_string);
break; break;
default: default:
subscr = NULL; subscr = NULL;

View File

@@ -41,7 +41,7 @@ int bsc_grace_paging_request(struct gsm_subscriber *subscr, int chan_needed,
{ {
struct gsm_bts *bts = NULL; struct gsm_bts *bts = NULL;
if (subscr->net->bsc_data->rf_ctrl->policy == S_RF_ON) if (subscr->group->net->bsc_data->rf_ctrl->policy == S_RF_ON)
goto page; goto page;
/* /*
@@ -49,7 +49,7 @@ int bsc_grace_paging_request(struct gsm_subscriber *subscr, int chan_needed,
* with NULL and iterate through all bts. * with NULL and iterate through all bts.
*/ */
do { do {
bts = gsm_bts_by_lac(subscr->net, subscr->lac, bts); bts = gsm_bts_by_lac(subscr->group->net, subscr->lac, bts);
if (!bts) if (!bts)
break; break;
@@ -68,7 +68,8 @@ int bsc_grace_paging_request(struct gsm_subscriber *subscr, int chan_needed,
/* All bts are either off or in the grace period */ /* All bts are either off or in the grace period */
return 0; return 0;
page: page:
return paging_request(subscr->net, subscr, chan_needed, NULL, msc); return paging_request(subscr->group->net, subscr, chan_needed, NULL,
msc);
} }
static int handle_sub(struct gsm_lchan *lchan, const char *text) static int handle_sub(struct gsm_lchan *lchan, const char *text)

View File

@@ -228,7 +228,7 @@ static void db_sync_timer_cb(void *data)
static void subscr_expire_cb(void *data) static void subscr_expire_cb(void *data)
{ {
subscr_expire(bsc_gsmnet); subscr_expire(bsc_gsmnet->subscr_group);
osmo_timer_schedule(&bsc_gsmnet->subscr_expire_timer, EXPIRE_INTERVAL); osmo_timer_schedule(&bsc_gsmnet->subscr_expire_timer, EXPIRE_INTERVAL);
} }

View File

@@ -74,7 +74,10 @@ int main(int argc, char **argv)
/* Create a dummy subscriber */ /* Create a dummy subscriber */
struct gsm_subscriber *subscr = subscr_alloc(); struct gsm_subscriber *subscr = subscr_alloc();
subscr->lac = 23; subscr->lac = 23;
subscr->net = network; subscr->group = network->subscr_group;
OSMO_ASSERT(subscr->group);
OSMO_ASSERT(subscr->group->net == network);
/* Ask for a channel... */ /* Ask for a channel... */
subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, subscr_cb, (void*)0x2342L); subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, subscr_cb, (void*)0x2342L);

View File

@@ -31,9 +31,10 @@
#include <inttypes.h> #include <inttypes.h>
static struct gsm_network dummy_net; static struct gsm_network dummy_net;
static struct gsm_subscriber_group dummy_sgrp;
#define SUBSCR_PUT(sub) \ #define SUBSCR_PUT(sub) \
sub->net = &dummy_net; \ sub->group = &dummy_sgrp; \
subscr_put(sub); subscr_put(sub);
#define COMPARE(original, copy) \ #define COMPARE(original, copy) \
@@ -70,7 +71,7 @@ static void test_sms(void)
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "9993245423445"); subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "9993245423445");
OSMO_ASSERT(subscr); OSMO_ASSERT(subscr);
subscr->net = &dummy_net; subscr->group = &dummy_sgrp;
sms = sms_alloc(); sms = sms_alloc();
sms->receiver = subscr_get(subscr); sms->receiver = subscr_get(subscr);
@@ -130,7 +131,7 @@ static void test_sms_migrate(void)
0xd0, 0xf1, 0xfd, 0x06, 0x00 }; 0xd0, 0xf1, 0xfd, 0x06, 0x00 };
rcv_subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "901010000001111"); rcv_subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "901010000001111");
rcv_subscr->net = &dummy_net; rcv_subscr->group = &dummy_sgrp;
sms = db_sms_get(&dummy_net, 1); sms = db_sms_get(&dummy_net, 1);
OSMO_ASSERT(sms->id == 1); OSMO_ASSERT(sms->id == 1);
@@ -159,6 +160,9 @@ int main()
osmo_init_logging(&log_info); osmo_init_logging(&log_info);
log_set_print_filename(osmo_stderr_target, 0); log_set_print_filename(osmo_stderr_target, 0);
dummy_net.subscr_group = &dummy_sgrp;
dummy_sgrp.net = &dummy_net;
if (db_init("hlr.sqlite3")) { if (db_init("hlr.sqlite3")) {
printf("DB: Failed to init database. Please check the option settings.\n"); printf("DB: Failed to init database. Please check the option settings.\n");
return 1; return 1;