modem: request an Uplink TBF, match Immediate Assignment
Change-Id: Iec0dcc629d29dec270649cf7428f71af0dfd2dbb Related: SYS#5500
This commit is contained in:
parent
e9abf7b61d
commit
49d993e4ab
|
@ -45,8 +45,28 @@
|
|||
static struct {
|
||||
enum ccch_mode ccch_mode;
|
||||
struct gsm48_sysinfo si;
|
||||
|
||||
/* TODO: use mobile->rrlayer API instead */
|
||||
struct {
|
||||
bool ref_valid;
|
||||
struct gsm48_req_ref ref;
|
||||
} chan_req;
|
||||
} app_data;
|
||||
|
||||
/* Generate a 8-bit CHANNEL REQUEST message as per 3GPP TS 44.018, 9.1.8 */
|
||||
static uint8_t gen_chan_req(bool single_block)
|
||||
{
|
||||
uint8_t rnd = (uint8_t)rand();
|
||||
|
||||
if (single_block) /* 01110xxx */
|
||||
return 0x70 | (rnd & 0x07);
|
||||
|
||||
/* 011110xx or 01111x0x or 01111xx0 */
|
||||
if ((rnd & 0x07) == 0x07)
|
||||
return 0x78;
|
||||
return 0x78 | (rnd & 0x07);
|
||||
}
|
||||
|
||||
static int handle_si1(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
int rc;
|
||||
|
@ -127,6 +147,7 @@ static int handle_si4(struct osmocom_ms *ms, struct msgb *msg)
|
|||
|
||||
static int handle_si13(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
int rc;
|
||||
|
||||
if (msgb_l3len(msg) != GSM_MACBLOCK_LEN)
|
||||
|
@ -138,6 +159,20 @@ static int handle_si13(struct osmocom_ms *ms, struct msgb *msg)
|
|||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
/* HACK: request an Uplink TBF here (one phase access) */
|
||||
if (rr->state == GSM48_RR_ST_IDLE) {
|
||||
if (!app_data.si.si1)
|
||||
return 0;
|
||||
if (!app_data.si.gprs.supported)
|
||||
return 0;
|
||||
|
||||
rr->cr_ra = gen_chan_req(false);
|
||||
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,
|
||||
app_data.ccch_mode == CCCH_MODE_COMBINED);
|
||||
rr->state = GSM48_RR_ST_CONN_PEND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -166,6 +201,7 @@ static int modem_rx_bcch(struct osmocom_ms *ms, struct msgb *msg)
|
|||
static int modem_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
const struct gsm48_imm_ass *ia = msgb_l3(msg);
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
uint8_t ch_type, ch_subch, ch_ts;
|
||||
int rc;
|
||||
|
||||
|
@ -173,6 +209,13 @@ static int modem_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
|
|||
if ((ia->page_mode >> 4) == 0)
|
||||
return 0;
|
||||
|
||||
if (rr->state != GSM48_RR_ST_CONN_PEND)
|
||||
return 0;
|
||||
if (!app_data.chan_req.ref_valid)
|
||||
return 0;
|
||||
if (memcmp(&ia->req_ref, &app_data.chan_req.ref, sizeof(ia->req_ref)))
|
||||
return 0;
|
||||
|
||||
if (rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts) != 0) {
|
||||
LOGP(DRR, LOGL_ERROR,
|
||||
"%s(): rsl_dec_chan_nr(chan_nr=0x%02x) failed\n",
|
||||
|
@ -190,9 +233,13 @@ static int modem_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
|
|||
"ARFCN=%u, TS=%u, SS=%u, TSC=%u)\n", ia->req_ref.ra,
|
||||
ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch,
|
||||
ia->chan_desc.h0.tsc);
|
||||
|
||||
l1ctl_tx_dm_est_req_h0(ms, arfcn, RSL_CHAN_OSMO_PDCH,
|
||||
ia->chan_desc.h0.tsc, GSM48_CMODE_SIGN, 0);
|
||||
} else {
|
||||
/* Hopping */
|
||||
uint8_t maio, hsn;
|
||||
uint8_t maio, hsn, ma_len;
|
||||
uint16_t ma[64];
|
||||
|
||||
hsn = ia->chan_desc.h1.hsn;
|
||||
maio = ia->chan_desc.h1.maio_low | (ia->chan_desc.h1.maio_high << 2);
|
||||
|
@ -201,6 +248,22 @@ static int modem_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
|
|||
"HSN=%u, MAIO=%u, TS=%u, SS=%u, TSC=%u)\n", ia->req_ref.ra,
|
||||
ia->chan_desc.chan_nr, hsn, maio, ch_ts, ch_subch,
|
||||
ia->chan_desc.h1.tsc);
|
||||
|
||||
for (unsigned int i = 1, j = 0; i <= 1024; i++) {
|
||||
unsigned int arfcn = i & 1023;
|
||||
unsigned int k;
|
||||
|
||||
if (~app_data.si.freq[arfcn].mask & 0x01)
|
||||
continue;
|
||||
|
||||
k = ia->mob_alloc_len - (j >> 3) - 1;
|
||||
if (ia->mob_alloc[k] & (1 << (j & 7)))
|
||||
ma[ma_len++] = arfcn;
|
||||
j++;
|
||||
}
|
||||
|
||||
l1ctl_tx_dm_est_req_h1(ms, maio, hsn, &ma[0], ma_len, RSL_CHAN_OSMO_PDCH,
|
||||
ia->chan_desc.h1.tsc, GSM48_CMODE_SIGN, 0);
|
||||
}
|
||||
|
||||
const uint8_t *data = msgb_l3(msg) + sizeof(*ia) + ia->mob_alloc_len;
|
||||
|
@ -213,6 +276,9 @@ static int modem_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* TODO: deliver decoded params to the RLC/MAC layer */
|
||||
|
||||
rr->state = GSM48_RR_ST_DEDICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -313,6 +379,31 @@ static int modem_rx_rslms_rll(struct osmocom_ms *ms, struct msgb *msg)
|
|||
}
|
||||
}
|
||||
|
||||
static int modem_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)\n",
|
||||
rr->cr_ra, ref->t1, ref->t3_high << 3 | ref->t3_low, ref->t2);
|
||||
memcpy(&app_data.chan_req.ref, ref, sizeof(*ref));
|
||||
app_data.chan_req.ref.ra = rr->cr_ra;
|
||||
app_data.chan_req.ref_valid = true;
|
||||
return 0;
|
||||
}
|
||||
/* fall-through */
|
||||
default:
|
||||
LOGP(DRSL, LOGL_NOTICE, "Unhandled RSLms CCHAN message "
|
||||
"(msg_type 0x%02x)\n", ch->c.msg_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int modem_rslms_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx)
|
||||
{
|
||||
const struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
|
||||
|
@ -322,6 +413,9 @@ static int modem_rslms_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx)
|
|||
case ABIS_RSL_MDISC_RLL:
|
||||
rc = modem_rx_rslms_rll((struct osmocom_ms *)ctx, msg);
|
||||
break;
|
||||
case ABIS_RSL_MDISC_COM_CHAN:
|
||||
rc = modem_rx_rslms_cchan((struct osmocom_ms *)ctx, msg);
|
||||
break;
|
||||
default:
|
||||
LOGP(DRSL, LOGL_NOTICE, "Unhandled RSLms message "
|
||||
"(msg_discr 0x%02x)\n", rslh->msg_discr);
|
||||
|
|
Loading…
Reference in New Issue