/** * @brief Handler for received L1CTL_DM_EST_REQ from L23. * * -- dedicated mode established request -- * * @param [in] msg the received message. * * Handle state change from idle to dedicated mode. * */ void l1ctl_rx_dm_est_req(struct l1_model_ms *ms, struct msgb *msg) { struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data; struct l1ctl_info_ul *ul = (struct l1ctl_info_ul *) l1h->data; struct l1ctl_dm_est_req *est_req = (struct l1ctl_dm_est_req *) ul->payload; uint8_t rsl_chantype, subslot, timeslot; rsl_dec_chan_nr(ul->chan_nr, &rsl_chantype, &subslot, ×lot); LOGPMS(DL1C, LOGL_INFO, ms, "Rx L1CTL_DM_EST_REQ (chan_nr=0x%02x, tn=%u, ss=%u)\n", ul->chan_nr, timeslot, subslot); ms->state.dedicated.chan_type = rsl_chantype; ms->state.dedicated.tn = timeslot; ms->state.dedicated.subslot = subslot; ms->state.state = MS_STATE_DEDICATED; /* TCH config */ if (rsl_chantype == RSL_CHAN_Bm_ACCHs || rsl_chantype == RSL_CHAN_Lm_ACCHs) { ms->state.tch_mode = est_req->tch_mode; l1_model_tch_mode_set(ms, est_req->tch_mode); ms->state.audio_mode = est_req->audio_mode; /* TODO: configure audio hardware for encoding / * decoding / recording / playing voice */ } }
int process_handle_burst(struct session_info *s, struct l1ctl_burst_ind *bi) { int ul; //int len; //uint32_t fn; uint8_t type, subch, ts; struct burst_buf *bb = 0; rsl_dec_chan_nr(bi->chan_nr, &type, &subch, &ts); //fn = ntohl(bi->frame_nr); ul = !!(ntohs(bi->band_arfcn) & ARFCN_UPLINK); //printf("fn %d ts %d ul %d snr %d ", fn, ts, ul, bi->snr); //printf(" sub %d\n", chan_detect(fn, ts, comb, &sub), sub); switch (type) { case RSL_CHAN_Lm_ACCHs: // interleaved user data and signalling break; case RSL_CHAN_Bm_ACCHs: if (bi->flags & BI_FLG_SACCH) { /* burst is SACCH/T */ process_ccch(s, &s->saccht[ul], bi); } else { //FIXME: detect type of channel /* try TCH (FACCH) */ //len = process_tch(s, bi, msg); /* try PDCH */ //len = process_pdch(s, bi, msg); } break; case RSL_CHAN_BCCH: //FIXME: check fn to know which type it really is case RSL_CHAN_SDCCH4_ACCH: //FIXME: check fn to know which type it really is case RSL_CHAN_SDCCH8_ACCH: //FIXME: check fn to know which type it really is if (bi->flags & BI_FLG_SACCH) { bb = &s->sacch; } else { bb = &s->sdcch; } process_ccch(s, bb, bi); break; case RSL_CHAN_RACH: case RSL_CHAN_PCH_AGCH: default: printf("Type not handled! %.02x\n", type); } return 0; }
static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg) { struct abis_rsl_rll_hdr *rllh = msgb_l2(msg); struct tlv_parsed tv; uint8_t ch_type, ch_subch, ch_ts; DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n", rllh->chan_nr, rllh->link_id); rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh)); if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) { DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n"); return -EIO; } msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO); if (state != SCAN_STATE_READ && state != SCAN_STATE_RACH) { return -EINVAL; } rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts); switch (ch_type) { case RSL_CHAN_PCH_AGCH: return pch_agch(ms, msg); case RSL_CHAN_BCCH: return bcch(ms, msg); #if 0 case RSL_CHAN_Bm_ACCHs: case RSL_CHAN_Lm_ACCHs: case RSL_CHAN_SDCCH4_ACCH: case RSL_CHAN_SDCCH8_ACCH: return rx_acch(ms, msg); #endif default: LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n", rllh->chan_nr); return -EINVAL; } }
static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg) { struct abis_rsl_rll_hdr *rllh = msgb_l2(msg); struct tlv_parsed tv; uint8_t ch_type, ch_subch, ch_ts; DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n", rllh->chan_nr, rllh->link_id); rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh)); if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) { DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n"); return -EIO; } msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO); rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts); switch (ch_type) { case RSL_CHAN_BCCH: return bcch(ms, msg); default: return 0; } }
/** * This method used to send a l1ctl_tx_dm_est_req_h0 or * a l1ctl_tx_dm_est_req_h1 to the layer1 to follow this * assignment. The code has been removed. */ static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms) { struct gsm48_imm_ass *ia = msgb_l3(msg); uint8_t ch_type, ch_subch, ch_ts; int rv; /* Discard packet TBF assignement */ if (ia->page_mode & 0xf0) return 0; /* If we're not ready yet, or just busy ... */ if ((!app_state.has_si1) || (app_state.dch_state != DCH_NONE)) return 0; rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts); if (!ia->chan_desc.h0.h) { /* Non-hopping */ uint16_t arfcn; arfcn = ia->chan_desc.h0.arfcn_low | (ia->chan_desc.h0.arfcn_high << 8); LOGP(DRR, LOGL_NOTICE, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, " "ARFCN=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra, ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch, ia->chan_desc.h0.tsc); /* request L1 to go to dedicated mode on assigned channel */ rv = l1ctl_tx_dm_est_req_h0(ms, arfcn, ia->chan_desc.chan_nr, ia->chan_desc.h0.tsc, GSM48_CMODE_SIGN, 0); } else { /* Hopping */ uint8_t maio, hsn, ma_len; uint16_t ma[64], arfcn; int i, j, k; hsn = ia->chan_desc.h1.hsn; maio = ia->chan_desc.h1.maio_low | (ia->chan_desc.h1.maio_high << 2); LOGP(DRR, LOGL_NOTICE, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, " "HSN=%u, MAIO=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra, ia->chan_desc.chan_nr, hsn, maio, ch_ts, ch_subch, ia->chan_desc.h1.tsc); /* decode mobile allocation */ ma_len = 0; for (i=1, j=0; i<=1024; i++) { arfcn = i & 1023; if (app_state.cell_arfcns[arfcn].mask & 0x01) { k = ia->mob_alloc_len - (j>>3) - 1; if (ia->mob_alloc[k] & (1 << (j&7))) { ma[ma_len++] = arfcn; } j++; } } /* request L1 to go to dedicated mode on assigned channel */ rv = l1ctl_tx_dm_est_req_h1(ms, maio, hsn, ma, ma_len, ia->chan_desc.chan_nr, ia->chan_desc.h1.tsc, GSM48_CMODE_SIGN, 0); }
/** * @brief Get the scheduled fn for a msg depending on its chan_nr and link_id. */ uint32_t sched_fn_ul(struct gsm_time cur_time, uint8_t chan_nr, uint8_t link_id) { uint8_t chan_type, chan_ss, chan_ts; uint32_t sched_fn = cur_time.fn; uint16_t mod_102 = cur_time.fn % 2 * 51; rsl_dec_chan_nr(chan_nr, &chan_type, &chan_ss, &chan_ts); /* TODO: Replace this spaghetti monster with some lookup table */ switch (chan_type) { case RSL_CHAN_Bm_ACCHs: switch (link_id) { case LID_DEDIC: /* dl=[0...11,13...24] ul=[0...11,13...24] * skip idle frames and frames reserved for TCH_ACCH */ if (cur_time.t2 == 12 || cur_time.t2 == 25) sched_fn++; break; /* dl=42, ul=42+15 */ case LID_SACCH: if ((chan_ts & 1)) { /* Odd traffic channel timeslot -> dl=[25] ul=[25] * TCH_ACCH always at the end of tch multiframe (mod 26) */ sched_fn -= cur_time.t2; sched_fn += 25; } else { /* Even traffic channel timeslot -> dl=[12] ul=[12] */ if (cur_time.t2 <= 12) { sched_fn -= cur_time.t2; sched_fn += 12; } else { sched_fn -= cur_time.t2; sched_fn += 26 + 12; } } break; } break; case RSL_CHAN_Lm_ACCHs: break; /* TCH/H not supported */ case RSL_CHAN_SDCCH4_ACCH: switch (chan_ss) { case 0: switch (link_id) { /* dl=22, ul=22+15 */ case LID_DEDIC: if (cur_time.t3 <= 22 + 15) { sched_fn -= cur_time.t3; sched_fn += 22 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 22 + 15; } break; /* dl=42, ul=42+15 */ case LID_SACCH: if (mod_102 <= 42 + 15) { sched_fn -= mod_102; sched_fn += 42 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 42 + 15; } break; } break; case 1: switch (link_id) { /* dl=26, ul=26+15 */ case LID_DEDIC: if (cur_time.t3 <= 26 + 15) { sched_fn -= cur_time.t3; sched_fn += 26 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 26 + 15; } break; /* dl=46, ul=46+15 */ case LID_SACCH: if (mod_102 <= 46 + 15) { sched_fn -= mod_102; sched_fn += 46 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 46 + 15; } break; } break; case 2: switch (link_id) { /* dl=32, ul=32+15 */ case LID_DEDIC: if (cur_time.t3 <= 32 + 15) { sched_fn -= cur_time.t3; sched_fn += 32 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 32 + 15; } break; /* dl=51+42, ul=51+42+15 */ case LID_SACCH: if (mod_102 <= 51 + 42 + 15) { sched_fn -= mod_102; sched_fn += 51 + 42 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 51 + 42 + 15; } break; } break; case 3: switch (link_id) { /* dl=36, ul=36+15 */ case LID_DEDIC: if (cur_time.t3 <= 36 + 15) { sched_fn -= cur_time.t3; sched_fn += 36 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 36 + 15; } break; /* dl=51+46, ul=51+46+15 */ case LID_SACCH: if (mod_102 <= 51 + 46 + 15) { sched_fn -= mod_102; sched_fn += 51 + 46 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 51 + 46 + 15; } break; } break; } break; case RSL_CHAN_SDCCH8_ACCH: switch (chan_ss) { case 0: switch (link_id) { /* dl=0, ul=0+15 */ case LID_DEDIC: if (cur_time.t3 <= 0 + 15) { sched_fn -= cur_time.t3; sched_fn += 0 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 0 + 15; } break; /* dl=32, ul=32+15 */ case LID_SACCH: if (mod_102 <= 32 + 15) { sched_fn -= mod_102; sched_fn += 32 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 32 + 15; } break; } break; case 1: switch (link_id) { /* dl=4, ul=4+15 */ case LID_DEDIC: if (cur_time.t3 <= 4 + 15) { sched_fn -= cur_time.t3; sched_fn += 4 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 4 + 15; } break; /* dl=36, ul=36+15 */ case LID_SACCH: if (mod_102 <= 36 + 15) { sched_fn -= mod_102; sched_fn += 36 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 36 + 15; } break; } break; case 2: switch (link_id) { /* dl=8, ul=8+15 */ case LID_DEDIC: if (cur_time.t3 <= 8 + 15) { sched_fn -= cur_time.t3; sched_fn += 8 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 8 + 15; } break; /* dl=40, ul=40+15 */ case LID_SACCH: if (mod_102 <= 40 + 15) { sched_fn -= mod_102; sched_fn += 40 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 40 + 15; } break; } break; case 3: switch (link_id) { /* dl=12, ul=12+15 */ case LID_DEDIC: if (cur_time.t3 <= 12 + 15) { sched_fn -= cur_time.t3; sched_fn += 12 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 12 + 15; } break; /* dl=44, ul=44+15 */ case LID_SACCH: if (mod_102 <= 44 + 15) { sched_fn -= mod_102; sched_fn += 44 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 44 + 15; } break; } break; case 4: switch (link_id) { /* dl=16, ul=16+15 */ case LID_DEDIC: if (cur_time.t3 <= 16 + 15) { sched_fn -= cur_time.t3; sched_fn += 16 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 16 + 15; } break; /* dl=51+32, ul=51+32+15 */ case LID_SACCH: if (mod_102 <= 51 + 32 + 15) { sched_fn -= mod_102; sched_fn += 51 + 32 + 15; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 51 + 32 + 15; } break; } break; case 5: switch (link_id) { /* dl=20, ul=36+15 */ case LID_DEDIC: if (cur_time.t3 <= 20 + 15) { sched_fn -= cur_time.t3; sched_fn += 20 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 20 + 15; } break; /* dl=51+36, ul=51+36+15 ==> 0 */ case LID_SACCH: if (mod_102 <= 0) { sched_fn -= mod_102; sched_fn += 0; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 0; } break; } break; case 6: switch (link_id) { /* dl=24, ul=24+15 */ case LID_DEDIC: if (cur_time.t3 <= 24 + 15) { sched_fn -= cur_time.t3; sched_fn += 24 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 24 + 15; } break; /* dl=51+40, ul=51+40+15 ==> 4 */ case LID_SACCH: if (mod_102 <= 4) { sched_fn -= mod_102; sched_fn += 4; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 4; } break; } break; case 7: switch (link_id) { /* dl=28, ul=28+15 */ case LID_DEDIC: if (cur_time.t3 <= 28 + 15) { sched_fn -= cur_time.t3; sched_fn += 28 + 15; } else { sched_fn -= cur_time.t3; sched_fn += 51 + 28 + 15; } break; /* dl=51+44, ul=51+44+15 ==> 8 */ case LID_SACCH: if (mod_102 <= 8) { sched_fn -= mod_102; sched_fn += 8; } else { sched_fn -= mod_102; sched_fn += 2 * 51 + 8; } break; } break; } break; case RSL_CHAN_RACH: break; /* Use virt_prim_rach.c for calculation of sched fn for rach */ default: break; /* Use current fn as default */ } return sched_fn; }
void parse_assignment(struct gsm48_hdr *hdr, unsigned len, struct gsm_sysinfo_freq *cell_arfcns, struct gsm_assignment *ga) { struct gsm48_ass_cmd *ac; struct gsm48_ho_cmd *hoc; struct gsm48_chan_desc *cd = NULL; int payload_len = 0; uint8_t *payload_data = NULL; struct tlv_parsed tp; uint8_t *ma = 0; uint8_t ma_len; uint8_t ch_type, ch_subch, ch_ts; unsigned i, mask; if (!ga) return; memset(ga, 0, sizeof(*ga)); /* handover */ if (hdr->msg_type == 0x2b) { if (len < (sizeof(*hdr) + sizeof(*hoc))) { return; } hoc = (struct gsm48_ho_cmd *) hdr->data; cd = &hoc->chan_desc; payload_len = len - sizeof(*hdr) - sizeof(*hoc); payload_data = hoc->data; ga->bcch_arfcn = hoc->cell_desc.arfcn_lo; ga->bcch_arfcn |= (hoc->cell_desc.arfcn_hi << 8); } /* assignment */ if (hdr->msg_type == 0x2e) { if (len < (sizeof(*hdr) + sizeof(*ac))) { return; } ac = (struct gsm48_ass_cmd *) hdr->data; cd = &ac->chan_desc; payload_len = len - sizeof(*hdr) - sizeof(*ac); payload_data = ac->data; } if (!cd) return; if (!payload_len) return; /* Parse TLV in the message */ tlv_parse(&tp, &gsm48_rr_att_tlvdef, payload_data, payload_len, 0, 0); ma_len = 0; ma = NULL; mask = 0; /* Cell channel description */ if (TLVP_PRESENT(&tp, GSM48_IE_CELL_CH_DESC)) { const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_CELL_CH_DESC); uint8_t len = TLVP_LEN(&tp, GSM48_IE_CELL_CH_DESC); gsm48_decode_freq_list(cell_arfcns, (uint8_t *) v, len, 0xff, 0x02); mask = 0x02; } else if (TLVP_PRESENT(&tp, GSM48_IE_MA_AFTER)) { /* Mobile allocation */ const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_MA_AFTER); uint8_t len = TLVP_LEN(&tp, GSM48_IE_MA_AFTER); ma_len = len; ma = (uint8_t *) v; mask = 0x01; } else if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_AFTER)) { /* Frequency list after time */ const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_FREQ_L_AFTER); uint8_t len = TLVP_LEN(&tp, GSM48_IE_FREQ_L_AFTER); gsm48_decode_freq_list(cell_arfcns, (uint8_t *) v, len, 0xff, 0x04); ma_len = 0; ma = NULL; mask = 0x04; } else { /* Use the old one */ for (i=0; i<1024; i++) { cell_arfcns[i].mask &= ~0x02; if (cell_arfcns[i].mask & 0x01) { cell_arfcns[i].mask |= 0x02; mask = 0x02; } } } /* Channel mode (HR/FR/EFR/AMR) */ if (TLVP_PRESENT(&tp, GSM48_IE_CHANMODE_1)) { const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_CHANMODE_1); //uint8_t len = TLVP_LEN(&tp, GSM48_IE_CHANMODE_1); ga->chan_mode = v[0]; } /* Multirate configuration */ if (TLVP_PRESENT(&tp, GSM48_IE_MUL_RATE_CFG)) { const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_MUL_RATE_CFG); //uint8_t len = TLVP_LEN(&tp, GSM48_IE_MUL_RATE_CFG); ga->rate_conf = v[1]; } rsl_dec_chan_nr(cd->chan_nr, &ch_type, &ch_subch, &ch_ts); ga->h = cd->h0.h; ga->chan_nr = cd->chan_nr; if (!ga->h) { /* Non-Hopping */ uint16_t arfcn = cd->h0.arfcn_low | (cd->h0.arfcn_high << 8); ga->tsc = cd->h0.tsc; ga->h0.band_arfcn = arfcn; } else { /* Hopping */ uint16_t arfcn; int i, j, k; ga->tsc = cd->h1.tsc; ga->h1.maio = cd->h1.maio_low | (cd->h1.maio_high << 2);; ga->h1.hsn = cd->h1.hsn; ga->h1.ma_len = 0; /* decode mobile allocation */ if (ma) { if (ma_len == 0) { return; } for (i=1, j=0; i<=1024; i++) { arfcn = i & 1023; if (cell_arfcns[arfcn].mask & mask) { k = ma_len - (j>>3) - 1; if (ma[k] & (1 << (j&7))) { ga->h1.ma[ga->h1.ma_len++] = arfcn; } j++; } } if (ga->h1.ma_len == 0) { /* cell information not found */ /* just compute ma_len */ for (i=0; i<(ma_len*8); i++){ int k = i/8; if (ma[k] & (1 << (i&7))) { ga->h1.ma_len++; } } } } else { for (i=1; i<=1024; i++) {
static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms) { struct gsm48_imm_ass *ia = msgb_l3(msg); uint8_t ch_type, ch_subch, ch_ts; int rv; /* Discard packet TBF assignement */ if (ia->page_mode & 0xf0) return 0; /* FIXME: compare RA and GSM time with when we sent RACH req */ rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts); if (!ia->chan_desc.h0.h) { /* Non-hopping */ uint16_t arfcn; arfcn = ia->chan_desc.h0.arfcn_low | (ia->chan_desc.h0.arfcn_high << 8); DEBUGP(DRR, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, " "ARFCN=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra, ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch, ia->chan_desc.h0.tsc); if (ch_ts >= 4) { DEBUGPC(DRR, "UNSUPPORTED!\n"); return 0; } /* request L1 to go to dedicated mode on assigned channel */ rv = l1ctl_tx_dm_est_req_h0(ms, arfcn, ia->chan_desc.chan_nr, ia->chan_desc.h0.tsc); } else { /* Hopping */ uint8_t maio, hsn, ma_len; uint16_t ma[64], arfcn; int i, j, k; hsn = ia->chan_desc.h1.hsn; maio = ia->chan_desc.h1.maio_low | (ia->chan_desc.h1.maio_high << 2); DEBUGP(DRR, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, " "HSN=%u, MAIO=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra, ia->chan_desc.chan_nr, hsn, maio, ch_ts, ch_subch, ia->chan_desc.h1.tsc); /* decode mobile allocation */ ma_len = 0; for (i=1, j=0; i<=1024; i++) { arfcn = i & 1023; if (app_state.cell_arfcns[arfcn].mask & 0x01) { k = ia->mob_alloc_len - (j>>3) - 1; if (ia->mob_alloc[k] & (1 << (j&7))) { ma[ma_len++] = arfcn; } j++; } } if (ch_ts >= 4) { DEBUGPC(DRR, "UNSUPPORTED!\n"); return 0; } /* request L1 to go to dedicated mode on assigned channel */ rv = l1ctl_tx_dm_est_req_h1(ms, maio, hsn, ma, ma_len, ia->chan_desc.chan_nr, ia->chan_desc.h1.tsc); }