Bug #3803

fix frame number calculation in scheduler_trx

Added by dexter almost 2 years ago. Updated about 1 year ago.

Target version:
Start date:
Due date:
% Done:


Spec Reference:


In rx_tchh_fn() and rx_tchh_fn() there is a formula used to calculate the frame number of the block that is passed up to the higher layers. The two functions collect a set of bursts and when complete, it is passed up. At the moment there are two indications generated when a block is completed. A measurement indication and a tch indication. Both should use the same fn. But the current implementation uses the stored *first_fn for the measurement indication and a formular that gets the fn of the last received block for the tch indication. Both seems to be incorrect because we need to take into account that TCH blocks are interleaved over 8 bursts. We need to tag each block with its starting frame number. To get this correct we need to check the formulas and make sure that the measurement indication and the tch indication use the same fn.

main.c main.c 1.68 KB dexter, 09/27/2019 10:04 AM

Related issues

Related to OsmoBTS - Feature #2977: OsmoBTS measurment processing at L1SAP too complex / pass measurements along with dataStalled02/21/2018

Related to OsmoBTS - Bug #3572: Incorrect TDMA frame number calculation on TCH channelsClosed09/19/2018

Related to OsmoBTS - Feature #3530: merge PRIM_INFO_MEAS into PRIM_PH_DATA and PRIM_TCHRejected09/06/2018


#1 Updated by dexter almost 2 years ago

  • Related to Feature #2977: OsmoBTS measurment processing at L1SAP too complex / pass measurements along with data added

#2 Updated by dexter almost 2 years ago

The first attempt to fix this was to use *first_fn for the tch indications because it sounded logical that the first_fn is indeed the first frame number but it turned out that the burst we see is not really the first burst where the block started. Due to the interleaving the block started earlier than first_fn indicates.

See also: (This patch also marks the locations in the code that are problematic)

#3 Updated by dexter almost 2 years ago

See also #2987 for information about the burst interleaving.

#4 Updated by dexter almost 2 years ago

Regarding the burst interleaving lets focus on TCH/F first. Each voice block is distributed over 8 half bursts like so:

       A       A 
   V       V       V

A and V are just markers for blocks which are ready and passed on. T shall be the left half and t shall be the right half. This means that every 4th burst one block gets finished, so we have the illusion that one block is distributed over 4 consecutive bursts, which we see in scheduler_trx.c. So as soon as we see the first burst of the block, we are in reality already at the 2nd of 8 bursts. So the formula basically calculates fn-7, so that looks correct and we could also use *first_fn-1 to get the same result.

I am now asking myself how the SACCH fits int this scheme. The 51 multiframe layout is basically 3 complete blocks, then a SACCH burst, and then again 3 complete blocks. Does the SACCH then use both half bursts at once or is it somehow blurring into to the voice blocks? To me it does not look like this.

T = Single traffic channel burst
I = Idle
M = Measurement report
          1         2         3         4         5         6         7         8         9         0
            v            v            v            v            v            v            v            v

interval start                                                                              interval end
M   M   M   MM   M   M    M   M   M    M   M   M    M   M   M    M   M   M    M   M   M    M   M   M    

I think we also should trace back where the fn and bit of rx_tchf_fn() comes from and how it is generated. This will presumably come more or less directly from osmo-trx.

#5 Updated by fixeria almost 2 years ago

In trxcon, I introduced a few functions for TCH/H and FACCH/H frame number calculations.
Please see:

In short, we define the block mappings, coming from GSM 05.02, clause 7, table 1,
i.e. *_block_map[X][Y], where each X is a block, and Y is:

  • fn % 13 for TCH/H
  • fn % 26 for FACCH/H

for example:

/* TCH/H speech block mapping for sub-slot 0 */
static const uint8_t tch_h0_traffic_block_map[3][4] = {
    /* B0(0,2,4,6), B1(4,6,8,10), B2(8,10,0,2) */
    { 0, 2, 4, 6 },
    { 4, 6, 8, 10 },
    { 8, 10, 0, 2 },

/* TCH/H speech block mapping for sub-slot 1 */
static const uint8_t tch_h1_traffic_block_map[3][4] = {
    /* B0(1,3,5,7), B1(5,7,9,11), B2(9,11,1,3) */
    { 1, 3, 5, 7 },
    { 5, 7, 9, 11 },
    { 9, 11, 1, 3 },

As you can see, the frame numbers of consequent blocks are overlapping.
This is due to the block diagonal interleaving - every TCH/H speech
block (4 bursts) has 50% bits of one L2 frame, 25% bits of the
previous one, and 25% of the next L2 frame.

The algorithm of finding the first TDMA frame number of a block using
the last one is simple:

1) Choose the corresponding block mapping definition. For TCH/H, there
are two block maps - sub-slot 0 and sub-slot 1. For FACCH/H, we
additionally need to distinguish between Uplink and Downlink,
having four maps in total.

2) Iterate over the chosen block mapping, and compare the last TDMA frame
number of each block with a given fn % 26.

3) If the matching block is found, you can compare the difference
between the first TDMA frame number of a block and the last one.

4) Finally, you can subtract this difference from a given last TDMA
frame number to get the first one.

Most likely, the proposed approach still needs some improvements.
While writing this description, I discovered that in case of TCH/H,
the difference between first and last TDMA frame numbers is almost
constant - 6, excluding both { 8, 10, 0, 2 } and { 9, 11, 1, 3 },
where it's 7. In case of FACCH/H, it's either 10, or 11.

For TCH/F it should be even simpler, as both TCH/F and FACCH/F
block types are interleaved over 8 consecutive bursts, unlike
4 and 6 in case of TCH/H and FACCH/H.

I would really love to see the final implementation as a part of
libosmogsm (new gsm_05_02.c?), so it could be also used by trxcon.

#6 Updated by fixeria almost 2 years ago

I am now asking myself how the SACCH fits int this scheme. The 51 multiframe layout is basically 3 complete blocks,
then a SACCH burst, and then again 3 complete blocks. Does the SACCH then use both half bursts at once or is it
somehow blurring into to the voice blocks? To me it does not look like this.

