From 900d1c1c9e67b89b570de201fea4d237e17d05f5 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 20 Feb 2008 16:52:34 +0000 Subject: major bugfixes in gsmdecode (fragmented packets) --- gsmdecode/src/data_out.c | 108 +++++++++++++++++++++++++++++++--------------- gsmdecode/src/data_out.h | 2 +- gsmdecode/src/gsmdecode.c | 17 ++++++-- 3 files changed, 89 insertions(+), 38 deletions(-) (limited to 'gsmdecode') diff --git a/gsmdecode/src/data_out.c b/gsmdecode/src/data_out.c index a419f58..873ea9e 100644 --- a/gsmdecode/src/data_out.c +++ b/gsmdecode/src/data_out.c @@ -77,6 +77,7 @@ static void l2_CCReleaseComplete(); static void l2_ChannelNeeded(char *str, unsigned char ch); static void l2_MNCC(const char *str, unsigned char a, unsigned char b, unsigned char c); +static void maio(); static char *BitRow(unsigned char c, int pos); static char *PageMode(unsigned char mode); static char *BitRowFill(unsigned char c, unsigned char mask); @@ -126,6 +127,7 @@ struct _nfo unsigned int flags; unsigned char seq_counter; unsigned char sapi; + int direction; /* 0 == downlink, 1 == uplink */ }; #define GSMSP_NFO_SMS (0x01) #define GSMSP_NFO_SEGMENTATION (0x02) @@ -156,11 +158,13 @@ struct _con { unsigned char buf[248 + 3]; unsigned char *ptr; + int logicalchannel; }; /* Is initialized to 0 (do not remove from .bss) */ static struct _sms_con sms_con; struct _con con[8]; +struct _con conuplink[8]; struct _con *conptr; @@ -169,18 +173,22 @@ struct _con *conptr; * B-format (and also A-Format) */ void -l2_data_out_B(int fn, const unsigned char *input_data, int len) +l2_data_out_B(int fn, const unsigned char *input_data, int len, int logicalchannel, int direction) { const unsigned char *from; + int val; data = input_data; start = data; end = data + len; - HEXDUMPF(data, 23 /*len*/, "Format B DATA\n"); + + HEXDUMPF(data, 23 /*len*/, "Format B DATA (%s)\n", direction?"up":"down"); + /* Need at least 3 octets */ if (data + 2 >= end) RETTRUNK(); memset(&nfo, 0, sizeof nfo); + nfo.direction = direction; dcch_address(); data++; dcch_control(); @@ -188,29 +196,36 @@ l2_data_out_B(int fn, const unsigned char *input_data, int len) /* FIXME: Why is extended length always set to 1? */ OUTF("%s EL, Extended Length: %s\n", BitRow(data[0], 0), (data[0] & 1)?"y":"n"); OUTF("%s M, segmentation: %c\n", BitRow(data[0], 1), ((data[0] >> 1) & 1)?'Y':'N'); + + /* Initialization. have to do this only once but there + * is no better place to do it atm + */ + if (conptr->ptr == NULL) + conptr->ptr = conptr->buf; + if ((data[0] >> 1) & 1) + { nfo.flags |= GSMSP_NFO_SEGMENTATION; + conptr->logicalchannel = logicalchannel; + } - OUTF("%s Length: %u\n", BitRowFill(data[0], 0xfc), data[0] >> 2); - if (data + (data[0] >> 2) < end) - end = data + (data[0] >> 2) + 1; + val = data[0] >> 2; + OUTF("%s Length: %u\n", BitRowFill(data[0], 0xfc), val); + if (data + val < end) + { + end = data + val + 1; + } data++; if (data >= end) return; - /* Initialization. have to do this only once but there - * is no better place to do it atm - */ - if (conptr->ptr == NULL) - conptr->ptr = conptr->buf; - /* Chunk of a fragmented. */ /* All SMS type messages go into the same buffer. * Other segmented messages are currently not supported. */ //if (nfo.flags & GSMSP_NFO_SMS) - if ((conptr->ptr > conptr->buf) || (nfo.flags & GSMSP_NFO_SEGMENTATION)) + if ((logicalchannel == conptr->logicalchannel) && ((conptr->ptr > conptr->buf) || (nfo.flags & GSMSP_NFO_SEGMENTATION))) { from = data; @@ -224,32 +239,41 @@ l2_data_out_B(int fn, const unsigned char *input_data, int len) } } - if (nfo.flags & GSMSP_NFO_SEGMENTATION) + //if (nfo.flags & GSMSP_NFO_SEGMENTATION) + if (conptr->ptr > conptr->buf) { - OUTF("-------- [MORE DATA FOLLOWS...]\n"); - /* More fragments follow. No need to decode yet */ - return; + if (nfo.flags & GSMSP_NFO_SEGMENTATION) + { + OUTF("-------- [SEGMENTED MESSAGE. MORE DATA FOLLOWS...]\n"); + /* More fragments follow. No need to decode yet */ + return; + } else + OUTF("-------- [SEGMENTED MESSAGE. LAST...]\n"); } /* Here: segmentation == No */ /* See if we get an SMS message and if this was the last fragment */ - if (conptr->ptr > conptr->buf) + /* Currently only 1 logical channel can contain segmented data. + * If there are two channels that both send segmented data + * then it's gettin muddled up. + */ + if ((logicalchannel == conptr->logicalchannel) && (conptr->ptr > conptr->buf)) { start = conptr->buf; data = conptr->buf; end = conptr->ptr; + if (nfo.flags & GSMSP_NFO_SMS) HEXDUMPF(data, end - data, "Format SMS data\n"); else HEXDUMPF(data, end - data, "Format Bbis (RR, MM or CC)\n"); + l2_Bbis(); conptr->ptr = conptr->buf; return; } - l2_Bbis(); - } static void @@ -326,7 +350,13 @@ dcch_address() { /* SAPI */ nfo.sapi = (data[0] >> 2) & 0x07; - conptr = &con[nfo.sapi]; + if (nfo.direction == 1) + { + conptr = &conuplink[nfo.sapi]; + } else { + conptr = &con[nfo.sapi]; + } + switch ((data[0] >> 2) & 0x07) { case 0x03: @@ -849,7 +879,7 @@ l2_RRimmediateAssignment() if ((data[0] >> 5) & 0x01) OUTF("--1----- Assigns a resource identified in the IA rest octets.\n"); else - OUTF("--0----- Downlink assig to MS: No meaning\n"); + OUTF("--0----- Downlink assign to MS: No meaning\n"); if ((data[0] >> 4) & 0x01) { OUTF("---1---- Temporary Block Flow (TBF)\n"); @@ -907,25 +937,33 @@ l2_SingleChannelC() static void l2_HoppingChannel() { - unsigned char maio = 0; OUTF("%s Training seq. code : %d\n", BitRowFill(data[0], 0xe0), data[0] >> 5); + + maio(); + RequestReference(); + TimingAdvance(); + l2_MobileAllocation(); + if (data >= end) + return; /* finished. not truncated! */ + + OUTF("FIXME, more data left here???\n"); +} + +static void +maio() +{ + unsigned char maio = 0; + OUTF("---1---- HoppingChannel\n"); maio = (data[0] & 0x0f) << 2; data++; if (data >= end) RETTRUNK(); maio |= (data[0] >> 6); - OUTF("........ MAIO %d\n", maio); + OUTF("........ Mobile Allocation Index Offset (MAIO) %d\n", maio); OUTF("%s Hopping Seq. Number: %d\n", BitRowFill(data[0], 0x3f), data[0] & 0x3f); data++; - RequestReference(); - TimingAdvance(); - l2_MobileAllocation(); - if (data >= end) - return; /* finished. not truncated! */ - - OUTF("FIXME, more data left here???\n"); } static void @@ -1817,8 +1855,8 @@ l2_RRimmAssTBFDirEncHoChaC() if (data >= end) RETTRUNK(); maio |= (data[0] >> 6); - OUTF("xxxxxxxx MAIO: %u\n", maio); - OUTF("%s HSN: %u\n", BitRowFill(data[0], 0x3f), data[0] & 0x3f); + OUTF("xxxxxxxx Mobile Allocation Index Offset (MAIO): %u\n", maio); + OUTF("%s Hopping Sequence Number: %u\n", BitRowFill(data[0], 0x3f), data[0] & 0x3f); data++; RequestReference(); @@ -1827,7 +1865,7 @@ l2_RRimmAssTBFDirEncHoChaC() l2_MobileAllocation(); if (data >= end) - RETTRUNK(); + return; if (data[0] == 0x7c) { StartingTime(); @@ -2601,7 +2639,9 @@ l2_SingleChannelAssCom() static void l2_HoppingChannelAssCom() { - OUTF("FIXME %s\n", __func__); + maio(); + OUTF("FIXME\n"); + } static void diff --git a/gsmdecode/src/data_out.h b/gsmdecode/src/data_out.h index 73da983..6d3f740 100644 --- a/gsmdecode/src/data_out.h +++ b/gsmdecode/src/data_out.h @@ -1,5 +1,5 @@ void l2_data_out_Bbis(int fn, const unsigned char *data, int len); -void l2_data_out_B(int fn, const unsigned char *data, int len); +void l2_data_out_B(int fn, const unsigned char *data, int len, int logicalchannel, int direction); diff --git a/gsmdecode/src/gsmdecode.c b/gsmdecode/src/gsmdecode.c index a2456d3..04d30ab 100644 --- a/gsmdecode/src/gsmdecode.c +++ b/gsmdecode/src/gsmdecode.c @@ -28,6 +28,7 @@ struct _ch_info unsigned char flags; int logical; int physical; + int direction; int fn; unsigned char data[23]; int data_len; @@ -120,6 +121,13 @@ xml_in(struct _ch_info *chinfo, unsigned char *str) xml_get_int(&chinfo->logical, str, (const unsigned char *)"logicalchannel"); // fprintf(stderr, "logical %u\n", chinfo->logical); + if (strstr((char *)str, "direction=\"up\"") != NULL) + { + chinfo->direction = 1; + } else if (strstr((char *)str, "direction=\"down\"") != NULL) { + chinfo->direction = 0; + } + /* Last see if there is a data="..." section. if so convert it into * binary and prefix it with pseudo length and up/down indicator * if required @@ -258,16 +266,19 @@ main(int argc, char *argv[]) if (chi.data_len <= 0) continue; if ((chi.logical == 112) || (chi.logical == 176) || (chi.logical == 128)) - l2_data_out_B(0, chi.data, chi.data_len); - else + { + l2_data_out_B(0, chi.data, chi.data_len, chi.logical, chi.direction); + } else { l2_data_out_Bbis(0, chi.data, chi.data_len); + } + memset(buf, 0, sizeof buf); continue; } memset(bin, 0, sizeof bin); len = hex2bin(bin, buf); if (opt.format == MSG_FORMAT_B) - l2_data_out_B(0, bin, len); + l2_data_out_B(0, bin, len, chi.logical, chi.direction); else l2_data_out_Bbis(0, bin, len); } -- cgit v1.2.3