This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/baseband-devel@lists.osmocom.org/.
bob wisebob avwiseav at gmail.comHi,List I found BB is a great project,and I want to study it. In my test network without encryption, I test the burst_id with dsp patch to capture the SMS, and also ,I patch the ccch_scan to capture the voice,but I met a few difficulty, but the amr voice file seems not good, I found it hard to find the error, anyone can help me? Thanks! the patch is following: static struct { int has_si1; int has_si3; int ccch_mode; int neci; int sys_count; enum dch_state_t dch_state; uint8_t dch_nr; int dch_badcnt; int dch_ciph; FILE * fh; sbit_t bursts_dl[116 * 4]; sbit_t bursts_ul[116 * 4]; sbit_t bursts_ccch[4][116*4]; sbit_t mI[8][114]; struct gsm_sysinfo_freq cell_arfcns[1024]; uint8_t kc[8]; } app_state; static char * void layer3_rx_burst(struct osmocom_ms *ms, struct msgb *msg) { struct l1ctl_burst_ind *bi; int16_t rx_dbm; uint16_t arfcn; int ul,do_rel=0; /* Header handling */ bi = (struct l1ctl_burst_ind *) msg->l1h; arfcn = ntohs(bi->band_arfcn); rx_dbm = rxlev2dbm(bi->rx_level); ul = !!(arfcn & ARFCN_UPLINK); if (app_state.dch_state == DCH_NONE) local_ccch_burst_decode(bi,ms); /* Check for channel start */ if (app_state.dch_state == DCH_WAIT_EST) { if (bi->chan_nr == app_state.dch_nr) { if (bi->snr > 64) { /* Change state */ app_state.dch_state = DCH_ACTIVE; app_state.dch_badcnt = 0; /* Open output */ //app_state.fh = fopen(gen_filename(ms, bi), "wb"); } else { /* Abandon ? */ do_rel = (app_state.dch_badcnt++) >= 4; } } } /* Check for channel end */ if (app_state.dch_state == DCH_ACTIVE) { if (!ul) { /* Bad burst counting */ if (bi->snr < 64) { app_state.dch_badcnt++; printf("sdcch app_state.dch_badcnt++\n"); } else if (app_state.dch_badcnt >= 2) app_state.dch_badcnt -= 2; else app_state.dch_badcnt = 0; /* Release condition */ do_rel = app_state.dch_badcnt >= 6; } } // when in TCH mode, we only measure the SACCH to kown the link quanlity if (app_state.dch_state == DCH_TCH) { //printf("app_state.dch_state == DCH_TCH\n"); if (!ul && (bi->flags & BI_FLG_SACCH)) { //printf("TCH SACCH\n"); /* Bad burst counting */ if (bi->snr < 40) { app_state.dch_badcnt++; printf("sacch app_state.dch_badcnt++\n"); } else if (app_state.dch_badcnt >= 2) app_state.dch_badcnt -= 2; else app_state.dch_badcnt = 0; /* Release condition */ do_rel = app_state.dch_badcnt >= 6; } } /* Release ? */ if (do_rel) { printf("The Delicate Channel is released because of bad SNR!\n"); /* L1 release */ l1ctl_tx_dm_rel_req(ms); l1ctl_tx_fbsb_req(ms, ms->test_arfcn, L1CTL_FBSB_F_FB01SB, 100, 0, app_state.ccch_mode); /* Change state */ app_state.dch_state = DCH_WAIT_REL; app_state.dch_badcnt = 0; app_state.dch_ciph = 0; /* Close output */ if (app_state.fh) { fclose(app_state.fh); app_state.fh = NULL; } } /* Save the burst */ if (app_state.dch_state == DCH_ACTIVE || app_state.dch_state == DCH_TCH) //fwrite(bi, sizeof(*bi), 1, app_state.fh); /* Try local decoding */ if (!ul && (app_state.dch_state == DCH_ACTIVE || app_state.dch_state == DCH_TCH)) local_burst_decode(ms,bi); } static void local_burst_decode(struct osmocom_ms *ms,struct l1ctl_burst_ind *bi) { int16_t rx_dbm; uint16_t arfcn; uint32_t fn; uint8_t cbits, tn, lch_idx; int ul, bid, i, d_tch_mode; sbit_t *bursts; ubit_t bt[116]; /* Get params (Only for SDCCH and SACCH/{4,8,F,H}) */ arfcn = ntohs(bi->band_arfcn); rx_dbm = rxlev2dbm(bi->rx_level); fn = ntohl(bi->frame_nr); ul = !!(arfcn & ARFCN_UPLINK); bursts = ul ? app_state.bursts_ul : app_state.bursts_dl; cbits = bi->chan_nr >> 3; tn = bi->chan_nr & 7; bid = -1; if (cbits == 0x01) { /* TCH/F */ lch_idx = 0; if (bi->flags & BI_FLG_SACCH) { uint32_t fn_report; fn_report = (fn - (tn * 13) + 104) % 104; bid = (fn_report - 12) / 26; printf(" SACCH fn = %d fn_report = %d\n",fn,fn_report); }else{ //printf(" TCH/F \n"); process_tch_f(ms,bi); } } else if ((cbits & 0x1e) == 0x02) { /* TCH/H */ lch_idx = cbits & 1; if (bi->flags & BI_FLG_SACCH) { uint32_t fn_report; uint8_t tn_report = (tn & ~1) | lch_idx; fn_report = (fn - (tn_report * 13) + 104) % 104; bid = (fn_report - 12) / 26; } } else if ((cbits & 0x1c) == 0x04) { /* SDCCH/4 */ lch_idx = cbits & 3; bid = bi->flags & 3; printf(" SDCCH/4\n"); } else if ((cbits & 0x18) == 0x08) { /* SDCCH/8 */ lch_idx = cbits & 7; bid = bi->flags & 3; //printf(" SDCCH/8\n"); } if (bid == -1) return; /* Clear if new set */ if (bid == 0) memset(bursts, 0x00, 116 * 4); /* Unpack (ignore hu/hl) */ osmo_pbit2ubit_ext(bt, 0, bi->bits, 0, 57, 0); osmo_pbit2ubit_ext(bt, 59, bi->bits, 57, 57, 0); bt[57] = bt[58] = 1; /* A5/x */ if (app_state.dch_ciph) { ubit_t ks_dl[114], ks_ul[114], *ks = ul ? ks_ul : ks_dl; osmo_a5(app_state.dch_ciph, app_state.kc, fn, ks_dl, ks_ul); for (i= 0; i< 57; i++) bt[i] ^= ks[i]; for (i=59; i<116; i++) bt[i] ^= ks[i-2]; } /* Convert to softbits */ for (i=0; i<116; i++) bursts[(116*bid)+i] = bt[i] ? - (bi->snr >> 1) : (bi->snr >> 1); /* If last, decode */ if (bid == 3) { uint8_t l2[23]; int rv,i; struct gsm48_ass_cmd *ia; uint8_t ch_type, ch_subch, ch_ts; uint8_t chan_req_val, chan_req_mask, ra; rv = xcch_decode(l2, bursts); if((l2[0] == 0x03) && (l2[4] == 0x2e)) { ia =(struct gsm48_ass_cmd *)&l2[5]; rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts); //l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED); printf("Jump to TCH Channel\n"); d_tch_mode = GSM48_CMODE_SPEECH_EFR; /* open speech file and configure d_tch_decoders */ switch (d_tch_mode) { case GSM48_CMODE_SPEECH_V1: d_speech_file = fopen( "speech.au.gsm", "wb" ); break; case GSM48_CMODE_SPEECH_EFR: d_speech_file = fopen( gen_filename(ms,bi), "wb" ); fwrite(amr_nb_magic, 1, 6, d_speech_file); /* Write header */ break; default: d_speech_file = NULL; } app_state.dch_state = DCH_TCH; 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, "ASS CMD(chan_nr=0x%02x, " "ARFCN=%u, TS=%u, SS=%u, TSC=%u) ", 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_SPEECH_EFR, 0); } #ifdef TCH_HOPPING else { /* Hopping is not support now! */ 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, "ASS CMD( chan_nr=0x%02x, " "HSN=%u, MAIO=%u, TS=%u, SS=%u, TSC=%u) ", 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_SPEECH_EFR, 0); } #endif } if (rv == 0) { uint8_t chan_type, chan_ts, chan_ss; uint8_t gsmtap_chan_type; /* Send to GSMTAP */ rsl_dec_chan_nr(bi->chan_nr, &chan_type, &chan_ss, &chan_ts); gsmtap_chan_type = chantype_rsl2gsmtap( chan_type, bi->flags & BI_FLG_SACCH ? 0x40 : 0x00 ); gsmtap_send(gsmtap_inst, arfcn, chan_ts, gsmtap_chan_type, chan_ss, ntohl(bi->frame_nr), bi->rx_level, bi->snr, l2, sizeof(l2) ); /* Crude CIPH.MOD.COMMAND detect */ if ((l2[3] == 0x06) && (l2[4] == 0x35) && (l2[5] & 1)) app_state.dch_ciph = 1 + ((l2[5] >> 1) & 7); } } } void tch_deinterleave(ubit_t *mC, int blockOffset) { int k; for (k = 0; k < 456; k++) { int B = ( k + blockOffset ) % 8; int j = 2 * ((49 * k) % 57) + ((k % 8) / 4); mC[k] = app_state.mI[B][j]; app_state.mI[B][j] = 0; //OBJDCOUT("deinterleave k="<<k<<" B="<<B<<" j="<<j); } } void tch_unmap(const uint16_t *map, size_t mapSize, ubit_t * dest, ubit_t * soure) { unsigned int i; for(i=0; i<mapSize; i++) { dest[map[i]] = soure[i]; } } void tch_map(const uint16_t *map, size_t mapSize, ubit_t * dest, ubit_t * soure) { unsigned int i; for(i=0; i<mapSize; i++) { dest[i] = soure[map[i]]; } } void fillField(ubit_t *mStart, size_t writeIndex, uint64_t value, unsigned length) { char *dpBase = mStart + writeIndex; char *dp = dpBase + length - 1; while (dp>=dpBase) { *dp-- = value & 0x01; value >>= 1; } } uint64_t count_tch = 0; static void process_tch_f(struct osmocom_ms *ms,struct l1ctl_burst_ind *bi) { int16_t rx_dbm; uint16_t arfcn; uint32_t fn,B; uint8_t cbits, tn, lch_idx; int ul, bid, i, k, length; sbit_t *bursts, mC[456]; ubit_t bt[114],convu[189],convd[189],tch_raw[260],TCHW[260],EFRBits[244],EFRAMR[8 + 244]; pbit_t voice[33]; /* Get params (Only for SDCCH and SACCH/{4,8,F,H}) */ arfcn = ntohs(bi->band_arfcn); rx_dbm = rxlev2dbm(bi->rx_level); fn = ntohl(bi->frame_nr); ul = !!(arfcn & ARFCN_UPLINK); cbits = bi->chan_nr >> 3; tn = bi->chan_nr & 7; B = -1; B = count_tch % 8; if (B == -1) return; /* Clear if new set */ if (B == 0){ for(i=0; i<4; i++){ memset(app_state.mI[i], 0x00, 114); } }else if(B == 4){ for(i=4; i<8; i++){ memset(app_state.mI[i], 0x00, 114); } } /* Unpack (ignore hu/hl) */ osmo_pbit2ubit_ext(bt, 0, bi->bits, 0, 57, 0); osmo_pbit2ubit_ext(bt, 57, bi->bits, 57, 57, 0); /* Convert to softbits */ for (i=0; i<114; i++) app_state.mI[B][i] = bt[i] ? - (bi->snr >> 1) : (bi->snr >> 1); count_tch++; // Deinterleave according to the diagonal "phase" of B. // See GSM 05.03 3.1.3. // Deinterleaves i[] to c[] if((B % 4 ==3)&&(count_tch >= 7)){ if(B == 3) { tch_deinterleave(mC, 4); }else{ tch_deinterleave(mC, 0); } for (k = 0; k < 78; k++) { tch_raw[182 + k] = mC[378 +k]; } osmo_conv_decode(&conv_tch_afs_12_2, mC, convu); // 3.1.2.1 // copy class 1 bits u[] to d[] for (k = 0; k <= 90; k++) { convd[2*k] = convu[k]; convd[2*k+1] = convu[184-k]; } memcpy(tch_raw,convd,182); // the last 78 bit has been stored! //now only process EFR or AMR 12_2, fix me! tch_unmap(gsm660_bitorder, 260, TCHW, tch_raw); // Remove repeating bits and CRC to get raw EFR frame (244 bits) for (k=0; k<71; k++) EFRBits[k] = TCHW[k] & 1; for (k=73; k<123; k++) EFRBits[k-2] = TCHW[k] & 1; for (k=125; k<178; k++) EFRBits[k-4] = TCHW[k] & 1; for (k=180; k<230; k++) EFRBits[k-6] = TCHW[k] & 1; for (k=232; k<252; k++) EFRBits[k-8] = TCHW[k] & 1; // Map bits as AMR 12.2k tch_map(gsm690_12_2_bitorder, 244, EFRAMR + 8,EFRBits); // Put the whole frame (hdr + payload) //mVFrameAMR.pack(mPrevGoodFrame); //mPrevGoodFrameLength = 32; fillField(EFRAMR, 0, 0x3c, 8); voice[32] = 0; length = osmo_ubit2pbit(voice, EFRAMR, 8 + 244); fwrite(voice, 1, 32, d_speech_file); } } -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/baseband-devel/attachments/20120618/aa14166f/attachment.htm>