Codebase list multimon-ng / e333069
Update upstream source from tag 'upstream/1.2.0+dfsg' Update to upstream version '1.2.0+dfsg' with Debian dir a08dccf413180be95b43682284aae1933ade1dfd Göran Weinholt 1 year, 6 months ago
10 changed file(s) with 1486 addition(s) and 104 deletion(s). Raw diff Collapse all Expand all
3838 ehthumbs.db
3939 Thumbs.db
4040 *.bak
41
42 # Tool cache #
43 ##############
44 *.sw[op]
1010 endif( NOT WIN32 )
1111
1212 set( TARGET "${PROJECT_NAME}" )
13 set( VERSION "1.1.9" )
13 set( VERSION "1.2.0" )
1414 set( MAJOR "1" )
15 set( MINOR "1" )
16 set( PATCH "9" )
15 set( MINOR "2" )
16 set( PATCH "0" )
1717 set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra" )
1818
1919 if( WIN32 )
112112 demod_afsk24_2.c
113113 demod_afsk12.c
114114 demod_flex.c
115 demod_flex_next.c
115116 costabi.c
116117 costabf.c
117118 clip.c
271271 if ( (i & 0x60) == 0 ) {
272272 verbprintf(0, " Current call charge");
273273 }
274 else if ( (i & 0x60) == 1 ) {
274 else if ( (i & 0x60) == 0x20 ) {
275275 verbprintf(0, " Accumulated charge (last call included)");
276276 }
277 else if ( (i & 0x60) == 2 ) {
277 else if ( (i & 0x60) == 0x40 ) {
278278 verbprintf(0, " Extra charge cumulated charging, e.g. call forwarded calls.");
279279 }
280280 else {
296296 verbprintf(0, (i & 4)?" Credit/Debit Card Charging":" Normal billing" );
297297 verbprintf(0, (i & 8)?" Charging information not available":" Charging information available" );
298298 verbprintf(0, (i & 0x10)?" Charged units or, charged units and price per unit":" Currency amount" );
299 if ( (i & 60) == 0 ) {
299 if ( (i & 0x60) == 0 ) {
300300 verbprintf(0, " Current call charge");
301301 }
302 else if ( (i & 60) == 1 ) {
302 else if ( (i & 0x60) == 0x20 ) {
303303 verbprintf(0, " Accumulated charge (last call included)");
304304 }
305 else if ( (i & 60) == 2 ) {
305 else if ( (i & 0x60) == 0x40 ) {
306306 verbprintf(0, " Extra charge cumulated charging, e.g. call forwarded calls.");
307307 }
308308 else {
341341 break;
342342 }
343343 }
344 else if ( (i & 0x70) == 7) {
344 else if ( (i & 0x70) == 0x70) {
345345 verbprintf(0, " Reserved for network operator use");
346346 }
347347 else {
121121 if (data == 13 || data == 10)
122122 // LF and CR are allowed
123123 return 1;
124 if (data >= 32 || data <= 126)
124 if (data >= 32 && data <= 126)
125125 // These text and punctuation characters are allowed
126126 return 1;
127127
230230 };
231231
232232
233 int is_alphanumeric_page(struct Flex * flex) {
233 static int is_alphanumeric_page(struct Flex * flex) {
234234 if (flex==NULL) return 0;
235235 return (flex->Decode.type == FLEX_PAGETYPE_ALPHANUMERIC ||
236236 flex->Decode.type == FLEX_PAGETYPE_SECURE);
237237 }
238238
239239
240 int is_numeric_page(struct Flex * flex) {
240 static int is_numeric_page(struct Flex * flex) {
241241 if (flex==NULL) return 0;
242242 return (flex->Decode.type == FLEX_PAGETYPE_STANDARD_NUMERIC ||
243243 flex->Decode.type == FLEX_PAGETYPE_SPECIAL_NUMERIC ||
245245 }
246246
247247
248 int is_tone_page(struct Flex * flex) {
248 static int is_tone_page(struct Flex * flex) {
249249 if (flex==NULL) return 0;
250250 return (flex->Decode.type == FLEX_PAGETYPE_TONE);
251251 }
252252
253253
254 unsigned int count_bits(struct Flex * flex, unsigned int data) {
254 static unsigned int count_bits(struct Flex * flex, unsigned int data) {
255255 if (flex==NULL) return 0;
256256 #ifdef USE_BUILTIN_POPCOUNT
257257 return __builtin_popcount(data);
11521152 }
11531153 }
11541154
1155 int buildSymbol(struct Flex * flex, double sample) {
1155 static int buildSymbol(struct Flex * flex, double sample) {
11561156 if (flex == NULL) return 0;
11571157
11581158 const int64_t phase_max = 100 * flex->Demodulator.sample_freq; // Maximum value for phase (calculated to divide by sample frequency without remainder)
12511251
12521252 }
12531253
1254 void Flex_Demodulate(struct Flex * flex, double sample) {
1254 static void Flex_Demodulate(struct Flex * flex, double sample) {
12551255 if(flex == NULL) return;
12561256
12571257 if (buildSymbol(flex, sample) == 1) {
13061306 report_state(flex);
13071307 }
13081308
1309 void Flex_Delete(struct Flex * flex) {
1309 static void Flex_Delete(struct Flex * flex) {
13101310 if (flex==NULL) return;
13111311
13121312 if (flex->Decode.BCHCode!=NULL) {
13181318 }
13191319
13201320
1321 struct Flex * Flex_New(unsigned int SampleFrequency) {
1321 static struct Flex * Flex_New(unsigned int SampleFrequency) {
13221322 struct Flex *flex=(struct Flex *)malloc(sizeof(struct Flex));
13231323 if (flex!=NULL) {
13241324 memset(flex, 0, sizeof(struct Flex));
0 /*
1 * demod_flex.c
2 *
3 * Copyright 2004,2006,2010 Free Software Foundation, Inc.
4 * Copyright (C) 2015 Craig Shelley (craig@microtron.org.uk)
5 *
6 * FLEX Radio Paging Decoder - Adapted from GNURadio for use with Multimon
7 *
8 * GNU Radio is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3, or (at your option)
11 * any later version.
12 *
13 * GNU Radio is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Radio; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street,
21 * Boston, MA 02110-1301, USA.
22 */
23 /*
24 * Modification (to this file) made by Ryan Farley (rfarley3@github)
25 * - Issue #139 !160 handle edge cases for start and end offsets (long vs short, single vs group)
26 * - Resolve type ambiguity to improve stability after Raspberry Pi compile
27 * - Compare algorithms to other open source libraries to reconcile group bit, frag bit, and capcode decode
28 * - Refactor message printing to single line, only printables, encoded % fmtstr directives
29 * Version 0.9.3v (28 Jan 2020)
30 * Modification made by bierviltje and implemented by Bruce Quinton (Zanoroy@gmail.com)
31 * - Issue #123 created by bierviltje (https://github.com/bierviltje) - Feature request: FLEX: put group messages in an array/list
32 * - This also changed the delimiter to a | rather than a space
33 * Version 0.9.2v (03 Apr 2019)
34 * Modification made by Bruce Quinton (Zanoroy@gmail.com)
35 * - Issue #120 created by PimHaarsma - Flex Tone-Only messages with short numeric body Bug fixed using code documented in the ticket system
36 * Version 0.9.1v (10 Jan 2019)
37 * Modification (to this file) made by Rob0101
38 * Fixed marking messages with K,F,C - One case had a 'C' marked as a 'K'
39 * Version 0.9.0v (22 May 2018)
40 * Modification (to this file) made by Bruce Quinton (zanoroy@gmail.com)
41 * - Addded Define at top of file to modify the way missed group messages are reported in the debug output (default is 1; report missed capcodes on the same line)
42 * REPORT_GROUP_CODES 1 // Report each cleared faulty group capcode : 0 = Each on a new line; 1 = All on the same line;
43 * Version 0.8.9 (20 Mar 2018)
44 * Modification (to this file) made by Bruce Quinton (zanoroy@gmail.com)
45 * - Issue #101 created by bertinhollan (https://github.com/bertinholland): Bug flex: Wrong split up group message after a data corruption frame.
46 * - Added logic to the FIW decoding that checks for any 'Group Messages' and if the frame has past them remove the group message and log output
47 * - The following settings (at the top of this file, just under these comments) have changed from:
48 * PHASE_LOCKED_RATE 0.150
49 * PHASE_UNLOCKED_RATE 0.150
50 * these new settings appear to work better when attempting to locate the Sync lock in the message preamble.
51 * Version 0.8.8v (20 APR 2018)
52 * Modification (to this file) made by Bruce Quinton (zanoroy@gmail.com)
53 * - Issue #101 created by bertinhollan (https://github.com/bertinholland): Bug flex: Wrong split up group message after a data corruption frame.
54 * Version 0.8.7v (11 APR 2018)
55 * Modification (to this file) made by Bruce Quinton (zanoroy@gmail.com) and Rob0101 (as seen on github: https://github.com/rob0101)
56 * - Issue *#95 created by rob0101: '-a FLEX dropping first character of some message on regular basis'
57 * - Implemented Rob0101's suggestion of K, F and C flags to indicate the message fragmentation:
58 * 'K' message is complete and O'K' to display to the world.
59 * 'F' message is a 'F'ragment and needs a 'C'ontinuation message to complete it. Message = Fragment + Continuation
60 * 'C' message is a 'C'ontinuation of another fragmented message
61 * Version 0.8.6v (18 Dec 2017)
62 * Modification (to this file) made by Bruce Quinton (Zanoroy@gmail.com) on behalf of bertinhollan (https://github.com/bertinholland)
63 * - Issue #87 created by bertinhollan: Reported issue is that the flex period timeout was too short and therefore some group messages were not being processed correctly
64 * After some testing bertinhollan found that increasing the timeout period fixed the issue in his area. I have done further testing in my local
65 * area and found the change has not reduced my success rate. I think the timeout is a localisation setting and I have added "DEMOD_TIMEOUT"
66 * to the definitions in the top of this file (the default value is 100 bertinhollan's prefered value, changed up from 50)
67 * Version 0.8.5v (08 Sep 2017)
68 * Modification made by Bruce Quinton (Zanoroy@gmail.com)
69 * - Issue #78 - Found a problem in the length detection sequence, modified the if statement to ensure the message length is
70 * only checked for Aplha messages, the other types calculate thier length while decoding
71 * Version 0.8.4v (05 Sep 2017)
72 * Modification made by Bruce Quinton (Zanoroy@gmail.com)
73 * - Found a bug in the code that was not handling multiple group messages within the same frame,
74 * and the long address bit was being miss treated in the same cases. Both issue have been fixed but further testing will help.
75 * Version 0.8.3v (22 Jun 2017)
76 * Modification made by Bruce Quinton (Zanoroy@gmail.com)
77 * - I had previously tagged Group Messages as GPN message types,
78 * this was my own identification rather than a Flex standard type.
79 * Now that I have cleaned up all identified (so far) issues I have changed back to the correct Flex message type of ALN (Alpha).
80 * Version 0.8.2v (21 Jun 2017)
81 * Modification made by Bruce Quinton (Zanoroy@gmail.com)
82 * - Fixed group messaging capcode issue - modified the Capcode Array to be int64_t rather than int (I was incorrectly casting the long to an int)
83 * Version 0.8.1v (16 Jun 2017)
84 * Modification made by Bruce Quinton (Zanoroy@gmail.com)
85 * - Added Debugging to help track the group messaging issues
86 * - Improved Alpha output and removed several loops to improve CPU cycles
87 * Version 0.8v (08 Jun 2017)
88 * Modification made by Bruce Quinton (Zanoroy@gmail.com)
89 * - Added Group Messaging
90 * - Fixed Phase adjustments (phasing as part of Symbol identification)
91 * - Fixed Alpha numeric length adjustments to stop "Invalid Vector" errors
92 * - Fixed numeric message treatment
93 * - Fixed invalid identification of "unknown" messages
94 * - Added 3200 2 fsk identification to all more message types to be processed (this was a big deal for NZ)
95 * - Changed uint to int variables
96 *
97 */
98
99 /* ---------------------------------------------------------------------- */
100
101 #include "multimon.h"
102 #include "filter.h"
103 #include "BCHCode.h"
104 #include <math.h>
105 #include <string.h>
106 #include <time.h>
107 #include <stdlib.h>
108 #include <stdio.h>
109 #define __STDC_FORMAT_MACROS
110 #include <inttypes.h>
111
112 /* ---------------------------------------------------------------------- */
113
114 #define FREQ_SAMP 22050
115 #define FILTLEN 1
116 #define REPORT_GROUP_CODES 1 // Report each cleared faulty group capcode : 0 = Each on a new line; 1 = All on the same line;
117
118 #define FLEX_SYNC_MARKER 0xA6C6AAAAul // Synchronisation code marker for FLEX
119 #define SLICE_THRESHOLD 0.667 // For 4 level code, levels 0 and 3 have 3 times the amplitude of levels 1 and 2, so quantise at 2/3
120 #define DC_OFFSET_FILTER 0.010 // DC Offset removal IIR filter response (seconds)
121 #define PHASE_LOCKED_RATE 0.045 // Correction factor for locked state
122 #define PHASE_UNLOCKED_RATE 0.050 // Correction factor for unlocked state
123 #define LOCK_LEN 24 // Number of symbols to check for phase locking (max 32)
124 #define IDLE_THRESHOLD 0 // Number of idle codewords allowed in data section
125 #define CAPCODES_INDEX 0
126 #define DEMOD_TIMEOUT 100 // Maximum number of periods with no zero crossings before we decide that the system is not longer within a Timing lock.
127 #define GROUP_BITS 17 // Centralized maximum of group msg cache
128 #define PHASE_WORDS 88 // per spec, there are 88 4B words per frame
129 // there are 3 chars per message word (mw)
130 // there are at most 88 words per frame's phase buffer of a page
131 // but at least 1 BIW 1 AW 1 VW, so max 85 data words (dw) for text
132 // each dw is 3 chars of 7b ASCII (21 bits of text, 11 bits of checksum)
133 // this is 256, BUT each char could need to be escaped (%, \n, \r, \t), so double it
134 #define MAX_ALN 512 // max possible ALN characters
135
136
137 enum Flex_PageTypeEnum {
138 FLEX_PAGETYPE_SECURE,
139 FLEX_PAGETYPE_SHORT_INSTRUCTION,
140 FLEX_PAGETYPE_TONE,
141 FLEX_PAGETYPE_STANDARD_NUMERIC,
142 FLEX_PAGETYPE_SPECIAL_NUMERIC,
143 FLEX_PAGETYPE_ALPHANUMERIC,
144 FLEX_PAGETYPE_BINARY,
145 FLEX_PAGETYPE_NUMBERED_NUMERIC
146 };
147
148
149 enum Flex_StateEnum {
150 FLEX_STATE_SYNC1,
151 FLEX_STATE_FIW,
152 FLEX_STATE_SYNC2,
153 FLEX_STATE_DATA
154 };
155
156 struct Flex_Demodulator {
157 unsigned int sample_freq;
158 double sample_last;
159 int locked;
160 int phase;
161 unsigned int sample_count;
162 unsigned int symbol_count;
163 double envelope_sum;
164 int envelope_count;
165 uint64_t lock_buf;
166 int symcount[4];
167 int timeout;
168 int nonconsec;
169 unsigned int baud; // Current baud rate
170 };
171
172 struct Flex_GroupHandler {
173 int64_t GroupCodes[GROUP_BITS][1000];
174 int GroupCycle[GROUP_BITS];
175 int GroupFrame[GROUP_BITS];
176 };
177
178 struct Flex_Modulation {
179 double symbol_rate;
180 double envelope;
181 double zero;
182 };
183
184
185 struct Flex_State {
186 unsigned int sync2_count;
187 unsigned int data_count;
188 unsigned int fiwcount;
189 enum Flex_StateEnum Current;
190 enum Flex_StateEnum Previous;
191 };
192
193
194 struct Flex_Sync {
195 unsigned int sync; // Outer synchronization code
196 unsigned int baud; // Baudrate of SYNC2 and DATA
197 unsigned int levels; // FSK encoding of SYNC2 and DATA
198 unsigned int polarity; // 0=Positive (Normal) 1=Negative (Inverted)
199 uint64_t syncbuf;
200 };
201
202
203 struct Flex_FIW {
204 unsigned int rawdata;
205 unsigned int checksum;
206 unsigned int cycleno;
207 unsigned int frameno;
208 unsigned int fix3;
209 };
210
211
212 struct Flex_Phase {
213 unsigned int buf[PHASE_WORDS];
214 int idle_count;
215 };
216
217
218 struct Flex_Data {
219 int phase_toggle;
220 unsigned int data_bit_counter;
221 struct Flex_Phase PhaseA;
222 struct Flex_Phase PhaseB;
223 struct Flex_Phase PhaseC;
224 struct Flex_Phase PhaseD;
225 };
226
227
228 struct Flex_Decode {
229 enum Flex_PageTypeEnum type;
230 int long_address;
231 int64_t capcode;
232 struct BCHCode * BCHCode;
233 };
234
235
236 struct Flex_Next {
237 struct Flex_Demodulator Demodulator;
238 struct Flex_Modulation Modulation;
239 struct Flex_State State;
240 struct Flex_Sync Sync;
241 struct Flex_FIW FIW;
242 struct Flex_Data Data;
243 struct Flex_Decode Decode;
244 struct Flex_GroupHandler GroupHandler;
245 };
246
247
248 static int is_alphanumeric_page(struct Flex_Next * flex) {
249 if (flex==NULL) return 0;
250 return (flex->Decode.type == FLEX_PAGETYPE_ALPHANUMERIC ||
251 flex->Decode.type == FLEX_PAGETYPE_SECURE);
252 }
253
254
255 static int is_numeric_page(struct Flex_Next * flex) {
256 if (flex==NULL) return 0;
257 return (flex->Decode.type == FLEX_PAGETYPE_STANDARD_NUMERIC ||
258 flex->Decode.type == FLEX_PAGETYPE_SPECIAL_NUMERIC ||
259 flex->Decode.type == FLEX_PAGETYPE_NUMBERED_NUMERIC);
260 }
261
262
263 static int is_tone_page(struct Flex_Next * flex) {
264 if (flex==NULL) return 0;
265 return (flex->Decode.type == FLEX_PAGETYPE_TONE);
266 }
267
268
269 static int is_binary_page(struct Flex_Next * flex) {
270 if (flex==NULL) return 0;
271 return (flex->Decode.type == FLEX_PAGETYPE_BINARY);
272 }
273
274
275 static unsigned int count_bits(struct Flex_Next * flex, unsigned int data) {
276 if (flex==NULL) return 0;
277 #ifdef USE_BUILTIN_POPCOUNT
278 return __builtin_popcount(data);
279 #else
280 unsigned int n = (data >> 1) & 0x77777777;
281 data = data - n;
282 n = (n >> 1) & 0x77777777;
283 data = data - n;
284 n = (n >> 1) & 0x77777777;
285 data = data - n;
286 data = (data + (data >> 4)) & 0x0f0f0f0f;
287 data = data * 0x01010101;
288 return data >> 24;
289 #endif
290 }
291
292 static int bch3121_fix_errors(struct Flex_Next * flex, uint32_t * data_to_fix, char PhaseNo) {
293 if (flex==NULL) return -1;
294 int i=0;
295 int recd[31];
296
297 /*Convert the data pattern into an array of coefficients*/
298 unsigned int data=*data_to_fix;
299 for (i=0; i<31; i++) {
300 recd[i] = (data>>30)&1;
301 data<<=1;
302 }
303
304 /*Decode and correct the coefficients*/
305 int decode_error=BCHCode_Decode(flex->Decode.BCHCode, recd);
306
307 /*Decode successful?*/
308 if (!decode_error) {
309 /*Convert the coefficient array back to a bit pattern*/
310 data=0;
311 for (i=0; i<31; i++) {
312 data<<=1;
313 data|=recd[i];
314 }
315 /*Count the number of fixed errors*/
316 int fixed=count_bits(flex, (*data_to_fix & 0x7FFFFFFF) ^ data);
317 if (fixed>0) {
318 verbprintf(3, "FLEX_NEXT: Phase %c Fixed %i errors @ 0x%08x (0x%08x -> 0x%08x)\n", PhaseNo, fixed, (*data_to_fix&0x7FFFFFFF) ^ data, (*data_to_fix&0x7FFFFFFF), data );
319 }
320
321 /*Write the fixed data back to the caller*/
322 *data_to_fix=data;
323
324 } else {
325 verbprintf(3, "FLEX_NEXT: Phase %c Data corruption - Unable to fix errors.\n", PhaseNo);
326 }
327
328 return decode_error;
329 }
330
331 static unsigned int flex_sync_check(struct Flex_Next * flex, uint64_t buf) {
332 if (flex==NULL) return 0;
333 // 64-bit FLEX sync code:
334 // AAAA:BBBBBBBB:CCCC
335 //
336 // Where BBBBBBBB is always 0xA6C6AAAA
337 // and AAAA^CCCC is 0xFFFF
338 //
339 // Specific values of AAAA determine what bps and encoding the
340 // packet is beyond the frame information word
341 //
342 // First we match on the marker field with a hamming distance < 4
343 // Then we match on the outer code with a hamming distance < 4
344
345 unsigned int marker = (buf & 0x0000FFFFFFFF0000ULL) >> 16;
346 unsigned short codehigh = (buf & 0xFFFF000000000000ULL) >> 48;
347 unsigned short codelow = ~(buf & 0x000000000000FFFFULL);
348
349 int retval=0;
350 if (count_bits(flex, marker ^ FLEX_SYNC_MARKER) < 4 && count_bits(flex, codelow ^ codehigh) < 4 ) {
351 retval=codehigh;
352 } else {
353 retval=0;
354 }
355
356 return retval;
357 }
358
359
360 static unsigned int flex_sync(struct Flex_Next * flex, unsigned char sym) {
361 if (flex==NULL) return 0;
362 int retval=0;
363 flex->Sync.syncbuf = (flex->Sync.syncbuf << 1) | ((sym < 2)?1:0);
364
365 retval=flex_sync_check(flex, flex->Sync.syncbuf);
366 if (retval!=0) {
367 flex->Sync.polarity=0;
368 } else {
369 /*If a positive sync pattern was not found, look for a negative (inverted) one*/
370 retval=flex_sync_check(flex, ~flex->Sync.syncbuf);
371 if (retval!=0) {
372 flex->Sync.polarity=1;
373 }
374 }
375
376 return retval;
377 }
378
379
380 static void decode_mode(struct Flex_Next * flex, unsigned int sync_code) {
381 if (flex==NULL) return;
382
383 // Something is off with these modes:
384 // * Where is 6400/4?
385 // * Why are there two 3200/4?
386 // * Why is there a 1600/4?
387 struct {
388 int sync;
389 unsigned int baud;
390 unsigned int levels;
391 } flex_modes[] = {
392 { 0x870C, 1600, 2 },
393 { 0xB068, 1600, 4 },
394 { 0x7B18, 3200, 2 },
395 { 0xDEA0, 3200, 4 },
396 { 0x4C7C, 3200, 4 },
397 {0,0,0}
398 };
399
400 int x=0;
401 int i=0;
402 for (i=0; flex_modes[i].sync!=0; i++) {
403 if (count_bits(flex, flex_modes[i].sync ^ sync_code) < 4) {
404 flex->Sync.sync = sync_code;
405 flex->Sync.baud = flex_modes[i].baud;
406 flex->Sync.levels = flex_modes[i].levels;
407 x = 1;
408 break;
409 }
410 }
411
412 if(x==0){
413 verbprintf(3, "FLEX_NEXT: Sync Code not found, defaulting to 1600bps 2FSK\n");
414 }
415 }
416
417
418 static void read_2fsk(struct Flex_Next * flex, unsigned int sym, unsigned int * dat) {
419 if (flex==NULL) return;
420 *dat = (*dat >> 1) | ((sym > 1)?0x80000000:0);
421 }
422
423
424 static int decode_fiw(struct Flex_Next * flex) {
425 if (flex==NULL) return -1;
426 unsigned int fiw = flex->FIW.rawdata;
427 int decode_error = bch3121_fix_errors(flex, &fiw, 'F');
428
429 if (decode_error) {
430 verbprintf(3, "FLEX_NEXT: Unable to decode FIW, too much data corruption\n");
431 return 1;
432 }
433
434 // The only relevant bits in the FIW word for the purpose of this function
435 // are those masked by 0x001FFFFF.
436 flex->FIW.checksum = fiw & 0xF;
437 flex->FIW.cycleno = (fiw >> 4) & 0xF;
438 flex->FIW.frameno = (fiw >> 8) & 0x7F;
439 flex->FIW.fix3 = (fiw >> 15) & 0x3F;
440
441 unsigned int checksum = (fiw & 0xF);
442 checksum += ((fiw >> 4) & 0xF);
443 checksum += ((fiw >> 8) & 0xF);
444 checksum += ((fiw >> 12) & 0xF);
445 checksum += ((fiw >> 16) & 0xF);
446 checksum += ((fiw >> 20) & 0x01);
447
448 checksum &= 0xF;
449
450 if (checksum == 0xF) {
451 int timeseconds = flex->FIW.cycleno*4*60 + flex->FIW.frameno*4*60/128;
452 verbprintf(2, "FLEX_NEXT: FrameInfoWord: cycleno=%02i frameno=%03i fix3=0x%02x time=%02i:%02i\n",
453 flex->FIW.cycleno,
454 flex->FIW.frameno,
455 flex->FIW.fix3,
456 timeseconds/60,
457 timeseconds%60);
458 // Lets check the FrameNo against the expected group message frames, if we have 'Missed a group message' tell the user and clear the Cap Codes
459 for(int g = 0; g < GROUP_BITS ;g++) {
460 // Do we have a group message pending for this groupbit?
461 if(flex->GroupHandler.GroupFrame[g] >= 0)
462 {
463 int Reset = 0;
464 verbprintf(4, "FLEX_NEXT: GroupBit %i, FrameNo: %i, Cycle No: %i target Cycle No: %i\n", g, flex->GroupHandler.GroupFrame[g], flex->GroupHandler.GroupCycle[g], (int)flex->FIW.cycleno);
465 // Now lets check if its expected in this frame..
466 if((int)flex->FIW.cycleno == flex->GroupHandler.GroupCycle[g])
467 {
468 if(flex->GroupHandler.GroupFrame[g] < (int)flex->FIW.frameno)
469 {
470 Reset = 1;
471 }
472 }
473 // Check if we should have sent a group message in the previous cycle
474 else if(flex->FIW.cycleno == 0)
475 {
476 if(flex->GroupHandler.GroupCycle[g] == 15)
477 {
478 Reset = 1;
479 }
480 }
481 // If we are waiting for the cycle to roll over then move onto the next for loop item
482 else if(flex->FIW.cycleno == 15 && flex->GroupHandler.GroupCycle[g] == 0)
483 {
484 continue;
485 }
486 // Otherwise if the target cycle is less than the current cycle, reset the data
487 else if(flex->GroupHandler.GroupCycle[g] < (int)flex->FIW.cycleno)
488 {
489 Reset = 1;
490 }
491
492
493 if(Reset == 1)
494 {
495
496 int endpoint = flex->GroupHandler.GroupCodes[g][CAPCODES_INDEX];
497 if(REPORT_GROUP_CODES > 0)
498 {
499 verbprintf(3,"FLEX_NEXT: Group messages seem to have been missed; Groupbit: %i; Total Capcodes: %i; Clearing Data; Capcodes: ", g, endpoint);
500 }
501
502 for(int capIndex = 1; capIndex <= endpoint; capIndex++)
503 {
504 if(REPORT_GROUP_CODES == 0)
505 {
506 verbprintf(3,"FLEX_NEXT: Group messages seem to have been missed; Groupbit: %i; Clearing data; Capcode: [%010" PRId64 "]\n", g, flex->GroupHandler.GroupCodes[g][capIndex]);
507 }
508 else
509 {
510 if(capIndex > 1)
511 {
512 verbprintf(3,",");
513 }
514 verbprintf(3,"[%010" PRId64 "]", flex->GroupHandler.GroupCodes[g][capIndex]);
515 }
516 }
517
518 if(REPORT_GROUP_CODES > 0)
519 {
520 verbprintf(3,"\n");
521 }
522
523 // reset the value
524 flex->GroupHandler.GroupCodes[g][CAPCODES_INDEX] = 0;
525 flex->GroupHandler.GroupFrame[g] = -1;
526 flex->GroupHandler.GroupCycle[g] = -1;
527 }
528 }
529 }
530 return 0;
531 } else {
532 verbprintf(3, "FLEX_NEXT: Bad Checksum 0x%x\n", checksum);
533
534 return 1;
535 }
536 }
537
538
539 /* Add a character to ALN messages, but avoid buffer overflows and special characters */
540 static unsigned int add_ch(unsigned char ch, unsigned char* buf, unsigned int idx) {
541 // avoid buffer overflow that has been happening
542 if (idx >= MAX_ALN) {
543 verbprintf(3, "FLEX_NEXT: idx %u >= MAX_ALN %u\n", idx, MAX_ALN);
544 return 0;
545 }
546 // TODO sanitize % or you will have uncontrolled format string vuln
547 // Originally, this only avoided storing ETX (end of text, 0x03).
548 // At minimum you'll also want to avoid storing NULL (str term, 0x00),
549 // otherwise verbprintf will truncate the message.
550 // ex: if (ch != 0x03 && ch != 0x00) { buf[idx] = ch; return 1; }
551 // But while we are here, make it print friendly and get it onto a single line
552 // * remove awkward ctrl chars (del, bs, bell, vertical tab, etc)
553 // * encode valuable ctrl chars (new line/line feed, carriage ret, tab)
554 // NOTE: if you post process FLEX ALN output by sed/grep/awk etc on non-printables
555 // then double check this doesn't mess with your pipeline
556 if (ch == 0x09 && idx < (MAX_ALN - 2)) { // '\t'
557 buf[idx] = '\\';
558 buf[idx + 1] = 't';
559 return 2;
560 }
561 if (ch == 0x0a && idx < (MAX_ALN - 2)) { // '\n'
562 buf[idx] = '\\';
563 buf[idx + 1] = 'n';
564 return 2;
565 }
566 if (ch == 0x0d && idx < (MAX_ALN - 2)) { // '\r'
567 buf[idx] = '\\';
568 buf[idx + 1] = 'r';
569 return 2;
570 }
571 // unixinput.c::_verbprintf uses this output as a format string
572 // which introduces an uncontrolled format string vulnerability
573 // and also, generally, risks stack corruption
574 if (ch == '%') {
575 if (idx < (MAX_ALN - 2)) {
576 buf[idx] = '%';
577 buf[idx + 1] = '%';
578 return 2;
579 }
580 return 0;
581 }
582 // only store ASCII printable
583 if (ch >= 32 && ch <= 126) {
584 buf[idx] = ch;
585 return 1;
586 }
587 // if you want all non-printables, show as hex, but also make MAX_ALN 1024
588 /* if (idx < (MAX_ALN - 4)) {
589 sprintf(buf + idx, "\\x%02x", ch);
590 return 4;
591 }*/
592 return 0;
593 }
594
595
596 static void parse_alphanumeric(struct Flex_Next * flex, unsigned int * phaseptr, unsigned int mw1, unsigned int len, int frag, int cont, int flex_groupmessage, int flex_groupbit) {
597 if (flex==NULL) return;
598
599 char frag_flag = '?';
600 if (cont == 0 && frag == 3) frag_flag = 'K'; // complete, ready to send
601 if (cont == 0 && frag != 3) frag_flag = 'C'; // incomplete until appended to 1 or more 'F's
602 if (cont == 1 ) frag_flag = 'F'; // incomplete until a 'C' fragment is appended
603 verbprintf(0, "%1d.%1d.%c|", frag, cont, frag_flag);
604
605 unsigned char message[MAX_ALN];
606 memset(message, '\0', MAX_ALN);
607 int currentChar = 0;
608 // (mw + i) < PHASE_WORDS (aka mw+len<=PW) enforced within decode_phase
609 for (unsigned int i = 0; i < len; i++) {
610 unsigned int dw = phaseptr[mw1 + i];
611 if (i > 0 || frag != 0x03) {
612 currentChar += add_ch(dw & 0x7Fl, message, currentChar);
613 }
614 currentChar += add_ch((dw >> 7) & 0x7Fl, message, currentChar);
615 currentChar += add_ch((dw >> 14) & 0x7Fl, message, currentChar);
616 }
617 message[currentChar] = '\0';
618
619 // Implemented bierviltje code from ticket: https://github.com/EliasOenal/multimon-ng/issues/123#
620 if(flex_groupmessage == 1) {
621 int endpoint = flex->GroupHandler.GroupCodes[flex_groupbit][CAPCODES_INDEX];
622 for(int g = 1; g <= endpoint;g++)
623 {
624 verbprintf(1, "FLEX Group message output: Groupbit: %i Total Capcodes; %i; index %i; Capcode: [%010" PRId64 "]\n", flex_groupbit, endpoint, g, flex->GroupHandler.GroupCodes[flex_groupbit][g]);
625 verbprintf(0, "%010" PRId64 "|", flex->GroupHandler.GroupCodes[flex_groupbit][g]);
626 }
627
628 // reset the value
629 flex->GroupHandler.GroupCodes[flex_groupbit][CAPCODES_INDEX] = 0;
630 flex->GroupHandler.GroupFrame[flex_groupbit] = -1;
631 flex->GroupHandler.GroupCycle[flex_groupbit] = -1;
632 }
633 verbprintf(0, message);
634 }
635
636 static void parse_numeric(struct Flex_Next * flex, unsigned int * phaseptr, int j) {
637 if (flex==NULL) return;
638 unsigned const char flex_bcd[17] = "0123456789 U -][";
639
640 int w1 = phaseptr[j] >> 7;
641 int w2 = w1 >> 7;
642 w1 = w1 & 0x7f;
643 w2 = (w2 & 0x07) + w1; // numeric message is 7 words max
644
645 // Get first dataword from message field or from second
646 // vector word if long address
647 int dw;
648 if(!flex->Decode.long_address) {
649 dw = phaseptr[w1];
650 w1++;
651 w2++;
652 } else {
653 dw = phaseptr[j+1];
654 }
655
656 unsigned char digit = 0;
657 int count = 4;
658 if(flex->Decode.type == FLEX_PAGETYPE_NUMBERED_NUMERIC) {
659 count += 10; // Skip 10 header bits for numbered numeric pages
660 } else {
661 count += 2; // Otherwise skip 2
662 }
663 int i;
664 for(i = w1; i <= w2; i++) {
665 int k;
666 for(k = 0; k < 21; k++) {
667 // Shift LSB from data word into digit
668 digit = (digit >> 1) & 0x0F;
669 if(dw & 0x01) {
670 digit ^= 0x08;
671 }
672 dw >>= 1;
673 if(--count == 0) {
674 // The following if statement removes spaces between the numbers
675 if(digit != 0x0C) {// Fill
676 verbprintf(0, "%c", flex_bcd[digit]);
677 }
678 count = 4;
679 }
680 }
681 dw = phaseptr[i];
682 }
683 }
684
685
686 static void parse_tone_only(struct Flex_Next * flex, unsigned int * phaseptr, int j) {
687 if (flex==NULL) return;
688 unsigned const char flex_bcd[17] = "0123456789 U -][";
689 // message type
690 // 1=tone-only, 0=short numeric
691 int w1 = phaseptr[j] >> 7 & 0x03;
692 if(!w1)
693 {
694 unsigned char digit = 0;
695 int i;
696 for (i=9; i<=17; i+=4)
697 {
698 digit = (phaseptr[j] >> i) & 0x0f;
699 verbprintf(0, "%c", flex_bcd[digit]);
700 }
701
702 if (flex->Decode.long_address)
703 {
704 for (i=0; i<=16; i+=4)
705 {
706 digit = (phaseptr[j+1] >> i) & 0x0f;
707 verbprintf(0, "%c", flex_bcd[digit]);
708 }
709 }
710 }
711 }
712
713 static void parse_binary(struct Flex_Next * flex, unsigned int * phaseptr, unsigned int mw1, unsigned int len) {
714 if (flex==NULL) return;
715 for (unsigned int i = 0; i < len; i++) {
716 verbprintf(0, "%08x", phaseptr[mw1 + i]);
717 if (i < (len - 1))
718 verbprintf(0, " ");
719 }
720 }
721
722
723 static void decode_phase(struct Flex_Next * flex, char PhaseNo) {
724 if (flex==NULL) return;
725 verbprintf(3, "FLEX_NEXT: Decoding phase %c\n", PhaseNo);
726
727 uint32_t *phaseptr=NULL;
728
729 switch (PhaseNo) {
730 case 'A': phaseptr=flex->Data.PhaseA.buf; break;
731 case 'B': phaseptr=flex->Data.PhaseB.buf; break;
732 case 'C': phaseptr=flex->Data.PhaseC.buf; break;
733 case 'D': phaseptr=flex->Data.PhaseD.buf; break;
734 }
735
736 for (unsigned int i = 0; i < PHASE_WORDS; i++) {
737 int decode_error=bch3121_fix_errors(flex, &phaseptr[i], PhaseNo);
738
739 if (decode_error) {
740 verbprintf(3, "FLEX_NEXT: Garbled message at block %u\n", i);
741
742 // If the previous frame was a short message then we need to Null out the Group Message pointer
743 // this issue and sugested resolution was presented by 'bertinholland'
744
745
746 return;
747 }
748
749 /*Extract just the message bits*/
750 phaseptr[i]&=0x1FFFFFL;
751 }
752
753 // Block information word is the first data word in frame
754 uint32_t biw = phaseptr[0];
755
756 // Nothing to see here, please move along
757 if (biw == 0 || (biw & 0x1FFFFFL) == 0x1FFFFFL) {
758 verbprintf(3, "FLEX_NEXT: Nothing to see here, please move along\n");
759 return;
760 }
761
762 // Address start address is bits 9-8, plus one for offset (to account for biw)
763 unsigned int aoffset = ((biw >> 8) & 0x3L) + 1;
764 // Vector start index is bits 15-10
765 unsigned int voffset = (biw >> 10) & 0x3fL;
766 if (voffset < aoffset) {
767 verbprintf(3, "FLEX_NEXT: Invalid biw");
768 return;
769 }
770 // long addresses use double AW and VW, so there are anywhere between ceil(v-a/2) to v-a pages in this frame
771 verbprintf(3, "FLEX_NEXT: BlockInfoWord: (Phase %c) BIW:%08X AW %02u VW %02u (up to %u pages)\n", PhaseNo, biw, aoffset, voffset, voffset-aoffset);
772
773 int flex_groupmessage = 0;
774 int flex_groupbit = 0;
775
776 // Iterate through pages and dispatch to appropriate handler
777 for (unsigned int i = aoffset; i < voffset; i++) {
778 verbprintf(3, "FLEX_NEXT: Processing page offset #%u AW:%08X VW:%08X\n", i - aoffset + 1, phaseptr[i], phaseptr[voffset + i - aoffset]);
779 if (phaseptr[i] == 0 ||
780 (phaseptr[i] & 0x1FFFFFL) == 0x1FFFFFL) {
781 verbprintf(3, "FLEX_NEXT: Idle codewords, invalid address\n");
782 continue;
783 }
784 /*********************
785 * Parse AW
786 */
787 uint32_t aiw = phaseptr[i];
788 flex->Decode.long_address = (aiw < 0x8001L) ||
789 (aiw > 0x1E0000L && aiw < 0x1F0001L) ||
790 (aiw > 0x1F7FFEL);
791
792 flex->Decode.capcode = aiw - 0x8000L; // if short address
793 if (flex->Decode.long_address) {
794 // Couldn't find spec on this, credit to PDW
795 flex->Decode.capcode = phaseptr[i + 1] ^ 0x1FFFFFL;
796 // 0x8000 or 32768 is 16b, use as upper part of 64b capcode
797 flex->Decode.capcode = flex->Decode.capcode << 15;
798 // add in 2068480 and first word, credit to PDW
799 // NOTE per PDW: this is not number given (2067456) in the patent for FLEX
800 flex->Decode.capcode += 2068480L + aiw;
801 }
802 if (flex->Decode.capcode > 4297068542LL || flex->Decode.capcode < 0) {
803 // Invalid address (by spec, maximum address)
804 verbprintf(3, "FLEX_NEXT: Invalid address, capcode out of range %" PRId64 "\n", flex->Decode.capcode);
805 continue;
806 }
807 verbprintf(3, "FLEX_NEXT: CAPCODE:%016" PRIx64 " %" PRId64 "\n", flex->Decode.capcode, flex->Decode.capcode);
808
809 flex_groupmessage = 0;
810 flex_groupbit = 0;
811 if ((flex->Decode.capcode >= 2029568) && (flex->Decode.capcode <= 2029583)) {
812 flex_groupmessage = 1;
813 flex_groupbit = flex->Decode.capcode - 2029568;
814 if(flex_groupbit < 0) continue;
815 }
816 if (flex_groupmessage && flex->Decode.long_address) {
817 // Invalid (by spec)
818 verbprintf(3, "FLEX_NEXT: Don't process group messages if a long address\n");
819 return;
820 }
821 verbprintf(3, "FLEX_NEXT: AIW %u: capcode:%" PRId64 " long:%d group:%d groupbit:%d\n", i, flex->Decode.capcode, flex->Decode.long_address, flex_groupmessage, flex_groupbit);
822
823 /*********************
824 * Parse VW
825 */
826 // Parse vector information word for address @ offset 'i'
827 unsigned int j = voffset+i-aoffset; // Start of vector field for address @ i
828 uint32_t viw = phaseptr[j];
829 flex->Decode.type = ((viw >> 4) & 0x7L);
830 unsigned int mw1 = (viw >> 7) & 0x7FL;
831 unsigned int len = (viw >> 14) & 0x7FL;
832 unsigned int hdr;
833 if (flex->Decode.long_address) {
834 // the header is within the next VW
835 hdr = j + 1;
836 if (len >= 1) {
837 // per PDW
838 len--;
839 }
840 } else { // if short address
841 // the header is within the message
842 hdr = mw1;
843 mw1++;
844 if (!flex_groupmessage && len >= 1) {
845 // not in spec, possible decode issue, but this fixed repeatedly observed len issues
846 len--;
847 }
848 }
849 if (hdr >= PHASE_WORDS) {
850 verbprintf(3, "FLEX_NEXT: Invalid VIW\n");
851 continue;
852 }
853 // get message fragment number (bits 11 and 12) from first header word
854 // if frag != 3 then this is a continued message
855 int frag = (int) (phaseptr[hdr] >> 11) & 0x3L;
856 // which spec documents a cont flag? it is used to derive the K/F/C frag_flag
857 int cont = (int) (phaseptr[hdr] >> 10) & 0x1L;;
858 verbprintf(3, "FLEX_NEXT: VIW %u: type:%d mw1:%u len:%u frag:%i\n", j, flex->Decode.type, mw1, len, frag);
859
860 if (flex->Decode.type == FLEX_PAGETYPE_SHORT_INSTRUCTION)
861 {
862 // if (flex_groupmessage == 1) continue;
863 unsigned int iAssignedFrame = (int)((viw >> 10) & 0x7f); // Frame with groupmessage
864 int groupbit = (int)((viw >> 17) & 0x7f); // Listen to this groupcode
865
866 ////////#############################################################################
867 ////////#############################################################################
868 flex->GroupHandler.GroupCodes[groupbit][CAPCODES_INDEX]++;
869 int CapcodePlacement = flex->GroupHandler.GroupCodes[groupbit][CAPCODES_INDEX];
870 verbprintf(1, "FLEX_NEXT: Found Short Instruction, Group bit: %i capcodes in group so far %i, adding Capcode: [%010" PRId64 "]\n", groupbit, CapcodePlacement, flex->Decode.capcode);
871
872 flex->GroupHandler.GroupCodes[groupbit][CapcodePlacement] = flex->Decode.capcode;
873 flex->GroupHandler.GroupFrame[groupbit] = iAssignedFrame;
874
875 // Ok, so the cycle and frame can be used to make sure we haven't missed the message frame.
876 // but the cycle is 0 - 15 and the frame is 0 - 127
877 if(iAssignedFrame > flex->FIW.frameno)
878 {
879 flex->GroupHandler.GroupCycle[groupbit] = (int)flex->FIW.cycleno;
880 verbprintf(4, "FLEX_NEXT: Message frame is in this cycle: %i\n", flex->GroupHandler.GroupCycle[groupbit]);
881
882 }
883 else
884 {
885 if(flex->FIW.cycleno == 15)
886 {
887 flex->GroupHandler.GroupCycle[groupbit] = 0;
888 }
889 else
890 {
891 flex->GroupHandler.GroupCycle[groupbit] = (int)flex->FIW.cycleno++;
892 }
893 verbprintf(4, "FLEX_NEXT: Message frame is in the next cycle: %i\n", flex->GroupHandler.GroupCycle[groupbit]);
894 }
895
896
897 // Nothing else to do with this word.. move on!!
898 continue;
899 }
900
901 // mw1 == 0, or anything less than the offset after all the VIW, is bad
902 if (len < 1 || mw1 < (voffset + (voffset - aoffset)) || mw1 >= PHASE_WORDS) {
903 verbprintf(3, "FLEX_NEXT: Invalid VIW\n");
904 continue;
905 }
906 // mw1 + len == 89 was observed, but still contained valid page, so truncate
907 if ((mw1 + len) > PHASE_WORDS){
908 len = PHASE_WORDS - mw1;
909 }
910
911 if (is_tone_page(flex))
912 mw1 = len = 0;
913
914 verbprintf(0, "FLEX_NEXT|%i/%i|%02i.%03i.%c|%010" PRId64 "|%c%c|%1d|", flex->Sync.baud, flex->Sync.levels, flex->FIW.cycleno, flex->FIW.frameno, PhaseNo, flex->Decode.capcode, (flex->Decode.long_address ? 'L' : 'S'), (flex_groupmessage ? 'G' : 'S'), flex->Decode.type);
915 // Check if this is an alpha message
916 if (is_alphanumeric_page(flex)) {
917 verbprintf(0, "ALN|");
918 parse_alphanumeric(flex, phaseptr, mw1, len, frag, cont, flex_groupmessage, flex_groupbit);
919 }
920 else if (is_numeric_page(flex)) {
921 verbprintf(0, "NUM|");
922 parse_numeric(flex, phaseptr, j);
923 }
924 else if (is_tone_page(flex)) {
925 verbprintf(0, "TON|");
926 parse_tone_only(flex, phaseptr, j);
927 }
928 else if (is_binary_page(flex)) {
929 verbprintf(0, "BIN|");
930 parse_binary(flex, phaseptr, mw1, len);
931 }
932 else {
933 verbprintf(0, "UNK|");
934 parse_binary(flex, phaseptr, mw1, len);
935 }
936 verbprintf(0, "\n");
937
938 // long addresses eat 2 aw and 2 vw, so skip the next aw-vw pair
939 if (flex->Decode.long_address) {
940 i++;
941 }
942 }
943 }
944
945
946 static void clear_phase_data(struct Flex_Next * flex) {
947 if (flex==NULL) return;
948 int i;
949 for (i = 0; i < PHASE_WORDS; i++) {
950 flex->Data.PhaseA.buf[i]=0;
951 flex->Data.PhaseB.buf[i]=0;
952 flex->Data.PhaseC.buf[i]=0;
953 flex->Data.PhaseD.buf[i]=0;
954 }
955
956 flex->Data.PhaseA.idle_count=0;
957 flex->Data.PhaseB.idle_count=0;
958 flex->Data.PhaseC.idle_count=0;
959 flex->Data.PhaseD.idle_count=0;
960
961 flex->Data.phase_toggle=0;
962 flex->Data.data_bit_counter=0;
963
964 }
965
966
967 static void decode_data(struct Flex_Next * flex) {
968 if (flex==NULL) return;
969
970 if (flex->Sync.baud == 1600) {
971 if (flex->Sync.levels==2) {
972 decode_phase(flex, 'A');
973 } else {
974 decode_phase(flex, 'A');
975 decode_phase(flex, 'B');
976 }
977 } else {
978 if (flex->Sync.levels==2) {
979 decode_phase(flex, 'A');
980 decode_phase(flex, 'C');
981 } else {
982 decode_phase(flex, 'A');
983 decode_phase(flex, 'B');
984 decode_phase(flex, 'C');
985 decode_phase(flex, 'D');
986 }
987 }
988 }
989
990
991 static int read_data(struct Flex_Next * flex, unsigned char sym) {
992 if (flex==NULL) return -1;
993 // Here is where we output a 1 or 0 on each phase according
994 // to current FLEX mode and symbol value. Unassigned phases
995 // are zero from the enter_idle() initialization.
996 //
997 // FLEX can transmit the data portion of the frame at either
998 // 1600 bps or 3200 bps, and can use either two- or four-level
999 // FSK encoding.
1000 //
1001 // At 1600 bps, 2-level, a single "phase" is transmitted with bit
1002 // value '0' using level '3' and bit value '1' using level '0'.
1003 //
1004 // At 1600 bps, 4-level, a second "phase" is transmitted, and the
1005 // di-bits are encoded with a gray code:
1006 //
1007 // Symbol Phase 1 Phase 2
1008 // ------ ------- -------
1009 // 0 1 1
1010 // 1 1 0
1011 // 2 0 0
1012 // 3 0 1
1013 //
1014 // At 1600 bps, 4-level, these are called PHASE A and PHASE B.
1015 //
1016 // At 3200 bps, the same 1 or 2 bit encoding occurs, except that
1017 // additionally two streams are interleaved on alternating symbols.
1018 // Thus, PHASE A (and PHASE B if 4-level) are decoded on one symbol,
1019 // then PHASE C (and PHASE D if 4-level) are decoded on the next.
1020
1021 int bit_a=0; //Received data bit for Phase A
1022 int bit_b=0; //Received data bit for Phase B
1023
1024 bit_a = (sym > 1);
1025 if (flex->Sync.levels == 4) {
1026 bit_b = (sym == 1) || (sym == 2);
1027 }
1028
1029 if (flex->Sync.baud == 1600) {
1030 flex->Data.phase_toggle=0;
1031 }
1032
1033 //By making the index scan the data words in this way, the data is deinterlaced
1034 //Bits 0, 1, and 2 map straight through to give a 0-7 sequence that repeats 32 times before moving to 8-15 repeating 32 times
1035 unsigned int idx= ((flex->Data.data_bit_counter>>5)&0xFFF8) | (flex->Data.data_bit_counter&0x0007);
1036
1037 if (flex->Data.phase_toggle==0) {
1038 flex->Data.PhaseA.buf[idx] = (flex->Data.PhaseA.buf[idx]>>1) | (bit_a?(0x80000000):0);
1039 flex->Data.PhaseB.buf[idx] = (flex->Data.PhaseB.buf[idx]>>1) | (bit_b?(0x80000000):0);
1040 flex->Data.phase_toggle=1;
1041
1042 if ((flex->Data.data_bit_counter & 0xFF) == 0xFF) {
1043 if (flex->Data.PhaseA.buf[idx] == 0x00000000 || flex->Data.PhaseA.buf[idx] == 0xffffffff) flex->Data.PhaseA.idle_count++;
1044 if (flex->Data.PhaseB.buf[idx] == 0x00000000 || flex->Data.PhaseB.buf[idx] == 0xffffffff) flex->Data.PhaseB.idle_count++;
1045 }
1046 } else {
1047 flex->Data.PhaseC.buf[idx] = (flex->Data.PhaseC.buf[idx]>>1) | (bit_a?(0x80000000):0);
1048 flex->Data.PhaseD.buf[idx] = (flex->Data.PhaseD.buf[idx]>>1) | (bit_b?(0x80000000):0);
1049 flex->Data.phase_toggle=0;
1050
1051 if ((flex->Data.data_bit_counter & 0xFF) == 0xFF) {
1052 if (flex->Data.PhaseC.buf[idx] == 0x00000000 || flex->Data.PhaseC.buf[idx] == 0xffffffff) flex->Data.PhaseC.idle_count++;
1053 if (flex->Data.PhaseD.buf[idx] == 0x00000000 || flex->Data.PhaseD.buf[idx] == 0xffffffff) flex->Data.PhaseD.idle_count++;
1054 }
1055 }
1056
1057 if (flex->Sync.baud == 1600 || flex->Data.phase_toggle==0) {
1058 flex->Data.data_bit_counter++;
1059 }
1060
1061 /*Report if all active phases have gone idle*/
1062 int idle=0;
1063 if (flex->Sync.baud == 1600) {
1064 if (flex->Sync.levels==2) {
1065 idle=(flex->Data.PhaseA.idle_count>IDLE_THRESHOLD);
1066 } else {
1067 idle=((flex->Data.PhaseA.idle_count>IDLE_THRESHOLD) && (flex->Data.PhaseB.idle_count>IDLE_THRESHOLD));
1068 }
1069 } else {
1070 if (flex->Sync.levels==2) {
1071 idle=((flex->Data.PhaseA.idle_count>IDLE_THRESHOLD) && (flex->Data.PhaseC.idle_count>IDLE_THRESHOLD));
1072 } else {
1073 idle=((flex->Data.PhaseA.idle_count>IDLE_THRESHOLD) && (flex->Data.PhaseB.idle_count>IDLE_THRESHOLD) && (flex->Data.PhaseC.idle_count>IDLE_THRESHOLD) && (flex->Data.PhaseD.idle_count>IDLE_THRESHOLD));
1074 }
1075 }
1076
1077 return idle;
1078 }
1079
1080
1081 static void report_state(struct Flex_Next * flex) {
1082 if (flex->State.Current != flex->State.Previous) {
1083 flex->State.Previous = flex->State.Current;
1084
1085 char * state="Unknown";
1086 switch (flex->State.Current) {
1087 case FLEX_STATE_SYNC1:
1088 state="SYNC1";
1089 break;
1090 case FLEX_STATE_FIW:
1091 state="FIW";
1092 break;
1093 case FLEX_STATE_SYNC2:
1094 state="SYNC2";
1095 break;
1096 case FLEX_STATE_DATA:
1097 state="DATA";
1098 break;
1099 default:
1100 break;
1101
1102 }
1103 verbprintf(1, "FLEX_NEXT: State: %s\n", state);
1104 }
1105 }
1106
1107 //Called for each received symbol
1108 static void flex_sym(struct Flex_Next * flex, unsigned char sym) {
1109 if (flex==NULL) return;
1110 /*If the signal has a negative polarity, the symbols must be inverted*/
1111 /*Polarity is determined during the IDLE/sync word checking phase*/
1112 unsigned char sym_rectified;
1113 if (flex->Sync.polarity) {
1114 sym_rectified=3-sym;
1115 } else {
1116 sym_rectified=sym;
1117 }
1118
1119 switch (flex->State.Current) {
1120 case FLEX_STATE_SYNC1:
1121 {
1122 // Continually compare the received symbol stream
1123 // against the known FLEX sync words.
1124 unsigned int sync_code=flex_sync(flex, sym); //Unrectified version of the symbol must be used here
1125 if (sync_code!=0) {
1126 decode_mode(flex,sync_code);
1127
1128 if (flex->Sync.baud!=0 && flex->Sync.levels!=0) {
1129 flex->State.Current=FLEX_STATE_FIW;
1130
1131 verbprintf(2, "FLEX_NEXT: SyncInfoWord: sync_code=0x%04x baud=%i levels=%i polarity=%s zero=%f envelope=%f symrate=%f\n",
1132 sync_code, flex->Sync.baud, flex->Sync.levels, flex->Sync.polarity?"NEG":"POS", flex->Modulation.zero, flex->Modulation.envelope, flex->Modulation.symbol_rate);
1133 } else {
1134 verbprintf(2, "FLEX_NEXT: Unknown Sync code = 0x%04x\n", sync_code);
1135 flex->State.Current=FLEX_STATE_SYNC1;
1136 }
1137 } else {
1138 flex->State.Current=FLEX_STATE_SYNC1;
1139 }
1140
1141 flex->State.fiwcount=0;
1142 flex->FIW.rawdata=0;
1143 break;
1144 }
1145 case FLEX_STATE_FIW:
1146 {
1147 // Skip 16 bits of dotting, then accumulate 32 bits
1148 // of Frame Information Word.
1149 // FIW is accumulated, call BCH to error correct it
1150 flex->State.fiwcount++;
1151 if (flex->State.fiwcount>=16) {
1152 read_2fsk(flex, sym_rectified, &flex->FIW.rawdata);
1153 }
1154
1155 if (flex->State.fiwcount==48) {
1156 if (decode_fiw(flex)==0) {
1157 flex->State.sync2_count=0;
1158 flex->Demodulator.baud = flex->Sync.baud;
1159 flex->State.Current=FLEX_STATE_SYNC2;
1160 } else {
1161 flex->State.Current=FLEX_STATE_SYNC1;
1162 }
1163 }
1164 break;
1165 }
1166 case FLEX_STATE_SYNC2:
1167 {
1168 // This part and the remainder of the frame are transmitted
1169 // at either 1600 bps or 3200 bps based on the received
1170 // FLEX sync word. The second SYNC header is 25ms of idle bits
1171 // at either speed.
1172 // Skip 25 ms = 40 bits @ 1600 bps, 80 @ 3200 bps
1173 if (++flex->State.sync2_count == flex->Sync.baud*25/1000) {
1174 flex->State.data_count=0;
1175 clear_phase_data(flex);
1176 flex->State.Current=FLEX_STATE_DATA;
1177 }
1178
1179 break;
1180 }
1181 case FLEX_STATE_DATA:
1182 {
1183 // The data portion of the frame is 1760 ms long at either
1184 // baudrate. This is 2816 bits @ 1600 bps and 5632 bits @ 3200 bps.
1185 // The output_symbol() routine decodes and doles out the bits
1186 // to each of the four transmitted phases of FLEX interleaved codes.
1187 int idle=read_data(flex, sym_rectified);
1188 if (++flex->State.data_count == flex->Sync.baud*1760/1000 || idle) {
1189 decode_data(flex);
1190 flex->Demodulator.baud = 1600;
1191 flex->State.Current=FLEX_STATE_SYNC1;
1192 flex->State.data_count=0;
1193 }
1194 break;
1195 }
1196 }
1197 }
1198
1199 static int buildSymbol(struct Flex_Next * flex, double sample) {
1200 if (flex == NULL) return 0;
1201
1202 const int64_t phase_max = 100 * flex->Demodulator.sample_freq; // Maximum value for phase (calculated to divide by sample frequency without remainder)
1203 const int64_t phase_rate = phase_max*flex->Demodulator.baud / flex->Demodulator.sample_freq; // Increment per baseband sample
1204 const double phasepercent = 100.0 * flex->Demodulator.phase / phase_max;
1205
1206 /*Update the sample counter*/
1207 flex->Demodulator.sample_count++;
1208
1209 /*Remove DC offset (FIR filter)*/
1210 if (flex->State.Current == FLEX_STATE_SYNC1) {
1211 flex->Modulation.zero = (flex->Modulation.zero*(FREQ_SAMP*DC_OFFSET_FILTER) + sample) / ((FREQ_SAMP*DC_OFFSET_FILTER) + 1);
1212 }
1213 sample -= flex->Modulation.zero;
1214
1215 if (flex->Demodulator.locked) {
1216 /*During the synchronisation period, establish the envelope of the signal*/
1217 if (flex->State.Current == FLEX_STATE_SYNC1) {
1218 flex->Demodulator.envelope_sum += fabs(sample);
1219 flex->Demodulator.envelope_count++;
1220 flex->Modulation.envelope = flex->Demodulator.envelope_sum / flex->Demodulator.envelope_count;
1221 }
1222 }
1223 else {
1224 /*Reset and hold in initial state*/
1225 flex->Modulation.envelope = 0;
1226 flex->Demodulator.envelope_sum = 0;
1227 flex->Demodulator.envelope_count = 0;
1228 flex->Demodulator.baud = 1600;
1229 flex->Demodulator.timeout = 0;
1230 flex->Demodulator.nonconsec = 0;
1231 flex->State.Current = FLEX_STATE_SYNC1;
1232 }
1233
1234 /* MID 80% SYMBOL PERIOD */
1235 if (phasepercent > 10 && phasepercent <90) {
1236 /*Count the number of occurrences of each symbol value for analysis at end of symbol period*/
1237 if (sample > 0) {
1238 if (sample > flex->Modulation.envelope*SLICE_THRESHOLD)
1239 flex->Demodulator.symcount[3]++;
1240 else
1241 flex->Demodulator.symcount[2]++;
1242 }
1243 else {
1244 if (sample < -flex->Modulation.envelope*SLICE_THRESHOLD)
1245 flex->Demodulator.symcount[0]++;
1246 else
1247 flex->Demodulator.symcount[1]++;
1248 }
1249 }
1250
1251 /* ZERO CROSSING */
1252 if ((flex->Demodulator.sample_last<0 && sample >= 0) || (flex->Demodulator.sample_last >= 0 && sample<0)) {
1253 /*The phase error has a direction towards the closest symbol boundary*/
1254 double phase_error = 0.0;
1255 if (phasepercent<50) {
1256 phase_error = flex->Demodulator.phase;
1257 }
1258 else {
1259 phase_error = flex->Demodulator.phase - phase_max;
1260 }
1261
1262 /*Phase lock with the signal*/
1263 if (flex->Demodulator.locked) {
1264 flex->Demodulator.phase -= phase_error * PHASE_LOCKED_RATE;
1265 }
1266 else {
1267 flex->Demodulator.phase -= phase_error * PHASE_UNLOCKED_RATE;
1268 }
1269
1270 /*If too many zero crossing occur within the mid 80% then indicate lock has been lost*/
1271 if (phasepercent > 10 && phasepercent < 90) {
1272 flex->Demodulator.nonconsec++;
1273 if (flex->Demodulator.nonconsec>20 && flex->Demodulator.locked) {
1274 verbprintf(1, "FLEX_NEXT: Synchronisation Lost\n");
1275 flex->Demodulator.locked = 0;
1276 }
1277 }
1278 else {
1279 flex->Demodulator.nonconsec = 0;
1280 }
1281
1282 flex->Demodulator.timeout = 0;
1283 }
1284 flex->Demodulator.sample_last = sample;
1285
1286 /* END OF SYMBOL PERIOD */
1287 flex->Demodulator.phase += phase_rate;
1288
1289 if (flex->Demodulator.phase > phase_max) {
1290 flex->Demodulator.phase -= phase_max;
1291 return 1;
1292 } else {
1293 return 0;
1294 }
1295
1296 }
1297
1298 static void Flex_Demodulate(struct Flex_Next * flex, double sample) {
1299 if(flex == NULL) return;
1300
1301 if (buildSymbol(flex, sample) == 1) {
1302 flex->Demodulator.nonconsec = 0;
1303 flex->Demodulator.symbol_count++;
1304 flex->Modulation.symbol_rate = 1.0 * flex->Demodulator.symbol_count*flex->Demodulator.sample_freq / flex->Demodulator.sample_count;
1305
1306 /*Determine the modal symbol*/
1307 int j;
1308 int decmax = 0;
1309 int modal_symbol = 0;
1310 for (j = 0; j<4; j++) {
1311 if (flex->Demodulator.symcount[j] > decmax) {
1312 modal_symbol = j;
1313 decmax = flex->Demodulator.symcount[j];
1314 }
1315 }
1316 flex->Demodulator.symcount[0] = 0;
1317 flex->Demodulator.symcount[1] = 0;
1318 flex->Demodulator.symcount[2] = 0;
1319 flex->Demodulator.symcount[3] = 0;
1320
1321
1322 if (flex->Demodulator.locked) {
1323 /*Process the symbol*/
1324 flex_sym(flex, modal_symbol);
1325 }
1326 else {
1327 /*Check for lock pattern*/
1328 /*Shift symbols into buffer, symbols are converted so that the max and min symbols map to 1 and 2 i.e each contain a single 1 */
1329 flex->Demodulator.lock_buf = (flex->Demodulator.lock_buf << 2) | (modal_symbol ^ 0x1);
1330 uint64_t lock_pattern = flex->Demodulator.lock_buf ^ 0x6666666666666666ull;
1331 uint64_t lock_mask = (1ull << (2 * LOCK_LEN)) - 1;
1332 if ((lock_pattern&lock_mask) == 0 || ((~lock_pattern)&lock_mask) == 0) {
1333 verbprintf(1, "FLEX_NEXT: Locked\n");
1334 flex->Demodulator.locked = 1;
1335 /*Clear the syncronisation buffer*/
1336 flex->Demodulator.lock_buf = 0;
1337 flex->Demodulator.symbol_count = 0;
1338 flex->Demodulator.sample_count = 0;
1339 }
1340 }
1341
1342 /*Time out after X periods with no zero crossing*/
1343 flex->Demodulator.timeout++;
1344 if (flex->Demodulator.timeout>DEMOD_TIMEOUT) {
1345 verbprintf(1, "FLEX_NEXT: Timeout\n");
1346 flex->Demodulator.locked = 0;
1347 }
1348 }
1349
1350 report_state(flex);
1351 }
1352
1353 static void Flex_Delete(struct Flex_Next * flex) {
1354 if (flex==NULL) return;
1355
1356 if (flex->Decode.BCHCode!=NULL) {
1357 BCHCode_Delete(flex->Decode.BCHCode);
1358 flex->Decode.BCHCode=NULL;
1359 }
1360
1361 free(flex);
1362 }
1363
1364
1365 static struct Flex_Next * Flex_New(unsigned int SampleFrequency) {
1366 struct Flex_Next *flex=(struct Flex_Next *)malloc(sizeof(struct Flex_Next));
1367 if (flex!=NULL) {
1368 memset(flex, 0, sizeof(struct Flex_Next));
1369
1370 flex->Demodulator.sample_freq=SampleFrequency;
1371 // The baud rate of first syncword and FIW is always 1600, so set that
1372 // rate to start.
1373 flex->Demodulator.baud = 1600;
1374
1375 /*Generator polynomial for BCH3121 Code*/
1376 int p[6];
1377 p[0] = p[2] = p[5] = 1; p[1] = p[3] = p[4] =0;
1378 flex->Decode.BCHCode=BCHCode_New( p, 5, 31, 21, 2);
1379 if (flex->Decode.BCHCode == NULL) {
1380 Flex_Delete(flex);
1381 flex=NULL;
1382 }
1383
1384 for(int g = 0; g < GROUP_BITS; g++)
1385 {
1386 flex->GroupHandler.GroupFrame[g] = -1;
1387 flex->GroupHandler.GroupCycle[g] = -1;
1388 }
1389 }
1390
1391 return flex;
1392 }
1393
1394
1395 static void flex_next_demod(struct demod_state *s, buffer_t buffer, int length) {
1396 if (s==NULL) return;
1397 if (s->l1.flex_next==NULL) return;
1398 int i;
1399 for (i=0; i<length; i++) {
1400 Flex_Demodulate(s->l1.flex_next, buffer.fbuffer[i]);
1401 }
1402 }
1403
1404
1405 static void flex_next_init(struct demod_state *s) {
1406 if (s==NULL) return;
1407 s->l1.flex_next=Flex_New(FREQ_SAMP);
1408 }
1409
1410
1411 static void flex_next_deinit(struct demod_state *s) {
1412 if (s==NULL) return;
1413 if (s->l1.flex_next==NULL) return;
1414
1415 Flex_Delete(s->l1.flex_next);
1416 s->l1.flex_next=NULL;
1417 }
1418
1419
1420 const struct demod_param demod_flex_next = {
1421 "FLEX_NEXT", true, FREQ_SAMP, FILTLEN, flex_next_init, flex_next_demod, flex_next_deinit
1422 };
4646 demod_afsk24_2.c \
4747 demod_afsk12.c \
4848 demod_flex.c \
49 demod_flex_next.c \
4950 BCHCode.c \
5051 costabi.c \
5152 costabf.c \
242242 } dumpcsv;
243243
244244 struct Flex * flex;
245 struct Flex_Next * flex_next;
245246
246247 struct l1_state_x10 {
247248 uint32_t current_sequence;
285286 extern const struct demod_param demod_poc12;
286287 extern const struct demod_param demod_poc24;
287288 extern const struct demod_param demod_flex;
289 extern const struct demod_param demod_flex_next;
288290
289291 extern const struct demod_param demod_eas;
290292
326328 #define SCOPE_DEMOD
327329 #endif
328330
329 #define ALL_DEMOD &demod_poc5, &demod_poc12, &demod_poc24, &demod_flex, &demod_eas, &demod_ufsk1200, &demod_clipfsk, &demod_fmsfsk, \
331 #define ALL_DEMOD &demod_poc5, &demod_poc12, &demod_poc24, &demod_flex, &demod_flex_next, &demod_eas, &demod_ufsk1200, &demod_clipfsk, &demod_fmsfsk, \
330332 &demod_afsk1200, &demod_afsk2400, &demod_afsk2400_2, &demod_afsk2400_3, &demod_hapn4800, \
331333 &demod_fsk9600, &demod_dtmf, &demod_zvei1, &demod_zvei2, &demod_zvei3, &demod_dzvei, \
332334 &demod_pzvei, &demod_eea, &demod_eia, &demod_ccir, &demod_morse, &demod_dumpcsv, &demod_x10 SCOPE_DEMOD
55 *
66 * Copyright (C) 2012-2014
77 * Elias Oenal (multimon-ng@eliasoenal.com)
8 *
9 * Copyright (C) 2022
10 * Tobias Girstmair (https://gir.st/)
811 *
912 * POCSAG (Post Office Code Standard Advisory Group)
1013 * Radio Paging Decoder
5255 #define POCSAG_SYNC_WORDS ((2000000 >> 3) << 13)
5356
5457 #define POCSAG_MESSAGE_DETECTION 0x80000000 // Most significant bit is a one
58
59 #define CAESAR_ALPHA 0
60 #define CAESAR_SKYPER 1 // skyper messages are ROT-1 enciphered
5561
5662 #define POSCAG
5763 /* ---------------------------------------------------------------------- */
370376 {
371377 trtab[0x40] = "Ž";
372378 trtab[0x5b] = "Š";
379 trtab[0x5d] = "Ć";
373380 trtab[0x5e] = "Č";
374381 trtab[0x60] = "ž";
375382 trtab[0x7b] = "š";
383 trtab[0x7d] = "ć";
376384 trtab[0x7e] = "č";
377385 }
378386 else if (strcmp(charset,"US")==0) // US charset
422430 return 0;
423431 }
424432
425 static unsigned int print_msg_numeric(struct l2_state_pocsag *rx, char* buff, unsigned int size)
433 static int print_msg_numeric(struct l2_state_pocsag *rx, char* buff, unsigned int size)
426434 {
427435 static const char *conv_table = "084 2.6]195-3U7[";
428436 unsigned char *bp = rx->buffer;
429437 int len = rx->numnibbles;
430438 char* cp = buff;
431 unsigned int guesstimate = 0;
439 int guesstimate = 0;
432440
433441 if ( (unsigned int) len >= size)
434442 len = size-1;
445453 return guesstimate;
446454 }
447455
448 static int print_msg_alpha(struct l2_state_pocsag *rx, char* buff, unsigned int size)
449 {
450 uint32_t data = 0;
451 int datalen = 0;
452 unsigned char *bp = rx->buffer;
453 int len = rx->numnibbles;
456 static unsigned char get7(const unsigned char *buf, int n)
457 {
458 /* returns the n-th seven bit word */
459 return ( buf[(n*7)/8]<<8 | buf[(n*7+6)/8] ) >> (n+1)%8;
460 }
461
462 static unsigned char rev7(unsigned char b)
463 {
464 /* reverses the bit order of a seven bit word */
465 return ((b << 6) & 64) | ((b >> 6) & 1) |
466 ((b << 4) & 32) | ((b >> 4) & 2) |
467 ((b << 2) & 16) | ((b >> 2) & 4) |
468 ((b << 0) & 8);
469 }
470
471 static int print_msg_alpha(struct l2_state_pocsag *rx, char* buff, unsigned int size, int caesar)
472 {
473 int len = rx->numnibbles * 4 / 7;
454474 char* cp = buff;
455475 int buffree = size-1;
456476 unsigned char curchr;
457477 char *tstr;
458478 int guesstimate = 0;
459479
460 while (len > 0)
480 for (int i = 0; i < len; i++)
461481 {
462 while (datalen < 7 && len > 0) {
463 if (len == 1) {
464 data = (data << 4) | ((*bp >> 4) & 0xf);
465 datalen += 4;
466 len = 0;
467 } else {
468 data = (data << 8) | *bp++;
469 datalen += 8;
470 len -= 2;
471 }
472 }
473 if (datalen < 7)
474 continue;
475 datalen -= 7;
476 curchr = ((data >> datalen) & 0x7f) << 1;
477 curchr = ((curchr & 0xf0) >> 4) | ((curchr & 0x0f) << 4);
478 curchr = ((curchr & 0xcc) >> 2) | ((curchr & 0x33) << 2);
479 curchr = ((curchr & 0xaa) >> 1) | ((curchr & 0x55) << 1);
482 curchr = rev7(get7(rx->buffer, i)) - caesar;
480483
481484 guesstimate += guesstimate_alpha(curchr);
482485
497500 }
498501 *cp = '\0';
499502
500 return guesstimate;
501 }
502
503 /* ---------------------------------------------------------------------- */
504
505 static int print_msg_skyper(struct l2_state_pocsag *rx, char* buff, unsigned int size)
506 {
507 uint32_t data = 0;
508 int datalen = 0;
509 unsigned char *bp = rx->buffer;
510 int len = rx->numnibbles;
511 char* cp = buff;
512 int buffree = size-1;
513 unsigned char curchr;
514 char *tstr;
515 unsigned int guesstimate = 0;
516
517 while (len > 0) {
518 while (datalen < 7 && len > 0) {
519 if (len == 1) {
520 data = (data << 4) | ((*bp >> 4) & 0xf);
521 datalen += 4;
522 len = 0;
523 } else {
524 data = (data << 8) | *bp++;
525 datalen += 8;
526 len -= 2;
527 }
528 }
529 if (datalen < 7)
530 continue;
531 datalen -= 7;
532 curchr = ((data >> datalen) & 0x7f) << 1;
533 curchr = ((curchr & 0xf0) >> 4) | ((curchr & 0x0f) << 4);
534 curchr = ((curchr & 0xcc) >> 2) | ((curchr & 0x33) << 2);
535 curchr = ((curchr & 0xaa) >> 1) | ((curchr & 0x55) << 1);
536
537 guesstimate += guesstimate_alpha(curchr-1);
538
539 tstr = translate_alpha(curchr-1);
540 if (tstr) {
541 int tlen = strlen(tstr);
542 if (buffree >= tlen) {
543 memcpy(cp, tstr, tlen);
544 cp += tlen;
545 buffree -= tlen;
546 }
547 } else if (buffree > 0) {
548 *cp++ = curchr-1;
549 buffree--;
550 }
551 }
552 *cp = '\0';
553503 return guesstimate;
554504 }
555505
583533 int func = 0;
584534
585535 guess_num = print_msg_numeric(&s->l2.pocsag, num_string, sizeof(num_string));
586 guess_alpha = print_msg_alpha(&s->l2.pocsag, alpha_string, sizeof(alpha_string));
587 guess_skyper = print_msg_skyper(&s->l2.pocsag, skyper_string, sizeof(skyper_string));
536 guess_alpha = print_msg_alpha(&s->l2.pocsag, alpha_string, sizeof(alpha_string), CAESAR_ALPHA);
537 guess_skyper = print_msg_alpha(&s->l2.pocsag, skyper_string, sizeof(skyper_string), CAESAR_SKYPER);
588538
589539 func = s->l2.pocsag.function;
590540
33 * Copyright (C) 1996
44 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu)
55 *
6 * Copyright (C) 2012-2020
6 * Copyright (C) 2012-2022
77 * Elias Oenal (multimon-ng@eliasoenal.com)
88 *
99 * This program is free software; you can redistribute it and/or modify
498498 perror("dup2");
499499 close(pipedes[1]); /* close writing pipe end */
500500 execlp("sox", "sox", repeatable_sox?"-R":"-V2", mute_sox?"-V1":"-V2",
501 "--ignore-length",
501502 "-t", type, fname,
502503 "-t", "raw", "-esigned-integer", "-b16", "-r", srate, "-", "remix", "1",
503504 NULL);
800801
801802 if ( !quietflg )
802803 { // pay heed to the quietflg
803 fprintf(stderr, "multimon-ng 1.1.9\n"
804 fprintf(stderr, "multimon-ng 1.2.0\n"
804805 " (C) 1996/1997 by Tom Sailer HB9JNX/AE4WA\n"
805 " (C) 2012-2020 by Elias Oenal\n"
806 " (C) 2012-2022 by Elias Oenal\n"
806807 "Available demodulators:");
807808 for (i = 0; (unsigned int) i < NUMDEMOD; i++) {
808809 fprintf(stderr, " %s", dem[i]->name);