Eric | b7253c6 | 2022-11-28 19:21:08 +0100 | [diff] [blame] | 1 | /* |
| 2 | * (C) 2022 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> |
| 3 | * All Rights Reserved |
| 4 | * |
| 5 | * Author: Eric Wild <ewild@sysmocom.de> |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU Affero General Public License as published by |
| 9 | * the Free Software Foundation; either version 3 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | * |
| 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 Affero General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU Affero General Public License |
| 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | * |
| 20 | */ |
| 21 | #include "ms.h" |
| 22 | #include "sigProcLib.h" |
| 23 | #include "signalVector.h" |
| 24 | #include "grgsm_vitac/grgsm_vitac.h" |
| 25 | extern "C" { |
| 26 | #include "sch.h" |
| 27 | } |
| 28 | |
| 29 | #if !defined(SYNCTHINGONLY) || !defined(NODAMNLOG) |
| 30 | #define DBGLG(...) ms_trx::dummy_log() |
| 31 | #else |
| 32 | #define DBGLG(...) std::cerr |
| 33 | #endif |
| 34 | |
| 35 | #if !defined(SYNCTHINGONLY) |
| 36 | #define DBGLG2(...) ms_trx::dummy_log() |
| 37 | #else |
| 38 | #define DBGLG2(...) std::cerr |
| 39 | #endif |
| 40 | |
| 41 | static bool decode_sch(float *bits, bool update_global_clock) |
| 42 | { |
| 43 | struct sch_info sch; |
| 44 | ubit_t info[GSM_SCH_INFO_LEN]; |
| 45 | sbit_t data[GSM_SCH_CODED_LEN]; |
| 46 | |
| 47 | float_to_sbit(&bits[3], &data[0], 62, 39); |
| 48 | float_to_sbit(&bits[106], &data[39], 62, 39); |
| 49 | |
| 50 | if (!gsm_sch_decode(info, data)) { |
| 51 | gsm_sch_parse(info, &sch); |
| 52 | |
| 53 | DBGLG() << "SCH : Decoded values" << std::endl; |
| 54 | DBGLG() << " BSIC: " << sch.bsic << std::endl; |
| 55 | DBGLG() << " TSC: " << (sch.bsic & 0x7) << std::endl; |
| 56 | DBGLG() << " T1 : " << sch.t1 << std::endl; |
| 57 | DBGLG() << " T2 : " << sch.t2 << std::endl; |
| 58 | DBGLG() << " T3p : " << sch.t3p << std::endl; |
| 59 | DBGLG() << " FN : " << gsm_sch_to_fn(&sch) << std::endl; |
| 60 | return true; |
| 61 | } |
| 62 | return false; |
| 63 | } |
| 64 | |
| 65 | static void check_rcv_fn(GSM::Time t, bool first, unsigned int &lastfn, unsigned int &fnbm) |
| 66 | { |
| 67 | if (first && t.TN() == 0) { |
| 68 | lastfn = t.FN(); |
| 69 | fnbm = 1 << 0; |
| 70 | first = false; |
| 71 | } |
| 72 | if (!first && t.FN() != (int)lastfn) { |
| 73 | if (fnbm != 255) |
| 74 | std::cerr << "rx " << lastfn << ":" << fnbm << " " << __builtin_popcount(fnbm) << std::endl; |
| 75 | lastfn = t.FN(); |
| 76 | fnbm = 1 << t.TN(); |
| 77 | } |
| 78 | |
| 79 | fnbm |= 1 << t.TN(); |
| 80 | } |
| 81 | |
| 82 | static void handle_it(one_burst &e, signalVector &burst, unsigned int tsc, int scale) |
| 83 | { |
| 84 | std::fill(burst.begin(), burst.begin() + burst.size(), 0.0); |
| 85 | const auto is_sch = gsm_sch_check_ts(e.gsmts.TN(), e.gsmts.FN()); |
| 86 | const auto is_fcch = gsm_fcch_check_ts(e.gsmts.TN(), e.gsmts.FN()); |
| 87 | |
| 88 | if (is_fcch) |
| 89 | return; |
| 90 | |
| 91 | if (is_sch) { |
| 92 | char outbin[148]; |
Eric Wild | 621a49e | 2023-01-12 16:21:58 +0100 | [diff] [blame^] | 93 | convert_and_scale(burst.begin(), e.burst, ONE_TS_BURST_LEN * 2, SAMPLE_SCALE_FACTOR); |
Eric | b7253c6 | 2022-11-28 19:21:08 +0100 | [diff] [blame] | 94 | std::stringstream dbgout; |
| 95 | #if 0 |
| 96 | { |
| 97 | struct estim_burst_params ebp; |
| 98 | auto rv2 = detectSCHBurst(burst, 4, 4, sch_detect_type::SCH_DETECT_FULL, &ebp); |
| 99 | auto bits = demodAnyBurst(burst, SCH, 4, &ebp); |
| 100 | // clamp_array(bits->begin(), 148, 1.5f); |
| 101 | for (auto &i : *bits) |
| 102 | i = (i > 0 ? 1 : -1); |
| 103 | |
| 104 | auto rv = decode_sch(bits->begin(), false); |
| 105 | dbgout << "U DET@" << (rv2 ? "yes " : " ") << "Timing offset " << ebp.toa |
| 106 | << " symbols, DECODE: " << (rv ? "yes" : "---") << " "; |
| 107 | |
| 108 | delete bits; |
| 109 | } |
| 110 | #endif |
| 111 | { |
Eric Wild | 621a49e | 2023-01-12 16:21:58 +0100 | [diff] [blame^] | 112 | convert_and_scale(burst.begin(), burst.begin(), ONE_TS_BURST_LEN * 2, 1.f / float(scale)); |
Eric | b7253c6 | 2022-11-28 19:21:08 +0100 | [diff] [blame] | 113 | |
| 114 | std::complex<float> channel_imp_resp[CHAN_IMP_RESP_LENGTH * d_OSR]; |
| 115 | auto ss = reinterpret_cast<std::complex<float> *>(burst.begin()); |
| 116 | int d_c0_burst_start = get_sch_chan_imp_resp(ss, &channel_imp_resp[0]); |
| 117 | detect_burst(ss, &channel_imp_resp[0], d_c0_burst_start, outbin); |
| 118 | |
| 119 | SoftVector bits; |
| 120 | bits.resize(148); |
| 121 | for (int i = 0; i < 148; i++) { |
| 122 | bits[i] = (!outbin[i]); // < 1 ? -1 : 1; |
| 123 | } |
| 124 | |
| 125 | auto rv = decode_sch(bits.begin(), false); |
| 126 | dbgout << "U SCH@" |
| 127 | << " " << e.gsmts.FN() << ":" << e.gsmts.TN() << " " << d_c0_burst_start |
| 128 | << " DECODE:" << (rv ? "yes" : "---") << std::endl; |
| 129 | } |
| 130 | |
| 131 | DBGLG() << dbgout.str(); |
| 132 | return; |
| 133 | } |
| 134 | #if 1 |
Eric Wild | 621a49e | 2023-01-12 16:21:58 +0100 | [diff] [blame^] | 135 | convert_and_scale(burst.begin(), e.burst, ONE_TS_BURST_LEN * 2, 1.f / float(scale)); |
Eric | b7253c6 | 2022-11-28 19:21:08 +0100 | [diff] [blame] | 136 | // std::cerr << "@" << tsc << " " << e.gsmts.FN() << ":" << e.gsmts.TN() << " " << ebp.toa << " " |
| 137 | // << std::endl; |
| 138 | |
| 139 | char outbin[148]; |
| 140 | auto ss = reinterpret_cast<std::complex<float> *>(burst.begin()); |
| 141 | float ncmax, dcmax; |
| 142 | std::complex<float> chan_imp_resp[CHAN_IMP_RESP_LENGTH * d_OSR], chan_imp_resp2[CHAN_IMP_RESP_LENGTH * d_OSR]; |
| 143 | auto normal_burst_start = get_norm_chan_imp_resp(ss, &chan_imp_resp[0], &ncmax, tsc); |
| 144 | auto dummy_burst_start = get_norm_chan_imp_resp(ss, &chan_imp_resp2[0], &dcmax, TS_DUMMY); |
| 145 | auto is_nb = ncmax > dcmax; |
| 146 | |
| 147 | DBGLG() << " U " << (is_nb ? "NB" : "DB") << "@ o nb: " << normal_burst_start << " o db: " << dummy_burst_start |
| 148 | << std::endl; |
| 149 | |
| 150 | if (is_nb) |
| 151 | detect_burst(ss, &chan_imp_resp[0], normal_burst_start, outbin); |
| 152 | else |
| 153 | detect_burst(ss, &chan_imp_resp2[0], dummy_burst_start, outbin); |
| 154 | ; |
| 155 | #ifdef DBGXX |
| 156 | // auto bits = SoftVector(148); |
| 157 | // for (int i = 0; i < 148; i++) |
| 158 | // (bits)[i] = outbin[i] < 1 ? -1 : 1; |
| 159 | #endif |
| 160 | #endif |
| 161 | } |
| 162 | |
| 163 | void rcv_bursts_test(rx_queue_t *q, unsigned int *tsc, int scale) |
| 164 | { |
| 165 | static bool first = true; |
| 166 | unsigned int lastfn = 0; |
| 167 | unsigned int fnbm = 0; |
| 168 | signalVector burst(ONE_TS_BURST_LEN, 100, 100); |
| 169 | |
| 170 | cpu_set_t cpuset; |
| 171 | |
| 172 | CPU_ZERO(&cpuset); |
| 173 | CPU_SET(1, &cpuset); |
| 174 | |
| 175 | auto rv = pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset); |
| 176 | if (rv < 0) { |
| 177 | std::cerr << "affinity: errreur! " << std::strerror(errno); |
| 178 | exit(0); |
| 179 | } |
| 180 | |
| 181 | int prio = sched_get_priority_max(SCHED_RR); |
| 182 | struct sched_param param; |
| 183 | param.sched_priority = prio; |
| 184 | rv = sched_setscheduler(0, SCHED_RR, ¶m); |
| 185 | if (rv < 0) { |
| 186 | std::cerr << "scheduler: errreur! " << std::strerror(errno); |
| 187 | exit(0); |
| 188 | } |
| 189 | |
| 190 | while (1) { |
| 191 | one_burst e; |
| 192 | while (!q->spsc_pop(&e)) { |
| 193 | q->spsc_prep_pop(); |
| 194 | } |
| 195 | |
| 196 | check_rcv_fn(e.gsmts, first, lastfn, fnbm); |
| 197 | |
| 198 | handle_it(e, burst, *tsc, scale); |
| 199 | #ifdef DBGXX |
| 200 | rv = detectSCHBurst(*burst, 4, 4, sch_detect_type::SCH_DETECT_FULL, &ebp); |
| 201 | if (rv > 0) |
| 202 | std::cerr << "#" << e.gsmts.FN() << ":" << e.gsmts.TN() << " " << ebp.toa << std::endl; |
| 203 | sched_yield(); |
| 204 | #endif |
| 205 | } |
| 206 | } |