my patch for decode using burst_id
bob wisebob
avwiseav at gmail.com
Mon Jun 18 10:32:52 CEST 2012
Hi,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-0001.html>
More information about the baseband-devel
mailing list