SACCH has dedicated slots in both TCH/F and TCH/H multi-frames, and doesn't use block-diagonal interleaving.
It works in the same way as any other xCCH - 4 consecutive bursts, so the *first_fn can be safely used.

If you actually meant FACCH, then the situation is different. FACCH has no dedicated blocks on the multi-frame
layout. Instead, one FACCH/F frame replaces one TCH/F (speech or CSD data) frame, and this is indicated by
stealing bits of burst. FACCH/F is interleaved over 8 consecutive bursts, just like a regular TCH/F frame.

Unlike FACCH/F, a FACCH/H frame is interleaved over 6 consecutive bursts, and replaces two regular TCH/H
frames. This is also indicated by stealing bits. This is why we have both dl_ongoing_facch and ul_ongoing_facch
variables - as soon as we have decoded a FACCH/H frame, we need to skip the next decoding attempt, because
we still shift the buffer by two bursts.

#7 Updated by fixeria almost 2 years ago

... and feel free to look at the multi-frame layouts, it simplifies a lot:

#8 Updated by fixeria almost 2 years ago

  • Related to Bug #3572: Incorrect TDMA frame number calculation on TCH channels added

#9 Updated by dexter over 1 year ago

  • Status changed from New to In Progress

fixeria thanks for your hints!

I have picked this one up again now. I have worked myself now through the frame number scheduling model. I think I now understood the scheduling of regular TCH frames in TCH/F and TCH/H now. I do not yet know how it exactly works for FACCH, I think it might not be much different only that the TCH frame becomes a SACCH frame when the stealing bits are set. With the SACCH frames I already have been in contact with wile analyzing the measurement problems we have. I will look deeper into this at next.

In any case I can say that with TCH/F we are off by one on every third block and with TCH/H we of by multiple frames, so the formula there seems to be just wrong.

I have verified my assumptions against osmo-bts-trx (we get the expected error) and osmo-bts-sysmo, where we get the exact frame numbers I have derived from the model I have created to get my head around this.

Since I now have some proven examples and a model that works I can start writing some functions for libosmocore that will calculate the start-frame number for a given end-frame number.

Here are some of my notes:

Block transmission plan:

          1         2         3         4         5         6         7         8         9         0
            v            v            v            v            v            v            v            v

       A        A       A        A        A       A        A        A       A        A        A       A 
           V        V        V       V        V        V       V        V        V       V        V        V

The blocks are diagonal interleaved. This means that each burst carrie indeed
only one half of a specific block. Since the blocks are inserted with a skew of
four bursts, every four bursts a full block can be reconstructed. This gives us
the illusion that each burst would carry 1/4 of a block, but in reality it
carries only 1/8 of two different blocks.

A and V mark the position where one block becomes ready. The frame number of
this position is the frame number of the end of a block However, this is not
the frame number we need. By defintion the block has to be tagged with the
frame number of its beginning, so we need to move back and look up the position
of the the beginning of the block.

Frame numbers derived from the model above:

Fn%104    Burst  Fn%104
last    loc.   first
3    V*     99
7    A      0
11    V      4
16    A      8
20    V      13
24    A      17
29    V      21
33    A      26
37    V      30
42    A      34
46    V      39
50    A      43
55    V      47
59    A      52
63    V      56
68    A      60
72    V      65
76    A      69
81    V      73
85    A      78
89    V      82
94    A      86
98    V      91
102    A      95

A = Frame constructed from left side of the burst
V = Frame constructed from right side of the burst
* = Frame contains 4 half-bursts from the previous group of 104 frames

Formula to derive the frame number in the code:

