diff options
author | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2023-06-09 21:58:48 +0700 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-07-24 14:00:41 +0200 |
commit | 3f0f1a421497657589268e5f4a37811232b05474 (patch) | |
tree | ce27b13a1caec6849ae2be28634bdc6c63c17d05 | |
parent | 19450eb435e07649b1f48201526ffda17f1e0219 (diff) |
layer23: modem: implement GPRS-RR FSM
Change-Id: I8a7d85df7b07d85ac86e0b7e340f6bbacc65e1bc
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/ms.h | 1 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/modem/grr.h | 23 | ||||
-rw-r--r-- | src/host/layer23/src/modem/app_modem.c | 41 | ||||
-rw-r--r-- | src/host/layer23/src/modem/grr.c | 338 | ||||
-rw-r--r-- | src/host/layer23/src/modem/rlcmac.c | 60 | ||||
-rw-r--r-- | src/host/layer23/src/modem/vty.c | 11 |
6 files changed, 341 insertions, 133 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/ms.h b/src/host/layer23/include/osmocom/bb/common/ms.h index bfbf879a..8d1ffc4e 100644 --- a/src/host/layer23/include/osmocom/bb/common/ms.h +++ b/src/host/layer23/include/osmocom/bb/common/ms.h @@ -100,6 +100,7 @@ struct osmocom_ms { /* GPRS */ struct gprs_settings gprs; struct osmobb_ms_gmm_layer gmmlayer; + struct osmo_fsm_inst *grr_fi; /* Audio I/O */ struct gapk_io_state *gapk_io; diff --git a/src/host/layer23/include/osmocom/bb/modem/grr.h b/src/host/layer23/include/osmocom/bb/modem/grr.h index 1f2b08c0..3472a103 100644 --- a/src/host/layer23/include/osmocom/bb/modem/grr.h +++ b/src/host/layer23/include/osmocom/bb/modem/grr.h @@ -6,7 +6,28 @@ struct msgb; struct osmocom_ms; struct lapdm_entity; +struct osmo_fsm; + +enum grr_fsm_state { + GRR_ST_PACKET_NOT_READY, + GRR_ST_PACKET_IDLE, + GRR_ST_PACKET_TRANSFER, +}; + +enum grr_fsm_event { + GRR_EV_BCCH_BLOCK_IND, + GRR_EV_PCH_AGCH_BLOCK_IND, + GRR_EV_RACH_REQ, + GRR_EV_RACH_CNF, + GRR_EV_PDCH_ESTABLISH_REQ, + GRR_EV_PDCH_RELEASE_REQ, + GRR_EV_PDCH_UL_TBF_CFG_REQ, + GRR_EV_PDCH_DL_TBF_CFG_REQ, + GRR_EV_PDCH_BLOCK_REQ, + GRR_EV_PDCH_BLOCK_IND, +}; + +extern struct osmo_fsm grr_fsm_def; int modem_grr_rslms_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx); -int modem_grr_tx_chan_req(struct osmocom_ms *ms, uint8_t chan_req); uint8_t modem_grr_gen_chan_req(bool single_block); diff --git a/src/host/layer23/src/modem/app_modem.c b/src/host/layer23/src/modem/app_modem.c index fdb38212..6871384e 100644 --- a/src/host/layer23/src/modem/app_modem.c +++ b/src/host/layer23/src/modem/app_modem.c @@ -62,34 +62,6 @@ struct modem_app app_data; -static bool modem_can_gprs_attach(const struct osmocom_ms *ms) -{ - const struct gsm_subscriber *subscr = &ms->subscr; - const struct gsm322_cellsel *cs = &ms->cellsel; - const struct gsm48_sysinfo *si = &cs->sel_si; - - if (!subscr->sim_valid) - goto ret_false; - - if (!si->si1 || !si->si3 || !si->si4 || !si->si13) - goto ret_false; - - if (!si->gprs.supported) - goto ret_false; - - return true; - -ret_false: - LOGP(DRLCMAC, LOGL_INFO, "Delaying GPRS attach, waiting for:%s%s%s%s%s%s\n", - subscr->sim_valid ? "" : " imsi", - si->si1 ? "" : " si1", - si->si3 ? "" : " si3", - si->si4 ? "" : " si4", - si->si13 ? "" : " si13", - si->gprs.supported ? "" : " GprsIndicator"); - return false; -} - int modem_gprs_attach_if_needed(struct osmocom_ms *ms) { int rc; @@ -97,7 +69,10 @@ int modem_gprs_attach_if_needed(struct osmocom_ms *ms) if (app_data.modem_state != MODEM_ST_IDLE) return 0; - if (!modem_can_gprs_attach(ms)) + if (ms->grr_fi->state == GRR_ST_PACKET_NOT_READY) + return 0; + + if (!ms->subscr.sim_valid) return 0; app_data.modem_state = MODEM_ST_ATTACHING; @@ -201,6 +176,8 @@ static int global_signal_cb(unsigned int subsys, unsigned int signal, switch (signal) { case S_L1CTL_RESET: ms = signal_data; + if (ms->started) + break; layer3_app_reset(); app_data.ms = ms; @@ -285,6 +262,12 @@ int l23_app_init(void) return rc; } + /* TODO: move to a separate function */ + app_data.ms->grr_fi = osmo_fsm_inst_alloc(&grr_fsm_def, NULL, + app_data.ms, LOGL_DEBUG, + app_data.ms->name); + OSMO_ASSERT(app_data.ms->grr_fi != NULL); + osmo_signal_register_handler(SS_L1CTL, &global_signal_cb, NULL); osmo_signal_register_handler(SS_L23_SUBSCR, &modem_l23_subscr_signal_cb, NULL); lapdm_channel_set_l3(&app_data.ms->lapdm_channel, &modem_grr_rslms_cb, app_data.ms); diff --git a/src/host/layer23/src/modem/grr.c b/src/host/layer23/src/modem/grr.c index bd55f300..a7185fe3 100644 --- a/src/host/layer23/src/modem/grr.c +++ b/src/host/layer23/src/modem/grr.c @@ -1,5 +1,8 @@ /* * (C) 2022-2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * Author: Pau Espin Pedrol <pespin@sysmocom.de> + * Author: Vadim Yanitskiy <vyanitskiy@sysmocom.de> + * * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -23,6 +26,7 @@ #include <string.h> #include <errno.h> +#include <osmocom/core/fsm.h> #include <osmocom/core/msgb.h> #include <osmocom/core/utils.h> #include <osmocom/core/logging.h> @@ -41,6 +45,7 @@ #include <osmocom/bb/common/l1ctl.h> #include <osmocom/bb/common/ms.h> #include <osmocom/bb/modem/modem.h> +#include <osmocom/bb/modem/grr.h> #include <osmocom/bb/mobile/gsm322.h> #include <osmocom/bb/mobile/gsm48_rr.h> @@ -87,29 +92,6 @@ static bool grr_match_req_ref(struct osmocom_ms *ms, return false; } -int modem_grr_tx_chan_req(struct osmocom_ms *ms, uint8_t chan_req) -{ - struct gsm322_cellsel *cs = &ms->cellsel; - struct gsm48_rrlayer *rr = &ms->rrlayer; - - OSMO_ASSERT(rr->state == GSM48_RR_ST_IDLE); - - if (!cs->sel_si.si1 || !cs->sel_si.si13) - return -EAGAIN; - if (!cs->sel_si.gprs.supported) - return -ENOTSUP; - - rr->cr_ra = chan_req; - memset(&rr->cr_hist[0], 0x00, sizeof(rr->cr_hist)); - - LOGP(DRR, LOGL_NOTICE, "Sending CHANNEL REQUEST (0x%02x)\n", rr->cr_ra); - l1ctl_tx_rach_req(ms, RSL_CHAN_RACH, 0x00, rr->cr_ra, 0, - cs->ccch_mode == CCCH_MODE_COMBINED); - - rr->state = GSM48_RR_ST_CONN_PEND; - return 0; -} - static int forward_to_rlcmac(struct osmocom_ms *ms, struct msgb *msg) { struct osmo_gprs_rlcmac_prim *rlcmac_prim; @@ -135,7 +117,6 @@ static int grr_handle_si1(struct osmocom_ms *ms, struct msgb *msg) return rc; } - modem_gprs_attach_if_needed(ms); return 0; } @@ -171,7 +152,6 @@ static int grr_handle_si3(struct osmocom_ms *ms, struct msgb *msg) LOGP(DRR, LOGL_NOTICE, "Found GPRS Indicator (RA Colour %u, SI13 on BCCH %s)\n", cs->sel_si.gprs.ra_colour, cs->sel_si.gprs.si13_pos ? "Ext" : "Norm"); - modem_gprs_attach_if_needed(ms); return 0; } @@ -199,7 +179,6 @@ static int grr_handle_si4(struct osmocom_ms *ms, struct msgb *msg) LOGP(DRR, LOGL_NOTICE, "Found GPRS Indicator (RA Colour %u, SI13 on BCCH %s)\n", cs->sel_si.gprs.ra_colour, cs->sel_si.gprs.si13_pos ? "Ext" : "Norm"); - modem_gprs_attach_if_needed(ms); return 0; } @@ -218,10 +197,7 @@ static int grr_handle_si13(struct osmocom_ms *ms, struct msgb *msg) return rc; /* Forward SI13 to RLC/MAC layer */ - rc = forward_to_rlcmac(ms, msg); - - modem_gprs_attach_if_needed(ms); - return rc; + return forward_to_rlcmac(ms, msg); } static int grr_rx_bcch(struct osmocom_ms *ms, struct msgb *msg) @@ -299,6 +275,11 @@ static int grr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg) return -EINVAL; } + /* FIXME: this event should be triggered by the RLC/MAC layers itself */ + rc = osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_ESTABLISH_REQ, NULL); + if (rc != 0) + return rc; + if (!ia->chan_desc.h0.h) { /* Non-hopping */ uint16_t arfcn; @@ -349,7 +330,6 @@ static int grr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg) if (rc < 0) return rc; - rr->state = GSM48_RR_ST_DEDICATED; return 0; } @@ -461,9 +441,9 @@ static int grr_rx_rslms_rll_ud(struct osmocom_ms *ms, struct msgb *msg) switch (rllh->chan_nr) { case RSL_CHAN_PCH_AGCH: - return grr_rx_ccch(ms, msg); + return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PCH_AGCH_BLOCK_IND, msg); case RSL_CHAN_BCCH: - return grr_rx_bcch(ms, msg); + return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_BCCH_BLOCK_IND, msg); default: return 0; } @@ -486,25 +466,11 @@ static int grr_rx_rslms_rll(struct osmocom_ms *ms, struct msgb *msg) static int grr_rx_rslms_cchan(struct osmocom_ms *ms, struct msgb *msg) { const struct abis_rsl_cchan_hdr *ch = msgb_l2(msg); - struct gsm48_rrlayer *rr = &ms->rrlayer; switch (ch->c.msg_type) { case RSL_MT_CHAN_CONF: /* RACH.conf */ - if (rr->state == GSM48_RR_ST_CONN_PEND) { - const struct gsm48_req_ref *ref = (void *)&ch->data[1]; - LOGP(DRSL, LOGL_NOTICE, - "Rx RACH.conf (RA=0x%02x, T1=%u, T3=%u, T2=%u, FN=%u)\n", - rr->cr_ra, ref->t1, ref->t3_high << 3 | ref->t3_low, ref->t2, - _gsm48_req_ref2fn(ref)); - /* shift the CHANNEL REQUEST history buffer */ - memmove(&rr->cr_hist[1], &rr->cr_hist[0], ARRAY_SIZE(rr->cr_hist) - 1); - /* store the new entry */ - rr->cr_hist[0].ref = *ref; - rr->cr_hist[0].ref.ra = rr->cr_ra; - rr->cr_hist[0].valid = 1; - return 0; - } - /* fall-through */ + return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_CNF, + (void *)&ch->data[1]); default: LOGP(DRSL, LOGL_NOTICE, "Unhandled RSLms CCHAN message " "(msg_type 0x%02x)\n", ch->c.msg_type); @@ -534,3 +500,277 @@ int modem_grr_rslms_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx) msgb_free(msg); return rc; } + +///////////////////////////////////////////////////////////////////////////////////////// + +#define S(x) (1 << (x)) + +#include <osmocom/gsm/gsm0502.h> // XXX + +static void handle_pdch_block_ind(struct osmocom_ms *ms, struct msgb *msg) +{ + const struct l1ctl_gprs_dl_block_ind *ind = (void *)msg->l1h; + const uint32_t fn = osmo_load32be(&ind->hdr.fn); + struct osmo_gprs_rlcmac_prim *prim; + + /* FIXME: sadly, rlcmac_prim_l1ctl_alloc() is not exposed */ + prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_data_ind(0, 0, 0, 0, 0, NULL, 0); + prim->l1ctl = (struct osmo_gprs_rlcmac_l1ctl_prim) { + .pdch_data_ind = { + .fn = fn, + .ts_nr = ind->hdr.tn, + .rx_lev = ind->meas.rx_lev, + .ber10k = osmo_load16be(&ind->meas.ber10k), + .ci_cb = osmo_load16be(&ind->meas.ci_cb), + .data_len = msgb_l2len(msg), + .data = msgb_l2(msg), + } + }; + osmo_gprs_rlcmac_prim_lower_up(prim); + + /* Do not send RTS.ind if we got PTCCH/D */ + if (fn % 104 == 12) + return; + + /* Every fn % 13 == 12 we have either a PTCCH or an IDLE slot, thus + * every fn % 13 == 8 we add 5 frames, or 4 frames othrwise. The + * resulting value is first fn of the next block. */ + const uint32_t rts_fn = GSM_TDMA_FN_SUM(fn, (fn % 13 == 8) ? 5 : 4); + prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_rts_ind(ind->hdr.tn, rts_fn, ind->usf); + osmo_gprs_rlcmac_prim_lower_up(prim); +} + +static bool grr_cell_is_usable(const struct osmocom_ms *ms) +{ + const struct gsm322_cellsel *cs = &ms->cellsel; + const struct gsm48_sysinfo *si = &cs->sel_si; + + if (!si->si1 || !si->si3 || !si->si4 || !si->si13) + return false; + if (!si->gprs.supported) + return false; + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static void grr_st_packet_not_ready_action(struct osmo_fsm_inst *fi, + uint32_t event, void *data) +{ + struct osmocom_ms *ms = fi->priv; + + switch (event) { + case GRR_EV_BCCH_BLOCK_IND: + grr_rx_bcch(ms, (struct msgb *)data); + if (grr_cell_is_usable(ms)) { + LOGPFSML(fi, LOGL_NOTICE, "Cell is usable, GRR becomes ready\n"); + osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_IDLE, 0, 0); + } + break; + case GRR_EV_PCH_AGCH_BLOCK_IND: + grr_rx_ccch(ms, (struct msgb *)data); + break; + default: + OSMO_ASSERT(0); + } +} + +static void grr_st_packet_idle_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct osmocom_ms *ms = fi->priv; + + modem_gprs_attach_if_needed(ms); +} + +static void grr_st_packet_idle_action(struct osmo_fsm_inst *fi, + uint32_t event, void *data) +{ + struct osmocom_ms *ms = fi->priv; + + switch (event) { + case GRR_EV_BCCH_BLOCK_IND: + grr_rx_bcch(ms, (struct msgb *)data); + if (!grr_cell_is_usable(ms)) { + LOGPFSML(fi, LOGL_NOTICE, "Cell is not usable, GRR becomes not ready\n"); + osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_NOT_READY, 0, 0); + } + break; + case GRR_EV_PCH_AGCH_BLOCK_IND: + grr_rx_ccch(ms, (struct msgb *)data); + break; + case GRR_EV_RACH_REQ: + { + const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data; + struct gsm48_rrlayer *rr = &ms->rrlayer; + + if (lp->rach_req.is_11bit) { /* TODO: implement 11-bit RACH */ + LOGPFSML(fi, LOGL_ERROR, "11-bit RACH is not supported\n"); + return; + } + + rr->cr_ra = lp->rach_req.ra; + memset(&rr->cr_hist[0], 0x00, sizeof(rr->cr_hist)); + + LOGPFSML(fi, LOGL_INFO, "Sending CHANNEL REQUEST (0x%02x)\n", rr->cr_ra); + l1ctl_tx_rach_req(ms, RSL_CHAN_RACH, 0x00, rr->cr_ra, 0, + ms->cellsel.ccch_mode == CCCH_MODE_COMBINED); + + rr->state = GSM48_RR_ST_CONN_PEND; + break; + } + case GRR_EV_RACH_CNF: + { + struct gsm48_rrlayer *rr = &ms->rrlayer; + const struct gsm48_req_ref *ref = data; + + LOGPFSML(fi, LOGL_NOTICE, + "Rx RACH.conf (RA=0x%02x, T1=%u, T3=%u, T2=%u, FN=%u)\n", + rr->cr_ra, ref->t1, ref->t3_high << 3 | ref->t3_low, ref->t2, + _gsm48_req_ref2fn(ref)); + + if (ms->rrlayer.state != GSM48_RR_ST_CONN_PEND) { + LOGPFSML(fi, LOGL_ERROR, "Rx unexpected RACH.conf\n"); + return; + } + + /* shift the CHANNEL REQUEST history buffer */ + memmove(&rr->cr_hist[1], &rr->cr_hist[0], ARRAY_SIZE(rr->cr_hist) - 1); + /* store the new entry */ + rr->cr_hist[0].ref = *ref; + rr->cr_hist[0].ref.ra = rr->cr_ra; + rr->cr_hist[0].valid = 1; + break; + } + case GRR_EV_PDCH_ESTABLISH_REQ: + /* TODO: send L1CTL_DM_EST_REQ here */ + osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_TRANSFER, 0, 0); + break; + default: + OSMO_ASSERT(0); + } +} + +static void grr_st_packet_transfer_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct osmocom_ms *ms = fi->priv; + + ms->rrlayer.state = GSM48_RR_ST_DEDICATED; +} + +static void grr_st_packet_transfer_onleave(struct osmo_fsm_inst *fi, uint32_t next_state) +{ + struct osmocom_ms *ms = fi->priv; + + ms->rrlayer.state = GSM48_RR_ST_IDLE; +} + +static void grr_st_packet_transfer_action(struct osmo_fsm_inst *fi, + uint32_t event, void *data) +{ + struct osmocom_ms *ms = fi->priv; + + switch (event) { + case GRR_EV_PDCH_UL_TBF_CFG_REQ: + { + const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data; + l1ctl_tx_gprs_ul_tbf_cfg_req(ms, + lp->cfg_ul_tbf_req.ul_tbf_nr, + lp->cfg_ul_tbf_req.ul_slotmask); + break; + } + case GRR_EV_PDCH_DL_TBF_CFG_REQ: + { + const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data; + l1ctl_tx_gprs_dl_tbf_cfg_req(ms, + lp->cfg_dl_tbf_req.dl_tbf_nr, + lp->cfg_dl_tbf_req.dl_slotmask, + lp->cfg_dl_tbf_req.dl_tfi); + break; + } + case GRR_EV_PDCH_BLOCK_REQ: + { + const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data; + l1ctl_tx_gprs_ul_block_req(ms, + lp->pdch_data_req.fn, + lp->pdch_data_req.ts_nr, + lp->pdch_data_req.data, + lp->pdch_data_req.data_len); + break; + } + case GRR_EV_PDCH_BLOCK_IND: + handle_pdch_block_ind(ms, (struct msgb *)data); + break; + case GRR_EV_PDCH_RELEASE_REQ: + l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL); + l1ctl_tx_fbsb_req(ms, ms->test_arfcn, + L1CTL_FBSB_F_FB01SB, 100, 0, + ms->cellsel.ccch_mode, dbm2rxlev(-85)); + osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_IDLE, 0, 0); + break; + default: + OSMO_ASSERT(0); + } +} + +static const struct osmo_fsm_state grr_fsm_states[] = { + [GRR_ST_PACKET_NOT_READY] = { + .name = "PACKET_NOT_READY", + .out_state_mask = S(GRR_ST_PACKET_IDLE), + .in_event_mask = S(GRR_EV_BCCH_BLOCK_IND) + | S(GRR_EV_PCH_AGCH_BLOCK_IND), + .action = &grr_st_packet_not_ready_action, + }, + [GRR_ST_PACKET_IDLE] = { + .name = "PACKET_IDLE", + .out_state_mask = S(GRR_ST_PACKET_NOT_READY) + | S(GRR_ST_PACKET_TRANSFER), + .in_event_mask = S(GRR_EV_BCCH_BLOCK_IND) + | S(GRR_EV_PCH_AGCH_BLOCK_IND) + | S(GRR_EV_RACH_REQ) + | S(GRR_EV_RACH_CNF) + | S(GRR_EV_PDCH_ESTABLISH_REQ), + .action = &grr_st_packet_idle_action, + .onenter = &grr_st_packet_idle_onenter, + }, + [GRR_ST_PACKET_TRANSFER] = { + .name = "PACKET_TRANSFER", + .out_state_mask = S(GRR_ST_PACKET_NOT_READY) + | S(GRR_ST_PACKET_IDLE), + .in_event_mask = S(GRR_EV_PDCH_UL_TBF_CFG_REQ) + | S(GRR_EV_PDCH_DL_TBF_CFG_REQ) + | S(GRR_EV_PDCH_BLOCK_REQ) + | S(GRR_EV_PDCH_BLOCK_IND) + | S(GRR_EV_PDCH_RELEASE_REQ), + .action = &grr_st_packet_transfer_action, + .onenter = &grr_st_packet_transfer_onenter, + .onleave = &grr_st_packet_transfer_onleave, + }, +}; + +static const struct value_string grr_fsm_event_names[] = { + OSMO_VALUE_STRING(GRR_EV_BCCH_BLOCK_IND), + OSMO_VALUE_STRING(GRR_EV_PCH_AGCH_BLOCK_IND), + OSMO_VALUE_STRING(GRR_EV_RACH_REQ), + OSMO_VALUE_STRING(GRR_EV_RACH_CNF), + OSMO_VALUE_STRING(GRR_EV_PDCH_ESTABLISH_REQ), + OSMO_VALUE_STRING(GRR_EV_PDCH_RELEASE_REQ), + OSMO_VALUE_STRING(GRR_EV_PDCH_UL_TBF_CFG_REQ), + OSMO_VALUE_STRING(GRR_EV_PDCH_DL_TBF_CFG_REQ), + OSMO_VALUE_STRING(GRR_EV_PDCH_BLOCK_REQ), + OSMO_VALUE_STRING(GRR_EV_PDCH_BLOCK_IND), + { 0, NULL } +}; + +struct osmo_fsm grr_fsm_def = { + .name = "GPRS-RR", + .log_subsys = DRR, + .states = grr_fsm_states, + .num_states = ARRAY_SIZE(grr_fsm_states), + .event_names = grr_fsm_event_names, +}; + +static __attribute__((constructor)) void on_dso_load(void) +{ + OSMO_ASSERT(osmo_fsm_register(&grr_fsm_def) == 0); +} diff --git a/src/host/layer23/src/modem/rlcmac.c b/src/host/layer23/src/modem/rlcmac.c index fcd2b2ea..d209ec49 100644 --- a/src/host/layer23/src/modem/rlcmac.c +++ b/src/host/layer23/src/modem/rlcmac.c @@ -22,6 +22,7 @@ #include <stdint.h> #include <stdbool.h> +#include <osmocom/core/fsm.h> #include <osmocom/core/msgb.h> #include <osmocom/core/bits.h> #include <osmocom/core/prim.h> @@ -38,13 +39,10 @@ #include <osmocom/gprs/gmm/gmm_prim.h> #include <osmocom/bb/common/logging.h> -#include <osmocom/bb/common/l1ctl.h> #include <osmocom/bb/common/ms.h> #include <osmocom/bb/modem/rlcmac.h> #include <osmocom/bb/modem/grr.h> -#include <l1ctl_proto.h> - static int modem_rlcmac_handle_grr(struct osmo_gprs_rlcmac_prim *rlcmac_prim) { int rc; @@ -141,33 +139,19 @@ static int modem_rlcmac_prim_up_cb(struct osmo_gprs_rlcmac_prim *rlcmac_prim, vo static int modem_rlcmac_prim_down_cb(struct osmo_gprs_rlcmac_prim *prim, void *user_data) { - const struct osmo_gprs_rlcmac_l1ctl_prim *lp = &prim->l1ctl; + struct osmo_gprs_rlcmac_l1ctl_prim *lp = &prim->l1ctl; const char *pdu_name = osmo_gprs_rlcmac_prim_name(prim); struct osmocom_ms *ms = user_data; switch (OSMO_PRIM_HDR(&prim->oph)) { case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_RACH, PRIM_OP_REQUEST): - if (lp->rach_req.is_11bit) { - LOGP(DRLCMAC, LOGL_NOTICE, - "%s(): 11-bit RACH is not supported\n", __func__); - return -ENOTSUP; - } - return modem_grr_tx_chan_req(ms, lp->rach_req.ra); + return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_REQ, lp); case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_PDCH_DATA, PRIM_OP_REQUEST): - return l1ctl_tx_gprs_ul_block_req(ms, - lp->pdch_data_req.fn, - lp->pdch_data_req.ts_nr, - lp->pdch_data_req.data, - lp->pdch_data_req.data_len); + return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_BLOCK_REQ, lp); case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_CFG_UL_TBF, PRIM_OP_REQUEST): - return l1ctl_tx_gprs_ul_tbf_cfg_req(ms, - lp->cfg_ul_tbf_req.ul_tbf_nr, - lp->cfg_ul_tbf_req.ul_slotmask); + return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_UL_TBF_CFG_REQ, lp); case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_CFG_DL_TBF, PRIM_OP_REQUEST): - return l1ctl_tx_gprs_dl_tbf_cfg_req(ms, - lp->cfg_dl_tbf_req.dl_tbf_nr, - lp->cfg_dl_tbf_req.dl_slotmask, - lp->cfg_dl_tbf_req.dl_tfi); + return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_DL_TBF_CFG_REQ, lp); default: LOGP(DRLCMAC, LOGL_DEBUG, "%s(): Unexpected Rx %s\n", __func__, pdu_name); OSMO_ASSERT(0); @@ -176,37 +160,7 @@ static int modem_rlcmac_prim_down_cb(struct osmo_gprs_rlcmac_prim *prim, void *u static int l1ctl_dl_block_cb(struct osmocom_ms *ms, struct msgb *msg) { - const struct l1ctl_gprs_dl_block_ind *ind = (void *)msg->l1h; - const uint32_t fn = osmo_load32be(&ind->hdr.fn); - struct osmo_gprs_rlcmac_prim *prim; - - /* FIXME: sadly, rlcmac_prim_l1ctl_alloc() is not exposed */ - prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_data_ind(0, 0, 0, 0, 0, NULL, 0); - prim->l1ctl = (struct osmo_gprs_rlcmac_l1ctl_prim) { - .pdch_data_ind = { - .fn = fn, - .ts_nr = ind->hdr.tn, - .rx_lev = ind->meas.rx_lev, - .ber10k = osmo_load16be(&ind->meas.ber10k), - .ci_cb = osmo_load16be(&ind->meas.ci_cb), - .data_len = msgb_l2len(msg), - .data = msgb_l2(msg), - } - }; - osmo_gprs_rlcmac_prim_lower_up(prim); - - /* Do not send RTS.ind if we got PTCCH/D */ - if (fn % 104 == 12) - return 0; - - /* Every fn % 13 == 12 we have either a PTCCH or an IDLE slot, thus - * every fn % 13 == 8 we add 5 frames, or 4 frames othrwise. The - * resulting value is first fn of the next block. */ - const uint32_t rts_fn = GSM_TDMA_FN_SUM(fn, (fn % 13 == 8) ? 5 : 4); - prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_rts_ind(ind->hdr.tn, rts_fn, ind->usf); - osmo_gprs_rlcmac_prim_lower_up(prim); - - return 0; + return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_BLOCK_IND, msg); } int modem_rlcmac_init(struct osmocom_ms *ms) diff --git a/src/host/layer23/src/modem/vty.c b/src/host/layer23/src/modem/vty.c index d827993e..da291658 100644 --- a/src/host/layer23/src/modem/vty.c +++ b/src/host/layer23/src/modem/vty.c @@ -19,6 +19,7 @@ #include <stdint.h> #include <stdbool.h> +#include <osmocom/core/fsm.h> #include <osmocom/core/utils.h> #include <osmocom/core/talloc.h> #include <osmocom/core/linuxlist.h> @@ -27,6 +28,7 @@ #include <osmocom/gprs/llc/llc_prim.h> #include <osmocom/gprs/gmm/gmm_prim.h> #include <osmocom/gprs/sm/sm_prim.h> +#include <osmocom/gprs/rlcmac/rlcmac_prim.h> #include <osmocom/vty/vty.h> @@ -84,7 +86,14 @@ DEFUN_HIDDEN(test_grr_tx_chan_req, return CMD_WARNING; chan_req = modem_grr_gen_chan_req(argv[1][0] == '2'); - if (modem_grr_tx_chan_req(ms, chan_req) != 0) { + const struct osmo_gprs_rlcmac_l1ctl_prim lp = { + .rach_req = { + .is_11bit = false, + .ra = chan_req, + } + }; + + if (osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_REQ, (void *)&lp)) { vty_out(vty, "Failed to send a CHANNEL REQUEST%s", VTY_NEWLINE); return CMD_WARNING; } |