diff options
Diffstat (limited to 'src/libvlr')
-rw-r--r-- | src/libvlr/vlr.c | 204 | ||||
-rw-r--r-- | src/libvlr/vlr_access_req_fsm.c | 34 | ||||
-rw-r--r-- | src/libvlr/vlr_lu_fsm.c | 28 | ||||
-rw-r--r-- | src/libvlr/vlr_sgs.c | 10 | ||||
-rw-r--r-- | src/libvlr/vlr_sgs_fsm.c | 6 |
5 files changed, 108 insertions, 174 deletions
diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c index c6d8805d6..508246989 100644 --- a/src/libvlr/vlr.c +++ b/src/libvlr/vlr.c @@ -33,6 +33,7 @@ #include <osmocom/msc/vlr_sgs.h> #include <osmocom/msc/vlr.h> #include <osmocom/msc/debug.h> +#include <osmocom/msc/gsup_client_mux.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -110,6 +111,18 @@ const char *vlr_subscr_name(const struct vlr_subscr *vsub) return buf; } +const char *vlr_subscr_short_name(const struct vlr_subscr *vsub, unsigned int maxlen) +{ + /* cast away the const so we can shorten the string within the static buffer */ + char *name = (char*)vlr_subscr_name(vsub); + size_t len = strlen(name); + if (maxlen < 2) + return "-"; + if (len > maxlen) + strcpy(name + maxlen - 2, ".."); + return name; +} + const char *vlr_subscr_msisdn_or_name(const struct vlr_subscr *vsub) { if (!vsub || !vsub->msisdn[0]) @@ -174,31 +187,6 @@ struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr, return NULL; } -/* Transmit GSUP message to HLR */ -static int vlr_tx_gsup_message(const struct vlr_instance *vlr, - const struct osmo_gsup_message *gsup_msg) -{ - struct msgb *msg = osmo_gsup_client_msgb_alloc(); - - int rc = osmo_gsup_encode(msg, gsup_msg); - if (rc < 0) { - LOGP(DVLR, LOGL_ERROR, "GSUP encoding failure: %s\n", strerror(-rc)); - return rc; - } - - if (!vlr->gsup_client) { - LOGP(DVLR, LOGL_NOTICE, "GSUP link is down, cannot " - "send GSUP: %s\n", msgb_hexdump(msg)); - msgb_free(msg); - return -ENOTSUP; - } - - LOGP(DVLR, LOGL_DEBUG, "GSUP tx: %s\n", - osmo_hexdump_nospc(msg->data, msg->len)); - - return osmo_gsup_client_send(vlr->gsup_client, msg); -} - /* Transmit GSUP message for subscriber to HLR, using IMSI from subscriber */ static int vlr_subscr_tx_gsup_message(const struct vlr_subscr *vsub, struct osmo_gsup_message *gsup_msg) @@ -208,40 +196,39 @@ static int vlr_subscr_tx_gsup_message(const struct vlr_subscr *vsub, if (strlen(gsup_msg->imsi) == 0) OSMO_STRLCPY_ARRAY(gsup_msg->imsi, vsub->imsi); - return vlr_tx_gsup_message(vlr, gsup_msg); -} - -/* Transmit GSUP error in response to original message */ -static int vlr_tx_gsup_error_reply(const struct vlr_instance *vlr, - struct osmo_gsup_message *gsup_orig, - enum gsm48_gmm_cause cause) -{ - struct osmo_gsup_message gsup_reply = {0}; - - OSMO_STRLCPY_ARRAY(gsup_reply.imsi, gsup_orig->imsi); - gsup_reply.cause = cause; - gsup_reply.message_type = - OSMO_GSUP_TO_MSGT_ERROR(gsup_orig->message_type); + gsup_msg->message_class = OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT; - return vlr_tx_gsup_message(vlr, &gsup_reply); + return gsup_client_mux_tx(vlr->gcm, gsup_msg); } static int vlr_subscr_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, const char *file, int line) { struct vlr_subscr *vsub = e->use_count->talloc_object; char buf[128]; + int32_t total; + int level; if (!e->use) return -EINVAL; - LOGPSRC(DREF, LOGL_DEBUG, file, line, "VLR subscr %s %s %s: now used by %s\n", + total = osmo_use_count_total(&vsub->use_count); + + if (total == 0 + || (total == 1 && old_use_count == 0 && e->count == 1)) + level = LOGL_INFO; + else + level = LOGL_DEBUG; + + LOGPSRC(DREF, level, 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) + vsub->max_total_use_count = OSMO_MAX(vsub->max_total_use_count, total); + + if (total <= 0) vlr_subscr_free(vsub); return 0; } @@ -261,6 +248,7 @@ static struct vlr_subscr *_vlr_subscr_alloc(struct vlr_instance *vlr) .talloc_object = vsub, .use_cb = vlr_subscr_use_cb, }, + .expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION, }; osmo_use_count_make_static_entries(&vsub->use_count, vsub->use_count_buf, ARRAY_SIZE(vsub->use_count_buf)); @@ -314,7 +302,8 @@ void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub, void vlr_subscr_free(struct vlr_subscr *vsub) { llist_del(&vsub->list); - DEBUGP(DREF, "freeing VLR subscr %s\n", vlr_subscr_name(vsub)); + DEBUGP(DVLR, "freeing VLR subscr %s (max total use count was %d)\n", vlr_subscr_name(vsub), + vsub->max_total_use_count); /* Make sure SGs timer Ts5 is removed */ osmo_timer_del(&vsub->sgs.Ts5); @@ -611,17 +600,14 @@ vlr_subscr_pdp_data_get_by_id(struct vlr_subscr *vsub, unsigned context_id) ***********************************************************************/ static int vlr_rx_gsup_unknown_imsi(struct vlr_instance *vlr, - struct osmo_gsup_message *gsup_msg) + const struct osmo_gsup_message *gsup_msg) { if (OSMO_GSUP_IS_MSGT_REQUEST(gsup_msg->message_type)) { - int rc = vlr_tx_gsup_error_reply(vlr, gsup_msg, GMM_CAUSE_IMSI_UNKNOWN); - if (rc < 0) - LOGP(DVLR, LOGL_ERROR, "Failed to send error reply for IMSI %s\n", gsup_msg->imsi); - LOGP(DVLR, LOGL_NOTICE, "Unknown IMSI %s, discarding GSUP request " "of type 0x%02x\n", gsup_msg->imsi, gsup_msg->message_type); + gsup_client_mux_tx_error_reply(vlr->gcm, gsup_msg, GMM_CAUSE_IMSI_UNKNOWN); } else if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) { LOGP(DVLR, LOGL_NOTICE, "Unknown IMSI %s, discarding GSUP error " @@ -640,7 +626,7 @@ static int vlr_rx_gsup_unknown_imsi(struct vlr_instance *vlr, } static int vlr_rx_gsup_purge_no_subscr(struct vlr_instance *vlr, - struct osmo_gsup_message *gsup_msg) + const struct osmo_gsup_message *gsup_msg) { if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) { LOGGSUPP(LOGL_NOTICE, gsup_msg, @@ -682,7 +668,9 @@ int vlr_subscr_req_sai(struct vlr_subscr *vsub, /* Initiate Check_IMEI_VLR Procedure (23.018 Chapter 7.1.2.9) */ int vlr_subscr_tx_req_check_imei(const struct vlr_subscr *vsub) { - struct osmo_gsup_message gsup_msg = {0}; + struct osmo_gsup_message gsup_msg = { + .message_class = OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT, + }; uint8_t imei_enc[GSM23003_IMEI_NUM_DIGITS+2]; /* +2: IE header */ int len; @@ -698,17 +686,19 @@ int vlr_subscr_tx_req_check_imei(const struct vlr_subscr *vsub) /* Send CHECK_IMEI_REQUEST */ gsup_msg.message_type = OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST; OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi); - return vlr_tx_gsup_message(vsub->vlr, &gsup_msg); + return gsup_client_mux_tx(vsub->vlr->gcm, &gsup_msg); } /* Tell HLR that authentication failure occurred */ int vlr_subscr_tx_auth_fail_rep(const struct vlr_subscr *vsub) { - struct osmo_gsup_message gsup_msg = {0}; + struct osmo_gsup_message gsup_msg = { + .message_class = OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT, + }; gsup_msg.message_type = OSMO_GSUP_MSGT_AUTH_FAIL_REPORT; OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi); - return vlr_tx_gsup_message(vsub->vlr, &gsup_msg); + return gsup_client_mux_tx(vsub->vlr->gcm, &gsup_msg); } /* Update the subscriber with GSUP-received auth tuples */ @@ -771,21 +761,6 @@ static int vlr_subscr_handle_sai_res(struct vlr_subscr *vsub, return 0; } -static int decode_bcd_number_safe(char *output, int output_len, - const uint8_t *bcd_lv, int input_len, - int h_len) -{ - uint8_t len; - OSMO_ASSERT(output_len >= 1); - *output = '\0'; - if (input_len < 1) - return -EIO; - len = bcd_lv[0]; - if (input_len < len) - return -EIO; - return gsm48_decode_bcd_number(output, output_len, bcd_lv, h_len); -} - static void vlr_subscr_gsup_insert_data(struct vlr_subscr *vsub, const struct osmo_gsup_message *gsup_msg) { @@ -793,9 +768,9 @@ static void vlr_subscr_gsup_insert_data(struct vlr_subscr *vsub, int rc; if (gsup_msg->msisdn_enc) {//FIXME: vlr_subscr_set_msisdn()? - decode_bcd_number_safe(vsub->msisdn, sizeof(vsub->msisdn), - gsup_msg->msisdn_enc, - gsup_msg->msisdn_enc_len, 0); + gsm48_decode_bcd_number2(vsub->msisdn, sizeof(vsub->msisdn), + gsup_msg->msisdn_enc, + gsup_msg->msisdn_enc_len, 0); LOGP(DVLR, LOGL_DEBUG, "IMSI:%s has MSISDN:%s\n", vsub->imsi, vsub->msisdn); } @@ -1033,7 +1008,7 @@ static void gmm_cause_to_fsm_and_mm_cause(enum gsm48_gmm_cause gmm_cause, /* Handle LOCATION CANCEL request from HLR */ static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub, - struct osmo_gsup_message *gsup_msg) + const struct osmo_gsup_message *gsup_msg) { enum gsm48_reject_value gsm48_rej; enum osmo_fsm_term_cause fsm_cause; @@ -1081,87 +1056,59 @@ static int vlr_subscr_handle_check_imei(struct vlr_subscr *vsub, const struct os /* Incoming handler for GSUP from HLR. * Keep this function non-static for direct invocation by unit tests. */ -int vlr_gsupc_read_cb(struct osmo_gsup_client *gsupc, struct msgb *msg) +int vlr_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *gsup) { - struct vlr_instance *vlr = (struct vlr_instance *) gsupc->data; + struct vlr_instance *vlr = data; struct vlr_subscr *vsub; - struct osmo_gsup_message gsup; int rc; - DEBUGP(DVLR, "GSUP rx %u: %s\n", msgb_l2len(msg), - osmo_hexdump_nospc(msgb_l2(msg), msgb_l2len(msg))); - - rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup); - if (rc < 0) { - LOGP(DVLR, LOGL_ERROR, - "decoding GSUP message fails with error '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, -rc), -rc); - goto msgb_free_and_return; - } - - if (!gsup.imsi[0]) { - LOGP(DVLR, LOGL_ERROR, "Missing IMSI in GSUP message\n"); - if (OSMO_GSUP_IS_MSGT_REQUEST(gsup.message_type)) { - rc = vlr_tx_gsup_error_reply(vlr, &gsup, GMM_CAUSE_INV_MAND_INFO); - if (rc < 0) - LOGP(DVLR, LOGL_ERROR, "Failed to send error reply for IMSI %s\n", gsup.imsi); - } - rc = -GMM_CAUSE_INV_MAND_INFO; - goto msgb_free_and_return; - } - - vsub = vlr_subscr_find_by_imsi(vlr, gsup.imsi, __func__); + vsub = vlr_subscr_find_by_imsi(vlr, gsup->imsi, __func__); if (!vsub) { - switch (gsup.message_type) { + switch (gsup->message_type) { case OSMO_GSUP_MSGT_PURGE_MS_RESULT: case OSMO_GSUP_MSGT_PURGE_MS_ERROR: - rc = vlr_rx_gsup_purge_no_subscr(vlr, &gsup); - goto msgb_free_and_return; + return vlr_rx_gsup_purge_no_subscr(vlr, gsup); default: - rc = vlr_rx_gsup_unknown_imsi(vlr, &gsup); - goto msgb_free_and_return; + return vlr_rx_gsup_unknown_imsi(vlr, gsup); } } - switch (gsup.message_type) { + switch (gsup->message_type) { case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: - rc = vlr_subscr_handle_sai_res(vsub, &gsup); + rc = vlr_subscr_handle_sai_res(vsub, gsup); break; case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: - rc = vlr_subscr_handle_isd_req(vsub, &gsup); + rc = vlr_subscr_handle_isd_req(vsub, gsup); break; case OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST: - rc = vlr_subscr_handle_cancel_req(vsub, &gsup); + rc = vlr_subscr_handle_cancel_req(vsub, gsup); break; case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: - rc = vlr_subscr_handle_lu_res(vsub, &gsup); + rc = vlr_subscr_handle_lu_res(vsub, gsup); break; case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: - rc = vlr_subscr_handle_lu_err(vsub, &gsup); + rc = vlr_subscr_handle_lu_err(vsub, gsup); break; case OSMO_GSUP_MSGT_PURGE_MS_ERROR: case OSMO_GSUP_MSGT_PURGE_MS_RESULT: case OSMO_GSUP_MSGT_DELETE_DATA_REQUEST: LOGVSUBP(LOGL_ERROR, vsub, "Rx GSUP msg_type=%d not yet implemented\n", - gsup.message_type); + gsup->message_type); rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; break; case OSMO_GSUP_MSGT_CHECK_IMEI_ERROR: case OSMO_GSUP_MSGT_CHECK_IMEI_RESULT: - rc = vlr_subscr_handle_check_imei(vsub, &gsup); + rc = vlr_subscr_handle_check_imei(vsub, gsup); break; default: - /* Forward message towards MSC */ - rc = vlr->ops.forward_gsup_msg(vsub, &gsup); + LOGP(DLGSUP, LOGL_ERROR, "GSUP Message type not handled by VLR: %d\n", gsup->message_type); + rc = -EINVAL; break; } vlr_subscr_put(vsub, __func__); - -msgb_free_and_return: - msgb_free(msg); return rc; } @@ -1304,7 +1251,6 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops) OSMO_ASSERT(ops->tx_common_id); OSMO_ASSERT(ops->subscr_update); OSMO_ASSERT(ops->subscr_assoc); - OSMO_ASSERT(ops->forward_gsup_msg); INIT_LLIST_HEAD(&vlr->subscribers); INIT_LLIST_HEAD(&vlr->operations); @@ -1314,7 +1260,7 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops) vlr->cfg.assign_tmsi = true; /* osmo_auth_fsm.c */ - osmo_fsm_register(&vlr_auth_fsm); + OSMO_ASSERT(osmo_fsm_register(&vlr_auth_fsm) == 0); /* osmo_lu_fsm.c */ vlr_lu_fsm_init(); /* vlr_access_request_fsm.c */ @@ -1325,18 +1271,15 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops) return vlr; } -int vlr_start(struct ipaccess_unit *ipa_dev, struct vlr_instance *vlr, - const char *gsup_server_addr_str, uint16_t gsup_server_port) +int vlr_start(struct vlr_instance *vlr, struct gsup_client_mux *gcm) { OSMO_ASSERT(vlr); - vlr->gsup_client = osmo_gsup_client_create2(vlr, ipa_dev, - gsup_server_addr_str, - gsup_server_port, - &vlr_gsupc_read_cb, NULL); - if (!vlr->gsup_client) - return -ENOMEM; - vlr->gsup_client->data = vlr; + vlr->gcm = gcm; + gcm->rx_cb[OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT] = (struct gsup_client_mux_rx_cb){ + .func = vlr_gsup_rx, + .data = vlr, + }; osmo_timer_setup(&vlr->lu_expire_timer, vlr_subscr_expire_lu, vlr); osmo_timer_schedule(&vlr->lu_expire_timer, VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0); @@ -1383,14 +1326,13 @@ int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99, } /* MSC->VLR: Receive result of Ciphering Mode Command from MS */ -void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, struct vlr_ciph_result *res) +void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, enum vlr_ciph_result_cause result) { if (vsub->lu_fsm && vsub->lu_fsm->state == VLR_ULA_S_WAIT_CIPH) - osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_CIPH_RES, res); + osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_CIPH_RES, &result); if (vsub->proc_arq_fsm && vsub->proc_arq_fsm->state == PR_ARQ_S_WAIT_CIPH) - osmo_fsm_inst_dispatch(vsub->proc_arq_fsm, PR_ARQ_E_CIPH_RES, - res); + osmo_fsm_inst_dispatch(vsub->proc_arq_fsm, PR_ARQ_E_CIPH_RES, &result); } /* Internal evaluation of requested ciphering mode. diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c index fccb6d321..7684d02f0 100644 --- a/src/libvlr/vlr_access_req_fsm.c +++ b/src/libvlr/vlr_access_req_fsm.c @@ -60,6 +60,7 @@ struct proc_arq_priv { void *parent_event_data; enum vlr_parq_type type; + enum osmo_cm_service_type cm_service_type; enum gsm48_reject_value result; /*< 0 on success */ bool by_tmsi; char imsi[16]; @@ -121,7 +122,8 @@ static void proc_arq_vlr_dispatch_result(struct osmo_fsm_inst *fi, if (par->type == VLR_PR_ARQ_T_CM_SERV_REQ) { if (success && !par->implicitly_accepted_parq_by_ciphering_cmd) { - rc = par->vlr->ops.tx_cm_serv_acc(par->msc_conn_ref); + rc = par->vlr->ops.tx_cm_serv_acc(par->msc_conn_ref, + par->cm_service_type); if (rc) { LOGPFSML(fi, LOGL_ERROR, "Failed to send CM Service Accept\n"); @@ -130,6 +132,7 @@ static void proc_arq_vlr_dispatch_result(struct osmo_fsm_inst *fi, } if (!success) { rc = par->vlr->ops.tx_cm_serv_rej(par->msc_conn_ref, + par->cm_service_type, par->result); if (rc) LOGPFSML(fi, LOGL_ERROR, @@ -445,37 +448,28 @@ static void proc_arq_vlr_fn_w_auth(struct osmo_fsm_inst *fi, static void proc_arq_vlr_fn_w_ciph(struct osmo_fsm_inst *fi, uint32_t event, void *data) { - struct proc_arq_priv *par = fi->priv; - struct vlr_subscr *vsub = par->vsub; - struct vlr_ciph_result res = { .cause = VLR_CIPH_REJECT }; + enum vlr_ciph_result_cause result = VLR_CIPH_REJECT; OSMO_ASSERT(event == PR_ARQ_E_CIPH_RES); if (!data) LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: NULL\n"); else - res = *(struct vlr_ciph_result*)data; + result = *(enum vlr_ciph_result_cause*)data; - switch (res.cause) { + switch (result) { case VLR_CIPH_COMPL: - break; + _proc_arq_vlr_node2_post_ciph(fi); + return; case VLR_CIPH_REJECT: LOGPFSM(fi, "ciphering rejected\n"); proc_arq_fsm_done(fi, GSM48_REJECT_ILLEGAL_MS); return; default: - LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: %d\n", - res.cause); + LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: %d\n", result); proc_arq_fsm_done(fi, GSM48_REJECT_ILLEGAL_MS); return; } - - - if (*res.imeisv) { - LOGPFSM(fi, "got IMEISV: %s\n", res.imeisv); - vlr_subscr_set_imeisv(vsub, res.imeisv); - } - _proc_arq_vlr_node2_post_ciph(fi); } /* Update_Location_Child_VLR has completed */ @@ -637,7 +631,8 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent, uint32_t parent_event_failure, void *parent_event_data, struct vlr_instance *vlr, void *msc_conn_ref, - enum vlr_parq_type type, const uint8_t *mi_lv, + enum vlr_parq_type type, enum osmo_cm_service_type cm_service_type, + const uint8_t *mi_lv, const struct osmo_location_area_id *lai, bool authentication_required, bool ciphering_required, @@ -659,6 +654,7 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent, par->vlr = vlr; par->msc_conn_ref = msc_conn_ref; par->type = type; + par->cm_service_type = cm_service_type; par->lai = *lai; par->parent_event_success = parent_event_success; par->parent_event_failure = parent_event_failure; @@ -779,6 +775,6 @@ static struct osmo_fsm upd_loc_child_vlr_fsm = { void vlr_parq_fsm_init(void) { - //osmo_fsm_register(&upd_loc_child_vlr_fsm); - osmo_fsm_register(&proc_arq_vlr_fsm); + //OSMO_ASSERT(osmo_fsm_register(&upd_loc_child_vlr_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&proc_arq_vlr_fsm) == 0); } diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c index ecf96fad5..27196d844 100644 --- a/src/libvlr/vlr_lu_fsm.c +++ b/src/libvlr/vlr_lu_fsm.c @@ -1133,36 +1133,28 @@ static void lu_fsm_wait_auth(struct osmo_fsm_inst *fi, uint32_t event, static void lu_fsm_wait_ciph(struct osmo_fsm_inst *fi, uint32_t event, void *data) { - struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi); - struct vlr_subscr *vsub = lfp->vsub; - struct vlr_ciph_result res = { .cause = VLR_CIPH_REJECT }; + enum vlr_ciph_result_cause result = VLR_CIPH_REJECT; OSMO_ASSERT(event == VLR_ULA_E_CIPH_RES); if (!data) LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: NULL\n"); else - res = *(struct vlr_ciph_result*)data; + result = *(enum vlr_ciph_result_cause*)data; - switch (res.cause) { + switch (result) { case VLR_CIPH_COMPL: - break; + vlr_loc_upd_post_ciph(fi); + return; case VLR_CIPH_REJECT: LOGPFSM(fi, "ciphering rejected\n"); lu_fsm_failure(fi, GSM48_REJECT_INVALID_MANDANTORY_INF); return; default: - LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: %d\n", - res.cause); + LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: %d\n", result); lu_fsm_failure(fi, GSM48_REJECT_INVALID_MANDANTORY_INF); return; } - - if (*res.imeisv) { - LOGPFSM(fi, "got IMEISV: %s\n", res.imeisv); - vlr_subscr_set_imeisv(vsub, res.imeisv); - } - vlr_loc_upd_post_ciph(fi); } static void lu_fsm_wait_imsi(struct osmo_fsm_inst *fi, uint32_t event, @@ -1516,8 +1508,8 @@ void vlr_loc_update_cancel(struct osmo_fsm_inst *fi, void vlr_lu_fsm_init(void) { - osmo_fsm_register(&vlr_lu_fsm); - osmo_fsm_register(&upd_hlr_vlr_fsm); - osmo_fsm_register(&sub_pres_vlr_fsm); - osmo_fsm_register(&lu_compl_vlr_fsm); + OSMO_ASSERT(osmo_fsm_register(&vlr_lu_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&upd_hlr_vlr_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&sub_pres_vlr_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&lu_compl_vlr_fsm) == 0); } diff --git a/src/libvlr/vlr_sgs.c b/src/libvlr/vlr_sgs.c index 3ee7799a8..452de2cca 100644 --- a/src/libvlr/vlr_sgs.c +++ b/src/libvlr/vlr_sgs.c @@ -18,6 +18,8 @@ * */ +#include <errno.h> + #include <osmocom/core/utils.h> #include <osmocom/core/fsm.h> #include <osmocom/msc/debug.h> @@ -247,7 +249,7 @@ void vlr_sgs_pag_rej(struct vlr_instance *vlr, const char *imsi, enum sgsap_sgs_ osmo_fsm_inst_dispatch(vsub->sgs_fsm, SGS_UE_E_RX_PAGING_FAILURE, &cause); /* Balance ref count increment from vlr_sgs_pag() */ - vlr_subscr_put(vsub, VSUB_USE_SGS_PAGING); + vlr_subscr_put(vsub, VSUB_USE_SGS_PAGING_REQ); vlr_subscr_put(vsub, __func__); } @@ -265,7 +267,7 @@ void vlr_sgs_pag_ack(struct vlr_instance *vlr, const char *imsi) /* Stop Ts5 and and consider the paging as successful */ osmo_timer_del(&vsub->sgs.Ts5); /* Balance ref count increment from vlr_sgs_pag() */ - vlr_subscr_put(vsub, VSUB_USE_SGS_PAGING); + vlr_subscr_put(vsub, VSUB_USE_SGS_PAGING_REQ); vlr_subscr_put(vsub, __func__); } @@ -306,7 +308,7 @@ static void Ts5_timeout_cb(void *arg) vlr_subscr_msisdn_or_name(vsub), vlr_sgs_state_timer_name(SGS_STATE_TS5)); /* Balance ref count increment from vlr_sgs_pag() */ - vlr_subscr_put(vsub, VSUB_USE_SGS_PAGING); + vlr_subscr_put(vsub, VSUB_USE_SGS_PAGING_REQ); return; } @@ -346,7 +348,7 @@ void vlr_sgs_pag(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind) /* Ensure that the reference count is increased by one while the * paging is happening. We will balance this again in vlr_sgs_pag_rej() * and vlr_sgs_pag_ack(); */ - vlr_subscr_get(vsub, VSUB_USE_SGS_PAGING); + vlr_subscr_get(vsub, VSUB_USE_SGS_PAGING_REQ); } /*! Check if the SGs interface is currently paging diff --git a/src/libvlr/vlr_sgs_fsm.c b/src/libvlr/vlr_sgs_fsm.c index a25d41c3b..13639ca3c 100644 --- a/src/libvlr/vlr_sgs_fsm.c +++ b/src/libvlr/vlr_sgs_fsm.c @@ -24,6 +24,7 @@ #include <osmocom/msc/debug.h> #include <osmocom/msc/vlr.h> #include <osmocom/msc/vlr_sgs.h> +#include <osmocom/msc/paging.h> #include "vlr_sgs_fsm.h" #include "vlr_core.h" @@ -77,7 +78,8 @@ static void to_null(struct osmo_fsm_inst *fi) vsub->tmsi_new = GSM_RESERVED_TMSI; /* Make sure any ongoing paging is aborted. */ - vsub->cs.is_paging = false; + if (vsub->cs.is_paging) + paging_expired(vsub); /* Ensure that Ts5 (pending paging via SGs) is deleted */ if (vlr_sgs_pag_pend(vsub)) @@ -344,7 +346,7 @@ static struct osmo_fsm sgs_ue_fsm = { void vlr_sgs_fsm_init(void) { if (osmo_fsm_find_by_name(sgs_ue_fsm.name) != &sgs_ue_fsm) - osmo_fsm_register(&sgs_ue_fsm); + OSMO_ASSERT(osmo_fsm_register(&sgs_ue_fsm) == 0); } /*! Crate SGs FSM in struct vlr_subscr. |