diff options
Diffstat (limited to 'src/osmo-bts-octphy/l1_oml.c')
-rw-r--r-- | src/osmo-bts-octphy/l1_oml.c | 176 |
1 files changed, 94 insertions, 82 deletions
diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index d44f7211..bb519a04 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -28,6 +28,7 @@ #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h> +#include <osmocom/core/fsm.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/logging.h> @@ -38,6 +39,7 @@ #include <osmo-bts/bts.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/l1sap.h> +#include <osmo-bts/nm_common_fsm.h> #include "l1_if.h" #include "l1_oml.h" @@ -54,7 +56,7 @@ bool no_fw_check = 0; -#define LOGPTRX(byTrxId, level, fmt, args...) \ +#define LOGPOCTTRX(byTrxId, level, fmt, args...) \ LOGP(DL1C, level, "(byTrxId %u) " fmt, byTrxId, ## args) /* Map OSMOCOM logical channel type to OctPHY Logical channel type */ @@ -185,26 +187,31 @@ extern uint8_t rach_detected_Other_g; static int opstart_compl(struct gsm_abis_mo *mo) { + struct gsm_bts_trx *trx = gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr); /* TODO: Send NACK in case of error! */ - /* Set to Operational State: Enabled */ - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); - - /* hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */ - if (mo->obj_class == NM_OC_CHANNEL && mo->obj_inst.trx_nr == 0 && - mo->obj_inst.ts_nr == 7) { - struct gsm_lchan *cbch = gsm_bts_get_cbch(mo->bts); - mo->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind = - LCHAN_REL_ACT_OML; - lchan_activate(&mo->bts->c0->ts[0].lchan[CCCH_LCHAN]); - if (cbch) { - cbch->rel_act_kind = LCHAN_REL_ACT_OML; - lchan_activate(cbch); + switch (mo->obj_class) { + case NM_OC_RADIO_CARRIER: + return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL); + case NM_OC_CHANNEL: + /* ugly hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */ + if (mo->obj_inst.trx_nr == 0 && + mo->obj_inst.ts_nr == 0) { + struct gsm_lchan *cbch = gsm_bts_get_cbch(mo->bts); + DEBUGP(DL1C, "====> trying to activate lchans of BCCH\n"); + mo->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind = + LCHAN_REL_ACT_OML; + lchan_activate(&mo->bts->c0->ts[0].lchan[CCCH_LCHAN]); + if (cbch) { + cbch->rel_act_kind = LCHAN_REL_ACT_OML; + lchan_activate(cbch); + } } + return osmo_fsm_inst_dispatch(trx->ts[mo->obj_inst.ts_nr].mo.fi, + NM_EV_OPSTART_ACK, NULL); + default: + OSMO_ASSERT(0); } - - /* Send OPSTART ack */ - return oml_mo_opstart_ack(mo); } static @@ -243,7 +250,7 @@ static void clear_amr_params(tOCTVC1_GSM_LOGICAL_CHANNEL_CONFIG * p_Config) p_Config->abyRate[i] = cOCTVC1_GSM_AMR_CODEC_MODE_ENUM_UNSET; } -static void lchan2lch_par(struct gsm_lchan *lchan, +static int lchan2lch_par(struct gsm_lchan *lchan, tOCTVC1_GSM_LOGICAL_CHANNEL_CONFIG * p_Config) { struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; @@ -252,7 +259,7 @@ static void lchan2lch_par(struct gsm_lchan *lchan, int j; LOGP(DL1C, LOGL_INFO, "%s: %s tch_mode=0x%02x\n", - gsm_lchan_name(lchan), __FUNCTION__, lchan->tch_mode); + gsm_lchan_name(lchan), __func__, lchan->tch_mode); switch (lchan->tch_mode) { case GSM48_CMODE_SIGN: @@ -341,11 +348,13 @@ static void lchan2lch_par(struct gsm_lchan *lchan, case GSM48_CMODE_DATA_12k0: case GSM48_CMODE_DATA_6k0: case GSM48_CMODE_DATA_3k6: - LOGP(DL1C, LOGL_ERROR, "%s: CSD not supported!\n", - gsm_lchan_name(lchan)); - break; - + default: + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Channel mode %s is not supported!\n", + gsm48_chan_mode_name(lchan->tch_mode)); + return -ENOTSUP; } + + return 0; } /*********************************************************************** @@ -381,7 +390,7 @@ static int lchan_act_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *d mOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_RSP_SWAP(ar); trx = trx_by_l1h(fl1, ar->TrxId.byTrxId); if (!trx) { - LOGPTRX(ar->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during lchan activation\n"); + LOGPOCTTRX(ar->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during lchan activation\n"); return -EINVAL; } @@ -437,6 +446,7 @@ static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_CMD *lac; + int rc; lac = (tOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_CMD *) msgb_put(msg, sizeof(*lac)); @@ -449,10 +459,12 @@ static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) lac->LchId.bySAPI = cmd->sapi; lac->LchId.byDirection = cmd->dir; - lac->Config.byTimingAdvance = lchan->rqd_ta; + lac->Config.byTimingAdvance = lchan->ta_ctrl.current; lac->Config.byBSIC = lchan->ts->trx->bts->bsic; - - lchan2lch_par(lchan, &lac->Config); + if ((rc = lchan2lch_par(lchan, &lac->Config)) != 0) { + talloc_free(msg); + return rc; + } mOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_CMD_SWAP(lac); @@ -496,7 +508,7 @@ static int set_ciph_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *da trx = trx_by_l1h(fl1, pcr->TrxId.byTrxId); if (!trx) { - LOGPTRX(pcr->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during cipher mode activation\n"); + LOGPOCTTRX(pcr->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during cipher mode activation\n"); return -EINVAL; } @@ -506,7 +518,7 @@ static int set_ciph_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *da * sub-channel, only th request contains this information :( */ lchan = &ts->lchan[(unsigned long) data]; - /* TODO: This state machine should be shared accross BTS models? */ + /* TODO: This state machine should be shared across BTS models? */ switch (lchan->ciph_state) { case LCHAN_CIPH_RX_REQ: lchan->ciph_state = LCHAN_CIPH_RX_CONF; @@ -700,7 +712,7 @@ static int lchan_deact_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void mOCTVC1_GSM_MSG_TRX_DEACTIVATE_LOGICAL_CHANNEL_RSP_SWAP(ldr); trx = trx_by_l1h(fl1, ldr->TrxId.byTrxId); if (!trx) { - LOGPTRX(ldr->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during lchan deactivation\n"); + LOGPOCTTRX(ldr->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during lchan deactivation\n"); return -EINVAL; } @@ -1095,9 +1107,6 @@ int lchan_activate(struct gsm_lchan *lchan) } enqueue_sapi_act_cmd(lchan, sapi, dir); } - - lchan_init_lapdm(lchan); - return 0; } @@ -1107,13 +1116,6 @@ int l1if_rsl_chan_act(struct gsm_lchan *lchan) return 0; } -#define talloc_replace(dst, ctx, src) \ - do { \ - if (dst) \ - talloc_free(dst); \ - dst = talloc_strdup(ctx, (const char *) src); \ - } while (0) - static int app_info_sys_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, void *data) { tOCTVC1_MAIN_MSG_APPLICATION_INFO_SYSTEM_RSP *aisr = @@ -1133,8 +1135,10 @@ static int app_info_sys_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, voi LOGP(DL1C, LOGL_INFO, "Note: compiled without multi-trx support.\n"); #endif - talloc_replace(fl1h->info.system.platform, fl1h, aisr->szPlatform); - talloc_replace(fl1h->info.system.version, fl1h, aisr->szVersion); + osmo_talloc_replace_string(fl1h, &fl1h->info.system.platform, + (const char *) aisr->szPlatform); + osmo_talloc_replace_string(fl1h, &fl1h->info.system.version, + (const char *) aisr->szVersion); msgb_free(resp); @@ -1169,7 +1173,7 @@ static int app_info_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, tOCTVC1_MAIN_MSG_APPLICATION_INFO_RSP *air = (tOCTVC1_MAIN_MSG_APPLICATION_INFO_RSP *) resp->l2h; - snprintf(ver_hdr, sizeof(ver_hdr), "%02i.%02i.%02i-B%i", + snprintf(ver_hdr, sizeof(ver_hdr), "%02d.%02d.%02d-B%d", cOCTVC1_MAIN_VERSION_MAJOR, cOCTVC1_MAIN_VERSION_MINOR, cOCTVC1_MAIN_VERSION_MAINTENANCE, cOCTVC1_MAIN_VERSION_BUILD); @@ -1191,16 +1195,19 @@ static int app_info_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, if (!no_fw_check) { LOGP(DL1C, LOGL_ERROR, - "use option -I to override the check (not recommened)\n"); + "use option -I to override the check (not recommended)\n"); LOGP(DL1C, LOGL_ERROR, "exiting...\n"); exit(1); } } - talloc_replace(fl1h->info.app.name, fl1h, air->szName); - talloc_replace(fl1h->info.app.description, fl1h, air->szDescription); - talloc_replace(fl1h->info.app.version, fl1h, air->szVersion); + osmo_talloc_replace_string(fl1h, &fl1h->info.app.name, + (const char *) air->szName); + osmo_talloc_replace_string(fl1h, &fl1h->info.app.description, + (const char *) air->szDescription); + osmo_talloc_replace_string(fl1h, &fl1h->info.app.version, + (const char *) air->szVersion); OSMO_ASSERT(strlen(ver_hdr) < sizeof(pinst->version)); osmo_strlcpy(pinst->version, ver_hdr, strlen(ver_hdr)); @@ -1283,7 +1290,7 @@ static int trx_open_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, void *d mOCTVC1_GSM_MSG_TRX_OPEN_RSP_SWAP(or); trx = trx_by_l1h(fl1h, or->TrxId.byTrxId); if (!trx) { - LOGPTRX(or->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during TRX opening procedure -- abort\n"); + LOGPOCTTRX(or->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during TRX opening procedure -- abort\n"); exit(1); } @@ -1340,13 +1347,13 @@ int l1if_trx_open(struct gsm_bts_trx *trx) } oc->Config.usBcchArfcn = trx->bts->c0->arfcn; #endif - oc->Config.usTsc = trx->bts->bsic & 0x7; + oc->Config.usTsc = BTS_TSC(trx->bts); oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; /* FIXME: compute this based on nominal transmit power, etc. */ if (plink->u.octphy.tx_atten_flag) { oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; } else { - /* Take the Tx Attn received in set radio attribures + /* Take the Tx Attn received in set radio attributes * x4 is for the value in db */ oc->RfConfig.ulTxAttndB = (trx->max_power_red) << 2; } @@ -1426,7 +1433,7 @@ static int l1if_over_sample_16x_modif(struct gsm_bts_trx *trx) } #endif -uint32_t trx_get_hlayer1(struct gsm_bts_trx * trx) +uint32_t trx_get_hlayer1(const struct gsm_bts_trx *trx) { return 0; } @@ -1437,8 +1444,9 @@ static int trx_init(struct gsm_bts_trx *trx) ARRAY_SIZE(trx_rqd_attr))) { /* HACK: spec says we need to decline, but openbsc * doesn't deal with this very well */ - return oml_mo_opstart_ack(&trx->mo); - /* return oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM); */ + return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL); + //return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK, + // (void*)(intptr_t)NM_NACK_CANT_PERFORM); } l1if_check_app_version(trx); @@ -1470,7 +1478,7 @@ static int pchan_act_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *d mOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_RSP_SWAP(ar); trx = trx_by_l1h(fl1, ar->TrxId.byTrxId); if (!trx) { - LOGPTRX(ar->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during physical channel activation -- abort\n"); + LOGPOCTTRX(ar->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during physical channel activation -- abort\n"); exit(1); } @@ -1507,8 +1515,7 @@ static int ts_connect_as(struct gsm_bts_trx_ts *ts, struct phy_instance *pinst = trx_phy_instance(ts->trx); struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *oc = - (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *) oc; + tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *oc; oc = (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD*) msgb_put(msg, sizeof(*oc)); @@ -1553,7 +1560,7 @@ static int ts_disconnect_cb(struct octphy_hdl *fl1, struct msgb *resp, trx = trx_by_l1h(fl1, ar->TrxId.byTrxId); if (!trx) { - LOGPTRX(ar->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during ts disconnection\n"); + LOGPOCTTRX(ar->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id during ts disconnection\n"); return -EINVAL; } @@ -1581,7 +1588,7 @@ static int ts_connect_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) mOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_RSP_SWAP(ar); trx = trx_by_l1h(fl1, ar->TrxId.byTrxId); if (!trx) { - LOGPTRX(ar->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id while connecting ts\n"); + LOGPOCTTRX(ar->TrxId.byTrxId, LOGL_ERROR, "response with unexpected physical transceiver-id while connecting ts\n"); return -EINVAL; } @@ -1678,7 +1685,7 @@ int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, bts_model_trx_deact_rf(trx); /* Close TRX */ - rc = bts_model_trx_close(trx); + rc = trx_close(trx); if (rc != 0) { LOGP(DL1C, LOGL_ERROR, "Cannot close TRX %d, it is already closed.\n", @@ -1716,10 +1723,11 @@ int bts_model_trx_deact_rf(struct gsm_bts_trx *trx) return l1if_activate_rf(trx, 0); } -int bts_model_trx_close(struct gsm_bts_trx *trx) +void bts_model_trx_close(struct gsm_bts_trx *trx) { /* FIXME: close only one TRX */ - return trx_close(trx); + int rc = trx_close(trx); + bts_model_trx_close_cb(trx, rc); } @@ -1733,41 +1741,46 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, } /* callback from OML */ -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) { - if (kind == NM_OC_RADIO_CARRIER) { - struct gsm_bts_trx *trx = obj; - /*struct octphy_hdl *fl1h = trx_octphy_hdl(trx); */ + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_bts_trx *trx; - power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0); + switch (foh->msg_type) { + case NM_MT_SET_RADIO_ATTR: + trx = obj; + power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0, NULL); + break; } - return oml_fom_ack_nack(msg, 0); + + return 0; } /* callback from OML */ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) { - int rc = -1; + struct gsm_bts_trx* trx; struct gsm_bts_trx_ts *ts; + int rc; switch (mo->obj_class) { - case NM_OC_RADIO_CARRIER: - rc = trx_init(obj); - break; - case NM_OC_CHANNEL: - ts = (struct gsm_bts_trx_ts*) obj; - rc = ts_connect_as(ts, ts->pchan, pchan_act_compl_cb, NULL); - break; - case NM_OC_BTS: case NM_OC_SITE_MANAGER: + case NM_OC_BTS: case NM_OC_BASEB_TRANSC: case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, -1); - rc = oml_mo_opstart_ack(mo); + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); + break; + case NM_OC_RADIO_CARRIER: + trx = (struct gsm_bts_trx*) obj; + rc = trx_init(trx); + break; + case NM_OC_CHANNEL: + ts = (struct gsm_bts_trx_ts*) obj; + rc = ts_connect_as(ts, ts->pchan, pchan_act_compl_cb, NULL); break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); @@ -1786,8 +1799,7 @@ int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts) struct phy_instance *pinst = trx_phy_instance(ts->trx); struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *oc = - (tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *) oc; + tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *oc; oc = (tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *) msgb_put(msg, sizeof(*oc)); @@ -1810,7 +1822,7 @@ void bts_model_ts_connect(struct gsm_bts_trx_ts *ts, { int rc; if (as_pchan == GSM_PCHAN_TCH_F_PDCH - || as_pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) { + || as_pchan == GSM_PCHAN_OSMO_DYN) { LOGP(DL1C, LOGL_ERROR, "%s Requested TS connect as %s," " expected a specific pchan instead\n", |