1 /* RF Channel utilities */
3 /* (C) 2010 by Sylvain Munaut <tnt@246tNt.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <osmocom/gsm/gsm_utils.h>
27 #include <layer1/sync.h>
31 * Hopping sequence generation
33 * The algorithm is explained in GSM 05.02 Section 6.2.3
35 * if HSN = 0 (cyclic hopping) then:
36 * MAI, integer (0 .. N-1) :
37 * MAI = (FN + MAIO) modulo N
40 * M, integer (0 .. 152) :
41 * M = T2 + RNTABLE((HSN xor T1R) + T3)
43 * S, integer (0 .. N-1) :
44 * M' = M modulo (2 ^ NBIN)
45 * T' = T3 modulo (2 ^ NBIN)
50 * S = (M'+T') modulo N
52 * MAI, integer (0 .. N-1) :
53 * MAI = (S + MAIO) modulo N
56 static uint8_t rn_table[114] = {
57 48, 98, 63, 1, 36, 95, 78, 102, 94, 73,
58 0, 64, 25, 81, 76, 59, 124, 23, 104, 100,
59 101, 47, 118, 85, 18, 56, 96, 86, 54, 2,
60 80, 34, 127, 13, 6, 89, 57, 103, 12, 74,
61 55, 111, 75, 38, 109, 71, 112, 29, 11, 88,
62 87, 19, 3, 68, 110, 26, 33, 31, 8, 45,
63 82, 58, 40, 107, 32, 5, 106, 92, 62, 67,
64 77, 108, 122, 37, 60, 66, 121, 42, 51, 126,
65 117, 114, 4, 90, 43, 52, 53, 113, 120, 72,
66 16, 49, 7, 79, 119, 61, 22, 84, 9, 97,
67 91, 15, 21, 24, 46, 39, 93, 105, 65, 70,
72 static int pow_nbin_mask(int n)
85 static int16_t rfch_hop_seq_gen(struct gsm_time *t,
86 uint8_t hsn, uint8_t maio,
87 uint8_t n, uint16_t *arfcn_tbl)
93 mai = (t->fn + maio) % n;
95 /* pseudo random hopping */
96 int m, mp, tp, s, pnm;
98 pnm = pow_nbin_mask(n);
100 m = t->t2 + rn_table[(hsn ^ (t->t1 & 63)) + t->t3];
110 mai = (s + maio) % n;
113 return arfcn_tbl ? arfcn_tbl[mai] : mai;
117 /* RF Channel parameters */
118 void rfch_get_params(struct gsm_time *t,
119 uint16_t *arfcn_p, uint8_t *tsc_p, uint8_t *tn_p)
121 if (l1s.dedicated.type == GSM_DCHAN_NONE) {
122 /* Serving cell only */
124 *arfcn_p = l1s.serving_cell.arfcn;
127 *tsc_p = l1s.serving_cell.bsic & 0x7;
132 /* Dedicated channel */
134 if (l1s.dedicated.h) {
135 *arfcn_p = rfch_hop_seq_gen(t,
136 l1s.dedicated.h1.hsn,
137 l1s.dedicated.h1.maio,
139 l1s.dedicated.h1.ma);
141 *arfcn_p = l1s.dedicated.h0.arfcn;
146 *tsc_p = l1s.dedicated.tsc;
149 *tn_p = l1s.dedicated.tn;