diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 8adefea..ed18ca4 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -188,6 +188,7 @@ void ue_context_free(struct ue_context *ue); struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_link *link, int new_fd); void hnb_context_release(struct hnb_context *ctx); +void hnb_context_release_ue_state(struct hnb_context *ctx); void hnbgw_vty_init(struct hnb_gw *gw, void *tall_ctx); int hnbgw_vty_go_parent(struct vty *vty); diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index 5dba1e3..3a6879e 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -395,15 +395,10 @@ const char *hnb_context_name(struct hnb_context *ctx) return umts_cell_id_name(&ctx->id); } -void hnb_context_release(struct hnb_context *ctx) +void hnb_context_release_ue_state(struct hnb_context *ctx) { struct hnbgw_context_map *map, *map2; - LOGHNB(ctx, DMAIN, LOGL_INFO, "Releasing HNB context\n"); - - /* remove from the list of HNB contexts */ - llist_del(&ctx->list); - /* deactivate all context maps */ llist_for_each_entry_safe(map, map2, &ctx->map_list, hnb_list) { /* remove it from list, as HNB context will soon be @@ -414,6 +409,16 @@ void hnb_context_release(struct hnb_context *ctx) context_map_deactivate(map); } ue_context_free_by_hnb(ctx->gw, ctx); +} + +void hnb_context_release(struct hnb_context *ctx) +{ + LOGHNB(ctx, DMAIN, LOGL_INFO, "Releasing HNB context\n"); + + /* remove from the list of HNB contexts */ + llist_del(&ctx->list); + + hnb_context_release_ue_state(ctx); if (ctx->conn) { /* we own a conn, we must free it: */ LOGHNB(ctx, DMAIN, LOGL_INFO, "Closing HNB SCTP connection %s\n", diff --git a/src/osmo-hnbgw/hnbgw_hnbap.c b/src/osmo-hnbgw/hnbgw_hnbap.c index 4aefe2b..19ebd38 100644 --- a/src/osmo-hnbgw/hnbgw_hnbap.c +++ b/src/osmo-hnbgw/hnbgw_hnbap.c @@ -467,7 +467,15 @@ static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, ANY_t *in) LOGHNB(ctx, DHNBAP, LOGL_DEBUG, "HNB-REGISTER-REQ %s MCC=%u,MNC=%u,LAC=%u,RAC=%u,SAC=%u,CID=%u from %s%s\n", ctx->identity_info, ctx->id.mcc, ctx->id.mnc, ctx->id.lac, ctx->id.rac, ctx->id.sac, ctx->id.cid, - name, ctx->hnb_registered ? " (duplicated)" : ""); + name, ctx->hnb_registered ? " (re-connecting)" : ""); + + if (ctx->hnb_registered) { + /* The HNB is already registered, and we are seeing a new HNB Register Request. The HNB has restarted + * without us noticing. Clearly, the HNB does not expect any UE state to be active here, so discard any + * UE contexts and SCCP connections associated with this HNB. */ + LOGHNB(ctx, DHNBAP, LOGL_NOTICE, "HNB reconnecting, discarding all previous UE state\n"); + hnb_context_release_ue_state(ctx); + } ctx->hnb_registered = true;