fn2 = (bi->fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME;

==> Makes no sense as the SACCH frames are not taken into accound. The formula
    only works when the bursts of the frames are not interrupted by an idle
    frame or an SACCH frame. If there is an interruption in between, the
    computed frame number will be one off.

==> This also explains why first_fn is unusable, this also does not take the
    SACCH / Ilde-Frames into account.

Verfifcation with real data from osmo-bts-trx:

Every third frame number is off by one because SACCH/idle frames are not

=====> TCH DONE: fn=538424, fn104=16 ---- fn2=538417, fn2104=9    ==> off by +one!
=====> TCH DONE: fn=538428, fn104=20 ---- fn2=538421, fn2104=13
=====> TCH DONE: fn=538432, fn104=24 ---- fn2=538425, fn2104=17
=====> TCH DONE: fn=538437, fn104=29 ---- fn2=538430, fn2104=22    ==> off by +one!
=====> TCH DONE: fn=538441, fn104=33 ---- fn2=538434, fn2104=26
=====> TCH DONE: fn=538445, fn104=37 ---- fn2=538438, fn2104=30
=====> TCH DONE: fn=538450, fn104=42 ---- fn2=538443, fn2104=35    ==> off by +one!
=====> TCH DONE: fn=538454, fn104=46 ---- fn2=538447, fn2104=39
=====> TCH DONE: fn=538458, fn104=50 ---- fn2=538451, fn2104=43
=====> TCH DONE: fn=538463, fn104=55 ---- fn2=538456, fn2104=48    ==> off by +one!
=====> TCH DONE: fn=538467, fn104=59 ---- fn2=538460, fn2104=52
=====> TCH DONE: fn=538471, fn104=63 ---- fn2=538464, fn2104=56
=====> TCH DONE: fn=538476, fn104=68 ---- fn2=538469, fn2104=61    ==> off by +one!
=====> TCH DONE: fn=538480, fn104=72 ---- fn2=538473, fn2104=65
=====> TCH DONE: fn=538484, fn104=76 ---- fn2=538477, fn2104=69
=====> TCH DONE: fn=538489, fn104=81 ---- fn2=538482, fn2104=74    ==> off by +one!
=====> TCH DONE: fn=538493, fn104=85 ---- fn2=538486, fn2104=78
=====> TCH DONE: fn=538497, fn104=89 ---- fn2=538490, fn2104=82
=====> TCH DONE: fn=538502, fn104=94 ---- fn2=538495, fn2104=87    ==> off by +one!
=====> TCH DONE: fn=538506, fn104=98 ---- fn2=538499, fn2104=91
=====> TCH DONE: fn=538510, fn104=102 ---- fn2=538503, fn2104=95
=====> TCH DONE: fn=538515, fn104=3 ---- fn2=538508, fn2104=100    ==> off by +one!
=====> TCH DONE: fn=538519, fn104=7 ---- fn2=538512, fn2104=0
=====> TCH DONE: fn=538523, fn104=11 ---- fn2=538516, fn2104=4

==> This is expected since we already assume that the calculation in
    osmo-bts-trx is wrong.

Verfifcation with real data from osmo-bts-sysmo:

======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15699, u32Fn%104=99
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15704, u32Fn%104=0
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15708, u32Fn%104=4
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15712, u32Fn%104=8
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15717, u32Fn%104=13
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15721, u32Fn%104=17
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15725, u32Fn%104=21
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15730, u32Fn%104=26
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15734, u32Fn%104=30
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15738, u32Fn%104=34
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15743, u32Fn%104=39
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15747, u32Fn%104=43
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15751, u32Fn%104=47
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15756, u32Fn%104=52
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15760, u32Fn%104=56
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15764, u32Fn%104=60
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15769, u32Fn%104=65
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15773, u32Fn%104=69
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15777, u32Fn%104=73
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15782, u32Fn%104=78
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15786, u32Fn%104=82
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15790, u32Fn%104=86
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15795, u32Fn%104=91
======> GOT FRAME! u8Tn=3, subCh=31, u32Fn=15799, u32Fn%104=95

==> The result matches thet tables which are derived from the model above.
    The phy of the sysmoBTS outputs exactly the same frame numbers, so we
    can conclude the the model above is correct.

Block transmission plan:
          1         2         3         4         5         6         7         8         9         0
            v            v            v            v            v            v            v            v

  A^      A^       A^       A^      A^       A^       A^      A^       A^       A^      A^       A^
      Vv       Vv      Vv       Vv       Vv      Vv       Vv       Vv      Vv       Vv       Vv      Vv    

A/V = Burst ready for SS0
v/^ = Burst ready for SS1

Frame numbers derived from the model above:

Fn%104    Burst  Fn%104
last    loc.   first
2    A*     99
6    V      0
10    A      4
15    V      8
19    A      13
23    V      17
28    A      21
32    V      26
36    A      30
41    V      34
45    A      39
49    V      43
54    A      47
58    V      52
62    A      56
67    V      60
71    A      65
75    V      69
80    A      73
84    V      78
88    A      82
93    V      86
97    A      91
101    V      95

Fn%104    Burst  Fn%104
last    loc.   first
3    ^*     100
7    v      1
11    ^      5
16    v      9
20    ^      14
24    v      18
29    ^      22 
33    v      27
37    ^      31
42    v      35
46    ^      40
50    v      44
55    ^      48
59    v      53
63    ^      57
68    v      61
72    ^      66
76    v      70
81    ^      74
85    v      79
89    ^      83
94    v      87
98    ^      92
102    v      96

A = Frame constructed from left side of the burst, SS0
V = Frame constructed from right side of the burst, SS0
^ = Frame constructed from left side of the burst, SS1
v = Frame constructed from right side of the burst, SS1
* = Frame contains 4 half-bursts from the previous group of 104 frames

Verfifcation with real data from osmo-bts-trx:

The calculation in osmo-bts-trx is done as follows:
fn2 = (bi->fn + GSM_HYPERFRAME - 10 - ((bi->fn%26)==19) - ((bi->fn%26)==20)) % GSM_HYPERFRAME;

=====> TCH DONE: fn=178466, fn104=2, lchan=0, fn2=178456, fn2104=96    ==> off by -one
=====> TCH DONE: fn=178470, fn104=6, lchan=0, fn2=178460, fn2104=100    ==> off by +3
=====> TCH DONE: fn=178474, fn104=10, lchan=0, fn2=178464, fn2104=0
=====> TCH DONE: fn=178479, fn104=15, lchan=0, fn2=178469, fn2104=5
=====> TCH DONE: fn=178483, fn104=19, lchan=0, fn2=178472, fn2104=8
=====> TCH DONE: fn=178487, fn104=23, lchan=0, fn2=178477, fn2104=13
=====> TCH DONE: fn=178492, fn104=28, lchan=0, fn2=178482, fn2104=18
=====> TCH DONE: fn=178496, fn104=32, lchan=0, fn2=178486, fn2104=22
=====> TCH DONE: fn=178500, fn104=36, lchan=0, fn2=178490, fn2104=26
=====> TCH DONE: fn=178505, fn104=41, lchan=0, fn2=178495, fn2104=31
=====> TCH DONE: fn=178509, fn104=45, lchan=0, fn2=178498, fn2104=34
=====> TCH DONE: fn=178513, fn104=49, lchan=0, fn2=178503, fn2104=39
=====> TCH DONE: fn=178518, fn104=54, lchan=0, fn2=178508, fn2104=44
=====> TCH DONE: fn=178522, fn104=58, lchan=0, fn2=178512, fn2104=48
=====> TCH DONE: fn=178526, fn104=62, lchan=0, fn2=178516, fn2104=52
=====> TCH DONE: fn=178531, fn104=67, lchan=0, fn2=178521, fn2104=57
=====> TCH DONE: fn=178535, fn104=71, lchan=0, fn2=178524, fn2104=60
=====> TCH DONE: fn=178539, fn104=75, lchan=0, fn2=178529, fn2104=65
=====> TCH DONE: fn=178544, fn104=80, lchan=0, fn2=178534, fn2104=70
=====> TCH DONE: fn=178548, fn104=84, lchan=0, fn2=178538, fn2104=74
=====> TCH DONE: fn=178552, fn104=88, lchan=0, fn2=178542, fn2104=78
=====> TCH DONE: fn=178557, fn104=93, lchan=0, fn2=178547, fn2104=83
=====> TCH DONE: fn=178561, fn104=97, lchan=0, fn2=178550, fn2104=86
=====> TCH DONE: fn=178565, fn104=101, lchan=0, fn2=178555, fn2104=91

=====> TCH DONE: fn=178467, fn104=3, lchan=1, fn2=178457, fn2104=97
=====> TCH DONE: fn=178471, fn104=7, lchan=1, fn2=178461, fn2104=101
=====> TCH DONE: fn=178475, fn104=11, lchan=1, fn2=178465, fn2104=1
=====> TCH DONE: fn=178480, fn104=16, lchan=1, fn2=178470, fn2104=6
=====> TCH DONE: fn=178484, fn104=20, lchan=1, fn2=178473, fn2104=9
=====> TCH DONE: fn=178488, fn104=24, lchan=1, fn2=178478, fn2104=14
=====> TCH DONE: fn=178493, fn104=29, lchan=1, fn2=178483, fn2104=19
=====> TCH DONE: fn=178497, fn104=33, lchan=1, fn2=178487, fn2104=23
=====> TCH DONE: fn=178501, fn104=37, lchan=1, fn2=178491, fn2104=27
=====> TCH DONE: fn=178506, fn104=42, lchan=1, fn2=178496, fn2104=32
=====> TCH DONE: fn=178510, fn104=46, lchan=1, fn2=178499, fn2104=35
=====> TCH DONE: fn=178514, fn104=50, lchan=1, fn2=178504, fn2104=40
=====> TCH DONE: fn=178519, fn104=55, lchan=1, fn2=178509, fn2104=45
=====> TCH DONE: fn=178523, fn104=59, lchan=1, fn2=178513, fn2104=49
=====> TCH DONE: fn=178527, fn104=63, lchan=1, fn2=178517, fn2104=53
=====> TCH DONE: fn=178532, fn104=68, lchan=1, fn2=178522, fn2104=58
=====> TCH DONE: fn=178536, fn104=72, lchan=1, fn2=178525, fn2104=61
=====> TCH DONE: fn=178540, fn104=76, lchan=1, fn2=178530, fn2104=66
=====> TCH DONE: fn=178545, fn104=81, lchan=1, fn2=178535, fn2104=71
=====> TCH DONE: fn=178549, fn104=85, lchan=1, fn2=178539, fn2104=75
=====> TCH DONE: fn=178553, fn104=89, lchan=1, fn2=178543, fn2104=79
=====> TCH DONE: fn=178558, fn104=94, lchan=1, fn2=178548, fn2104=84
=====> TCH DONE: fn=178562, fn104=98, lchan=1, fn2=178551, fn2104=87
=====> TCH DONE: fn=178566, fn104=102, lchan=1, fn2=178556, fn2104=92

==> The results are very fare off, however this is expected as we already
    assume that the formula above is wrong.

Verfifcation with real data from osmo-bts-sysmo:

======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19131, u32Fn%104=99
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19136, u32Fn%104=0
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19140, u32Fn%104=4
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19144, u32Fn%104=8
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19149, u32Fn%104=13
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19153, u32Fn%104=17
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19157, u32Fn%104=21
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19162, u32Fn%104=26
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19166, u32Fn%104=30
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19170, u32Fn%104=34
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19175, u32Fn%104=39
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19179, u32Fn%104=43
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19183, u32Fn%104=47
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19188, u32Fn%104=52
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19192, u32Fn%104=56
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19196, u32Fn%104=60
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19201, u32Fn%104=65
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19205, u32Fn%104=69
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19209, u32Fn%104=73
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19214, u32Fn%104=78
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19218, u32Fn%104=82
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19222, u32Fn%104=86
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19227, u32Fn%104=91
======> GOT FRAME! u8Tn=2, subCh=0, u32Fn=19231, u32Fn%104=95

======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19236, u32Fn%104=100
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19241, u32Fn%104=1
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19245, u32Fn%104=5
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19249, u32Fn%104=9
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19254, u32Fn%104=14
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19258, u32Fn%104=18
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19262, u32Fn%104=22
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19267, u32Fn%104=27
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19271, u32Fn%104=31
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19275, u32Fn%104=35
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19280, u32Fn%104=40
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19284, u32Fn%104=44
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19288, u32Fn%104=48
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19293, u32Fn%104=53
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19297, u32Fn%104=57
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19301, u32Fn%104=61
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19306, u32Fn%104=66
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19310, u32Fn%104=70
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19314, u32Fn%104=74
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19319, u32Fn%104=79
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19323, u32Fn%104=83
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19327, u32Fn%104=87
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19332, u32Fn%104=92
======> GOT FRAME! u8Tn=2, subCh=1, u32Fn=19336, u32Fn%104=96

==> The result matches thet tables which are derived from the model above.
    The phy of the sysmoBTS outputs exactly the same frame numbers, so we
    can conclude the the model above is correct.

#10 Updated by dexter over 1 year ago

For For TCH_F I think the soultion is quite simple. It looks like that the formula fn2 = (bi->fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME; is not so wrong as it looks. It just contains a little thinking mistake. The constant -7 can be replaced with a distance value from a table with three possible values (7,7,8).

For my experiment I get results that look correct:

fn=1036987, fn104=3, fn13=3, sub=8, fn_map=1036979, fn_map104=99
fn=1036991, fn104=7, fn13=7, sub=7, fn_map=1036984, fn_map104=0
fn=1036995, fn104=11, fn13=11, sub=7, fn_map=1036988, fn_map104=4
fn=1037000, fn104=16, fn13=3, sub=8, fn_map=1036992, fn_map104=8
fn=1037004, fn104=20, fn13=7, sub=7, fn_map=1036997, fn_map104=13
fn=1037008, fn104=24, fn13=11, sub=7, fn_map=1037001, fn_map104=17
fn=1037013, fn104=29, fn13=3, sub=8, fn_map=1037005, fn_map104=21
fn=1037017, fn104=33, fn13=7, sub=7, fn_map=1037010, fn_map104=26
fn=1037021, fn104=37, fn13=11, sub=7, fn_map=1037014, fn_map104=30
fn=1037026, fn104=42, fn13=3, sub=8, fn_map=1037018, fn_map104=34
fn=1037030, fn104=46, fn13=7, sub=7, fn_map=1037023, fn_map104=39
fn=1037034, fn104=50, fn13=11, sub=7, fn_map=1037027, fn_map104=43
fn=1037039, fn104=55, fn13=3, sub=8, fn_map=1037031, fn_map104=47
fn=1037043, fn104=59, fn13=7, sub=7, fn_map=1037036, fn_map104=52
fn=1037047, fn104=63, fn13=11, sub=7, fn_map=1037040, fn_map104=56
fn=1037052, fn104=68, fn13=3, sub=8, fn_map=1037044, fn_map104=60
fn=1037056, fn104=72, fn13=7, sub=7, fn_map=1037049, fn_map104=65
fn=1037060, fn104=76, fn13=11, sub=7, fn_map=1037053, fn_map104=69
fn=1037065, fn104=81, fn13=3, sub=8, fn_map=1037057, fn_map104=73
fn=1037069, fn104=85, fn13=7, sub=7, fn_map=1037062, fn_map104=78
fn=1037073, fn104=89, fn13=11, sub=7, fn_map=1037066, fn_map104=82
fn=1037078, fn104=94, fn13=3, sub=8, fn_map=1037070, fn_map104=86
fn=1037082, fn104=98, fn13=7, sub=7, fn_map=1037075, fn_map104=91
fn=1037086, fn104=102, fn13=11, sub=7, fn_map=1037079, fn_map104=95
fn=1037091, fn104=3, fn13=3, sub=8, fn_map=1037083, fn_map104=99
fn=1037095, fn104=7, fn13=7, sub=7, fn_map=1037088, fn_map104=0
fn=1037099, fn104=11, fn13=11, sub=7, fn_map=1037092, fn_map104=4
fn=1037104, fn104=16, fn13=3, sub=8, fn_map=1037096, fn_map104=8
fn=1037108, fn104=20, fn13=7, sub=7, fn_map=1037101, fn_map104=13
fn=1037112, fn104=24, fn13=11, sub=7, fn_map=1037105, fn_map104=17
fn=1037117, fn104=29, fn13=3, sub=8, fn_map=1037109, fn_map104=21
fn=1037121, fn104=33, fn13=7, sub=7, fn_map=1037114, fn_map104=26
fn=1037125, fn104=37, fn13=11, sub=7, fn_map=1037118, fn_map104=30
fn=1037130, fn104=42, fn13=3, sub=8, fn_map=1037122, fn_map104=34
fn=1037134, fn104=46, fn13=7, sub=7, fn_map=1037127, fn_map104=39
fn=1037138, fn104=50, fn13=11, sub=7, fn_map=1037131, fn_map104=43
fn=1037143, fn104=55, fn13=3, sub=8, fn_map=1037135, fn_map104=47
fn=1037147, fn104=59, fn13=7, sub=7, fn_map=1037140, fn_map104=52
fn=1037151, fn104=63, fn13=11, sub=7, fn_map=1037144, fn_map104=56
fn=1037156, fn104=68, fn13=3, sub=8, fn_map=1037148, fn_map104=60
fn=1037160, fn104=72, fn13=7, sub=7, fn_map=1037153, fn_map104=65
fn=1037164, fn104=76, fn13=11, sub=7, fn_map=1037157, fn_map104=69
fn=1037169, fn104=81, fn13=3, sub=8, fn_map=1037161, fn_map104=73
fn=1037173, fn104=85, fn13=7, sub=7, fn_map=1037166, fn_map104=78
fn=1037177, fn104=89, fn13=11, sub=7, fn_map=1037170, fn_map104=82
fn=1037182, fn104=94, fn13=3, sub=8, fn_map=1037174, fn_map104=86
fn=1037186, fn104=98, fn13=7, sub=7, fn_map=1037179, fn_map104=91
fn=1037190, fn104=102, fn13=11, sub=7, fn_map=1037183, fn_map104=95
fn=1037195, fn104=3, fn13=3, sub=8, fn_map=1037187, fn_map104=99
fn=1037199, fn104=7, fn13=7, sub=7, fn_map=1037192, fn_map104=0
fn=1037203, fn104=11, fn13=11, sub=7, fn_map=1037196, fn_map104=4
fn=1037208, fn104=16, fn13=3, sub=8, fn_map=1037200, fn_map104=8
fn=1037212, fn104=20, fn13=7, sub=7, fn_map=1037205, fn_map104=13
fn=1037216, fn104=24, fn13=11, sub=7, fn_map=1037209, fn_map104=17
fn=1037221, fn104=29, fn13=3, sub=8, fn_map=1037213, fn_map104=21
fn=1037225, fn104=33, fn13=7, sub=7, fn_map=1037218, fn_map104=26
fn=1037229, fn104=37, fn13=11, sub=7, fn_map=1037222, fn_map104=30
fn=1037234, fn104=42, fn13=3, sub=8, fn_map=1037226, fn_map104=34
fn=1037238, fn104=46, fn13=7, sub=7, fn_map=1037231, fn_map104=39
fn=1037242, fn104=50, fn13=11, sub=7, fn_map=1037235, fn_map104=43
fn=1037247, fn104=55, fn13=3, sub=8, fn_map=1037239, fn_map104=47
fn=1037251, fn104=59, fn13=7, sub=7, fn_map=1037244, fn_map104=52
fn=1037255, fn104=63, fn13=11, sub=7, fn_map=1037248, fn_map104=56
fn=1037260, fn104=68, fn13=3, sub=8, fn_map=1037252, fn_map104=60
fn=1037264, fn104=72, fn13=7, sub=7, fn_map=1037257, fn_map104=65
fn=1037268, fn104=76, fn13=11, sub=7, fn_map=1037261, fn_map104=69
fn=1037273, fn104=81, fn13=3, sub=8, fn_map=1037265, fn_map104=73
fn=1037277, fn104=85, fn13=7, sub=7, fn_map=1037270, fn_map104=78
fn=1037281, fn104=89, fn13=11, sub=7, fn_map=1037274, fn_map104=82
fn=1037286, fn104=94, fn13=3, sub=8, fn_map=1037278, fn_map104=86
fn=1037290, fn104=98, fn13=7, sub=7, fn_map=1037283, fn_map104=91
fn=1037294, fn104=102, fn13=11, sub=7, fn_map=1037287, fn_map104=95

#11 Updated by dexter over 1 year ago

  • % Done changed from 10 to 30

I have now improved my testcode so that it computes correct correct frame numbers for TCH/H0, TCH/H1 and TCH/F. The tables for this (blockend/distance) are computed automatically from traffic block mappings of the follwing format:

/* TCH/H speech block mapping for sub-slot 0 */
static const uint8_t tch_h0_traffic_block_map[3][4] = {
    /* B0(0,2,4,6), B1(4,6,8,10), B2(8,10,0,2) */
    { 0, 2, 4, 6 },
    { 4, 6, 8, 10 },
    { 8, 10, 0, 2 },

The Idea about this is that those formats are basically 1:1 what GSM 05.02, Section 7 Table 2 of 5 lists. Using this format as input makes the implementation less error prone because we can just go to the pdf and copy+past what is listed there. I wrote some code that takes those tables as they are and computes the block-ending / distance values we need for the block ending calculation from that tables. The computation of those values is done once at startup to minimize the effort a bit.

Since I now get correct values for TCH/F, TCH/H0 and TCH/H1 I need to get my head around the FACCH.

I also revisited the code to identify the locations where we use the fn weongly:

    l1sap.u.rach_ind.fn = bi->fn;

    l1if_process_meas_res(l1t->trx, bi->tn, *first_fn, ...
    return _sched_compose_ph_data_ind(l1t, bi->tn, *first_fn,...

    l1if_process_meas_res(l1t->trx, bi->tn, *first_fn,
    return _sched_compose_ph_data_ind(l1t, bi->tn,
                      *first_fn, chan, l2, rc,....

    l1if_process_meas_res(l1t->trx, bi->tn, *first_fn,
    _sched_compose_ph_data_ind(l1t, bi->tn,
        /* FIXME: this calculation is wrong */
        (bi->fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME, chan, .... (FACCH)
    return _sched_compose_tch_ind(l1t, bi->tn,
        /* FIXME: this calculation is wrong */
        (bi->fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME, chan,

    l1if_process_meas_res(l1t->trx, bi->tn,
        *first_fn /* FIXME: this is wrong */,

    _sched_compose_ph_data_ind(l1t, bi->tn,
        /* FIXME: what the hell is this?!? */
        (bi->fn + GSM_HYPERFRAME - 10 - ((bi->fn % 26) >= 19)) % GSM_HYPERFRAME, chan,
        tch_data + amr, GSM_MACBLOCK_LEN,

    return _sched_compose_tch_ind(l1t, bi->tn,
        /* FIXME: what the hell is this?!? */
        (bi->fn + GSM_HYPERFRAME - 10 - ((bi->fn%26)==19) - ((bi->fn%26)==20)) % GSM_HYPERFRAME,
        chan, tch_data, rc);

#12 Updated by dexter over 1 year ago

  • % Done changed from 30 to 50

I now have looked at the FACCH scheduling and I think I got this right now as well. For FACCH/F thinks seem to be easy, the scheduling is the same as for a TCH/F. For TCH/H the FACCH is scheduled a little bit odd. I was expecting 8 bursts for one FACCH block, but GSM 05.02 specifies 6 bursts, but the model looks consistent. Here are some of my notes:


Block transmission plan:

Note: For FACCH/F, the transmission plan is the same as for TCH/F, therefore the
      beginning of the a FACCH/F block can be calculated the same way as for
      TCH/F blocks.

Test data from osmo-bts-sysmo:

=====> ph_data_ind with fn=21718, fn104=86
=====> ph_data_ind with fn=21749, fn104=13
=====> ph_data_ind with fn=21779, fn104=43
=====> ph_data_ind with fn=22633, fn104=65
=====> ph_data_ind with fn=22667, fn104=99
=====> ph_data_ind with fn=24123, fn104=99
=====> ph_data_ind with fn=24158, fn104=30
=====> ph_data_ind with fn=24193, fn104=65

==> Data seems to be correct as all fn104 values can also be found in the
    resulting test data for TCH/F

Test data from osmo-bts-trx:

=====> FACCH DONE: fn=177275, fn104=59 ---- fn2=177268, fn2104=52
=====> FACCH DONE: fn=177314, fn104=98 ---- fn2=177307, fn2104=91
=====> FACCH DONE: fn=177336, fn104=16 ---- fn2=177329, fn2104=9 (off by +one)
=====> FACCH DONE: fn=177375, fn104=55 ---- fn2=177368, fn2104=48 (off by +one)
=====> FACCH DONE: fn=177396, fn104=76 ---- fn2=177389, fn2104=69
=====> FACCH DONE: fn=177435, fn104=11 ---- fn2=177428, fn2104=4
=====> FACCH DONE: fn=178328, fn104=72 ---- fn2=178321, fn2104=65
=====> FACCH DONE: fn=178367, fn104=7 ---- fn2=178360, fn2104=0
=====> FACCH DONE: fn=178393, fn104=33 ---- fn2=178386, fn2104=26
=====> FACCH DONE: fn=180014, fn104=94 ---- fn2=180007, fn2104=87 (off by +one)
=====> FACCH DONE: fn=180053, fn104=29 ---- fn2=180046, fn2104=22 (off by +one)
=====> FACCH DONE: fn=180079, fn104=55 ---- fn2=180072, fn2104=48 (off by +one)
=====> FACCH DONE: fn=180113, fn104=89 ---- fn2=180106, fn2104=82
=====> FACCH DONE: fn=180144, fn104=16 ---- fn2=180137, fn2104=9 (off by +one)
=====> FACCH DONE: fn=180183, fn104=55 ---- fn2=180176, fn2104=48 (off by +one)

==> The data shows the same problems we already see for a regular TCH/F. The
    calculation is wrong here in ths same way, correct would be the following:

fn=177275, fn104=59, fn13=7, sub=7, fn_map=177268, fn_map104=52
fn=177314, fn104=98, fn13=7, sub=7, fn_map=177307, fn_map104=91
fn=177336, fn104=16, fn13=3, sub=8, fn_map=177328, fn_map104=8
fn=177375, fn104=55, fn13=3, sub=8, fn_map=177367, fn_map104=47
fn=177396, fn104=76, fn13=11, sub=7, fn_map=177389, fn_map104=69
fn=177435, fn104=11, fn13=11, sub=7, fn_map=177428, fn_map104=4
fn=178328, fn104=72, fn13=7, sub=7, fn_map=178321, fn_map104=65
fn=178367, fn104=7, fn13=7, sub=7, fn_map=178360, fn_map104=0
fn=178393, fn104=33, fn13=7, sub=7, fn_map=178386, fn_map104=26
fn=180014, fn104=94, fn13=3, sub=8, fn_map=180006, fn_map104=86
fn=180053, fn104=29, fn13=3, sub=8, fn_map=180045, fn_map104=21
fn=180079, fn104=55, fn13=3, sub=8, fn_map=180071, fn_map104=47
fn=180113, fn104=89, fn13=11, sub=7, fn_map=180106, fn_map104=82
fn=180144, fn104=16, fn13=3, sub=8, fn_map=180136, fn_map104=8
fn=180183, fn104=55, fn13=3, sub=8, fn_map=180175, fn_map104=47


Block transmission plan:
          1         2         3         4         5         6         7         8         9         0
            v            v            v            v            v            v            v            v

  A^      A^       A^       A^      A^       A^       A^      A^       A^       A^      A^       A^

A/V = Burst ready for SS0
v/^ = Burst ready for SS1
Note: One FACCH block is 6 bursts long

Test data from osmo-bts-trx:

=====> FACCH DONE: fn=499956, fn104=28, lchan=0, fn2=499946, fn2104=18 (off by +one)
=====> FACCH DONE: fn=499999, fn104=71, lchan=0, fn2=499988, fn2104=60
=====> FACCH DONE: fn=500034, fn104=2, lchan=0, fn2=500024, fn2104=96 (off by +one)
=====> FACCH DONE: fn=500077, fn104=45, lchan=0, fn2=500066, fn2104=34
=====> FACCH DONE: fn=500952, fn104=88, lchan=0, fn2=500942, fn2104=78
=====> FACCH DONE: fn=501836, fn104=36, lchan=0, fn2=501826, fn2104=26
=====> FACCH DONE: fn=501880, fn104=80, lchan=0, fn2=501870, fn2104=70 (off by +one)
=====> FACCH DONE: fn=502850, fn104=10, lchan=0, fn2=502840, fn2104=0
=====> FACCH DONE: fn=502894, fn104=54, lchan=0, fn2=502884, fn2104=44 (off by +one)
=====> FACCH DONE: fn=502937, fn104=97, lchan=0, fn2=502926, fn2104=86
=====> FACCH DONE: fn=503006, fn104=62, lchan=0, fn2=502996, fn2104=52
=====> FACCH DONE: fn=503050, fn104=2, lchan=0, fn2=503040, fn2104=96 (off by +one)

Correct would be:
fn=499956, fn104=28, fn_cycle=2, sub=11, fn_map=499945, fn_map104=17
fn=499999, fn104=71, fn_cycle=19, sub=11, fn_map=499988, fn_map104=60
fn=500034, fn104=2, fn_cycle=2, sub=11, fn_map=500023, fn_map104=95
fn=500077, fn104=45, fn_cycle=19, sub=11, fn_map=500066, fn_map104=34
fn=500952, fn104=88, fn_cycle=10, sub=10, fn_map=500942, fn_map104=78
fn=501836, fn104=36, fn_cycle=10, sub=10, fn_map=501826, fn_map104=26
fn=501880, fn104=80, fn_cycle=2, sub=11, fn_map=501869, fn_map104=69
fn=502850, fn104=10, fn_cycle=10, sub=10, fn_map=502840, fn_map104=0
fn=502894, fn104=54, fn_cycle=2, sub=11, fn_map=502883, fn_map104=43
fn=502937, fn104=97, fn_cycle=19, sub=11, fn_map=502926, fn_map104=86
fn=503006, fn104=62, fn_cycle=10, sub=10, fn_map=502996, fn_map104=52
fn=503050, fn104=2, fn_cycle=2, sub=11, fn_map=503039, fn_map104=95

=====> FACCH DONE: fn=500728, fn104=72, lchan=1, fn2=500717, fn2104=61
=====> FACCH DONE: fn=500771, fn104=11, lchan=1, fn2=500761, fn2104=1
=====> FACCH DONE: fn=500797, fn104=37, lchan=1, fn2=500787, fn2104=27
=====> FACCH DONE: fn=500841, fn104=81, lchan=1, fn2=500831, fn2104=71 (off by +one)
=====> FACCH DONE: fn=500875, fn104=11, lchan=1, fn2=500865, fn2104=1
=====> FACCH DONE: fn=500919, fn104=55, lchan=1, fn2=500909, fn2104=45 (off by +one)
=====> FACCH DONE: fn=501751, fn104=55, lchan=1, fn2=501741, fn2104=45 (off by +one)
=====> FACCH DONE: fn=501794, fn104=98, lchan=1, fn2=501783, fn2104=87
=====> FACCH DONE: fn=501837, fn104=37, lchan=1, fn2=501827, fn2104=27
=====> FACCH DONE: fn=502782, fn104=46, lchan=1, fn2=502771, fn2104=35
=====> FACCH DONE: fn=502825, fn104=89, lchan=1, fn2=502815, fn2104=79
=====> FACCH DONE: fn=502869, fn104=29, lchan=1, fn2=502859, fn2104=19 (off by +one)
=====> FACCH DONE: fn=502903, fn104=63, lchan=1, fn2=502893, fn2104=53
=====> FACCH DONE: fn=502955, fn104=11, lchan=1, fn2=502945, fn2104=1
=====> FACCH DONE: fn=502999, fn104=55, lchan=1, fn2=502989, fn2104=45 (off by +one)

Correct would be:
fn=500728, fn104=72, fn_cycle=20, sub=11, fn_map=500717, fn_map104=61
fn=500771, fn104=11, fn_cycle=11, sub=10, fn_map=500761, fn_map104=1
fn=500797, fn104=37, fn_cycle=11, sub=10, fn_map=500787, fn_map104=27
fn=500841, fn104=81, fn_cycle=3, sub=11, fn_map=500830, fn_map104=70
fn=500875, fn104=11, fn_cycle=11, sub=10, fn_map=500865, fn_map104=1
fn=500919, fn104=55, fn_cycle=3, sub=11, fn_map=500908, fn_map104=44
fn=501751, fn104=55, fn_cycle=3, sub=11, fn_map=501740, fn_map104=44
fn=501794, fn104=98, fn_cycle=20, sub=11, fn_map=501783, fn_map104=87
fn=501837, fn104=37, fn_cycle=11, sub=10, fn_map=501827, fn_map104=27
fn=502782, fn104=46, fn_cycle=20, sub=11, fn_map=502771, fn_map104=35
fn=502825, fn104=89, fn_cycle=11, sub=10, fn_map=502815, fn_map104=79
fn=502869, fn104=29, fn_cycle=3, sub=11, fn_map=502858, fn_map104=18
fn=502903, fn104=63, fn_cycle=11, sub=10, fn_map=502893, fn_map104=53
fn=502955, fn104=11, fn_cycle=11, sub=10, fn_map=502945, fn_map104=1
fn=502999, fn104=55, fn_cycle=3, sub=11, fn_map=502988, fn_map104=44

Test data from osmo-bts-sysmo:

=====> ph_data_ind with fn=21164, fn104=52, chan_nr=18
=====> ph_data_ind with fn=21207, fn104=95, chan_nr=18
=====> ph_data_ind with fn=21640, fn104=8, chan_nr=18
=====> ph_data_ind with fn=22360, fn104=0, chan_nr=18
=====> ph_data_ind with fn=23972, fn104=52, chan_nr=18
=====> ph_data_ind with fn=24024, fn104=0, chan_nr=18
=====> ph_data_ind with fn=24076, fn104=52, chan_nr=18

=====> ph_data_ind with fn=21520, fn104=96, chan_nr=26
=====> ph_data_ind with fn=21555, fn104=27, chan_nr=26
=====> ph_data_ind with fn=21598, fn104=70, chan_nr=26
=====> ph_data_ind with fn=22300, fn104=44, chan_nr=26
=====> ph_data_ind with fn=22352, fn104=96, chan_nr=26
=====> ph_data_ind with fn=24016, fn104=96, chan_nr=26
=====> ph_data_ind with fn=24068, fn104=44, chan_nr=26
=====> ph_data_ind with fn=24103, fn104=79, chan_nr=26

==> Looks correct as all values matches the model above

So I think we are almost there, but before we Integrate this is in libosmocore / osmo-bts-trx, we sould also look closer at rx_data_fn and the SACCH. SACCH caused a lot of trouble in the past and I want to make sure that everything is correct here. As far as I know the function uses first_fn to determine the beginning frame number. This may be even correct since we do not have any diagonal interleaving on the SACCH but we will see.

#13 Updated by dexter over 1 year ago

  • % Done changed from 50 to 60

I have now added a remap function to libosmocore that can remap TCH and FACCH frame numbers. I did not include SACCH since the amount of additional lookuptables would be large. Each timeslot requires its own table since the SACCH ending is different for every timeslot. However since SAACH is not affected by the diagonal interleaving we can safely rely on the first_fn here. gsm0508: add functions to calculate beginning of a block

#14 Updated by dexter over 1 year ago

  • % Done changed from 60 to 80

I have now integrated the change into libosmocore, so with this patch we should get correct frame numbers now. scheduler_trx: use gsm0502_fn_remap() to calculate frame number

#15 Updated by dexter over 1 year ago

  • Related to Feature #3530: merge PRIM_INFO_MEAS into PRIM_PH_DATA and PRIM_TCH added

#16 Updated by dexter over 1 year ago

The libosmocore and the osmo-bts patch is still under review. Once we have resolved this we can move on with #3530

#17 Updated by fixeria over 1 year ago

I have been working on the Uplink measurement processing, and sporadically came up with the idea that frame numbers can be handled in the same way. Please see the following changes: osmo-bts-trx/scheduler: refactor Uplink measurement processing osmo-bts-trx/scheduler: refactor the first frame number calculation

From the commit message:

This is not a silver bullet, because in some cases the measurement
history may be incomplete (until we start handling NOPE.ind from
the transceiver, see OS#3428). In such cases we would still need
to look up the first frame number using the block mapping tables
defined in 3GPP TS 45.002.

so it does not mean that the work done by dexter goes to /dev/null.

#18 Updated by dexter about 1 year ago

  • % Done changed from 80 to 90

As far as I can see the frame number calculation functions are now in libosmocore. The patch for osmo-bts seems to be ready for merge, however before we merge we should run the TTCN3 tests one last time in docker to be sure nothing behaves oddly.

#19 Updated by dexter about 1 year ago

  • Status changed from In Progress to Resolved
  • % Done changed from 90 to 100

The related patches are merged. We are now getting correct frame numbers from osmo-bts-trx.

Also available in: Atom PDF

Add picture from clipboard (Maximum size: 48.8 MB)