vlr_subscr: use osmo_use_count
Depends: Ife31e6798b4e728a23913179e346552a7dd338c0 (libosmocore) Change-Id: Ib06d030e8464abe415ff597d462ed40eeddef475changes/36/13136/5
parent
d553c085e7
commit
7c5346cd70
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "gsm_subscriber.h"
|
||||
|
||||
#define VSUB_USE_SMS_RECEIVER "SMS-receiver"
|
||||
|
||||
struct gsm_network;
|
||||
struct gsm_sms;
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define LOG_RAN_CONN_CAT(conn, subsys, level, fmt, args ...) \
|
||||
LOGPFSMSL((conn)? (conn)->fi : NULL, subsys, level, fmt, ## args)
|
||||
|
||||
#define VSUB_USE_CONN "conn"
|
||||
|
||||
enum ran_conn_fsm_event {
|
||||
/* Accepted the initial Complete Layer 3 (starting to evaluate Authentication and Ciphering) */
|
||||
RAN_CONN_E_COMPLETE_LAYER_3,
|
||||
|
|
|
@ -5,6 +5,8 @@ struct gsm_network;
|
|||
struct gsm_sms_queue;
|
||||
struct vty;
|
||||
|
||||
#define VSUB_USE_SMS_PENDING "SMS-pending"
|
||||
|
||||
int sms_queue_start(struct gsm_network *, int in_flight);
|
||||
int sms_queue_trigger(struct gsm_sms_queue *);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/fsm.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/use_count.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
#include <osmocom/gsm/gsm23003.h>
|
||||
|
@ -26,6 +27,8 @@ struct log_target;
|
|||
#define VLR_SUBSCRIBER_NO_EXPIRATION 0
|
||||
#define VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL 60 /* in seconds */
|
||||
|
||||
#define VSUB_USE_ATTACHED "attached"
|
||||
|
||||
/* from 3s to 10s */
|
||||
#define GSM_29002_TIMER_S 10
|
||||
/* from 15s to 30s */
|
||||
|
@ -158,7 +161,8 @@ struct vlr_subscr {
|
|||
bool ms_not_reachable_flag; /* 2.10.2 (MNRF) */
|
||||
bool la_allowed;
|
||||
|
||||
int use_count;
|
||||
struct osmo_use_count use_count;
|
||||
struct osmo_use_count_entry use_count_buf[10];
|
||||
|
||||
struct osmo_fsm_inst *lu_fsm;
|
||||
struct osmo_fsm_inst *auth_fsm;
|
||||
|
@ -349,49 +353,56 @@ lu_compl_vlr_proc_start(struct osmo_fsm_inst *parent,
|
|||
const char *vlr_subscr_name(const struct vlr_subscr *vsub);
|
||||
const char *vlr_subscr_msisdn_or_name(const struct vlr_subscr *vsub);
|
||||
|
||||
#define vlr_subscr_find_by_imsi(vlr, imsi) \
|
||||
_vlr_subscr_find_by_imsi(vlr, imsi, __FILE__, __LINE__)
|
||||
#define vlr_subscr_find_or_create_by_imsi(vlr, imsi, created) \
|
||||
_vlr_subscr_find_or_create_by_imsi(vlr, imsi, created, \
|
||||
#define vlr_subscr_find_by_imsi(vlr, imsi, USE) \
|
||||
_vlr_subscr_find_by_imsi(vlr, imsi, USE, __FILE__, __LINE__)
|
||||
#define vlr_subscr_find_or_create_by_imsi(vlr, imsi, USE, created) \
|
||||
_vlr_subscr_find_or_create_by_imsi(vlr, imsi, USE, created, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
#define vlr_subscr_find_by_tmsi(vlr, tmsi) \
|
||||
_vlr_subscr_find_by_tmsi(vlr, tmsi, __FILE__, __LINE__)
|
||||
#define vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created) \
|
||||
_vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created, \
|
||||
#define vlr_subscr_find_by_tmsi(vlr, tmsi, USE) \
|
||||
_vlr_subscr_find_by_tmsi(vlr, tmsi, USE, __FILE__, __LINE__)
|
||||
#define vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, USE, created) \
|
||||
_vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, USE, created, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
#define vlr_subscr_find_by_msisdn(vlr, msisdn) \
|
||||
_vlr_subscr_find_by_msisdn(vlr, msisdn, __FILE__, __LINE__)
|
||||
#define vlr_subscr_find_by_msisdn(vlr, msisdn, USE) \
|
||||
_vlr_subscr_find_by_msisdn(vlr, msisdn, USE, __FILE__, __LINE__)
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
|
||||
const char *imsi,
|
||||
const char *use,
|
||||
const char *file, int line);
|
||||
struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
|
||||
const char *imsi,
|
||||
const char *use,
|
||||
bool *created,
|
||||
const char *file,
|
||||
int line);
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr,
|
||||
uint32_t tmsi,
|
||||
const char *use,
|
||||
const char *file, int line);
|
||||
struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr,
|
||||
uint32_t tmsi,
|
||||
const char *use,
|
||||
bool *created,
|
||||
const char *file,
|
||||
int line);
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
|
||||
const char *msisdn,
|
||||
const char *use,
|
||||
const char *file, int line);
|
||||
|
||||
#define vlr_subscr_get(sub) _vlr_subscr_get(sub, __FILE__, __LINE__)
|
||||
#define vlr_subscr_put(sub) _vlr_subscr_put(sub, __FILE__, __LINE__)
|
||||
struct vlr_subscr *_vlr_subscr_get(struct vlr_subscr *sub, const char *file, int line);
|
||||
struct vlr_subscr *_vlr_subscr_put(struct vlr_subscr *sub, const char *file, int line);
|
||||
#define vlr_subscr_get(VSUB, USE) vlr_subscr_get_src(VSUB, USE, __FILE__, __LINE__)
|
||||
#define vlr_subscr_put(VSUB, USE) vlr_subscr_put_src(VSUB, USE, __FILE__, __LINE__)
|
||||
|
||||
#define vlr_subscr_get_src(VSUB, USE, SRCFILE, SRCLINE) \
|
||||
OSMO_ASSERT(_osmo_use_count_get_put(&(VSUB)->use_count, USE, 1, SRCFILE, SRCLINE) == 0)
|
||||
#define vlr_subscr_put_src(VSUB, USE, SRCFILE, SRCLINE) \
|
||||
OSMO_ASSERT(_osmo_use_count_get_put(&(VSUB)->use_count, USE, -1, SRCFILE, SRCLINE) == 0)
|
||||
|
||||
struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr);
|
||||
void vlr_subscr_free(struct vlr_subscr *vsub);
|
||||
int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub);
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ enum vlr_lu_type;
|
|||
struct vlr_subscr;
|
||||
struct vlr_instance;
|
||||
|
||||
#define VSUB_USE_SGS "SGs"
|
||||
#define VSUB_USE_SGS_PAGING "SGs-paging"
|
||||
|
||||
/* See also 3GPP TS 29.118, chapter 4.2.2 States at the VLR */
|
||||
enum sgs_ue_fsm_state {
|
||||
SGS_UE_ST_NULL,
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define VSUB_USE_CTRL "CTRL"
|
||||
|
||||
static struct gsm_network *msc_ctrl_net = NULL;
|
||||
|
||||
static int get_subscriber_list(struct ctrl_cmd *cmd, void *d)
|
||||
|
@ -73,7 +75,7 @@ static int set_sub_expire(struct ctrl_cmd *cmd, void *data)
|
|||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
vsub = vlr_subscr_find_by_imsi(msc_ctrl_net->vlr, cmd->value);
|
||||
vsub = vlr_subscr_find_by_imsi(msc_ctrl_net->vlr, cmd->value, VSUB_USE_CTRL);
|
||||
if (!vsub) {
|
||||
LOGP(DCTRL, LOGL_ERROR, "Attempt to expire unknown subscriber IMSI=%s\n", cmd->value);
|
||||
cmd->reply = "IMSI unknown";
|
||||
|
@ -85,11 +87,11 @@ static int set_sub_expire(struct ctrl_cmd *cmd, void *data)
|
|||
if (vlr_subscr_expire(vsub))
|
||||
LOGP(DCTRL, LOGL_NOTICE, "VLR released subscriber %s\n", vlr_subscr_name(vsub));
|
||||
|
||||
if (vsub->use_count > 1)
|
||||
if (osmo_use_count_total(&vsub->use_count) > 1)
|
||||
LOGP(DCTRL, LOGL_NOTICE, "Subscriber %s is still in use, should be released soon\n",
|
||||
vlr_subscr_name(vsub));
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_CTRL);
|
||||
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
|
|
@ -769,7 +769,7 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul
|
|||
daddr = dbi_result_get_string(result, "dest_addr");
|
||||
if (daddr)
|
||||
OSMO_STRLCPY_ARRAY(sms->dst.addr, daddr);
|
||||
sms->receiver = vlr_subscr_find_by_msisdn(net->vlr, sms->dst.addr);
|
||||
sms->receiver = vlr_subscr_find_by_msisdn(net->vlr, sms->dst.addr, VSUB_USE_SMS_RECEIVER);
|
||||
|
||||
sms->src.npi = dbi_result_get_ulonglong(result, "src_npi");
|
||||
sms->src.ton = dbi_result_get_ulonglong(result, "src_ton");
|
||||
|
|
|
@ -878,10 +878,10 @@ static int gsm48_rx_mm_imsi_detach_ind(struct ran_conn *conn, struct msgb *msg)
|
|||
switch (mi_type) {
|
||||
case GSM_MI_TYPE_TMSI:
|
||||
vsub = vlr_subscr_find_by_tmsi(network->vlr,
|
||||
tmsi_from_string(mi_string));
|
||||
tmsi_from_string(mi_string), __func__);
|
||||
break;
|
||||
case GSM_MI_TYPE_IMSI:
|
||||
vsub = vlr_subscr_find_by_imsi(network->vlr, mi_string);
|
||||
vsub = vlr_subscr_find_by_imsi(network->vlr, mi_string, __func__);
|
||||
break;
|
||||
case GSM_MI_TYPE_IMEI:
|
||||
case GSM_MI_TYPE_IMEISV:
|
||||
|
@ -909,7 +909,7 @@ static int gsm48_rx_mm_imsi_detach_ind(struct ran_conn *conn, struct msgb *msg)
|
|||
|
||||
vlr_subscr_rx_imsi_detach(vsub);
|
||||
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_DETACHED, vsub);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
}
|
||||
|
||||
ran_conn_close(conn, 0);
|
||||
|
@ -1768,8 +1768,8 @@ void ran_conn_rx_sec_mode_compl(struct ran_conn *conn)
|
|||
/* VLR informs us that the subscriber data has somehow been modified */
|
||||
static void msc_vlr_subscr_update(struct vlr_subscr *subscr)
|
||||
{
|
||||
LOGVSUBP(LOGL_NOTICE, subscr, "VLR: update for IMSI=%s (MSISDN=%s, used=%d)\n",
|
||||
subscr->imsi, subscr->msisdn, subscr->use_count);
|
||||
LOGVSUBP(LOGL_NOTICE, subscr, "VLR: update for IMSI=%s (MSISDN=%s)\n",
|
||||
subscr->imsi, subscr->msisdn);
|
||||
ran_conn_update_id_for_vsub(subscr);
|
||||
}
|
||||
|
||||
|
@ -1806,7 +1806,8 @@ static int msc_vlr_subscr_assoc(void *msc_conn_ref,
|
|||
}
|
||||
}
|
||||
|
||||
conn->vsub = vlr_subscr_get(vsub);
|
||||
vlr_subscr_get(vsub, VSUB_USE_CONN);
|
||||
conn->vsub = vsub;
|
||||
OSMO_ASSERT(conn->vsub);
|
||||
conn->vsub->cs.attached_via_ran = conn->via_ran;
|
||||
|
||||
|
|
|
@ -1897,9 +1897,9 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
|
|||
/* New transaction due to setup, find subscriber */
|
||||
if (data->called.number[0])
|
||||
vsub = vlr_subscr_find_by_msisdn(net->vlr,
|
||||
data->called.number);
|
||||
data->called.number, __func__);
|
||||
else
|
||||
vsub = vlr_subscr_find_by_imsi(net->vlr, data->imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(net->vlr, data->imsi, __func__);
|
||||
|
||||
/* update the subscriber we deal with */
|
||||
log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
|
||||
|
@ -1921,7 +1921,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
|
|||
"Received '%s' from MNCC with "
|
||||
"detached subscriber %s\n", data->called.number,
|
||||
get_mncc_name(msg_type), vlr_subscr_name(vsub));
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
/* Temporarily out of order */
|
||||
return mncc_release_ind(net, NULL, data->callref,
|
||||
GSM48_CAUSE_LOC_PRN_S_LU,
|
||||
|
@ -1932,7 +1932,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
|
|||
TRANS_ID_UNASSIGNED, data->callref);
|
||||
if (!trans) {
|
||||
LOGP(DCC, LOGL_ERROR, "No memory for trans.\n");
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
/* Ressource unavailable */
|
||||
mncc_release_ind(net, NULL, data->callref,
|
||||
GSM48_CAUSE_LOC_PRN_S_LU,
|
||||
|
@ -1957,7 +1957,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
|
|||
"started for lac %d.\n",
|
||||
data->called.number,
|
||||
get_mncc_name(msg_type), vsub->cgi.lai.lac);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
trans_free(trans);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1973,18 +1973,18 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
|
|||
SGSAP_SERV_IND_CS_CALL);
|
||||
if (!trans->paging_request) {
|
||||
LOGP(DCC, LOGL_ERROR, "Failed to allocate paging token.\n");
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
trans_free(trans);
|
||||
return 0;
|
||||
}
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Assign conn */
|
||||
trans->conn = ran_conn_get(conn, RAN_CONN_USE_TRANS_CC);
|
||||
trans->dlci = 0x00; /* SAPI=0, not SACCH */
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
} else {
|
||||
/* update the subscriber we deal with */
|
||||
log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
|
||||
|
|
|
@ -71,7 +71,7 @@ void sms_free(struct gsm_sms *sms)
|
|||
{
|
||||
/* drop references to subscriber structure */
|
||||
if (sms->receiver)
|
||||
vlr_subscr_put(sms->receiver);
|
||||
vlr_subscr_put(sms->receiver, VSUB_USE_SMS_RECEIVER);
|
||||
#ifdef BUILD_SMPP
|
||||
if (sms->smpp.esme)
|
||||
smpp_esme_put(sms->smpp.esme);
|
||||
|
@ -89,7 +89,8 @@ struct gsm_sms *sms_from_text(struct vlr_subscr *receiver,
|
|||
if (!sms)
|
||||
return NULL;
|
||||
|
||||
sms->receiver = vlr_subscr_get(receiver);
|
||||
vlr_subscr_get(receiver, VSUB_USE_SMS_RECEIVER);
|
||||
sms->receiver = receiver;
|
||||
OSMO_STRLCPY_ARRAY(sms->text, text);
|
||||
|
||||
OSMO_STRLCPY_ARRAY(sms->src.addr, sender_msisdn);
|
||||
|
@ -441,8 +442,7 @@ try_local:
|
|||
#endif
|
||||
|
||||
/* determine gsms->receiver based on dialled number */
|
||||
gsms->receiver = vlr_subscr_find_by_msisdn(conn->network->vlr,
|
||||
gsms->dst.addr);
|
||||
gsms->receiver = vlr_subscr_find_by_msisdn(conn->network->vlr, gsms->dst.addr, VSUB_USE_SMS_RECEIVER);
|
||||
if (!gsms->receiver) {
|
||||
#ifdef BUILD_SMPP
|
||||
/* Avoid a second look-up */
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include <osmocom/msc/a_iface.h>
|
||||
#include <osmocom/msc/sgs_iface.h>
|
||||
|
||||
#define VSUB_USE_PAGING "Paging"
|
||||
|
||||
void subscr_paging_cancel(struct vlr_subscr *vsub, enum gsm_paging_event event)
|
||||
{
|
||||
subscr_paging_dispatch(GSM_HOOK_RR_PAGING, event, NULL, NULL, vsub);
|
||||
|
@ -106,7 +108,7 @@ int subscr_paging_dispatch(unsigned int hooknum, unsigned int event,
|
|||
|
||||
/* balanced with the moment we start paging */
|
||||
vsub->cs.is_paging = false;
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_PAGING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -168,7 +170,7 @@ struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub,
|
|||
return NULL;
|
||||
}
|
||||
/* reduced on the first paging callback */
|
||||
vlr_subscr_get(vsub);
|
||||
vlr_subscr_get(vsub, VSUB_USE_PAGING);
|
||||
vsub->cs.is_paging = true;
|
||||
osmo_timer_setup(&vsub->cs.paging_response_timer, paging_response_timer_cb, vsub);
|
||||
osmo_timer_schedule(&vsub->cs.paging_response_timer, net->paging_response_timer, 0);
|
||||
|
|
|
@ -68,6 +68,8 @@ struct cmd_node net_node = {
|
|||
1,
|
||||
};
|
||||
|
||||
#define VSUB_USE_VTY "VTY"
|
||||
|
||||
#define NETWORK_STR "Configure the GSM network\n"
|
||||
#define CODE_CMD_STR "Code commands\n"
|
||||
#define NAME_CMD_STR "Name Commands\n"
|
||||
|
@ -671,6 +673,7 @@ static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
|
|||
struct gsm_trans *trans;
|
||||
int reqs;
|
||||
struct llist_head *entry;
|
||||
char buf[128];
|
||||
|
||||
if (strlen(vsub->name))
|
||||
vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
|
||||
|
@ -755,7 +758,7 @@ static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
|
|||
else
|
||||
vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
|
||||
|
||||
vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
|
||||
vty_out(vty, " Use: %s%s", osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count), VTY_NEWLINE);
|
||||
|
||||
/* Connection */
|
||||
if (vsub->msc_conn_ref) {
|
||||
|
@ -882,11 +885,11 @@ static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
|
|||
const char *id)
|
||||
{
|
||||
if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
|
||||
return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
|
||||
return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
|
||||
else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
|
||||
return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
|
||||
return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
|
||||
else if (!strcmp(type, "tmsi"))
|
||||
return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
|
||||
return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -916,7 +919,7 @@ DEFUN(show_subscr,
|
|||
/* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
|
||||
* This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
|
||||
* this, and since this is not multi-threaded, this vlr_subscr_put() cannot possibly reach a count of 0. */
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
|
||||
subscr_dump_full_vty(vty, vsub);
|
||||
|
||||
|
@ -955,7 +958,7 @@ DEFUN(subscriber_send_pending_sms,
|
|||
if (sms)
|
||||
gsm411_send_sms(gsmnet, sms->receiver, sms);
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
@ -979,7 +982,7 @@ DEFUN(subscriber_sms_delete_all,
|
|||
|
||||
db_sms_delete_by_msisdn(vsub->msisdn);
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
@ -1011,7 +1014,7 @@ DEFUN(subscriber_send_sms,
|
|||
goto err;
|
||||
}
|
||||
sender_msisdn = sender->msisdn;
|
||||
vlr_subscr_put(sender);
|
||||
vlr_subscr_put(sender, VSUB_USE_VTY);
|
||||
}
|
||||
|
||||
str = argv_concat(argv, argc, 4);
|
||||
|
@ -1020,7 +1023,7 @@ DEFUN(subscriber_send_sms,
|
|||
|
||||
err:
|
||||
if (vsub)
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -1053,7 +1056,7 @@ DEFUN(subscriber_silent_sms,
|
|||
goto err;
|
||||
}
|
||||
sender_msisdn = sender->msisdn;
|
||||
vlr_subscr_put(sender);
|
||||
vlr_subscr_put(sender, VSUB_USE_VTY);
|
||||
}
|
||||
|
||||
str = argv_concat(argv, argc, 4);
|
||||
|
@ -1062,7 +1065,7 @@ DEFUN(subscriber_silent_sms,
|
|||
|
||||
err:
|
||||
if (vsub)
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -1161,7 +1164,7 @@ DEFUN(subscriber_silent_call_start,
|
|||
break;
|
||||
}
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
return rc ? CMD_WARNING : CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1197,7 +1200,7 @@ DEFUN(subscriber_silent_call_stop,
|
|||
break;
|
||||
}
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
return rc ? CMD_WARNING : CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1224,7 +1227,7 @@ DEFUN(subscriber_ussd_notify,
|
|||
level = atoi(argv[2]);
|
||||
text = argv_concat(argv, argc, 3);
|
||||
if (!text) {
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1235,7 @@ DEFUN(subscriber_ussd_notify,
|
|||
if (!conn) {
|
||||
vty_out(vty, "%% An active connection is required for %s %s%s",
|
||||
argv[0], argv[1], VTY_NEWLINE);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
talloc_free(text);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
@ -1242,7 +1245,7 @@ DEFUN(subscriber_ussd_notify,
|
|||
* we use dummy GSM 04.07 transaction ID. */
|
||||
msc_send_ussd_release_complete(conn, 0x00);
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
talloc_free(text);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
@ -1267,7 +1270,7 @@ DEFUN(subscriber_paging,
|
|||
else
|
||||
vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
return req ? CMD_SUCCESS : CMD_WARNING;
|
||||
}
|
||||
|
||||
|
@ -1323,7 +1326,7 @@ DEFUN(subscriber_mstest_close,
|
|||
if (!conn) {
|
||||
vty_out(vty, "%% An active connection is required for %s %s%s",
|
||||
argv[0], argv[1], VTY_NEWLINE);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
|
@ -1351,7 +1354,7 @@ DEFUN(subscriber_mstest_open,
|
|||
if (!conn) {
|
||||
vty_out(vty, "%% An active connection is required for %s %s%s",
|
||||
argv[0], argv[1], VTY_NEWLINE);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
|
@ -1378,12 +1381,12 @@ DEFUN(ena_subscr_expire,
|
|||
vty_out(vty, "%% VLR released subscriber %s%s",
|
||||
vlr_subscr_name(vsub), VTY_NEWLINE);
|
||||
|
||||
if (vsub->use_count > 1)
|
||||
if (osmo_use_count_total(&vsub->use_count) > 1)
|
||||
vty_out(vty, "%% Subscriber %s is still in use,"
|
||||
" should be released soon%s",
|
||||
vlr_subscr_name(vsub), VTY_NEWLINE);
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_VTY);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1575,7 +1578,7 @@ DEFUN(logging_fltr_imsi,
|
|||
if (!tgt)
|
||||
return CMD_WARNING;
|
||||
|
||||
vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
|
||||
vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
|
||||
|
||||
if (!vlr_subscr) {
|
||||
vty_out(vty, "%%no subscriber with IMSI(%s)%s",
|
||||
|
@ -1584,6 +1587,7 @@ DEFUN(logging_fltr_imsi,
|
|||
}
|
||||
|
||||
log_set_filter_vlr_subscr(tgt, vlr_subscr);
|
||||
vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -552,7 +552,7 @@ static void ran_conn_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_ca
|
|||
DEBUGP(DRLL, "%s: Freeing RAN connection\n", vlr_subscr_name(conn->vsub));
|
||||
conn->vsub->lu_fsm = NULL;
|
||||
conn->vsub->msc_conn_ref = NULL;
|
||||
vlr_subscr_put(conn->vsub);
|
||||
vlr_subscr_put(conn->vsub, VSUB_USE_CONN);
|
||||
conn->vsub = NULL;
|
||||
} else
|
||||
DEBUGP(DRLL, "Freeing RAN connection with NULL subscriber\n");
|
||||
|
|
|
@ -98,6 +98,7 @@ static struct ran_conn *subscr_conn_allocate_sgs(struct sgs_connection *sgc, str
|
|||
return NULL;
|
||||
}
|
||||
|
||||
vlr_subscr_get(vsub, VSUB_USE_CONN);
|
||||
conn->vsub = vsub;
|
||||
conn->vsub->cs.attached_via_ran = conn->via_ran;
|
||||
|
||||
|
@ -264,7 +265,7 @@ static bool check_sgs_association(struct sgs_connection *sgc, struct msgb *msg,
|
|||
uint8_t msg_type = msg->data[0];
|
||||
|
||||
/* Subscriber must be known by the VLR */
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
|
||||
if (!vsub) {
|
||||
LOGSGC(sgc, LOGL_NOTICE, "SGsAP Message %s with unknown IMSI (%s), releasing\n",
|
||||
sgsap_msg_type_name(msg_type), imsi);
|
||||
|
@ -279,11 +280,11 @@ static bool check_sgs_association(struct sgs_connection *sgc, struct msgb *msg,
|
|||
vlr_subscr_name(vsub), sgsap_msg_type_name(msg_type));
|
||||
resp = gsm29118_create_release_req(vsub->imsi, SGSAP_SGS_CAUSE_IMSI_DET_EPS_NONEPS);
|
||||
sgs_tx(sgc, resp);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -316,12 +317,12 @@ const char *subscr_info(const char *imsi)
|
|||
struct vlr_subscr *vsub;
|
||||
|
||||
if (imsi) {
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
|
||||
if (!vsub)
|
||||
subscr_string = imsi;
|
||||
else {
|
||||
subscr_string = vlr_subscr_name(vsub);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -556,10 +557,10 @@ static int sgs_rx_loc_upd_req(struct sgs_connection *sgc, struct msgb *msg, cons
|
|||
struct vlr_subscr *vsub;
|
||||
|
||||
/* Check for lingering connections */
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
|
||||
if (vsub) {
|
||||
subscr_conn_toss(vsub);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
}
|
||||
|
||||
/* Determine MME-Name */
|
||||
|
@ -675,7 +676,7 @@ static int sgs_rx_pag_rej(struct sgs_connection *sgc, struct msgb *msg, const st
|
|||
return 0;
|
||||
|
||||
/* Subscriber must be known by the VLR */
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
|
||||
if (!vsub)
|
||||
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_IMSI_UNKNOWN, msg, SGSAP_IE_IMSI);
|
||||
|
||||
|
@ -698,7 +699,7 @@ static int sgs_rx_pag_rej(struct sgs_connection *sgc, struct msgb *msg, const st
|
|||
OSMO_ASSERT(false);
|
||||
}
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -739,7 +740,7 @@ static int sgs_rx_service_req(struct sgs_connection *sgc, struct msgb *msg, cons
|
|||
if (!check_sgs_association(sgc, msg, imsi))
|
||||
return 0;
|
||||
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
|
||||
/* Note: vsub is already sufficiently verified by check_sgs_association(),
|
||||
* we must have a vsub at this point! */
|
||||
OSMO_ASSERT(vsub);
|
||||
|
@ -747,13 +748,13 @@ static int sgs_rx_service_req(struct sgs_connection *sgc, struct msgb *msg, cons
|
|||
/* The Service request is intended as a paging response, if one is
|
||||
* received while nothing is paging something is very wrong! */
|
||||
if (!vlr_sgs_pag_pend(vsub)) {
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MSG_INCOMP_STATE, msg, -1);
|
||||
}
|
||||
serv_ind_ie = TLVP_VAL_MINLEN(tp, SGSAP_IE_SERVICE_INDICATOR, 1);
|
||||
|
||||
if (!serv_ind_ie) {
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MISSING_MAND_IE, msg, SGSAP_IE_SERVICE_INDICATOR);
|
||||
}
|
||||
if (serv_ind_ie[0] == SGSAP_SERV_IND_CS_CALL)
|
||||
|
@ -761,7 +762,7 @@ static int sgs_rx_service_req(struct sgs_connection *sgc, struct msgb *msg, cons
|
|||
else if (serv_ind_ie[0] == SGSAP_SERV_IND_SMS)
|
||||
serv_ind = serv_ind_ie[0];
|
||||
else {
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_INVALID_MAND_IE, msg, SGSAP_IE_SERVICE_INDICATOR);
|
||||
}
|
||||
|
||||
|
@ -776,17 +777,19 @@ static int sgs_rx_service_req(struct sgs_connection *sgc, struct msgb *msg, cons
|
|||
* the connection will be allocated when the MS is appearing on the
|
||||
* A-Interface. */
|
||||
if (serv_ind == SGSAP_SERV_IND_CS_CALL) {
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate subscriber connection */
|
||||
conn = subscr_conn_allocate_sgs(sgc, vsub, true);
|
||||
if (!conn) {
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MSG_INCOMP_STATE, msg, -1);
|
||||
}
|
||||
|
||||
/* The conn has added a get() for the vsub, balance above vlr_subscr_find_by_imsi() */
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -795,14 +798,13 @@ static int sgs_rx_ul_ud(struct sgs_connection *sgc, struct msgb *msg, const stru
|
|||
{
|
||||
struct dtap_header *dtap;
|
||||
struct ran_conn *conn;
|
||||
bool ran_conn_created = false;
|
||||
const uint8_t *nas_msg_container_ie;
|
||||
struct vlr_subscr *vsub;
|
||||
|
||||
if (!check_sgs_association(sgc, msg, imsi))
|
||||
return 0;
|
||||
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
|
||||
/* Note: vsub is already sufficiently verified by check_sgs_association(),
|
||||
* we must have a vsub at this point! */
|
||||
OSMO_ASSERT(vsub);
|
||||
|
@ -811,7 +813,6 @@ static int sgs_rx_ul_ud(struct sgs_connection *sgc, struct msgb *msg, const stru
|
|||
conn = connection_for_subscr(vsub);
|
||||
if (!conn) {
|
||||
conn = subscr_conn_allocate_sgs(sgc, vsub, false);
|
||||
ran_conn_created = true;
|
||||
} else {
|
||||
if (conn->via_ran != OSMO_RAT_EUTRAN_SGS) {
|
||||
LOGSGC(sgc, LOGL_ERROR,
|
||||
|
@ -821,16 +822,17 @@ static int sgs_rx_ul_ud(struct sgs_connection *sgc, struct msgb *msg, const stru
|
|||
}
|
||||
}
|
||||
|
||||
/* Balance above vlr_subscr_find_by_imsi() */
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
|
||||
/* If we do not find an existing connection and allocating a new one
|
||||
* faild, give up and return status. */
|
||||
if (!conn) {
|
||||
vlr_subscr_put(vsub);
|
||||
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MSG_INCOMP_STATE, msg, 0);
|
||||
}
|
||||
|
||||
nas_msg_container_ie = TLVP_VAL_MINLEN(tp, SGSAP_IE_NAS_MSG_CONTAINER, 1);
|
||||
if (!nas_msg_container_ie) {
|
||||
vlr_subscr_put(vsub);
|
||||
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MISSING_MAND_IE, msg, SGSAP_IE_NAS_MSG_CONTAINER);
|
||||
}
|
||||
|
||||
|
@ -842,12 +844,6 @@ static int sgs_rx_ul_ud(struct sgs_connection *sgc, struct msgb *msg, const stru
|
|||
/* Forward dtap payload into the msc */
|
||||
ran_conn_dtap(conn, msg);
|
||||
|
||||
/* If we did not create the conn right here, we just handle the ref
|
||||
* counting normally. Otherwise we are in the same role as
|
||||
* sgs_rx_service_req() and we want that the refcount says incremented
|
||||
* througout the lifetime of the newly created conn. */
|
||||
if (!ran_conn_created)
|
||||
vlr_subscr_put(vsub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -860,7 +856,7 @@ static int sgs_rx_csfb_ind(struct sgs_connection *sgc, struct msgb *msg, const s
|
|||
* to the 4G network, so we use the SGs interface again for further
|
||||
* communication with the UE. */
|
||||
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
|
||||
if (!vsub)
|
||||
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_IMSI_UNKNOWN, msg, SGSAP_IE_IMSI);
|
||||
|
||||
|
@ -868,7 +864,7 @@ static int sgs_rx_csfb_ind(struct sgs_connection *sgc, struct msgb *msg, const s
|
|||
subscr_conn_toss(vsub);
|
||||
|
||||
vsub->cs.attached_via_ran = OSMO_RAT_EUTRAN_SGS;
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
|
||||
#include "smpp_smsc.h"
|
||||
|
||||
#define VSUB_USE_SMPP "SMPP"
|
||||
#define VSUB_USE_SMPP_CMD "SMPP-cmd"
|
||||
|
||||
/*! \brief find vlr_subscr for a given SMPP NPI/TON/Address */
|
||||
static struct vlr_subscr *subscr_by_dst(struct gsm_network *net,
|
||||
uint8_t npi, uint8_t ton,
|
||||
|
@ -57,11 +60,11 @@ static struct vlr_subscr *subscr_by_dst(struct gsm_network *net,
|
|||
|
||||
switch (npi) {
|
||||
case NPI_Land_Mobile_E212:
|
||||
vsub = vlr_subscr_find_by_imsi(net->vlr, addr);
|
||||
vsub = vlr_subscr_find_by_imsi(net->vlr, addr, VSUB_USE_SMPP);
|
||||
break;
|
||||
case NPI_ISDN_E163_E164:
|
||||
case NPI_Private:
|
||||
vsub = vlr_subscr_find_by_msisdn(net->vlr, addr);
|
||||
vsub = vlr_subscr_find_by_msisdn(net->vlr, addr, VSUB_USE_SMPP);
|
||||
break;
|
||||
default:
|
||||
LOGP(DSMPP, LOGL_NOTICE, "Unsupported NPI: %u\n", npi);
|
||||
|
@ -117,7 +120,7 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
|
|||
if (smpp34_submit_tlv_msg_payload(t, submit, &sms_msg,
|
||||
&sms_msg_len) < 0) {
|
||||
if (dest)
|
||||
vlr_subscr_put(dest);
|
||||
vlr_subscr_put(dest, VSUB_USE_SMPP);
|
||||
return ESME_ROPTPARNOTALLWD;
|
||||
}
|
||||
break;
|
||||
|
@ -136,7 +139,7 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
|
|||
} else {
|
||||
LOGP(DLSMS, LOGL_ERROR,
|
||||
"SMPP neither message payload nor valid sm_length.\n");
|
||||
vlr_subscr_put(dest);
|
||||
vlr_subscr_put(dest, VSUB_USE_SMPP);
|
||||
return ESME_RINVPARLEN;
|
||||
}
|
||||
}
|
||||
|
@ -532,7 +535,7 @@ static void smpp_cmd_free(struct osmo_smpp_cmd *cmd)
|
|||
{
|
||||
osmo_timer_del(&cmd->response_timer);
|
||||
llist_del(&cmd->list);
|
||||
vlr_subscr_put(cmd->vsub);
|
||||
vlr_subscr_put(cmd->vsub, VSUB_USE_SMPP_CMD);
|
||||
talloc_free(cmd);
|
||||
}
|
||||
|
||||
|
@ -619,7 +622,8 @@ static int smpp_cmd_enqueue(struct osmo_esme *esme,
|
|||
cmd->is_report = sms->is_report;
|
||||
cmd->gsm411_msg_ref = sms->gsm411.msg_ref;
|
||||
cmd->gsm411_trans_id = sms->gsm411.transaction_id;
|
||||
cmd->vsub = vlr_subscr_get(vsub);
|
||||
vlr_subscr_get(vsub, VSUB_USE_SMPP_CMD);
|
||||
cmd->vsub = vsub;
|
||||
|
||||
/* FIXME: No predefined value for this response_timer as specified by
|
||||
* SMPP 3.4 specs, section 7.2. Make this configurable? Don't forget
|
||||
|
|
|
@ -118,14 +118,15 @@ static struct gsm_sms_pending *sms_pending_from(struct gsm_sms_queue *smsq,
|
|||
if (!pending)
|
||||
return NULL;
|
||||
|
||||
pending->vsub = vlr_subscr_get(sms->receiver);
|
||||
vlr_subscr_get(sms->receiver, VSUB_USE_SMS_PENDING);
|
||||
pending->vsub = sms->receiver;
|
||||
pending->sms_id = sms->id;
|
||||
return pending;
|
||||
}
|
||||
|
||||
static void sms_pending_free(struct gsm_sms_pending *pending)
|
||||
{
|
||||
vlr_subscr_put(pending->vsub);
|
||||
vlr_subscr_put(pending->vsub, VSUB_USE_SMS_PENDING);
|
||||
llist_del(&pending->entry);
|
||||
talloc_free(pending);
|
||||
}
|
||||
|
@ -482,12 +483,13 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal,
|
|||
case S_SMS_DELIVERED:
|
||||
/* Remember the subscriber and clear the pending entry */
|
||||
network->sms_queue->pending -= 1;
|
||||
vsub = vlr_subscr_get(pending->vsub);
|
||||
vsub = pending->vsub;
|
||||
vlr_subscr_get(vsub, __func__);
|
||||
db_sms_delete_sent_message_by_id(pending->sms_id);
|
||||
sms_pending_free(pending);
|
||||
/* Attempt to send another SMS to this subscriber */
|
||||
sms_send_next(vsub);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
break;
|
||||
case S_SMS_MEM_EXCEEDED:
|
||||
network->sms_queue->pending -= 1;
|
||||
|
|
|
@ -93,6 +93,11 @@ struct gsm_trans *trans_find_by_sm_rp_mr(const struct gsm_network *net,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *trans_vsub_use(uint8_t proto)
|
||||
{
|
||||
return get_value_string_or_null(gsm48_pdisc_names, proto) ? : "trans-proto-unknown";
|
||||
}
|
||||
|
||||
/*! Allocate a new transaction and add it to network list
|
||||
* \param[in] net Netwokr in which we allocate transaction
|
||||
* \param[in] subscr Subscriber for which we allocate transaction
|
||||
|
@ -121,8 +126,8 @@ struct gsm_trans *trans_alloc(struct gsm_network *net,
|
|||
if (!trans)
|
||||
return NULL;
|
||||
|
||||
trans->vsub = vlr_subscr_get(vsub);
|
||||
|
||||
vlr_subscr_get(vsub, trans_vsub_use(protocol));
|
||||
trans->vsub = vsub;
|
||||
trans->protocol = protocol;
|
||||
trans->transaction_id = trans_id;
|
||||
trans->callref = callref;
|
||||
|
@ -165,7 +170,7 @@ void trans_free(struct gsm_trans *trans)
|
|||
}
|
||||
|
||||
if (trans->vsub) {
|
||||
vlr_subscr_put(trans->vsub);
|
||||
vlr_subscr_put(trans->vsub, trans_vsub_use(trans->protocol));
|
||||
trans->vsub = NULL;
|
||||
}
|
||||
|
||||
|
|
110
src/libvlr/vlr.c
110
src/libvlr/vlr.c
|
@ -119,6 +119,7 @@ const char *vlr_subscr_msisdn_or_name(const struct vlr_subscr *vsub)
|
|||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
|
||||
const char *imsi,
|
||||
const char *use,
|
||||
const char *file, int line)
|
||||
{
|
||||
struct vlr_subscr *vsub;
|
||||
|
@ -127,14 +128,17 @@ struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
|
|||
return NULL;
|
||||
|
||||
llist_for_each_entry(vsub, &vlr->subscribers, list) {
|
||||
if (vlr_subscr_matches_imsi(vsub, imsi))
|
||||
return _vlr_subscr_get(vsub, file, line);
|
||||
if (vlr_subscr_matches_imsi(vsub, imsi)) {
|
||||
vlr_subscr_get_src(vsub, use, file, line);
|
||||
return vsub;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr,
|
||||
uint32_t tmsi,
|
||||
const char *use,
|
||||
const char *file, int line)
|
||||
{
|
||||
struct vlr_subscr *vsub;
|
||||
|
@ -143,14 +147,17 @@ struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr,
|
|||
return NULL;
|
||||
|
||||
llist_for_each_entry(vsub, &vlr->subscribers, list) {
|
||||
if (vlr_subscr_matches_tmsi(vsub, tmsi))
|
||||
return _vlr_subscr_get(vsub, file, line);
|
||||
if (vlr_subscr_matches_tmsi(vsub, tmsi)) {
|
||||
vlr_subscr_get_src(vsub, use, file, line);
|
||||
return vsub;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
|
||||
const char *msisdn,
|
||||
const char *use,
|
||||
const char *file, int line)
|
||||
{
|
||||
struct vlr_subscr *vsub;
|
||||
|
@ -159,8 +166,10 @@ struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
|
|||
return NULL;
|
||||
|
||||
llist_for_each_entry(vsub, &vlr->subscribers, list) {
|
||||
if (vlr_subscr_matches_msisdn(vsub, msisdn))
|
||||
return _vlr_subscr_get(vsub, file, line);
|
||||
if (vlr_subscr_matches_msisdn(vsub, msisdn)) {
|
||||
vlr_subscr_get_src(vsub, use, file, line);
|
||||
return vsub;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -217,30 +226,24 @@ static int vlr_tx_gsup_error_reply(const struct vlr_instance *vlr,
|
|||
return vlr_tx_gsup_message(vlr, &gsup_reply);
|
||||
}
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_get(struct vlr_subscr *sub, const char *file, int line)
|
||||
static int vlr_subscr_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, const char *file, int line)
|
||||
{
|
||||
if (!sub)
|
||||
return NULL;
|
||||
OSMO_ASSERT(sub->use_count < INT_MAX);
|
||||
sub->use_count++;
|
||||
LOGPSRC(DREF, LOGL_DEBUG, file, line,
|
||||
"VLR subscr %s usage increases to: %d\n",
|
||||
vlr_subscr_name(sub), sub->use_count);
|
||||
return sub;
|
||||
}
|
||||
struct vlr_subscr *vsub = e->use_count->talloc_object;
|
||||
char buf[128];
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_put(struct vlr_subscr *sub, const char *file, int line)
|
||||
{
|
||||
if (!sub)
|
||||
return NULL;
|
||||
sub->use_count--;
|
||||
LOGPSRC(DREF, sub->use_count >= 0? LOGL_DEBUG : LOGL_ERROR,
|
||||
file, line,
|
||||
"VLR subscr %s usage decreases to: %d\n",
|
||||
vlr_subscr_name(sub), sub->use_count);
|
||||
if (sub->use_count <= 0)
|
||||
vlr_subscr_free(sub);
|
||||
return NULL;
|
||||
if (!e->use)
|
||||
return -EINVAL;
|
||||
|
||||
LOGPSRC(DREF, LOGL_DEBUG, file, line, "VLR subscr %s %s %s: now used by %s\n",
|
||||
vlr_subscr_name(vsub), (e->count - old_use_count) > 0? "+" : "-", e->use,
|
||||
osmo_use_count_name_buf(buf, sizeof(buf), e->use_count));
|
||||
|
||||
if (e->count < 0)
|
||||
return -ERANGE;
|
||||
|
||||
if (osmo_use_count_total(e->use_count) <= 0)
|
||||
vlr_subscr_free(vsub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate a new subscriber and insert it into list */
|
||||
|
@ -250,9 +253,16 @@ static struct vlr_subscr *_vlr_subscr_alloc(struct vlr_instance *vlr)
|
|||
int i;
|
||||
|
||||
vsub = talloc_zero(vlr, struct vlr_subscr);
|
||||
vsub->vlr = vlr;
|
||||
vsub->tmsi = GSM_RESERVED_TMSI;
|
||||
vsub->tmsi_new = GSM_RESERVED_TMSI;
|
||||
*vsub = (struct vlr_subscr){
|
||||
.vlr = vlr,
|
||||
.tmsi = GSM_RESERVED_TMSI,
|
||||
.tmsi_new = GSM_RESERVED_TMSI,
|
||||
.use_count = (struct osmo_use_count){
|
||||
.talloc_object = vsub,
|
||||
.use_cb = vlr_subscr_use_cb,
|
||||
},
|
||||
};
|
||||
osmo_use_count_make_static_entries(&vsub->use_count, vsub->use_count_buf, ARRAY_SIZE(vsub->use_count_buf));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(vsub->auth_tuples); i++)
|
||||
vsub->auth_tuples[i].key_seq = VLR_KEY_SEQ_INVAL;
|
||||
|
@ -269,11 +279,6 @@ static struct vlr_subscr *_vlr_subscr_alloc(struct vlr_instance *vlr)
|
|||
return vsub;
|
||||
}
|
||||
|
||||
struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr)
|
||||
{
|
||||
return vlr_subscr_get(_vlr_subscr_alloc(vlr));
|
||||
}
|
||||
|
||||
/* Send a GSUP Purge MS request.
|
||||
* TODO: this should be sent to the *previous* VLR when this VLR is "taking"
|
||||
* this subscriber, not to the HLR? */
|
||||
|
@ -297,12 +302,12 @@ void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub,
|
|||
if (!vsub)
|
||||
return;
|
||||
|
||||
vlr_subscr_get(vsub);
|
||||
vlr_subscr_get(vsub, __func__);
|
||||
if (vsub->lu_fsm)
|
||||
vlr_loc_update_cancel(vsub->lu_fsm, fsm_cause, gsm48_cause);
|
||||
if (vsub->proc_arq_fsm)
|
||||
vlr_parq_cancel(vsub->proc_arq_fsm, fsm_cause, gsm48_cause);
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
}
|
||||
|
||||
/* Call vlr_subscr_cancel(), then completely drop the entry from the VLR */
|
||||
|
@ -327,6 +332,7 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub)
|
|||
struct vlr_instance *vlr = vsub->vlr;
|
||||
uint32_t tmsi;
|
||||
int tried, rc;
|
||||
struct vlr_subscr *other_vsub;
|
||||
|
||||
for (tried = 0; tried < 100; tried++) {
|
||||
rc = osmo_get_rand_id((uint8_t *) &tmsi, sizeof(tmsi));
|
||||
|
@ -349,8 +355,10 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub)
|
|||
}
|
||||
|
||||
/* If this TMSI is already in use, try another one. */
|
||||
if (vlr_subscr_find_by_tmsi(vlr, tmsi))
|
||||
if ((other_vsub = vlr_subscr_find_by_tmsi(vlr, tmsi, __func__))) {
|
||||
vlr_subscr_put(other_vsub, __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
vsub->tmsi_new = tmsi;
|
||||
vsub->vlr->ops.subscr_update(vsub);
|
||||
|
@ -368,21 +376,23 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub)
|
|||
* \param[out] created if non-NULL, returns whether a new entry was created. */
|
||||
struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
|
||||
const char *imsi,
|
||||
const char *use,
|
||||
bool *created,
|
||||
const char *file,
|
||||
int line)
|
||||
{
|
||||
struct vlr_subscr *vsub;
|
||||
vsub = _vlr_subscr_find_by_imsi(vlr, imsi, file, line);
|
||||
vsub = _vlr_subscr_find_by_imsi(vlr, imsi, use, file, line);
|
||||
if (vsub) {
|
||||
if (created)
|
||||
*created = false;
|
||||
return vsub;
|
||||
}
|
||||
|
||||
vsub = _vlr_subscr_get(_vlr_subscr_alloc(vlr), file, line);
|
||||
vsub = _vlr_subscr_alloc(vlr);
|
||||
if (!vsub)
|
||||
return NULL;
|
||||
vlr_subscr_get_src(vsub, use, file, line);
|
||||
vlr_subscr_set_imsi(vsub, imsi);
|
||||
LOGP(DVLR, LOGL_INFO, "New subscr, IMSI: %s\n", vsub->imsi);
|
||||
if (created)
|
||||
|
@ -396,21 +406,23 @@ struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
|
|||
* \param[out] created if non-NULL, returns whether a new entry was created. */
|
||||
struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr,
|
||||
uint32_t tmsi,
|
||||
const char *use,
|
||||
bool *created,
|
||||
const char *file,
|
||||
int line)
|
||||
{
|
||||
struct vlr_subscr *vsub;
|
||||
vsub = _vlr_subscr_find_by_tmsi(vlr, tmsi, file, line);
|
||||
vsub = _vlr_subscr_find_by_tmsi(vlr, tmsi, use, file, line);
|
||||
if (vsub) {
|
||||
if (created)
|
||||
*created = false;
|
||||
return vsub;
|
||||
}
|
||||
|
||||
vsub = _vlr_subscr_get(_vlr_subscr_alloc(vlr), file, line);
|
||||
vsub = _vlr_subscr_alloc(vlr);
|
||||
if (!vsub)
|
||||
return NULL;
|
||||
vlr_subscr_get_src(vsub, use, file, line);
|
||||
vsub->tmsi = tmsi;
|
||||
LOGP(DVLR, LOGL_INFO, "New subscr, TMSI: 0x%08x\n", vsub->tmsi);
|
||||
if (created)
|
||||
|
@ -1098,7 +1110,7 @@ int vlr_gsupc_read_cb(struct osmo_gsup_client *gsupc, struct msgb *msg)
|
|||
goto msgb_free_and_return;
|
||||
}
|
||||
|
||||
vsub = vlr_subscr_find_by_imsi(vlr, gsup.imsi);
|
||||
vsub = vlr_subscr_find_by_imsi(vlr, gsup.imsi, __func__);
|
||||
if (!vsub) {
|
||||
switch (gsup.message_type) {
|
||||
case OSMO_GSUP_MSGT_PURGE_MS_RESULT:
|
||||
|
@ -1146,7 +1158,7 @@ int vlr_gsupc_read_cb(struct osmo_gsup_client *gsupc, struct msgb *msg)
|
|||
break;
|
||||
}
|
||||
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, __func__);
|
||||
|
||||
msgb_free_and_return:
|
||||
msgb_free(msg);
|
||||
|
@ -1239,7 +1251,7 @@ bool vlr_subscr_expire(struct vlr_subscr *vsub)
|
|||
if (vsub->lu_complete) {
|
||||
/* balancing the get from vlr_lu_compl_fsm_success() */
|
||||
vsub->lu_complete = false;
|
||||
vlr_subscr_put(vsub);
|
||||
vlr_subscr_put(vsub, VSUB_USE_ATTACHED);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1425,16 +1437,18 @@ void log_set_filter_vlr_subscr(struct log_target *target,
|
|||
struct vlr_subscr *vlr_subscr)
|
||||
{
|
||||
struct vlr_subscr **fsub = (void*)&target->filter_data[LOG_FLT_VLR_SUBSCR];
|
||||
const char *use = "logfilter";
|
||||
|
||||
/* free the old data */
|
||||
if (*fsub) {
|
||||
vlr_subscr_put(*fsub);
|
||||
vlr_subscr_put(*fsub, use);
|
||||
*fsub = NULL;
|
||||
}
|
||||
|
||||
if (vlr_subscr) {
|
||||
target->filter_map |= (1 << LOG_FLT_VLR_SUBSCR);
|
||||
*fsub = vlr_subscr_get(vlr_subscr);
|
||||
vlr_subscr_get(vlr_subscr, use);
|
||||
*fsub = vlr_subscr;
|
||||
} else
|
||||
target->filter_map &= ~(1 << LOG_FLT_VLR_SUBSCR);
|
||||
}
|
||||
|
|
|
@ -356,10 +356,10 @@ static void proc_arq_vlr_fn_init(struct osmo_fsm_inst *fi,
|
|||
/* Obtain_Identity_VLR */
|
||||
if (!par->by_tmsi) {
|
||||
/* IMSI was included */
|
||||
vsub = vlr_subscr_find_by_imsi |