1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | #if defined(HAVE_CONFIG_H1) |
29 | #include "config.h" |
30 | #endif |
31 | |
32 | #include <stdlib.h> |
33 | #include <inttypes.h> |
34 | #include <string.h> |
35 | #if defined(HAVE_TGMATH_H1) |
36 | #include <tgmath.h> |
37 | #endif |
38 | #if defined(HAVE_MATH_H1) |
39 | #include <math.h> |
40 | #endif |
41 | #if defined(HAVE_STDBOOL_H1) |
42 | #include <stdbool.h> |
43 | #else |
44 | #include "spandsp/stdbool.h" |
45 | #endif |
46 | #include "floating_fudge.h" |
47 | #include <assert.h> |
48 | |
49 | #include "spandsp/telephony.h" |
50 | #include "spandsp/alloc.h" |
51 | #include "spandsp/complex.h" |
52 | #include "spandsp/dds.h" |
53 | #include "spandsp/power_meter.h" |
54 | #include "spandsp/bit_operations.h" |
55 | #include "spandsp/async.h" |
56 | #include "spandsp/fsk.h" |
57 | |
58 | #include "spandsp/private/power_meter.h" |
59 | #include "spandsp/private/fsk.h" |
60 | |
61 | const fsk_spec_t preset_fsk_specs[] = |
62 | { |
63 | { |
64 | |
65 | "V21 ch 1", |
66 | 1080 + 100, |
67 | 1080 - 100, |
68 | -14, |
69 | -30, |
70 | 300*100 |
71 | }, |
72 | { |
73 | |
74 | |
75 | "V21 ch 2", |
76 | 1750 + 100, |
77 | 1750 - 100, |
78 | -14, |
79 | -30, |
80 | 300*100 |
81 | }, |
82 | { |
83 | |
84 | "V23 ch 1", |
85 | 1700 + 400, |
86 | 1700 - 400, |
87 | -14, |
88 | -30, |
89 | 1200*100 |
90 | }, |
91 | { |
92 | "V23 ch 2", |
93 | 420 + 30, |
94 | 420 - 30, |
95 | -14, |
96 | -30, |
97 | 75*100 |
98 | }, |
99 | { |
100 | |
101 | "Bell103 ch 1", |
102 | 1170 - 100, |
103 | 1170 + 100, |
104 | -14, |
105 | -30, |
106 | 300*100 |
107 | }, |
108 | { |
109 | |
110 | "Bell103 ch 2", |
111 | 2125 - 100, |
112 | 2125 + 100, |
113 | -14, |
114 | -30, |
115 | 300*100 |
116 | }, |
117 | { |
118 | "Bell202", |
119 | 1700 + 500, |
120 | 1700 - 500, |
121 | -14, |
122 | -30, |
123 | 1200*100 |
124 | }, |
125 | { |
126 | |
127 | "Weitbrecht 45.45", |
128 | 1600 + 200, |
129 | 1600 - 200, |
130 | -14, |
131 | -30, |
132 | 4545 |
133 | }, |
134 | { |
135 | |
136 | "Weitbrecht 50", |
137 | 1600 + 200, |
138 | 1600 - 200, |
139 | -14, |
140 | -30, |
141 | 50*100 |
142 | }, |
143 | { |
144 | |
145 | "Weitbrecht 47.6", |
146 | 1600 + 200, |
147 | 1600 - 200, |
148 | -14, |
149 | -30, |
150 | 4760 |
151 | }, |
152 | { |
153 | "V21 (110bps) ch 1", |
154 | 1080 + 100, |
155 | 1080 - 100, |
156 | -14, |
157 | -30, |
158 | 110*100 |
159 | } |
160 | }; |
161 | |
162 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_tx(fsk_tx_state_t *s, int16_t amp[], int len) |
163 | { |
164 | int sample; |
165 | int bit; |
166 | |
167 | if (s->shutdown) |
168 | return 0; |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | for (sample = 0; sample < len; sample++) |
175 | { |
176 | if ((s->baud_frac += s->baud_rate) >= SAMPLE_RATE8000*100) |
177 | { |
178 | s->baud_frac -= SAMPLE_RATE8000*100; |
179 | if ((bit = s->get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA) |
180 | { |
181 | if (s->status_handler) |
182 | s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA); |
183 | |
184 | if (s->status_handler) |
185 | s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE); |
186 | |
187 | s->shutdown = true1; |
188 | break; |
189 | } |
190 | |
191 | s->current_phase_rate = s->phase_rates[bit & 1]; |
192 | } |
193 | |
194 | amp[sample] = dds_mod(&s->phase_acc, s->current_phase_rate, s->scaling, 0); |
195 | } |
196 | |
197 | return sample; |
198 | } |
199 | |
200 | |
201 | SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_tx_power(fsk_tx_state_t *s, float power) |
202 | { |
203 | s->scaling = dds_scaling_dbm0(power); |
204 | } |
205 | |
206 | |
207 | SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_tx_set_get_bit(fsk_tx_state_t *s, span_get_bit_func_t get_bit, void *user_data) |
208 | { |
209 | s->get_bit = get_bit; |
210 | s->get_bit_user_data = user_data; |
211 | } |
212 | |
213 | |
214 | SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_tx_set_modem_status_handler(fsk_tx_state_t *s, span_modem_status_func_t handler, void *user_data) |
215 | { |
216 | s->status_handler = handler; |
217 | s->status_user_data = user_data; |
218 | } |
219 | |
220 | |
221 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_tx_restart(fsk_tx_state_t *s, const fsk_spec_t *spec) |
222 | { |
223 | s->baud_rate = spec->baud_rate; |
224 | s->phase_rates[0] = dds_phase_rate((float) spec->freq_zero); |
225 | s->phase_rates[1] = dds_phase_rate((float) spec->freq_one); |
226 | s->scaling = dds_scaling_dbm0((float) spec->tx_level); |
227 | |
228 | s->phase_acc = 0; |
229 | s->baud_frac = 0; |
230 | s->current_phase_rate = s->phase_rates[1]; |
231 | |
232 | s->shutdown = false0; |
233 | return 0; |
234 | } |
235 | |
236 | |
237 | SPAN_DECLARE(fsk_tx_state_t *)__attribute__((visibility("default"))) fsk_tx_state_t * fsk_tx_init(fsk_tx_state_t *s, |
238 | const fsk_spec_t *spec, |
239 | span_get_bit_func_t get_bit, |
240 | void *user_data) |
241 | { |
242 | if (s == NULL((void*)0)) |
243 | { |
244 | if ((s = (fsk_tx_state_t *) span_alloc(sizeof(*s))) == NULL((void*)0)) |
245 | return NULL((void*)0); |
246 | |
247 | } |
248 | |
249 | memset(s, 0, sizeof(*s)); |
250 | |
251 | s->get_bit = get_bit; |
252 | s->get_bit_user_data = user_data; |
253 | fsk_tx_restart(s, spec); |
254 | return s; |
255 | } |
256 | |
257 | |
258 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_tx_release(fsk_tx_state_t *s) |
259 | { |
260 | return 0; |
261 | } |
262 | |
263 | |
264 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_tx_free(fsk_tx_state_t *s) |
265 | { |
266 | span_free(s); |
267 | return 0; |
268 | } |
269 | |
270 | |
271 | SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_rx_set_signal_cutoff(fsk_rx_state_t *s, float cutoff) |
272 | { |
273 | |
274 | s->carrier_on_power = (int32_t) (power_meter_level_dbm0(cutoff + 2.5f - 6.04f)); |
275 | s->carrier_off_power = (int32_t) (power_meter_level_dbm0(cutoff - 2.5f - 6.04f)); |
276 | } |
277 | |
278 | |
279 | SPAN_DECLARE(float)__attribute__((visibility("default"))) float fsk_rx_signal_power(fsk_rx_state_t *s) |
280 | { |
281 | return power_meter_current_dbm0(&s->power); |
282 | } |
283 | |
284 | |
285 | SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_rx_set_put_bit(fsk_rx_state_t *s, span_put_bit_func_t put_bit, void *user_data) |
286 | { |
287 | s->put_bit = put_bit; |
288 | s->put_bit_user_data = user_data; |
289 | } |
290 | |
291 | |
292 | SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_rx_set_modem_status_handler(fsk_rx_state_t *s, span_modem_status_func_t handler, void *user_data) |
293 | { |
294 | s->status_handler = handler; |
295 | s->status_user_data = user_data; |
296 | } |
297 | |
298 | |
299 | SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_rx_set_frame_parameters(fsk_rx_state_t *s, |
300 | int data_bits, |
301 | int parity, |
302 | int stop_bits) |
303 | { |
304 | if (s->framing_mode == FSK_FRAME_MODE_FRAMED) |
305 | { |
306 | s->data_bits = data_bits; |
307 | s->parity = parity; |
308 | s->stop_bits = stop_bits; |
309 | s->total_data_bits = s->data_bits; |
310 | if (s->parity != ASYNC_PARITY_NONE) |
311 | s->total_data_bits++; |
312 | |
313 | } |
314 | |
315 | } |
316 | |
317 | |
318 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_get_parity_errors(fsk_rx_state_t *s, bool_Bool reset) |
319 | { |
320 | int errors; |
321 | |
322 | errors = s->parity_errors; |
323 | if (reset) |
324 | s->parity_errors = 0; |
325 | |
326 | return errors; |
327 | } |
328 | |
329 | |
330 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_get_framing_errors(fsk_rx_state_t *s, bool_Bool reset) |
331 | { |
332 | int errors; |
333 | |
334 | errors = s->framing_errors; |
335 | if (reset) |
336 | s->framing_errors = 0; |
337 | |
338 | return errors; |
339 | } |
340 | |
341 | |
342 | static void report_status_change(fsk_rx_state_t *s, int status) |
343 | { |
344 | if (s->status_handler) |
345 | s->status_handler(s->status_user_data, status); |
346 | else if (s->put_bit) |
347 | s->put_bit(s->put_bit_user_data, status); |
348 | |
349 | } |
350 | |
351 | |
352 | static void put_frame(fsk_rx_state_t *s, uint16_t frame) |
353 | { |
354 | uint16_t parity_bit_a; |
355 | uint16_t parity_bit_b; |
| 25 | | 'parity_bit_b' declared without an initial value | |
|
356 | |
357 | if (s->parity != ASYNC_PARITY_NONE) |
| 26 | | Assuming the condition is true | |
|
| |
358 | { |
359 | parity_bit_a = (frame >> 15) & 0x01; |
360 | |
361 | frame &= 0x7FFF; |
362 | frame >>= (16 - s->total_data_bits); |
363 | switch (s->parity) |
| 28 | | 'Default' branch taken. Execution continues on line 379 | |
|
364 | { |
365 | case ASYNC_PARITY_ODD: |
366 | parity_bit_b = parity8(frame) ^ 1; |
367 | break; |
368 | case ASYNC_PARITY_EVEN: |
369 | parity_bit_b = parity8(frame); |
370 | break; |
371 | case ASYNC_PARITY_MARK: |
372 | parity_bit_b = 1; |
373 | break; |
374 | case ASYNC_PARITY_SPACE: |
375 | parity_bit_b = 0; |
376 | break; |
377 | } |
378 | |
379 | if (parity_bit_a == parity_bit_b) |
| 29 | | The right operand of '==' is a garbage value |
|
380 | s->put_bit(s->put_bit_user_data, frame); |
381 | else |
382 | s->parity_errors++; |
383 | |
384 | } |
385 | else |
386 | { |
387 | frame >>= (16 - s->total_data_bits); |
388 | s->put_bit(s->put_bit_user_data, frame); |
389 | } |
390 | |
391 | } |
392 | |
393 | |
394 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len) |
395 | { |
396 | int buf_ptr; |
397 | int baudstate; |
398 | int i; |
399 | int j; |
400 | int16_t x; |
401 | int32_t dot; |
402 | int32_t sum[2]; |
403 | int32_t power; |
404 | complexi_t ph; |
405 | |
406 | buf_ptr = s->buf_ptr; |
407 | for (i = 0; i < len; i++) |
| |
| 2 | | Loop condition is true. Entering loop body | |
|
408 | { |
409 | |
410 | |
411 | |
412 | for (j = 0; j < 2; j++) |
| 3 | | Loop condition is true. Entering loop body | |
|
| 4 | | Loop condition is true. Entering loop body | |
|
| 5 | | Loop condition is false. Execution continues on line 435 | |
|
413 | { |
414 | s->dot[j].re -= s->window[j][buf_ptr].re; |
415 | s->dot[j].im -= s->window[j][buf_ptr].im; |
416 | |
417 | ph = dds_complexi(&s->phase_acc[j], s->phase_rate[j]); |
418 | s->window[j][buf_ptr].re = (ph.re*amp[i]) >> s->scaling_shift; |
419 | s->window[j][buf_ptr].im = (ph.im*amp[i]) >> s->scaling_shift; |
420 | |
421 | s->dot[j].re += s->window[j][buf_ptr].re; |
422 | s->dot[j].im += s->window[j][buf_ptr].im; |
423 | |
424 | dot = s->dot[j].re >> 15; |
425 | sum[j] = dot*dot; |
426 | dot = s->dot[j].im >> 15; |
427 | sum[j] += dot*dot; |
428 | } |
429 | |
430 | |
431 | |
432 | |
433 | |
434 | |
435 | x = amp[i] >> 1; |
436 | power = power_meter_update(&s->power, x - s->last_sample); |
437 | s->last_sample = x; |
438 | if (s->signal_present) |
| 6 | | Assuming the condition is true | |
|
| |
439 | { |
440 | |
441 | if (power < s->carrier_off_power) |
| |
442 | { |
443 | if (--s->signal_present <= 0) |
444 | { |
445 | |
446 | |
447 | report_status_change(s, SIG_STATUS_CARRIER_DOWN); |
448 | s->baud_phase = 0; |
449 | continue; |
450 | } |
451 | |
452 | } |
453 | |
454 | } |
455 | else |
456 | { |
457 | |
458 | if (power < s->carrier_on_power) |
459 | { |
460 | s->baud_phase = 0; |
461 | continue; |
462 | } |
463 | |
464 | if (s->baud_phase < (s->correlation_span >> 1) - 30) |
465 | { |
466 | s->baud_phase++; |
467 | continue; |
468 | } |
469 | |
470 | s->signal_present = 1; |
471 | |
472 | s->baud_phase = 0; |
473 | s->frame_pos = -2; |
474 | s->frame_in_progress = 0; |
475 | s->last_bit = 0; |
476 | report_status_change(s, SIG_STATUS_CARRIER_UP); |
477 | } |
478 | |
479 | |
480 | |
481 | |
482 | |
483 | |
484 | baudstate = (sum[0] < sum[1]); |
485 | switch (s->framing_mode) |
| 9 | | Control jumps to the 'default' case at line 535 | |
|
486 | { |
487 | case FSK_FRAME_MODE_SYNC: |
488 | |
489 | if (s->last_bit != baudstate) |
490 | { |
491 | |
492 | s->last_bit = baudstate; |
493 | |
494 | |
495 | if (s->baud_phase < (SAMPLE_RATE8000*50)) |
496 | s->baud_phase += (s->baud_rate >> 3); |
497 | else |
498 | s->baud_phase -= (s->baud_rate >> 3); |
499 | |
500 | } |
501 | |
502 | if ((s->baud_phase += s->baud_rate) >= (SAMPLE_RATE8000*100)) |
503 | { |
504 | |
505 | |
506 | s->baud_phase -= (SAMPLE_RATE8000*100); |
507 | s->put_bit(s->put_bit_user_data, baudstate); |
508 | } |
509 | |
510 | break; |
511 | case FSK_FRAME_MODE_ASYNC: |
512 | |
513 | if (s->last_bit != baudstate) |
514 | { |
515 | |
516 | s->last_bit = baudstate; |
517 | |
518 | |
519 | |
520 | |
521 | |
522 | |
523 | s->baud_phase = SAMPLE_RATE8000*50; |
524 | } |
525 | |
526 | if ((s->baud_phase += s->baud_rate) >= (SAMPLE_RATE8000*100)) |
527 | { |
528 | |
529 | |
530 | s->baud_phase -= (SAMPLE_RATE8000*100); |
531 | s->put_bit(s->put_bit_user_data, baudstate); |
532 | } |
533 | |
534 | break; |
535 | default: |
536 | |
537 | |
538 | |
539 | if (s->frame_pos == -2) |
| 10 | | Assuming the condition is false | |
|
| |
540 | { |
541 | |
542 | if (baudstate == 0) |
543 | { |
544 | s->baud_phase = SAMPLE_RATE8000*(100 - 40)/2; |
545 | s->frame_pos = -1; |
546 | s->frame_in_progress = 0; |
547 | s->last_bit = -1; |
548 | } |
549 | |
550 | } |
551 | else if (s->frame_pos == -1) |
| 12 | | Assuming the condition is false | |
|
| |
552 | { |
553 | |
554 | |
555 | if (baudstate != 0) |
556 | { |
557 | |
558 | s->frame_pos = -2; |
559 | } |
560 | else |
561 | { |
562 | s->baud_phase += s->baud_rate; |
563 | if (s->baud_phase >= SAMPLE_RATE8000*100) |
564 | { |
565 | s->frame_pos = 0; |
566 | s->last_bit = baudstate; |
567 | } |
568 | |
569 | } |
570 | |
571 | } |
572 | else |
573 | { |
574 | s->baud_phase += s->baud_rate; |
575 | if (s->baud_phase >= SAMPLE_RATE8000*(100 - 40)) |
| 14 | | Assuming the condition is true | |
|
| |
576 | { |
577 | if (s->last_bit < 0) |
| 16 | | Assuming the condition is false | |
|
| |
578 | s->last_bit = baudstate; |
579 | |
580 | |
581 | if (s->last_bit != baudstate) |
| |
582 | { |
583 | s->frame_pos = -2; |
584 | s->framing_errors++; |
585 | } |
586 | else |
587 | { |
588 | if (s->baud_phase >= SAMPLE_RATE8000*100) |
| 19 | | Assuming the condition is true | |
|
| |
589 | { |
590 | |
591 | |
592 | if (s->frame_pos++ > s->total_data_bits) |
| |
593 | { |
594 | |
595 | if (baudstate == 1) |
| 22 | | Assuming 'baudstate' is equal to 1 | |
|
| |
596 | { |
597 | put_frame(s, s->frame_in_progress); |
| |
598 | } |
599 | else |
600 | { |
601 | s->framing_errors++; |
602 | } |
603 | |
604 | s->frame_pos = -2; |
605 | } |
606 | else |
607 | { |
608 | s->frame_in_progress = (s->frame_in_progress >> 1) | (baudstate << 15); |
609 | } |
610 | |
611 | s->baud_phase -= (SAMPLE_RATE8000*100); |
612 | s->last_bit = -1; |
613 | } |
614 | |
615 | } |
616 | |
617 | } |
618 | |
619 | } |
620 | |
621 | break; |
622 | } |
623 | |
624 | if (++buf_ptr >= s->correlation_span) |
625 | buf_ptr = 0; |
626 | |
627 | } |
628 | |
629 | s->buf_ptr = buf_ptr; |
630 | return 0; |
631 | } |
632 | |
633 | |
634 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_fillin(fsk_rx_state_t *s, int len) |
635 | { |
636 | int buf_ptr; |
637 | int i; |
638 | int j; |
639 | |
640 | |
641 | |
642 | |
643 | buf_ptr = s->buf_ptr; |
644 | for (i = 0; i < len; i++) |
645 | { |
646 | for (j = 0; j < 2; j++) |
647 | { |
648 | s->dot[j].re -= s->window[j][buf_ptr].re; |
649 | s->dot[j].im -= s->window[j][buf_ptr].im; |
650 | |
651 | dds_advance(&s->phase_acc[j], s->phase_rate[j]); |
652 | |
653 | s->window[j][buf_ptr].re = 0; |
654 | s->window[j][buf_ptr].im = 0; |
655 | |
656 | s->dot[j].re += s->window[j][buf_ptr].re; |
657 | s->dot[j].im += s->window[j][buf_ptr].im; |
658 | } |
659 | |
660 | } |
661 | |
662 | s->buf_ptr = buf_ptr; |
663 | return 0; |
664 | } |
665 | |
666 | |
667 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_restart(fsk_rx_state_t *s, |
668 | const fsk_spec_t *spec, |
669 | int framing_mode) |
670 | { |
671 | int chop; |
672 | |
673 | s->baud_rate = spec->baud_rate; |
674 | s->framing_mode = framing_mode; |
675 | if (s->framing_mode == FSK_FRAME_MODE_FRAMED) |
676 | fsk_rx_set_frame_parameters(s, 8, ASYNC_PARITY_NONE, 1); |
677 | |
678 | fsk_rx_set_signal_cutoff(s, (float) spec->min_level); |
679 | |
680 | |
681 | |
682 | |
683 | |
684 | |
685 | s->phase_rate[0] = dds_phase_rate((float) spec->freq_zero); |
686 | s->phase_rate[1] = dds_phase_rate((float) spec->freq_one); |
687 | s->phase_acc[0] = 0; |
688 | s->phase_acc[1] = 0; |
689 | s->last_sample = 0; |
690 | |
691 | |
692 | s->correlation_span = SAMPLE_RATE8000*100/spec->baud_rate; |
693 | |
694 | |
695 | if (s->correlation_span > FSK_MAX_WINDOW_LEN128) |
696 | s->correlation_span = FSK_MAX_WINDOW_LEN128; |
697 | |
698 | |
699 | |
700 | s->scaling_shift = 0; |
701 | chop = s->correlation_span; |
702 | while (chop != 0) |
703 | { |
704 | s->scaling_shift++; |
705 | chop >>= 1; |
706 | } |
707 | |
708 | |
709 | |
710 | s->baud_phase = 0; |
711 | s->frame_pos = -2; |
712 | s->frame_in_progress = 0; |
713 | s->last_bit = 0; |
714 | |
715 | |
716 | power_meter_init(&s->power, 4); |
717 | s->signal_present = 0; |
718 | return 0; |
719 | } |
720 | |
721 | |
722 | SPAN_DECLARE(fsk_rx_state_t *)__attribute__((visibility("default"))) fsk_rx_state_t * fsk_rx_init(fsk_rx_state_t *s, |
723 | const fsk_spec_t *spec, |
724 | int framing_mode, |
725 | span_put_bit_func_t put_bit, |
726 | void *user_data) |
727 | { |
728 | if (s == NULL((void*)0)) |
729 | { |
730 | if ((s = (fsk_rx_state_t *) span_alloc(sizeof(*s))) == NULL((void*)0)) |
731 | return NULL((void*)0); |
732 | |
733 | } |
734 | |
735 | memset(s, 0, sizeof(*s)); |
736 | |
737 | s->put_bit = put_bit; |
738 | s->put_bit_user_data = user_data; |
739 | fsk_rx_restart(s, spec, framing_mode); |
740 | return s; |
741 | } |
742 | |
743 | |
744 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_release(fsk_rx_state_t *s) |
745 | { |
746 | return 0; |
747 | } |
748 | |
749 | |
750 | SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_free(fsk_rx_state_t *s) |
751 | { |
752 | span_free(s); |
753 | return 0; |
754 | } |
755 | |
756 | |