X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Fhost%2Flayer23%2Fsrc%2Fl1ctl.c;h=051b3d88c188ea2b939227eb0fe583c122ae3baf;hb=78f6fb7713beb247c07327a1f802b14ebd2b830a;hp=d6aa1763859ed9d05dd7461403812372e9927dcc;hpb=2bb14aa3bbd7ddfe18ccee0b0e0a5ce608213936;p=osmocom-bb.git diff --git a/src/host/layer23/src/l1ctl.c b/src/host/layer23/src/l1ctl.c index d6aa176..051b3d8 100644 --- a/src/host/layer23/src/l1ctl.c +++ b/src/host/layer23/src/l1ctl.c @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -64,30 +65,40 @@ static struct msgb *osmo_l1_alloc(uint8_t msg_type) } -static int osmo_make_band_arfcn(struct osmocom_ms *ms) +static int osmo_make_band_arfcn(struct osmocom_ms *ms, uint16_t arfcn) { /* TODO: Include the band */ - return ms->arfcn; + return arfcn; } -static int rx_l1_ccch_resp(struct osmocom_ms *ms, struct msgb *msg) +static int rx_l1_fbsb_resp(struct osmocom_ms *ms, struct msgb *msg) { struct l1ctl_info_dl *dl; - struct l1ctl_sync_new_ccch_resp *sb; + struct l1ctl_fbsb_resp *sb; struct gsm_time tm; - if (msgb_l3len(msg) < sizeof(*sb)) { - LOGP(DL1C, LOGL_ERROR, "MSG too short for CCCH RESP: %u\n", + if (msgb_l3len(msg) < sizeof(*dl) + sizeof(*sb)) { + LOGP(DL1C, LOGL_ERROR, "FBSB RESP: MSG too short %u\n", msgb_l3len(msg)); return -1; } dl = (struct l1ctl_info_dl *) msg->l1h; - sb = (struct l1ctl_sync_new_ccch_resp *) dl->payload; + sb = (struct l1ctl_fbsb_resp *) dl->payload; + + printf("snr=%04x, arfcn=%u result=%u\n", dl->snr, ntohs(dl->band_arfcn), + sb->result); + + if (sb->result != 0) { + LOGP(DL1C, LOGL_ERROR, "FBSB RESP: result=%u\n", sb->result); + dispatch_signal(SS_L1CTL, S_L1CTL_FBSB_ERR, ms); + return 0; + } gsm_fn2gsmtime(&tm, ntohl(dl->frame_nr)); DEBUGP(DL1C, "SCH: SNR: %u TDMA: (%.4u/%.2u/%.2u) bsic: %d\n", dl->snr, tm.t1, tm.t2, tm.t3, sb->bsic); + dispatch_signal(SS_L1CTL, S_L1CTL_FBSB_RESP, ms); return 0; } @@ -132,6 +143,7 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg) if (msgb_l3len(msg) < sizeof(*ccch)) { LOGP(DL1C, LOGL_ERROR, "MSG too short Data Ind: %u\n", msgb_l3len(msg)); + msgb_free(msg); return -1; } @@ -145,6 +157,12 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg) chan_nr2string(dl->chan_nr), tm.t1, tm.t2, tm.t3, hexdump(ccch->data, sizeof(ccch->data))); + if (dl->num_biterr) { + LOGP(DL1C, LOGL_NOTICE, "Dropping frame with %u bit errors\n", + dl->num_biterr); + return 0; + } + /* send CCCH data via GSMTAP */ gsmtap_chan_type = chantype_rsl2gsmtap(chan_type, dl->link_id); gsmtap_sendmsg(dl->band_arfcn, chan_ts, gsmtap_chan_type, chan_ss, @@ -213,18 +231,28 @@ int tx_ph_data_req(struct osmocom_ms *ms, struct msgb *msg, return osmo_send_l1(ms, msg); } -/* Transmit NEW_CCCH_REQ */ -int l1ctl_tx_ccch_req(struct osmocom_ms *ms) +/* Transmit FBSB_REQ */ +int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn, + uint8_t flags, uint16_t timeout, uint8_t sync_info_idx) { struct msgb *msg; - struct l1ctl_sync_new_ccch_req *req; + struct l1ctl_fbsb_req *req; - msg = osmo_l1_alloc(L1CTL_NEW_CCCH_REQ); + msg = osmo_l1_alloc(L1CTL_FBSB_REQ); if (!msg) return -1; - req = (struct l1ctl_sync_new_ccch_req *) msgb_put(msg, sizeof(*req)); - req->band_arfcn = osmo_make_band_arfcn(ms); + req = (struct l1ctl_fbsb_req *) msgb_put(msg, sizeof(*req)); + req->band_arfcn = htons(osmo_make_band_arfcn(ms, arfcn)); + req->timeout = htons(timeout); + /* Threshold when to consider FB_MODE1: 4kHz - 1kHz */ + req->freq_err_thresh1 = htons(4000 - 1000); + /* Threshold when to consider SCH: 1kHz - 200Hz */ + req->freq_err_thresh2 = htons(1000 - 200); + /* not used yet! */ + req->num_freqerr_avg = 3; + req->flags = flags; + req->sync_info_idx = sync_info_idx; return osmo_send_l1(ms, msg); } @@ -267,7 +295,7 @@ int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr ul->link_id = 0; ul->tx_power = 0; /* FIXME: initial TX power */ req = (struct l1ctl_dm_est_req *) msgb_put(msg, sizeof(*req)); - req->band_arfcn = band_arfcn; + req->band_arfcn = htons(band_arfcn); return osmo_send_l1(ms, msg); } @@ -314,6 +342,8 @@ static int rx_l1_reset(struct osmocom_ms *ms) { printf("Layer1 Reset.\n"); dispatch_signal(SS_L1CTL, S_L1CTL_RESET, ms); + + return 0; } /* Receive L1CTL_PM_RESP */ @@ -344,6 +374,7 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg) if (msgb_l2len(msg) < sizeof(*dl)) { LOGP(DL1C, LOGL_ERROR, "Short Layer2 message: %u\n", msgb_l2len(msg)); + msgb_free(msg); return -1; } @@ -354,22 +385,26 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg) msg->l1h = l1h->data; switch (l1h->msg_type) { - case L1CTL_NEW_CCCH_RESP: - rc = rx_l1_ccch_resp(ms, msg); + case L1CTL_FBSB_RESP: + rc = rx_l1_fbsb_resp(ms, msg); + msgb_free(msg); break; case L1CTL_DATA_IND: rc = rx_ph_data_ind(ms, msg); break; case L1CTL_RESET: rc = rx_l1_reset(ms); + msgb_free(msg); break; case L1CTL_PM_RESP: rc = rx_l1_pm_resp(ms, msg); + msgb_free(msg); if (l1h->flags & L1CTL_F_DONE) dispatch_signal(SS_L1CTL, S_L1CTL_PM_DONE, ms); break; default: fprintf(stderr, "Unknown MSG: %u\n", l1h->msg_type); + msgb_free(msg); break; }