return;
}
+int gsm48_rr_rach_conf(struct osmocom_ms *ms, uint32_t fn)
+{
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
+
+ LOGP(DRR, LOGL_INFO, "RACH confirm framenr=%u\n", fn);
+ rr->cr_hist[0].valid = 2;
+ rr->cr_hist[0].fn = fn;
+
+ return 0;
+}
+
/* start random access */
static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging)
{
/* store value, mask and history */
rr->chan_req_val = chan_req_val;
rr->chan_req_mask = chan_req_mask;
- rr->cr_hist[2] = -1;
- rr->cr_hist[1] = -1;
- rr->cr_hist[0] = -1;
+ rr->cr_hist[2].valid = 0;
+ rr->cr_hist[1].valid = 0;
+ rr->cr_hist[0].valid = 0;
/* if channel is already active somehow */
if (cs->ccch_state == GSM322_CCCH_ST_DATA)
#endif
/* shift history and store */
- rr->cr_hist[2] = rr->cr_hist[1];
- rr->cr_hist[1] = rr->cr_hist[0];
- rr->cr_hist[0] = chan_req;
+ memcpy(&(rr->cr_hist[2]), &(rr->cr_hist[1]),
+ sizeof(struct gsm48_cr_hist));
+ memcpy(&(rr->cr_hist[1]), &(rr->cr_hist[0]),
+ sizeof(struct gsm48_cr_hist));
+ rr->cr_hist[0].valid = 1;
+ rr->cr_hist[0].chan_req = chan_req;
#ifdef TODO
add layer 1 conrols to RSL...
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
int i;
+ struct gsm_time tm;
+ uint8_t ia_t1, ia_t2, ia_t3;
for (i = 0; i < 3; i++) {
- if (rr->cr_hist[i] >= 0
- && ref->ra == rr->cr_hist[i]) {
- LOGP(DRR, LOGL_INFO, "request %02x matches\n", ref->ra);
- // todo: match timeslot
- return 1;
+ /* filter confirmed RACH requests only */
+ if (rr->cr_hist[i].valid == 2
+ && ref->ra == rr->cr_hist[i].chan_req) {
+ ia_t1 = ref->t1;
+ ia_t2 = ref->t2;
+ ia_t3 = (ref->t3_high << 3) | ref->t3_low;
+ gsm_fn2gsmtime(&tm, rr->cr_hist[i].fn);
+ if (ia_t1 == (tm.t1 & 0x1f) && ia_t2 == tm.t2
+ && ia_t3 == tm.t3) {
+ LOGP(DRR, LOGL_INFO, "request %02x matches "
+ "(fn=%d,%d,%d)\n", ref->ra, ia_t1,
+ ia_t2, ia_t3);
+ return 1;
+ } else
+ LOGP(DRR, LOGL_INFO, "request %02x matches "
+ "but not frame number (IMM.ASS "
+ "fn=%d,%d,%d != RACH fn=%d,%d,%d)\n",
+ ref->ra, ia_t1, ia_t2, ia_t3,
+ tm.t1 & 0x1f, tm.t2, tm.t3);
}
}
return 0;
}
+static int rx_l1_rach_conf(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct l1ctl_info_dl *dl;
+ struct osmobb_rach_conf rc;
+
+ if (msgb_l3len(msg) < sizeof(*dl)) {
+ LOGP(DL1C, LOGL_ERROR, "RACH CONF: MSG too short %u\n",
+ msgb_l3len(msg));
+ return -1;
+ }
+
+ dl = (struct l1ctl_info_dl *) msg->l1h;
+
+ printf("RACH CONF: arfcn=%u fn=%u\n", dl->snr, ntohl(dl->frame_nr));
+
+ rc.fn = htonl(dl->frame_nr);
+ rc.ms = ms;
+ dispatch_signal(SS_L1CTL, S_L1CTL_RACH_CONF, &rc);
+
+ return 0;
+}
+
char *chan_nr2string(uint8_t chan_nr)
{
static char str[20];
break;
case L1CTL_RESET_CONF:
LOGP(DL1C, LOGL_NOTICE, "L1CTL_RESET_CONF\n");
+ msgb_free(msg);
break;
case L1CTL_RACH_CONF:
LOGP(DL1C, LOGL_NOTICE, "L1CTL_RACH_CONF\n");
+ rc = rx_l1_rach_conf(ms, msg);
+ msgb_free(msg);
break;
case L1CTL_DATA_CONF:
LOGP(DL1C, LOGL_NOTICE, "L1CTL_DATA_CONF\n");
+ msgb_free(msg);
break;
default:
fprintf(stderr, "Unknown MSG: %u\n", l1h->msg_type);