From: Andreas.Eversberg Date: Mon, 28 Jun 2010 13:33:14 +0000 (+0000) Subject: [layer23] Updated layer23 to current L1 support and forthcomming hopping. X-Git-Url: http://git.rot13.org/?a=commitdiff_plain;h=f2b1e55c1e33b4645e2249b2d347955345622ebb;p=osmocom-bb.git [layer23] Updated layer23 to current L1 support and forthcomming hopping. --- diff --git a/include/l1a_l23_interface.h b/include/l1a_l23_interface.h index 05c3a5d..5408c48 100644 --- a/include/l1a_l23_interface.h +++ b/include/l1a_l23_interface.h @@ -152,7 +152,9 @@ struct l1ctl_ccch_mode_req { /* the l1_info_ul header is in front */ struct l1ctl_rach_req { uint8_t ra; - uint8_t padding[3]; + uint8_t fn51; + uint8_t mf_off; + uint8_t padding[1]; } __attribute__((packed)); struct l1ctl_dm_est_req { diff --git a/src/host/layer23/include/osmocom/gsm322.h b/src/host/layer23/include/osmocom/gsm322.h index 3a275b1..d9cd226 100755 --- a/src/host/layer23/include/osmocom/gsm322.h +++ b/src/host/layer23/include/osmocom/gsm322.h @@ -149,6 +149,7 @@ struct gsm322_cellsel { uint32_t scan_state; /* special state of current scan */ uint8_t ccch_state; /* special state of current ccch */ uint16_t arfcn; /* current tuned idle mode arfcn */ + uint8_t ccch_mode; /* curren CCCH_MODE_* */ struct gsm48_sysinfo *si; /* current sysinfo */ uint8_t selected; /* if a cell is selected */ diff --git a/src/host/layer23/include/osmocom/l1ctl.h b/src/host/layer23/include/osmocom/l1ctl.h index cac37cf..e5b91e7 100644 --- a/src/host/layer23/include/osmocom/l1ctl.h +++ b/src/host/layer23/include/osmocom/l1ctl.h @@ -17,8 +17,11 @@ int tx_ph_data_req(struct osmocom_ms *ms, struct msgb *msg, int tx_ph_rach_req(struct osmocom_ms *ms); /* Transmit L1CTL_DM_EST_REQ */ -int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, - uint8_t chan_nr, uint8_t tsc); +int tx_ph_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, + uint8_t chan_nr, uint8_t tsc, uint8_t tx_power); +int tx_ph_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, + uint16_t *ma, uint8_t ma_len, uint8_t chan_nr, uint8_t tsc, + uint8_t tx_power); /* Transmit L1CTL_DM_REL_REQ */ int tx_ph_dm_rel_req(struct osmocom_ms *ms); diff --git a/src/host/layer23/include/osmocom/osmocom_data.h b/src/host/layer23/include/osmocom/osmocom_data.h index 691fa4b..e4430fc 100644 --- a/src/host/layer23/include/osmocom/osmocom_data.h +++ b/src/host/layer23/include/osmocom/osmocom_data.h @@ -58,6 +58,7 @@ enum osmobb_meas_sig { S_L1CTL_PM_RES, S_L1CTL_PM_DONE, S_L1CTL_RACH_CONF, + S_L1CTL_CCCH_MODE_CONF, }; struct osmobb_meas_res { @@ -71,4 +72,9 @@ struct osmobb_rach_conf { uint32_t fn; }; +struct osmobb_ccch_mode_conf { + struct osmocom_ms *ms; + uint8_t ccch_mode; +}; + #endif diff --git a/src/host/layer23/src/gsm322.c b/src/host/layer23/src/gsm322.c index b59763a..94e9caa 100644 --- a/src/host/layer23/src/gsm322.c +++ b/src/host/layer23/src/gsm322.c @@ -219,12 +219,30 @@ int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg) * support */ -static int gsm322_sync_to_cell(struct osmocom_ms *ms, struct gsm322_cellsel *cs) +static int gsm322_sync_to_cell(struct gsm322_cellsel *cs) { + struct osmocom_ms *ms = cs->ms; + struct gsm48_sysinfo *s = cs->si; + + cs->ccch_state = GSM322_CCCH_ST_INIT; + if (s) { + if (s->ccch_conf == 1) { + LOGP(DCS, LOGL_INFO, "Sysinfo, ccch mode COMB\n"); + cs->ccch_mode = CCCH_MODE_COMBINED; + } else { + LOGP(DCS, LOGL_INFO, "Sysinfo, ccch mode NON-COMB\n"); + cs->ccch_mode = CCCH_MODE_NON_COMBINED; + } + } else { + LOGP(DCS, LOGL_INFO, "No sysinfo, ccch mode NONE\n"); + cs->ccch_mode = CCCH_MODE_NONE; + } +// printf("s->ccch_conf %d\n", cs->si->ccch_conf); + // l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL); return l1ctl_tx_fbsb_req(ms, cs->arfcn, L1CTL_FBSB_F_FB01SB, 100, 0, - CCCH_MODE_COMBINED); + cs->ccch_mode); } static void gsm322_unselect_cell(struct gsm322_cellsel *cs) @@ -1651,9 +1669,8 @@ static int gsm322_cs_scan(struct osmocom_ms *ms) cs->arfcn = cs->sel_arfcn; LOGP(DCS, LOGL_INFO, "Tuning back to frequency %d (rxlev " "%d).\n", cs->arfcn, cs->list[cs->arfcn].rxlev_db); - cs->ccch_state = GSM322_CCCH_ST_INIT; hack = 5; - gsm322_sync_to_cell(ms, cs); + gsm322_sync_to_cell(cs); // start_cs_timer(cs, ms->support.sync_to, 0); return 0; @@ -1683,9 +1700,8 @@ static int gsm322_cs_scan(struct osmocom_ms *ms) /* tune */ cs->arfcn = found; cs->si = cs->list[cs->arfcn].sysinfo; - cs->ccch_state = GSM322_CCCH_ST_INIT; hack = 5; - gsm322_sync_to_cell(ms, cs); + gsm322_sync_to_cell(cs); /* selected PLMN (manual) or any PLMN (auto) */ switch (ms->settings.plmn_mode) { @@ -1750,9 +1766,8 @@ static int gsm322_cs_scan(struct osmocom_ms *ms) cs->arfcn = weight & 1023; LOGP(DCS, LOGL_INFO, "Scanning frequency %d (rxlev %d).\n", cs->arfcn, cs->list[cs->arfcn].rxlev_db); - cs->ccch_state = GSM322_CCCH_ST_INIT; hack = 5; - gsm322_sync_to_cell(ms, cs); + gsm322_sync_to_cell(cs); // start_cs_timer(cs, ms->support.sync_to, 0); /* Allocate/clean system information. */ @@ -1877,9 +1892,8 @@ static int gsm322_cs_store(struct osmocom_ms *ms) /* tune */ cs->arfcn = found; cs->si = cs->list[cs->arfcn].sysinfo; - cs->ccch_state = GSM322_CCCH_ST_INIT; hack = 5; - gsm322_sync_to_cell(ms, cs); + gsm322_sync_to_cell(cs); /* selected PLMN (manual) or any PLMN (auto) */ switch (ms->settings.plmn_mode) { @@ -2279,9 +2293,8 @@ static int gsm322_cs_powerscan(struct osmocom_ms *ms) LOGP(DCS, LOGL_INFO, "Tuning back to frequency " "%d (rxlev %d).\n", cs->arfcn, cs->list[cs->arfcn].rxlev_db); - cs->ccch_state = GSM322_CCCH_ST_INIT; hack = 5; - gsm322_sync_to_cell(ms, cs); + gsm322_sync_to_cell(cs); // start_cs_timer(cs, ms->support.sync_to, 0); } else @@ -2385,7 +2398,7 @@ static int gsm322_l1_signal(unsigned int subsys, unsigned int signal, if (hack) { ms = signal_data; cs = &ms->cellsel; - gsm322_sync_to_cell(ms, cs); + gsm322_sync_to_cell(cs); hack--; LOGP(DCS, LOGL_INFO, "Channel sync error, try again.\n"); break; @@ -2833,9 +2846,8 @@ static int gsm322_c_conn_mode_1(struct osmocom_ms *ms, struct msgb *msg) /* be sure to go to current camping frequency on return */ LOGP(DCS, LOGL_INFO, "Going to camping frequency %d.\n", cs->arfcn); - cs->ccch_state = GSM322_CCCH_ST_INIT; hack = 5; - gsm322_sync_to_cell(ms, cs); + gsm322_sync_to_cell(cs); cs->si = cs->list[cs->arfcn].sysinfo; //#warning TESTING!!!! //usleep(300000); @@ -2854,9 +2866,8 @@ static int gsm322_c_conn_mode_2(struct osmocom_ms *ms, struct msgb *msg) /* be sure to go to current camping frequency on return */ LOGP(DCS, LOGL_INFO, "Going to camping frequency %d.\n", cs->arfcn); - cs->ccch_state = GSM322_CCCH_ST_INIT; hack = 5; - gsm322_sync_to_cell(ms, cs); + gsm322_sync_to_cell(cs); cs->si = cs->list[cs->arfcn].sysinfo; return 0; diff --git a/src/host/layer23/src/gsm48_rr.c b/src/host/layer23/src/gsm48_rr.c index 20580b2..2754949 100644 --- a/src/host/layer23/src/gsm48_rr.c +++ b/src/host/layer23/src/gsm48_rr.c @@ -825,28 +825,26 @@ static int gsm48_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg) /* TODO: turn this into a channel activation timeout, later */ #define RSL_MT_CHAN_CNF 0x19 #include -static void temp_rach_to(void *arg) -{ - struct gsm48_rrlayer *rr = arg; - struct osmocom_ms *ms = rr->ms; - struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm RR"); - struct abis_rsl_rll_hdr *rllh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rllh)); - - rllh->c.msg_type = RSL_MT_CHAN_CNF; - msg->l2h = (unsigned char *)rllh; - gsm48_rcv_rsl(ms, msg); - - return; -} - int gsm48_rr_rach_conf(struct osmocom_ms *ms, uint32_t fn) { struct gsm48_rrlayer *rr = &ms->rrlayer; + struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm RR"); + struct abis_rsl_rll_hdr *rllh = + (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rllh)); + if (!rr->wait_assign) { + LOGP(DRR, LOGL_INFO, "RACH confirm ignored, not waiting for " + "assignment.\n"); + return 0; + } LOGP(DRR, LOGL_INFO, "RACH confirm framenr=%u\n", fn); rr->cr_hist[0].valid = 2; rr->cr_hist[0].fn = fn; + rllh->c.msg_type = RSL_MT_CHAN_CNF; + msg->l2h = (unsigned char *)rllh; + gsm48_rcv_rsl(ms, msg); + return 0; } @@ -1018,11 +1016,6 @@ cause = RR_EST_CAUSE_LOC_UPD; return -EINVAL; } -// TODO: turn this into the channel activation timer - rr->temp_rach_ti.cb = temp_rach_to; - rr->temp_rach_ti.data = rr; - bsc_schedule_timer(&rr->temp_rach_ti, ms->support.sync_to, 0); - /* store value, mask and history */ rr->chan_req_val = chan_req_val; rr->chan_req_mask = chan_req_mask; @@ -1100,26 +1093,31 @@ int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg) slots = 55; else slots = 41; + break; case 4: case 9: case 16: if (s->ccch_conf != 1) slots = 76; else slots = 52; + break; case 5: case 10: case 20: if (s->ccch_conf != 1) slots = 109; else slots = 58; + break; case 6: case 11: case 25: if (s->ccch_conf != 1) slots = 163; else slots = 86; + break; default: if (s->ccch_conf != 1) slots = 217; else slots = 115; + break; } } @@ -1141,20 +1139,13 @@ int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg) chan_req &= rr->chan_req_mask; chan_req |= rr->chan_req_val; nra->ra = chan_req; -#ifdef TODO - at this point we require chan req to be sent at a given delay - also we require a confirm from radio part - nra->delay = (random() % s->tx_integer) + slots; +#warning TODO + nra->mf_off = 1; // (random() % s->tx_integer) + slots; + nra->fn51 = (s->ccch_conf == 1) ? 27 : 50; - LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (ra 0x%02x delay %d)\n", nra->ra, - nra->delay); -#else - rr->temp_rach_ti.cb = temp_rach_to; - rr->temp_rach_ti.data = rr; - bsc_schedule_timer(&rr->temp_rach_ti, 0, 900000); - - LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (ra 0x%02x)\n", nra->ra); -#endif + LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (Tx-integer %d combined %s " + "S(lots) %d ra 0x%02x offset %d)\n", s->tx_integer, + (s->ccch_conf == 1) ? "yes": "no", slots, nra->ra, nra->mf_off); /* shift history and store */ memcpy(&(rr->cr_hist[2]), &(rr->cr_hist[1]), @@ -1671,7 +1662,7 @@ static int gsm48_decode_ccd(struct gsm48_sysinfo *s, /* decode "Mobile Allocation" (10.5.2.21) */ static int gsm48_decode_mobile_alloc(struct gsm48_sysinfo *s, - uint8_t *ma, uint8_t len) + uint8_t *ma, uint8_t len, uint16_t *hopping, uint8_t *hopp_len, int si4) { int i, j = 0; uint16_t f[len << 3]; @@ -1681,13 +1672,17 @@ static int gsm48_decode_mobile_alloc(struct gsm48_sysinfo *s, return -EINVAL; /* tabula rasa */ - s->hopp_len = 0; - for (i = 0; i < 1024; i++) - s->freq[i].mask &= ~FREQ_TYPE_HOPP; + *hopp_len = 0; + if (si4) { + for (i = 0; i < 1024; i++) + s->freq[i].mask &= ~FREQ_TYPE_HOPP; + } /* generating list of all frequencies (1..1023,0) */ for (i = 1; i <= 1024; i++) { if ((s->freq[i & 1023].mask & FREQ_TYPE_SERV)) { + LOGP(DRR, LOGL_INFO, "Serving cell ARFCN #%d: %d\n", + j, i & 1023); f[j++] = i & 1023; if (j == (len << 3)) break; @@ -1700,6 +1695,8 @@ static int gsm48_decode_mobile_alloc(struct gsm48_sysinfo *s, for (i = 0; i < (len << 3); i++) { /* if bit is set, this frequency index is used for hopping */ if ((ma[len - 1 - (i >> 3)] & (1 << (i & 7)))) { + LOGP(DRR, LOGL_INFO, "Hopping ARFCN: %d (bit %d)\n", + i, f[i]); /* index higher than entries in list ? */ if (i >= j) { LOGP(DRR, LOGL_NOTICE, "Mobile Allocation " @@ -1708,8 +1705,9 @@ static int gsm48_decode_mobile_alloc(struct gsm48_sysinfo *s, i + 1, j); break; } - s->hopping[s->hopp_len++] = f[i]; - s->freq[f[i]].mask |= FREQ_TYPE_HOPP; + hopping[(*hopp_len)++] = f[i]; + if (si4) + s->freq[f[i]].mask |= FREQ_TYPE_HOPP; } } @@ -1995,7 +1993,8 @@ static int gsm48_rr_rx_sysinfo2ter(struct osmocom_ms *ms, struct msgb *msg) static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg) { struct gsm48_system_information_type_3 *si = msgb_l3(msg); - struct gsm48_sysinfo *s = ms->cellsel.si; + struct gsm322_cellsel *cs = &ms->cellsel; + struct gsm48_sysinfo *s = cs->si; int payload_len = msgb_l3len(msg) - sizeof(*si); if (!s) { @@ -2036,6 +2035,14 @@ static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg) s->si3 = 1; + if (cs->ccch_mode == CCCH_MODE_NONE) { + cs->ccch_mode = (s->ccch_conf == 1) ? CCCH_MODE_COMBINED : + CCCH_MODE_NON_COMBINED; + LOGP(DRR, LOGL_NOTICE, "Changing CCCH_MODE to %d\n", + cs->ccch_mode); + l1ctl_tx_ccch_mode_req(ms, cs->ccch_mode); + } + return gsm48_send_sysinfo(ms, si->header.system_information); } @@ -2062,6 +2069,12 @@ static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg) return -EINVAL; } + if (!s->si1) { + LOGP(DRR, LOGL_NOTICE, "Ignoring SYSTEM INFORMATION 4 " + "until SI 1 is received.\n"); + return -EBUSY; + } + if (!memcmp(si, s->si4_msg, MIN(msgb_l3len(msg), sizeof(s->si4_msg)))) return 0; memcpy(s->si4_msg, si, MIN(msgb_l3len(msg), sizeof(s->si4_msg))); @@ -2091,7 +2104,8 @@ static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg) if (payload_len >= 1 && data[0] == GSM48_IE_CBCH_MOB_AL) { if (payload_len < 1 || payload_len < 2 + data[1]) goto short_read; - gsm48_decode_mobile_alloc(s, data + 2, si->data[1]); + gsm48_decode_mobile_alloc(s, data + 2, si->data[1], s->hopping, + &s->hopp_len, 1); payload_len -= 2 + data[1]; data += 2 + data[1]; } @@ -2945,26 +2959,27 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms) { struct gsm48_rrlayer *rr = &ms->rrlayer; struct gsm_subscriber *subscr = &ms->subscr; + struct gsm322_cellsel *cs = &ms->cellsel; + struct gsm48_sysinfo *s = cs->si; struct msgb *nmsg; struct gsm48_hdr *gh; struct gsm48_pag_rsp *pr; uint8_t mi[11]; uint8_t ch_type, ch_subch, ch_ts; + uint16_t ma[64]; + uint8_t ma_len; /* 3.3.1.1.3.1 */ stop_rr_t3126(rr); - /* flush pending RACH requests */ -#ifdef TODO - rr->n_chan_req = 0; // just to be safe - nmsg = msgb_alloc_headroom(20, 16, "RAND_FLUSH"); - if (!nmsg) - return -ENOMEM; - gsm48_send_rsl(ms, RSL_MT_RAND_ACC_FLSH, msg); -#else - if (bsc_timer_pending(&rr->temp_rach_ti)) - bsc_del_timer(&rr->temp_rach_ti); -#endif + if (rr->cd_now.h) { + gsm48_decode_mobile_alloc(s, rr->cd_now.mob_alloc_lv + 1, + rr->cd_now.mob_alloc_lv[0], ma, &ma_len, 0); + if (ma_len < 1) { + LOGP(DRR, LOGL_NOTICE, "Hopping, but no allocation\n"); + return -EINVAL; + } + } /* send DL_EST_REQ */ if (rr->rr_est_msg) { @@ -3007,10 +3022,6 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms) #ifdef TODO RSL_MT_ to activate channel with all the cd_now informations #else - if (rr->cd_now.h) { - printf("FIXME: Channel hopping not supported, exitting.\n"); - exit(-ENOTSUP); - } rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type, &ch_subch, &ch_ts); if ((ch_type != RSL_CHAN_SDCCH8_ACCH && ch_type != RSL_CHAN_SDCCH4_ACCH) || ch_ts > 4) { @@ -3018,8 +3029,12 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms) "exitting.\n", ch_type, ch_subch, ch_ts); exit(-ENOTSUP); } - tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr, - rr->cd_now.tsc); + if (rr->cd_now.h) + tx_ph_dm_est_req_h1(ms, rr->cd_now.maio, rr->cd_now.hsn, + ma, ma_len, rr->cd_now.chan_nr, rr->cd_now.tsc, 0); + else + tx_ph_dm_est_req_h0(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr, + rr->cd_now.tsc, 0); #endif /* start establishmnet */ @@ -3517,15 +3532,6 @@ static int gsm48_rr_rx_pch_agch(struct osmocom_ms *ms, struct msgb *msg) struct gsm48_system_information_type_header *sih = msgb_l3(msg); switch (sih->system_information) { - case GSM48_MT_RR_SYSINFO_5: - return gsm48_rr_rx_sysinfo5(ms, msg); - case GSM48_MT_RR_SYSINFO_5bis: - return gsm48_rr_rx_sysinfo5bis(ms, msg); - case GSM48_MT_RR_SYSINFO_5ter: - return gsm48_rr_rx_sysinfo5ter(ms, msg); - case GSM48_MT_RR_SYSINFO_6: - return gsm48_rr_rx_sysinfo6(ms, msg); - case GSM48_MT_RR_PAG_REQ_1: return gsm48_rr_rx_pag_req_1(ms, msg); case GSM48_MT_RR_PAG_REQ_2: @@ -3540,10 +3546,29 @@ static int gsm48_rr_rx_pch_agch(struct osmocom_ms *ms, struct msgb *msg) case GSM48_MT_RR_IMM_ASS_REJ: return gsm48_rr_rx_imm_ass_rej(ms, msg); default: -#if 0 LOGP(DRR, LOGL_NOTICE, "CCCH message type 0x%02x unknown.\n", sih->system_information); -#endif + return -EINVAL; + } +} + +/* receive ACCH at RR layer */ +static int gsm48_rr_rx_acch(struct osmocom_ms *ms, struct msgb *msg) +{ + struct gsm48_system_information_type_header *sih = msgb_l3(msg); + + switch (sih->system_information) { + case GSM48_MT_RR_SYSINFO_5: + return gsm48_rr_rx_sysinfo5(ms, msg); + case GSM48_MT_RR_SYSINFO_5bis: + return gsm48_rr_rx_sysinfo5bis(ms, msg); + case GSM48_MT_RR_SYSINFO_5ter: + return gsm48_rr_rx_sysinfo5ter(ms, msg); + case GSM48_MT_RR_SYSINFO_6: + return gsm48_rr_rx_sysinfo6(ms, msg); + default: + LOGP(DRR, LOGL_NOTICE, "ACCH message type 0x%02x unknown.\n", + sih->system_information); return -EINVAL; } } @@ -3604,24 +3629,17 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg) // TODO: timer depends on BCCH config } - switch (rllh->chan_nr) { - case RSL_CHAN_PCH_AGCH: + if (rllh->chan_nr == RSL_CHAN_PCH_AGCH) return gsm48_rr_rx_pch_agch(ms, msg); - case RSL_CHAN_BCCH: -#if 0 -#warning testing corrupt frames -{int i; -if (ms->cellsel.state == GSM322_C7_CAMPED_ANY_CELL) -for(i=0;il3h[i] = random(); - } -#endif + if (rllh->chan_nr == RSL_CHAN_BCCH) return gsm48_rr_rx_bcch(ms, msg); - default: - LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n", - rllh->chan_nr); - return -EINVAL; - } + if ((rllh->chan_nr & 0xf0) == RSL_CHAN_SDCCH4_ACCH) + return gsm48_rr_rx_acch(ms, msg); + if ((rllh->chan_nr & 0xf0) == RSL_CHAN_SDCCH8_ACCH) + return gsm48_rr_rx_acch(ms, msg); + LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n", + rllh->chan_nr); + return -EINVAL; } /* 3.4.13.3 RR abort in dedicated mode (also in conn. pending mode) */ @@ -3669,8 +3687,8 @@ static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg) struct msgb *nmsg; /* change radio to new channel */ - tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr, - rr->cd_now.tsc); +//todo tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr, +// rr->cd_now.tsc); /* send DL-ESTABLISH REQUEST */ nmsg = gsm48_l3_msgb_alloc(); diff --git a/src/host/layer23/src/l1ctl.c b/src/host/layer23/src/l1ctl.c index 38d4f5d..8d5e569 100644 --- a/src/host/layer23/src/l1ctl.c +++ b/src/host/layer23/src/l1ctl.c @@ -336,8 +336,8 @@ int tx_ph_rach_req(struct osmocom_ms *ms) } /* Transmit L1CTL_DM_EST_REQ */ -int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr, - uint8_t tsc) +int tx_ph_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, + uint8_t chan_nr, uint8_t tsc, uint8_t tx_power) { struct msgb *msg; struct l1ctl_info_ul *ul; @@ -353,7 +353,7 @@ int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul)); ul->chan_nr = chan_nr; ul->link_id = 0; - ul->tx_power = 0; /* FIXME: initial TX power */ + ul->tx_power = tx_power; req = (struct l1ctl_dm_est_req *) msgb_put(msg, sizeof(*req)); req->tsc = tsc; @@ -363,6 +363,39 @@ int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr return osmo_send_l1(ms, msg); } +int tx_ph_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, + uint16_t *ma, uint8_t ma_len, uint8_t chan_nr, uint8_t tsc, + uint8_t tx_power) +{ + struct msgb *msg; + struct l1ctl_info_ul *ul; + struct l1ctl_dm_est_req *req; + int i; + + msg = osmo_l1_alloc(L1CTL_DM_EST_REQ); + if (!msg) + return -1; + + DEBUGP(DL1C, "Tx Dedic.Mode Est Req (maio=%u, hsn=%u, " + "chan_nr=0x%02x)\n", maio, hsn, chan_nr); + + ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul)); + ul->chan_nr = chan_nr; + ul->link_id = 0; + ul->tx_power = tx_power; + + req = (struct l1ctl_dm_est_req *) msgb_put(msg, sizeof(*req)); + req->tsc = tsc; + req->h = 1; + req->h1.maio = maio; + req->h1.hsn = hsn; + req->h1.n = ma_len; + for (i = 0; i < ma_len; i++) + req->h1.ma[i] = htons(ma[i]); + + return osmo_send_l1(ms, msg); +} + /* Transmit L1CTL_DM_REL_REQ */ int tx_ph_dm_rel_req(struct osmocom_ms *ms) { @@ -461,6 +494,29 @@ static int rx_l1_pm_conf(struct osmocom_ms *ms, struct msgb *msg) return 0; } +/* Receive L1CTL_MODE_CONF */ +static int rx_l1_ccch_mode_conf(struct osmocom_ms *ms, struct msgb *msg) +{ + struct osmobb_ccch_mode_conf mc; + struct l1ctl_ccch_mode_conf *conf; + + if (msgb_l3len(msg) < sizeof(*conf)) { + LOGP(DL1C, LOGL_ERROR, "MODE CONF: MSG too short %u\n", + msgb_l3len(msg)); + return -1; + } + + conf = (struct l1ctl_ccch_mode_conf *) msg->l1h; + + printf("mode=%u\n", conf->ccch_mode); + + mc.ccch_mode = conf->ccch_mode; + mc.ms = ms; + dispatch_signal(SS_L1CTL, S_L1CTL_CCCH_MODE_CONF, &mc); + + return 0; +} + /* Receive incoming data from L1 using L1CTL format */ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg) { @@ -507,6 +563,10 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg) rc = rx_l1_rach_conf(ms, msg); msgb_free(msg); break; + case L1CTL_CCCH_MODE_CONF: + rc = rx_l1_ccch_mode_conf(ms, msg); + msgb_free(msg); + break; default: fprintf(stderr, "Unknown MSG: %u\n", l1h->msg_type); msgb_free(msg); diff --git a/src/host/layer23/src/layer3.c b/src/host/layer23/src/layer3.c index 7f37db1..978ea10 100644 --- a/src/host/layer23/src/layer3.c +++ b/src/host/layer23/src/layer3.c @@ -187,8 +187,8 @@ static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms) } /* request L1 to go to dedicated mode on assigned channel */ - tx_ph_dm_est_req(ms, arfcn, ia->chan_desc.chan_nr, - ia->chan_desc.h0.tsc); + tx_ph_dm_est_req_h0(ms, arfcn, ia->chan_desc.chan_nr, + ia->chan_desc.h0.tsc, 0); /* request L2 to establish the SAPI0 connection */ gsm48_tx_loc_upd_req(ms, ia->chan_desc.chan_nr);