Piotr Krysik | 70c25a1 | 2017-01-03 08:01:23 +0100 | [diff] [blame] | 1 | /* |
| 2 | * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu> |
| 3 | * (C) 2016 by Tom Tsou <tom.tsou@ettus.com> |
| 4 | * |
| 5 | * All Rights Reserved |
| 6 | * |
Piotr Krysik | 9e2e835 | 2018-02-27 12:16:25 +0100 | [diff] [blame] | 7 | * SPDX-License-Identifier: GPL-2.0+ |
| 8 | * |
Piotr Krysik | 70c25a1 | 2017-01-03 08:01:23 +0100 | [diff] [blame] | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | * it under the terms of the GNU General Public License as published by |
| 11 | * the Free Software Foundation; either version 2 of the License, or |
| 12 | * (at your option) any later version. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | * GNU General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU General Public License along |
| 20 | * with this program; if not, write to the Free Software Foundation, Inc., |
| 21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 22 | */ |
| 23 | |
| 24 | #include <stdint.h> |
| 25 | #include <string.h> |
| 26 | |
| 27 | #include <osmocom/core/bits.h> |
Piotr Krysik | 9e2e835 | 2018-02-27 12:16:25 +0100 | [diff] [blame] | 28 | #include <osmocom/coding/gsm0503_mapping.h> |
| 29 | |
| 30 | /*! \addtogroup mapping |
| 31 | * @{ |
| 32 | * |
| 33 | * GSM TS 05.03 burst mapping |
| 34 | * |
| 35 | * This module contains burst mapping routines as specified in 3GPP TS |
| 36 | * 05.03 / 45.003. |
| 37 | * |
| 38 | * \file gsm0503_mapping.c */ |
Piotr Krysik | 70c25a1 | 2017-01-03 08:01:23 +0100 | [diff] [blame] | 39 | |
| 40 | void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, |
| 41 | sbit_t *hl, sbit_t *hn) |
| 42 | { |
| 43 | memcpy(iB, eB, 57); |
| 44 | memcpy(iB + 57, eB + 59, 57); |
| 45 | |
| 46 | if (hl) |
| 47 | *hl = eB[57]; |
| 48 | |
| 49 | if (hn) |
| 50 | *hn = eB[58]; |
| 51 | } |
| 52 | |
Piotr Krysik | 9e2e835 | 2018-02-27 12:16:25 +0100 | [diff] [blame] | 53 | void gsm0503_xcch_burst_map(const ubit_t *iB, ubit_t *eB, const ubit_t *hl, |
Piotr Krysik | 70c25a1 | 2017-01-03 08:01:23 +0100 | [diff] [blame] | 54 | const ubit_t *hn) |
| 55 | { |
| 56 | memcpy(eB, iB, 57); |
| 57 | memcpy(eB + 59, iB + 57, 57); |
| 58 | |
| 59 | if (hl) |
| 60 | eB[57] = *hl; |
| 61 | if (hn) |
| 62 | eB[58] = *hn; |
| 63 | } |
| 64 | |
Piotr Krysik | 9e2e835 | 2018-02-27 12:16:25 +0100 | [diff] [blame] | 65 | void gsm0503_tch_burst_unmap(sbit_t *iB, const sbit_t *eB, sbit_t *h, int odd) |
Piotr Krysik | 70c25a1 | 2017-01-03 08:01:23 +0100 | [diff] [blame] | 66 | { |
| 67 | int i; |
| 68 | |
| 69 | /* brainfuck: only copy even or odd bits */ |
| 70 | if (iB) { |
| 71 | for (i = odd; i < 57; i += 2) |
| 72 | iB[i] = eB[i]; |
| 73 | for (i = 58 - odd; i < 114; i += 2) |
| 74 | iB[i] = eB[i + 2]; |
| 75 | } |
| 76 | |
| 77 | if (h) { |
| 78 | if (!odd) |
| 79 | *h = eB[58]; |
| 80 | else |
| 81 | *h = eB[57]; |
| 82 | } |
| 83 | } |
| 84 | |
Piotr Krysik | 9e2e835 | 2018-02-27 12:16:25 +0100 | [diff] [blame] | 85 | void gsm0503_tch_burst_map(const ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd) |
Piotr Krysik | 70c25a1 | 2017-01-03 08:01:23 +0100 | [diff] [blame] | 86 | { |
| 87 | int i; |
| 88 | |
| 89 | /* brainfuck: only copy even or odd bits */ |
| 90 | if (eB) { |
| 91 | for (i = odd; i < 57; i += 2) |
| 92 | eB[i] = iB[i]; |
| 93 | for (i = 58 - odd; i < 114; i += 2) |
| 94 | eB[i + 2] = iB[i]; |
Piotr Krysik | 9e2e835 | 2018-02-27 12:16:25 +0100 | [diff] [blame] | 95 | if (h) |
| 96 | eB[odd ? 57 : 58] = *h; |
Piotr Krysik | 70c25a1 | 2017-01-03 08:01:23 +0100 | [diff] [blame] | 97 | } |
| 98 | } |
| 99 | |
| 100 | void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, |
| 101 | const ubit_t *hi, const ubit_t *up, int B) |
| 102 | { |
| 103 | int j; |
| 104 | int q[8] = { 0, 0, 0, 0, 0, 0, 0, 0, }; |
| 105 | |
| 106 | for (j = 0; j < 156; j++) |
| 107 | eB[j] = di[312 * B + j]; |
| 108 | for (j = 156; j < 168; j++) |
| 109 | eB[j] = hi[25 * B + j - 156]; |
| 110 | for (j = 168; j < 174; j++) |
| 111 | eB[j] = up[9 * B + j - 168]; |
| 112 | for (j = 174; j < 176; j++) |
| 113 | eB[j] = q[2 * B + j - 174]; |
| 114 | for (j = 176; j < 179; j++) |
| 115 | eB[j] = up[9 * B + j - 170]; |
| 116 | for (j = 179; j < 192; j++) |
| 117 | eB[j] = hi[25 * B + j - 167]; |
| 118 | for (j = 192; j < 348; j++) |
| 119 | eB[j] = di[312 * B + j - 36]; |
| 120 | } |
| 121 | |
| 122 | void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, |
| 123 | sbit_t *hi, sbit_t *up, int B) |
| 124 | { |
| 125 | int j; |
| 126 | |
| 127 | for (j = 0; j < 156; j++) |
| 128 | di[312 * B + j] = eB[j]; |
| 129 | for (j = 156; j < 168; j++) |
| 130 | hi[25 * B + j - 156] = eB[j]; |
| 131 | for (j = 168; j < 174; j++) |
| 132 | up[9 * B + j - 168] = eB[j]; |
| 133 | |
| 134 | for (j = 176; j < 179; j++) |
| 135 | up[9 * B + j - 170] = eB[j]; |
| 136 | for (j = 179; j < 192; j++) |
| 137 | hi[25 * B + j - 167] = eB[j]; |
| 138 | for (j = 192; j < 348; j++) |
| 139 | di[312 * B + j - 36] = eB[j]; |
| 140 | } |
| 141 | |
| 142 | void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, |
| 143 | const ubit_t *hi, int B) |
| 144 | { |
| 145 | int j; |
| 146 | |
| 147 | for (j = 0; j < 156; j++) |
| 148 | eB[j] = di[312 * B + j]; |
| 149 | for (j = 156; j < 174; j++) |
| 150 | eB[j] = hi[34 * B + j - 156]; |
| 151 | for (j = 174; j < 176; j++) |
| 152 | eB[j] = 0; |
| 153 | for (j = 176; j < 192; j++) |
| 154 | eB[j] = hi[34 * B + j - 158]; |
| 155 | for (j = 192; j < 348; j++) |
| 156 | eB[j] = di[312 * B + j - 36]; |
| 157 | } |
| 158 | |
| 159 | void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, |
| 160 | sbit_t *hi, int B) |
| 161 | { |
| 162 | int j; |
| 163 | |
| 164 | for (j = 0; j < 156; j++) |
| 165 | di[312 * B + j] = eB[j]; |
| 166 | for (j = 156; j < 174; j++) |
| 167 | hi[34 * B + j - 156] = eB[j]; |
| 168 | for (j = 176; j < 192; j++) |
| 169 | hi[34 * B + j - 158] = eB[j]; |
| 170 | for (j = 192; j < 348; j++) |
| 171 | di[312 * B + j - 36] = eB[j]; |
| 172 | } |
| 173 | |
| 174 | void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, |
| 175 | const ubit_t *hi, const ubit_t *up, int B) |
| 176 | { |
| 177 | int j; |
| 178 | int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; |
| 179 | |
| 180 | for (j = 0; j < 153; j++) |
| 181 | eB[j] = di[306 * B + j]; |
| 182 | for (j = 153; j < 168; j++) |
| 183 | eB[j] = hi[31 * B + j - 153]; |
| 184 | for (j = 168; j < 174; j++) |
| 185 | eB[j] = up[9 * B + j - 168]; |
| 186 | for (j = 174; j < 176; j++) |
| 187 | eB[j] = q[2 * B + j - 174]; |
| 188 | for (j = 176; j < 179; j++) |
| 189 | eB[j] = up[9 * B + j - 170]; |
| 190 | for (j = 179; j < 195; j++) |
| 191 | eB[j] = hi[31 * B + j - 164]; |
| 192 | for (j = 195; j < 348; j++) |
| 193 | eB[j] = di[306 * B + j - 42]; |
| 194 | } |
| 195 | |
| 196 | void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, |
| 197 | sbit_t *hi, sbit_t *up, int B) |
| 198 | { |
| 199 | int j; |
| 200 | |
| 201 | for (j = 0; j < 153; j++) |
| 202 | di[306 * B + j] = eB[j]; |
| 203 | for (j = 153; j < 168; j++) |
| 204 | hi[31 * B + j - 153] = eB[j]; |
| 205 | for (j = 168; j < 174; j++) |
| 206 | up[9 * B + j - 168] = eB[j]; |
| 207 | |
| 208 | for (j = 176; j < 179; j++) |
| 209 | up[9 * B + j - 170] = eB[j]; |
| 210 | for (j = 179; j < 195; j++) |
| 211 | hi[31 * B + j - 164] = eB[j]; |
| 212 | for (j = 195; j < 348; j++) |
| 213 | di[306 * B + j - 42] = eB[j]; |
| 214 | } |
| 215 | |
| 216 | void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, |
| 217 | const ubit_t *hi, int B) |
| 218 | { |
| 219 | int j; |
| 220 | int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; |
| 221 | |
| 222 | for (j = 0; j < 153; j++) |
| 223 | eB[j] = di[306 * B + j]; |
| 224 | for (j = 153; j < 174; j++) |
| 225 | eB[j] = hi[40 * B + j - 153]; |
| 226 | for (j = 174; j < 176; j++) |
| 227 | eB[j] = q[2 * B + j - 174]; |
| 228 | for (j = 176; j < 195; j++) |
| 229 | eB[j] = hi[40 * B + j - 155]; |
| 230 | for (j = 195; j < 348; j++) |
| 231 | eB[j] = di[306 * B + j - 42]; |
| 232 | } |
| 233 | |
| 234 | void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, |
| 235 | sbit_t *hi, int B) |
| 236 | { |
| 237 | int j; |
| 238 | |
| 239 | for (j = 0; j < 153; j++) |
| 240 | di[306 * B + j] = eB[j]; |
| 241 | for (j = 153; j < 174; j++) |
| 242 | hi[40 * B + j - 153] = eB[j]; |
| 243 | |
| 244 | for (j = 176; j < 195; j++) |
| 245 | hi[40 * B + j - 155] = eB[j]; |
| 246 | for (j = 195; j < 348; j++) |
| 247 | di[306 * B + j - 42] = eB[j]; |
| 248 | } |
| 249 | |
| 250 | void gsm0503_mcs5_burst_swap(sbit_t *eB) |
| 251 | { |
| 252 | sbit_t t[14]; |
| 253 | |
| 254 | t[0] = eB[155]; |
| 255 | t[1] = eB[158]; |
| 256 | t[2] = eB[161]; |
| 257 | t[3] = eB[164]; |
| 258 | t[4] = eB[167]; |
| 259 | t[5] = eB[170]; |
| 260 | t[6] = eB[173]; |
| 261 | t[7] = eB[195]; |
| 262 | t[8] = eB[196]; |
| 263 | t[9] = eB[198]; |
| 264 | t[10] = eB[199]; |
| 265 | t[11] = eB[201]; |
| 266 | t[12] = eB[202]; |
| 267 | t[13] = eB[204]; |
| 268 | |
| 269 | eB[155] = eB[142]; |
| 270 | eB[158] = eB[144]; |
| 271 | eB[161] = eB[145]; |
| 272 | eB[164] = eB[147]; |
| 273 | eB[167] = eB[148]; |
| 274 | eB[170] = eB[150]; |
| 275 | eB[173] = eB[151]; |
| 276 | eB[195] = eB[176]; |
| 277 | eB[196] = eB[179]; |
| 278 | eB[198] = eB[182]; |
| 279 | eB[199] = eB[185]; |
| 280 | eB[201] = eB[188]; |
| 281 | eB[202] = eB[191]; |
| 282 | eB[204] = eB[194]; |
| 283 | |
| 284 | eB[142] = t[0]; |
| 285 | eB[144] = t[1]; |
| 286 | eB[145] = t[2]; |
| 287 | eB[147] = t[3]; |
| 288 | eB[148] = t[4]; |
| 289 | eB[150] = t[5]; |
| 290 | eB[151] = t[6]; |
| 291 | eB[176] = t[7]; |
| 292 | eB[179] = t[8]; |
| 293 | eB[182] = t[9]; |
| 294 | eB[185] = t[10]; |
| 295 | eB[188] = t[11]; |
| 296 | eB[191] = t[12]; |
| 297 | eB[194] = t[13]; |
| 298 | } |
Piotr Krysik | 9e2e835 | 2018-02-27 12:16:25 +0100 | [diff] [blame] | 299 | |
| 300 | /*! @} */ |