Neels Hofmeyr | 17518fe | 2017-06-20 04:35:06 +0200 | [diff] [blame] | 1 | /*! \file gsm610.c |
| 2 | * GSM 06.10 - GSM FR codec. */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 3 | /* |
| 4 | * (C) 2010 Sylvain Munaut <tnt@246tNt.com> |
| 5 | * |
| 6 | * All Rights Reserved |
| 7 | * |
Harald Welte | e08da97 | 2017-11-13 01:00:26 +0900 | [diff] [blame] | 8 | * SPDX-License-Identifier: GPL-2.0+ |
| 9 | * |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by |
| 12 | * the Free Software Foundation; either version 2 of the License, or |
| 13 | * (at your option) any later version. |
| 14 | * |
| 15 | * This program is distributed in the hope that it will be useful, |
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | * GNU General Public License for more details. |
| 19 | * |
| 20 | * You should have received a copy of the GNU General Public License along |
| 21 | * with this program; if not, write to the Free Software Foundation, Inc., |
| 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 23 | * |
| 24 | */ |
| 25 | |
| 26 | #include <stdint.h> |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 27 | #include <stdbool.h> |
| 28 | |
| 29 | #include <osmocom/core/bitvec.h> |
| 30 | #include <osmocom/core/utils.h> |
Harald Welte | dee7172 | 2017-05-31 02:48:48 +0200 | [diff] [blame] | 31 | #include <osmocom/codec/codec.h> |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 32 | |
| 33 | /* GSM FR - subjective importance bit ordering */ |
| 34 | /* This array encodes GSM 05.03 Table 2. |
| 35 | * It's also GSM 06.10 Table A.2.1a |
| 36 | * |
| 37 | * It converts between serial parameter output by the encoder and the |
| 38 | * order needed before channel encoding. |
| 39 | */ |
Diego Elio Pettenò | 23431c7 | 2012-06-29 13:01:27 -0700 | [diff] [blame] | 40 | const uint16_t gsm610_bitorder[260] = { |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 41 | 0, /* LARc0:5 */ |
| 42 | 47, /* Xmaxc0:5 */ |
| 43 | 103, /* Xmaxc1:5 */ |
| 44 | 159, /* Xmaxc2:5 */ |
| 45 | 215, /* Xmaxc3:5 */ |
| 46 | 1, /* LARc0:4 */ |
| 47 | 6, /* LARc1:5 */ |
| 48 | 12, /* LARc2:4 */ |
| 49 | 2, /* LARc0:3 */ |
| 50 | 7, /* LARc1:4 */ |
| 51 | 13, /* LARc2:3 */ |
| 52 | 17, /* LARc3:4 */ |
| 53 | 36, /* Nc0:6 */ |
| 54 | 92, /* Nc1:6 */ |
| 55 | 148, /* Nc2:6 */ |
| 56 | 204, /* Nc3:6 */ |
| 57 | 48, /* Xmaxc0:4 */ |
| 58 | 104, /* Xmaxc1:4 */ |
| 59 | 160, /* Xmaxc2:4 */ |
| 60 | 216, /* Xmaxc3:4 */ |
| 61 | 8, /* LARc1:3 */ |
| 62 | 22, /* LARc4:3 */ |
| 63 | 26, /* LARc5:3 */ |
| 64 | 37, /* Nc0:5 */ |
| 65 | 93, /* Nc1:5 */ |
| 66 | 149, /* Nc2:5 */ |
| 67 | 205, /* Nc3:5 */ |
| 68 | 38, /* Nc0:4 */ |
| 69 | 94, /* Nc1:4 */ |
| 70 | 150, /* Nc2:4 */ |
| 71 | 206, /* Nc3:4 */ |
| 72 | 39, /* Nc0:3 */ |
| 73 | 95, /* Nc1:3 */ |
| 74 | 151, /* Nc2:3 */ |
| 75 | 207, /* Nc3:3 */ |
| 76 | 40, /* Nc0:2 */ |
| 77 | 96, /* Nc1:2 */ |
| 78 | 152, /* Nc2:2 */ |
| 79 | 208, /* Nc3:2 */ |
| 80 | 49, /* Xmaxc0:3 */ |
| 81 | 105, /* Xmaxc1:3 */ |
| 82 | 161, /* Xmaxc2:3 */ |
| 83 | 217, /* Xmaxc3:3 */ |
| 84 | 3, /* LARc0:2 */ |
| 85 | 18, /* LARc3:3 */ |
| 86 | 30, /* LARc6:2 */ |
| 87 | 41, /* Nc0:1 */ |
| 88 | 97, /* Nc1:1 */ |
| 89 | 153, /* Nc2:1 */ |
| 90 | 209, /* Nc3:1 */ |
| 91 | 23, /* LARc4:2 */ |
| 92 | 27, /* LARc5:2 */ |
| 93 | 43, /* bc0:1 */ |
| 94 | 99, /* bc1:1 */ |
| 95 | 155, /* bc2:1 */ |
| 96 | 211, /* bc3:1 */ |
| 97 | 42, /* Nc0:0 */ |
| 98 | 98, /* Nc1:0 */ |
| 99 | 154, /* Nc2:0 */ |
| 100 | 210, /* Nc3:0 */ |
| 101 | 45, /* Mc0:1 */ |
| 102 | 101, /* Mc1:1 */ |
| 103 | 157, /* Mc2:1 */ |
| 104 | 213, /* Mc3:1 */ |
| 105 | 4, /* LARc0:1 */ |
| 106 | 9, /* LARc1:2 */ |
| 107 | 14, /* LARc2:2 */ |
| 108 | 33, /* LARc7:2 */ |
| 109 | 19, /* LARc3:2 */ |
| 110 | 24, /* LARc4:1 */ |
| 111 | 31, /* LARc6:1 */ |
| 112 | 44, /* bc0:0 */ |
| 113 | 100, /* bc1:0 */ |
| 114 | 156, /* bc2:0 */ |
| 115 | 212, /* bc3:0 */ |
| 116 | 50, /* Xmaxc0:2 */ |
| 117 | 106, /* Xmaxc1:2 */ |
| 118 | 162, /* Xmaxc2:2 */ |
| 119 | 218, /* Xmaxc3:2 */ |
| 120 | 53, /* xmc0_0:2 */ |
| 121 | 56, /* xmc0_1:2 */ |
| 122 | 59, /* xmc0_2:2 */ |
| 123 | 62, /* xmc0_3:2 */ |
| 124 | 65, /* xmc0_4:2 */ |
| 125 | 68, /* xmc0_5:2 */ |
| 126 | 71, /* xmc0_6:2 */ |
| 127 | 74, /* xmc0_7:2 */ |
| 128 | 77, /* xmc0_8:2 */ |
| 129 | 80, /* xmc0_9:2 */ |
| 130 | 83, /* xmc0_10:2 */ |
| 131 | 86, /* xmc0_11:2 */ |
| 132 | 89, /* xmc0_12:2 */ |
| 133 | 109, /* xmc1_0:2 */ |
| 134 | 112, /* xmc1_1:2 */ |
| 135 | 115, /* xmc1_2:2 */ |
| 136 | 118, /* xmc1_3:2 */ |
| 137 | 121, /* xmc1_4:2 */ |
| 138 | 124, /* xmc1_5:2 */ |
| 139 | 127, /* xmc1_6:2 */ |
| 140 | 130, /* xmc1_7:2 */ |
| 141 | 133, /* xmc1_8:2 */ |
| 142 | 136, /* xmc1_9:2 */ |
| 143 | 139, /* xmc1_10:2 */ |
| 144 | 142, /* xmc1_11:2 */ |
| 145 | 145, /* xmc1_12:2 */ |
| 146 | 165, /* xmc2_0:2 */ |
| 147 | 168, /* xmc2_1:2 */ |
| 148 | 171, /* xmc2_2:2 */ |
| 149 | 174, /* xmc2_3:2 */ |
| 150 | 177, /* xmc2_4:2 */ |
| 151 | 180, /* xmc2_5:2 */ |
| 152 | 183, /* xmc2_6:2 */ |
| 153 | 186, /* xmc2_7:2 */ |
| 154 | 189, /* xmc2_8:2 */ |
| 155 | 192, /* xmc2_9:2 */ |
| 156 | 195, /* xmc2_10:2 */ |
| 157 | 198, /* xmc2_11:2 */ |
| 158 | 201, /* xmc2_12:2 */ |
| 159 | 221, /* xmc3_0:2 */ |
| 160 | 224, /* xmc3_1:2 */ |
| 161 | 227, /* xmc3_2:2 */ |
| 162 | 230, /* xmc3_3:2 */ |
| 163 | 233, /* xmc3_4:2 */ |
| 164 | 236, /* xmc3_5:2 */ |
| 165 | 239, /* xmc3_6:2 */ |
| 166 | 242, /* xmc3_7:2 */ |
| 167 | 245, /* xmc3_8:2 */ |
| 168 | 248, /* xmc3_9:2 */ |
| 169 | 251, /* xmc3_10:2 */ |
| 170 | 254, /* xmc3_11:2 */ |
| 171 | 257, /* xmc3_12:2 */ |
| 172 | 46, /* Mc0:0 */ |
| 173 | 102, /* Mc1:0 */ |
| 174 | 158, /* Mc2:0 */ |
| 175 | 214, /* Mc3:0 */ |
| 176 | 51, /* Xmaxc0:1 */ |
| 177 | 107, /* Xmaxc1:1 */ |
| 178 | 163, /* Xmaxc2:1 */ |
| 179 | 219, /* Xmaxc3:1 */ |
| 180 | 54, /* xmc0_0:1 */ |
| 181 | 57, /* xmc0_1:1 */ |
| 182 | 60, /* xmc0_2:1 */ |
| 183 | 63, /* xmc0_3:1 */ |
| 184 | 66, /* xmc0_4:1 */ |
| 185 | 69, /* xmc0_5:1 */ |
| 186 | 72, /* xmc0_6:1 */ |
| 187 | 75, /* xmc0_7:1 */ |
| 188 | 78, /* xmc0_8:1 */ |
| 189 | 81, /* xmc0_9:1 */ |
| 190 | 84, /* xmc0_10:1 */ |
| 191 | 87, /* xmc0_11:1 */ |
| 192 | 90, /* xmc0_12:1 */ |
| 193 | 110, /* xmc1_0:1 */ |
| 194 | 113, /* xmc1_1:1 */ |
| 195 | 116, /* xmc1_2:1 */ |
| 196 | 119, /* xmc1_3:1 */ |
| 197 | 122, /* xmc1_4:1 */ |
| 198 | 125, /* xmc1_5:1 */ |
| 199 | 128, /* xmc1_6:1 */ |
| 200 | 131, /* xmc1_7:1 */ |
| 201 | 134, /* xmc1_8:1 */ |
| 202 | 137, /* xmc1_9:1 */ |
| 203 | 140, /* xmc1_10:1 */ |
| 204 | 143, /* xmc1_11:1 */ |
| 205 | 146, /* xmc1_12:1 */ |
| 206 | 166, /* xmc2_0:1 */ |
| 207 | 169, /* xmc2_1:1 */ |
| 208 | 172, /* xmc2_2:1 */ |
| 209 | 175, /* xmc2_3:1 */ |
| 210 | 178, /* xmc2_4:1 */ |
| 211 | 181, /* xmc2_5:1 */ |
| 212 | 184, /* xmc2_6:1 */ |
| 213 | 187, /* xmc2_7:1 */ |
| 214 | 190, /* xmc2_8:1 */ |
| 215 | 193, /* xmc2_9:1 */ |
| 216 | 196, /* xmc2_10:1 */ |
| 217 | 199, /* xmc2_11:1 */ |
| 218 | 202, /* xmc2_12:1 */ |
| 219 | 222, /* xmc3_0:1 */ |
| 220 | 225, /* xmc3_1:1 */ |
| 221 | 228, /* xmc3_2:1 */ |
| 222 | 231, /* xmc3_3:1 */ |
| 223 | 234, /* xmc3_4:1 */ |
| 224 | 237, /* xmc3_5:1 */ |
| 225 | 240, /* xmc3_6:1 */ |
| 226 | 243, /* xmc3_7:1 */ |
| 227 | 246, /* xmc3_8:1 */ |
| 228 | 249, /* xmc3_9:1 */ |
| 229 | 252, /* xmc3_10:1 */ |
| 230 | 255, /* xmc3_11:1 */ |
| 231 | 258, /* xmc3_12:1 */ |
| 232 | 5, /* LARc0:0 */ |
| 233 | 10, /* LARc1:1 */ |
| 234 | 15, /* LARc2:1 */ |
| 235 | 28, /* LARc5:1 */ |
| 236 | 32, /* LARc6:0 */ |
| 237 | 34, /* LARc7:1 */ |
| 238 | 35, /* LARc7:0 */ |
| 239 | 16, /* LARc2:0 */ |
| 240 | 20, /* LARc3:1 */ |
| 241 | 21, /* LARc3:0 */ |
| 242 | 25, /* LARc4:0 */ |
| 243 | 52, /* Xmaxc0:0 */ |
| 244 | 108, /* Xmaxc1:0 */ |
| 245 | 164, /* Xmaxc2:0 */ |
| 246 | 220, /* Xmaxc3:0 */ |
| 247 | 55, /* xmc0_0:0 */ |
| 248 | 58, /* xmc0_1:0 */ |
| 249 | 61, /* xmc0_2:0 */ |
| 250 | 64, /* xmc0_3:0 */ |
| 251 | 67, /* xmc0_4:0 */ |
| 252 | 70, /* xmc0_5:0 */ |
| 253 | 73, /* xmc0_6:0 */ |
| 254 | 76, /* xmc0_7:0 */ |
| 255 | 79, /* xmc0_8:0 */ |
| 256 | 82, /* xmc0_9:0 */ |
| 257 | 85, /* xmc0_10:0 */ |
| 258 | 88, /* xmc0_11:0 */ |
| 259 | 91, /* xmc0_12:0 */ |
| 260 | 111, /* xmc1_0:0 */ |
| 261 | 114, /* xmc1_1:0 */ |
| 262 | 117, /* xmc1_2:0 */ |
| 263 | 120, /* xmc1_3:0 */ |
| 264 | 123, /* xmc1_4:0 */ |
| 265 | 126, /* xmc1_5:0 */ |
| 266 | 129, /* xmc1_6:0 */ |
| 267 | 132, /* xmc1_7:0 */ |
| 268 | 135, /* xmc1_8:0 */ |
| 269 | 138, /* xmc1_9:0 */ |
| 270 | 141, /* xmc1_10:0 */ |
| 271 | 144, /* xmc1_11:0 */ |
| 272 | 147, /* xmc1_12:0 */ |
| 273 | 167, /* xmc2_0:0 */ |
| 274 | 170, /* xmc2_1:0 */ |
| 275 | 173, /* xmc2_2:0 */ |
| 276 | 176, /* xmc2_3:0 */ |
| 277 | 179, /* xmc2_4:0 */ |
| 278 | 182, /* xmc2_5:0 */ |
| 279 | 185, /* xmc2_6:0 */ |
| 280 | 188, /* xmc2_7:0 */ |
| 281 | 191, /* xmc2_8:0 */ |
| 282 | 194, /* xmc2_9:0 */ |
| 283 | 197, /* xmc2_10:0 */ |
| 284 | 200, /* xmc2_11:0 */ |
| 285 | 203, /* xmc2_12:0 */ |
| 286 | 223, /* xmc3_0:0 */ |
| 287 | 226, /* xmc3_1:0 */ |
| 288 | 229, /* xmc3_2:0 */ |
| 289 | 232, /* xmc3_3:0 */ |
| 290 | 235, /* xmc3_4:0 */ |
| 291 | 238, /* xmc3_5:0 */ |
| 292 | 241, /* xmc3_6:0 */ |
| 293 | 244, /* xmc3_7:0 */ |
| 294 | 247, /* xmc3_8:0 */ |
| 295 | 250, /* xmc3_9:0 */ |
| 296 | 253, /* xmc3_10:0 */ |
| 297 | 256, /* xmc3_11:0 */ |
| 298 | 259, /* xmc3_12:0 */ |
| 299 | 11, /* LARc1:0 */ |
| 300 | 29, /* LARc5:0 */ |
| 301 | }; |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 302 | |
Neels Hofmeyr | 87e4550 | 2017-06-20 00:17:59 +0200 | [diff] [blame] | 303 | /*! Check whether RTP frame contains FR SID code word according to |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 304 | * TS 101 318 §5.1.2 |
| 305 | * \param[in] rtp_payload Buffer with RTP payload |
| 306 | * \param[in] payload_len Length of payload |
| 307 | * \returns true if code word is found, false otherwise |
| 308 | */ |
Harald Welte | 6789ba3 | 2017-05-31 02:47:43 +0200 | [diff] [blame] | 309 | bool osmo_fr_check_sid(const uint8_t *rtp_payload, size_t payload_len) |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 310 | { |
| 311 | struct bitvec bv; |
Jean-Francois Dionne | 43058ef | 2017-04-27 10:11:31 -0400 | [diff] [blame] | 312 | uint16_t i, z_bits[] = { 57, 58, 60, 61, 63, 64, 66, 67, 69, 70, 72, 73, |
| 313 | 75, 76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91, |
| 314 | 93, 94, 113, 114, 116, 117, 119, 120, 122, 123, |
| 315 | 125, 126, 128, 129, 131, 132, 134, 135, 137, |
| 316 | 138, 140, 141, 143, 144, 146, 147, 149, 150, |
| 317 | 169, 170, 172, 173, 175, 176, 178, 179, 181, |
| 318 | 182, 184, 185, 187, 188, 190, 191, 193, 194, |
| 319 | 196, 197, 199, 200, 202, 203, 205, 206, 225, |
| 320 | 226, 228, 229, 231, 232, 234, 235, 237, 240, |
| 321 | 243, 246, 249, 252, 255, 258, 261 }; |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 322 | |
| 323 | /* signature does not match Full Rate SID */ |
| 324 | if ((rtp_payload[0] >> 4) != 0xD) |
| 325 | return false; |
| 326 | |
Harald Welte | 6789ba3 | 2017-05-31 02:47:43 +0200 | [diff] [blame] | 327 | bv.data = (uint8_t *) rtp_payload; |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 328 | bv.data_len = payload_len; |
| 329 | |
| 330 | /* code word is all 0 at given bits, numbered from 1 */ |
| 331 | for (i = 0; i < ARRAY_SIZE(z_bits); i++) |
| 332 | if (bitvec_get_bit_pos(&bv, z_bits[i]) != ZERO) |
| 333 | return false; |
| 334 | |
| 335 | return true; |
| 336 | } |