diff options
Diffstat (limited to 'src/nacc_fsm.c')
-rw-r--r-- | src/nacc_fsm.c | 120 |
1 files changed, 79 insertions, 41 deletions
diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c index 738b2c58..ca226acb 100644 --- a/src/nacc_fsm.c +++ b/src/nacc_fsm.c @@ -361,28 +361,13 @@ static void st_initial(struct osmo_fsm_inst *fi, uint32_t event, void *data) } } -static void st_wait_resolve_rac_ci_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +static int send_neigh_addr_req_ctrl_iface(struct nacc_fsm_ctx *ctx) { - struct nacc_fsm_ctx *ctx = (struct nacc_fsm_ctx *)fi->priv; struct gprs_rlcmac_bts *bts = ctx->ms->bts; struct gprs_pcu *pcu = bts->pcu; - const struct osmo_cell_global_id_ps *cgi_ps; struct ctrl_cmd *cmd = NULL; int rc; - /* First try to find the value in the cache */ - cgi_ps = neigh_cache_lookup_value(pcu->neigh_cache, &ctx->neigh_key); - if (cgi_ps) { - ctx->cgi_ps = *cgi_ps; - nacc_fsm_state_chg(fi, NACC_ST_WAIT_REQUEST_SI); - return; - } - - /* CGI-PS not in cache, resolve it using BSC Neighbor Resolution CTRL interface */ - - LOGPFSML(fi, LOGL_DEBUG, "No CGI-PS found in cache, resolving " NEIGH_CACHE_ENTRY_KEY_FMT "...\n", - NEIGH_CACHE_ENTRY_KEY_ARGS(&ctx->neigh_key)); - /* We may have changed to this state previously (eg: we are handling * another Pkt cell Change Notify with different target). Avoid * re-creating the socket in that case. */ @@ -392,7 +377,7 @@ static void st_wait_resolve_rac_ci_on_enter(struct osmo_fsm_inst *fi, uint32_t p NULL, 0, pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port, OSMO_SOCK_F_CONNECT); if (rc < 0) { - LOGPFSML(fi, LOGL_ERROR, + LOGPFSML(ctx->fi, LOGL_ERROR, "Failed to establish CTRL (neighbor resolution) connection to BSC r=%s:%u\n\n", pcu->vty.neigh_ctrl_addr, pcu->vty.neigh_ctrl_port); goto err_term; @@ -401,7 +386,7 @@ static void st_wait_resolve_rac_ci_on_enter(struct osmo_fsm_inst *fi, uint32_t p cmd = ctrl_cmd_create(ctx, CTRL_TYPE_GET); if (!cmd) { - LOGPFSML(fi, LOGL_ERROR, "CTRL msg creation failed\n"); + LOGPFSML(ctx->fi, LOGL_ERROR, "CTRL msg creation failed\n"); goto err_term; } @@ -412,16 +397,52 @@ static void st_wait_resolve_rac_ci_on_enter(struct osmo_fsm_inst *fi, uint32_t p ctx->neigh_key.tgt_arfcn, ctx->neigh_key.tgt_bsic); rc = ctrl_cmd_send(&ctx->neigh_ctrl_conn->write_queue, cmd); if (rc) { - LOGPFSML(fi, LOGL_ERROR, "CTRL msg sent failed: %d\n", rc); + LOGPFSML(ctx->fi, LOGL_ERROR, "CTRL msg sent failed: %d\n", rc); goto err_term; } talloc_free(cmd); - return; + return 0; err_term: talloc_free(cmd); - nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE); + return -1; +} + +static int send_neigh_addr_req(struct nacc_fsm_ctx *ctx) +{ + struct gprs_rlcmac_bts *bts = ctx->ms->bts; + + /* If PCU was configured to use the old CTRL interface, use it: */ + if (ctx->neigh_ctrl_conn) + return send_neigh_addr_req_ctrl_iface(ctx); + + /* Otherwise, by default the new PCUIF over IPA Abis multiplex proto should be used: */ + return pcu_tx_neigh_addr_res_req(bts, &ctx->neigh_key); +} + +static void st_wait_resolve_rac_ci_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct nacc_fsm_ctx *ctx = (struct nacc_fsm_ctx *)fi->priv; + struct gprs_rlcmac_bts *bts = ctx->ms->bts; + struct gprs_pcu *pcu = bts->pcu; + const struct osmo_cell_global_id_ps *cgi_ps; + + /* First try to find the value in the cache */ + cgi_ps = neigh_cache_lookup_value(pcu->neigh_cache, &ctx->neigh_key); + if (cgi_ps) { + ctx->cgi_ps = *cgi_ps; + nacc_fsm_state_chg(fi, NACC_ST_WAIT_REQUEST_SI); + return; + } + + /* CGI-PS not in cache, resolve it using BSC Neighbor Resolution CTRL interface */ + + LOGPFSML(fi, LOGL_DEBUG, "No CGI-PS found in cache, resolving " NEIGH_CACHE_ENTRY_KEY_FMT "...\n", + NEIGH_CACHE_ENTRY_KEY_ARGS(&ctx->neigh_key)); + + if (send_neigh_addr_req(ctx) < 0) + nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE); } static void st_wait_resolve_rac_ci(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -435,8 +456,13 @@ static void st_wait_resolve_rac_ci(struct osmo_fsm_inst *fi, uint32_t event, voi handle_retrans_pkt_cell_chg_notif(ctx, notif); break; case NACC_EV_RX_RAC_CI: - /* Assumption: ctx->cgi_ps has been filled by caller of the event */ - nacc_fsm_state_chg(fi, NACC_ST_WAIT_REQUEST_SI); + /* data is NULL upon failure */ + if (data) { + ctx->cgi_ps = *(struct osmo_cell_global_id_ps *)data; + nacc_fsm_state_chg(fi, NACC_ST_WAIT_REQUEST_SI); + } else { + nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE); + } break; default: OSMO_ASSERT(0); @@ -740,12 +766,13 @@ void nacc_fsm_ctrl_reply_cb(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd, void struct nacc_fsm_ctx *ctx = (struct nacc_fsm_ctx *)data; char *tmp = NULL, *tok, *saveptr; unsigned int exp_id; + struct osmo_cell_global_id_ps cgi_ps; LOGPFSML(ctx->fi, LOGL_NOTICE, "Received CTRL message: type=%d %s %s: %s\n", cmd->type, cmd->variable, cmd->id, osmo_escape_str(cmd->reply, -1)); if (cmd->type != CTRL_TYPE_GET_REPLY || !cmd->reply) { - nacc_fsm_state_chg(ctx->fi, NACC_ST_TX_CELL_CHG_CONTINUE); + osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL); return; } @@ -771,33 +798,33 @@ void nacc_fsm_ctrl_reply_cb(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd, void if (!(tok = strtok_r(tmp, "-", &saveptr))) goto free_ret; - ctx->cgi_ps.rai.lac.plmn.mcc = atoi(tok); + cgi_ps.rai.lac.plmn.mcc = atoi(tok); if (!(tok = strtok_r(NULL, "-", &saveptr))) goto free_ret; - ctx->cgi_ps.rai.lac.plmn.mnc = atoi(tok); + cgi_ps.rai.lac.plmn.mnc = atoi(tok); if (!(tok = strtok_r(NULL, "-", &saveptr))) goto free_ret; - ctx->cgi_ps.rai.lac.lac = atoi(tok); + cgi_ps.rai.lac.lac = atoi(tok); if (!(tok = strtok_r(NULL, "-", &saveptr))) goto free_ret; - ctx->cgi_ps.rai.rac = atoi(tok); + cgi_ps.rai.rac = atoi(tok); if (!(tok = strtok_r(NULL, "\0", &saveptr))) goto free_ret; - ctx->cgi_ps.cell_identity = atoi(tok); + cgi_ps.cell_identity = atoi(tok); /* Cache the cgi_ps so we can avoid requesting again same resolution for a while */ - neigh_cache_add(ctx->ms->bts->pcu->neigh_cache, &ctx->neigh_key, &ctx->cgi_ps); + neigh_cache_add(ctx->ms->bts->pcu->neigh_cache, &ctx->neigh_key, &cgi_ps); - osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL); + osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, &cgi_ps); return; free_ret: talloc_free(tmp); - nacc_fsm_state_chg(ctx->fi, NACC_ST_TX_CELL_CHG_CONTINUE); + osmo_fsm_inst_dispatch(ctx->fi, NACC_EV_RX_RAC_CI, NULL); return; } @@ -834,18 +861,29 @@ struct nacc_fsm_ctx *nacc_fsm_alloc(struct GprsMs* ms) if (!ctx->fi) goto free_ret; - ctx->neigh_ctrl = ctrl_handle_alloc(ctx, ctx, NULL); - ctx->neigh_ctrl->reply_cb = nacc_fsm_ctrl_reply_cb; - ctx->neigh_ctrl_conn = osmo_ctrl_conn_alloc(ctx, ctx->neigh_ctrl); - if (!ctx->neigh_ctrl_conn) - goto free_ret; - /* Older versions of osmo_ctrl_conn_alloc didn't properly initialize fd to -1, - * so make sure to do it here otherwise fd may be valid fd 0 and cause trouble */ - ctx->neigh_ctrl_conn->write_queue.bfd.fd = -1; - llist_add(&ctx->neigh_ctrl_conn->list_entry, &ctx->neigh_ctrl->ccon_list); + /* If CTRL ip present, use the old CTRL interface for neighbor resolution */ + if (ms->bts->pcu->vty.neigh_ctrl_addr) { + ctx->neigh_ctrl = ctrl_handle_alloc(ctx, ctx, NULL); + ctx->neigh_ctrl->reply_cb = nacc_fsm_ctrl_reply_cb; + ctx->neigh_ctrl_conn = osmo_ctrl_conn_alloc(ctx, ctx->neigh_ctrl); + if (!ctx->neigh_ctrl_conn) + goto free_ret; + /* Older versions of osmo_ctrl_conn_alloc didn't properly initialize fd to -1, + * so make sure to do it here otherwise fd may be valid fd 0 and cause trouble */ + ctx->neigh_ctrl_conn->write_queue.bfd.fd = -1; + llist_add(&ctx->neigh_ctrl_conn->list_entry, &ctx->neigh_ctrl->ccon_list); + } return ctx; free_ret: talloc_free(ctx); return NULL; } + +bool nacc_fsm_is_waiting_addr_resolution(const struct nacc_fsm_ctx *ctx, + const struct neigh_cache_entry_key *neigh_key) +{ + if (ctx->fi->state != NACC_ST_WAIT_RESOLVE_RAC_CI) + return false; + return neigh_cache_entry_key_eq(&ctx->neigh_key, neigh_key); +} |