Compare commits

..

1 Commits

Author SHA1 Message Date
Harald Welte b18ac21691 src/test/Makefile.am: Fix some typos of sources .x -> .c 2022-05-01 12:49:21 +02:00
209 changed files with 127194 additions and 152656 deletions

8
.gitignore vendored
View File

@ -32,8 +32,6 @@ src/libsquelch/libsquelch.a
src/libhagelbarger/libhagelbarger.a
src/libdtmf/libdtmf.a
src/libtimer/libtimer.a
src/libselect/libselect.a
src/libph_socket/libph_socket.a
src/libsamplerate/libsamplerate.a
src/libscrambler/libscrambler.a
src/libemphasis/libemphasis.a
@ -64,8 +62,8 @@ src/nmt/nmt
src/amps/libusatone.a
src/amps/libamps.a
src/amps/amps
src/amps/tacs
src/amps/jtacs
src/tacs/tacs
src/jtacs/jtacs
src/r2000/radiocom2000
src/imts/imts
src/imts/imts-dialer
@ -73,7 +71,6 @@ src/mpt1327/mpt1327
src/jolly/jollycom
src/eurosignal/eurosignal
src/pocsag/pocsag
src/golay/golay
src/fuenf/5-ton-folge
src/tv/osmotv
src/radio/osmoradio
@ -83,7 +80,6 @@ src/sim/cnetz_sim
src/magnetic/cnetz_magnetic
src/fuvst/fuvst
src/fuvst/fuvst_sniffer
src/dcf77/dcf77
extra/cnetz_memory_card_generator
src/test/test_filter
src/test/test_sendevolumenregler

14
README
View File

@ -24,13 +24,11 @@ Additionally the following communication services are implemented:
* TV Transmitter with test Images
* Radio transmitter / receiver
* Analog Modem Emulation 'Datenklo' (AM7911)
* Analog Modem Emulation (AM7911)
* German classic 'Zeitansage' (talking clock)
* POCSAG transmitter / receiver
* Golay/GSC transmitter / receiver
* DCF77 time signal transmitter and receiver with weather info
* C-Netz SIM emulator
* C-Netz magnetic card emulator
* 5-Ton-Folge + Sirenensteuerung
USE AT YOUR OWN RISK!
@ -69,10 +67,10 @@ providing memory cards to be programmed for older C-Netz phone.
Dieter Spaar providing TACS recordings to verify and debug TACS support.
Hans Wigger providing Radiocom 2000 recordings, to reverse-enigineer the
standard, which seems not to exist anymore...
Hans Wigger providing Radiocom 2000 recordings, to reverse-enigeer the standard,
which seems not to exist anymore...
Peter, Peter, Friedhelm and Stephan for providing documentation and hardware
Peter, Peter and Friedhelm and Stephan for providing documentation and hardware
for C-Netz Base Station and other C-Netz documents.
Carsten Wollesen for donating MPT1327 radios and programming tools.

View File

@ -74,8 +74,6 @@ AC_OUTPUT(
src/libhagelbarger/Makefile
src/libdtmf/Makefile
src/libtimer/Makefile
src/libselect/Makefile
src/libph_socket/Makefile
src/libsamplerate/Makefile
src/libscrambler/Makefile
src/libemphasis/Makefile
@ -100,13 +98,14 @@ AC_OUTPUT(
src/cnetz/Makefile
src/nmt/Makefile
src/amps/Makefile
src/tacs/Makefile
src/jtacs/Makefile
src/r2000/Makefile
src/imts/Makefile
src/mpt1327/Makefile
src/jolly/Makefile
src/eurosignal/Makefile
src/pocsag/Makefile
src/golay/Makefile
src/fuenf/Makefile
src/tv/Makefile
src/radio/Makefile
@ -115,7 +114,6 @@ AC_OUTPUT(
src/sim/Makefile
src/magnetic/Makefile
src/fuvst/Makefile
src/dcf77/Makefile
src/test/Makefile
src/Makefile
extra/Makefile

View File

@ -54,7 +54,7 @@ A caller must not know the location of the phone anymore to reach the right base
<li>Channel spacing: 10 KHz and optionally 12.5 KHz
<li>Voice modulation: FM
<li>Signaling modulation: carrier FSK
<li>Frequency deviation: 2.5 KHz (FSK); 2.4 or 4 KHz (Voice)
<li>Frequency deviation: 2.5 KHz (FSK); 4 KHz (Voice)
<li>Mobile station transmit power: 50 mW up to 15 Watts
<li>Base station transmit power: 25 Watts
<li>Features: Speech Compandor, Audio scrambling

View File

@ -129,10 +129,8 @@ Additional features:
<li><a href="magnetic.html">C-Netz Magnetic Card</a></li>
<li>Zeitansage (German talking clock)</li>
<li>C-Netz FuVSt (MSC to control a real base station)</li>
<li>POCSAG (paging system)</li>
<li>Golay / GSC (paging system)</li>
<li>POCSAG</li>
<li>5-Ton-Ruf (firefighter's pagers and siren control)</li>
<li>DCF77 The German longwave time signal transmitter/receiver</li>
</ul>
</td></tr></table></center>

View File

@ -173,13 +173,13 @@ Use GIT to clone latest source repository. First you need to install GIT.
</pre>
<p>
Then you can clone osmocom-analog from <a href="https://gitea.osmocom.org/cellular-infrastructure/osmocom-analog">https://gitea.osmocom.org/cellular-infrastructure/osmocom-analog</a> in your home directory.
Then you can clone osmocom-analog from <a href="git://git.osmocom.org/osmocom-analog">git://git.osmocom.org/osmocom-analog</a> in your home directory.
</p>
<pre>
# cd ~
# git clone https://gitea.osmocom.org/cellular-infrastructure/osmocom-analog
# git clone git://git.osmocom.org/osmocom-analog
Cloning into 'osmocom-analog'...
...

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

View File

@ -158,12 +158,6 @@ Be sure to print it without scaling!
<center><img src="mag1.jpg"/></center>
<p>
Also there is a KiCad version with the coil on PCB and space for battery holder:
</p>
<center><img src="mag5.jpg"/></center>
<p>
Leave the fuses of the ATTINY85 as it is shipped by default.
The fuses are set to use the internal 8 MHz clock with scaling to 1 MHz.
@ -289,8 +283,6 @@ The Security code must be a 16 bit unsigned integer, entered in decimal notation
BSA 44 Service Cards
</p>
<center><img src="mag3.jpg"/></center>
<p>
When inserting (simulating) a service card, a BSA44 phone will show "Wartungskarte" on its LC display.
Turn off the phone and then turn it on again, but leave card inserted and power connected.

View File

@ -293,7 +293,7 @@ Build Your Own SIM Card
You find the PCB drawings inside the "layout" directory of the git repository.
Be sure to print it without scaling!
Check if the printed size matches an ISO card.
Also there are the source files for the 'Eagle' and 'KiCad' layout programs.
Also there is the source files for the 'Eagle' layout program, if you like to change it.
</p>
<p>
@ -463,8 +463,6 @@ To program one of the following service cards, change the subscriber data to the
<tr><td>Philips Miniporty<br><a href="monitorkarte.pdf">extended cell monitor</a></td><td>-</td><td>-</td><td>-</td><td>900</td><td>2729</td></tr>
<tr><td>Philips Porty<br>service mode</td><td>0</td><td>0</td><td>0</td><td>2304</td><td>-</td></tr>
<tr><td>Philips Porty<br>cell monitor</td><td>-</td><td>-</td><td>-</td><td>898</td><td>-</td></tr>
<tr><td>AEG Telecar C<br>service mode</td><td>-</td><td>-</td><td>-</td><td>144 or 911</td><td>-</td></tr>
<tr><td>AEG Telecar C<br>cell monitor</td><td>-</td><td>-</td><td>-</td><td>899</td><td>-</td></tr>
</table>
</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 172 KiB

View File

@ -15,7 +15,7 @@ To get a list of all options, run the base station software (E.g bnetz) with no
</p>
<p class="toppic">
Sound interface using ALSA
Sound interface
</p>
<p>
@ -64,69 +64,6 @@ If you prefer card 2, device 0, add '-a hw:2,0' or '--audio-device hw:2,0' to th
</pre>
<p class="toppic">
Prevent Puleaudio from occupying a sound adapter
</p>
<p>
In some cases, pulseaudio occupies the sound interface, so that it cannot be used via ALSA API.
"Device or resource busy" will be reported by the application.
One way would be to stop pulseaudio daemon, if there is only a single audio device available.
If an extra sound device, like an USB stick shall be used, we can just block it for pulseaudio, using udev rule.
</p>
<p>
First, we need to check the device ID using lsusb (USB) or lspci (PCI):
</p>
<pre>
# lsusb
...
Bus 001 Device 030: ID 0bda:4937 Realtek Semiconductor Corp. Realtek Audio USB
...
</pre>
<p>
In this case there is an USB stick with vendor ID "0bda" and device ID "4937".
If nano is our favorite editor, we add a new udev rule (sudo or be root):
</p>
<pre>
# nano /etc/udev/rules.d/89-pulseaudio-ignore_0bda_4937.rules
</pre>
<p>
Choose any index (like 89), but be sure that it must be lower than any other pulseaudio rule, if there is any at all. Add some name that explains exactly what device is blocked, but feel free to user any other name.
</p>
<p>
Add this line to block the device shown above, but use the right IDs:
</p>
<pre>
ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4937", ENV{PULSE_IGNORE}="1"
</pre>
<p>
When using PCI, you need to reboot.
When using USB, unplug it and then load the new rules before replugging it:
</p>
<pre>
udevadm control --reload-rules
</pre>
<p>
To verify that the rule works, check if the device is available using "pavucontrol".
Do that before and after, to see the effect.
</p>
<p class="toppic">
Basic level adjustment
</p>

View File

@ -17,13 +17,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* NOTE: Reset must be an input pin, not the reset of the controller.
* The clock pulse must be detected during reset.
*/
#if defined(__AVR_ATtiny85__)
#define RST_PIN 2
#define CLK_PIN 3
#define DATA_PIN 4
#error UNTESTED!
#else
#define CLK_PIN 5
#define RST_PIN 6
@ -31,14 +29,15 @@
#endif
uint8_t card_data[] = {
/* Example: Service card for AEG OLYMPIA. */
0xff, 0xf7, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0x38,
0x78, 0x28, 0x07, 0x8c, 0xc7, 0x03, 0xfe, 0xfd,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4b, 0x90,
0x5f, 0x25, 0x07, 0x0c, 0x00, 0x00, 0xfe, 0xfd,
0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
volatile uint8_t *rst_in, *clk_in, *data_in, *data_out, *data_mode;
@ -71,8 +70,6 @@ void setup()
data_out = portOutputRegister(port);
data_in = portInputRegister(port);
*data_mode |= data_bit; /* output */
/* wait for reset */
while (!(*rst_in & rst_bit));
}
uint8_t byte_count;
@ -81,14 +78,22 @@ uint8_t bit_count;
void loop()
{
reset:
/* initial reset state */
byte_count = 0;
bit_count = 0;
*data_out |= data_bit; /* high */
/* now we have reset, so we wait for the first clock pulse */
while (!(*clk_in & clk_bit));
while ((*clk_in & clk_bit));
/* wait for reset to become low, if not already before first clock pulse (AEG phone) */
/* wait for reset pulse */
while (!(*rst_in & rst_bit));
/* now we have reset, so we wait for clock pulse */
while (!(*clk_in & clk_bit)) {
/* if we lost reset, go to start */
if (!(*rst_in & rst_bit))
goto reset;
}
while ((*clk_in & clk_bit)) {
/* if we lost reset, go to start */
if (!(*rst_in & rst_bit))
goto reset;
}
while ((*rst_in & rst_bit));
next_bit:

View File

@ -1,87 +0,0 @@
(module LOGO (layer F.Cu)
(at 0 0)
(fp_text reference "G***" (at 0 0) (layer F.SilkS) hide
(effects (font (thickness 0.3)))
)
(fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide
(effects (font (thickness 0.3)))
)
(fp_poly (pts (xy 3.066152 -6.121191) (xy 3.428893 -6.120766) (xy 3.752319 -6.119859) (xy 4.038875 -6.118399) (xy 4.291009 -6.116313) (xy 4.511168 -6.113530) (xy 4.701799 -6.109980) (xy 4.865348 -6.105590)
(xy 5.004263 -6.100290) (xy 5.120991 -6.094008) (xy 5.217978 -6.086672) (xy 5.297671 -6.078211) (xy 5.362518 -6.068554) (xy 5.414965 -6.057629) (xy 5.457458 -6.045365) (xy 5.492446 -6.031691)
(xy 5.522375 -6.016535) (xy 5.549692 -5.999825) (xy 5.576844 -5.981491) (xy 5.606277 -5.961461) (xy 5.621560 -5.951464) (xy 5.802237 -5.806446) (xy 5.943182 -5.626144) (xy 6.008480 -5.504621)
(xy 6.081889 -5.348111) (xy 6.081889 5.065889) (xy 6.008480 5.222399) (xy 5.886481 5.426964) (xy 5.729099 5.591065) (xy 5.622219 5.668819) (xy 5.590776 5.689726) (xy 5.562762 5.708887)
(xy 5.535715 5.726375) (xy 5.507170 5.742266) (xy 5.474661 5.756634) (xy 5.435724 5.769553) (xy 5.387896 5.781099) (xy 5.328710 5.791346) (xy 5.255703 5.800368) (xy 5.166409 5.808240)
(xy 5.058365 5.815037) (xy 4.929106 5.820832) (xy 4.776167 5.825702) (xy 4.597084 5.829720) (xy 4.389392 5.832960) (xy 4.150626 5.835498) (xy 3.878322 5.837408) (xy 3.570016 5.838765)
(xy 3.223242 5.839643) (xy 2.835536 5.840116) (xy 2.404434 5.840260) (xy 1.927471 5.840149) (xy 1.402182 5.839857) (xy 0.826103 5.839459) (xy 0.196769 5.839030) (xy 0.001126 5.838908)
(xy -0.535567 5.838462) (xy -1.058045 5.837786) (xy -1.563427 5.836894) (xy -2.048833 5.835799) (xy -2.511382 5.834517) (xy -2.948193 5.833062) (xy -3.356385 5.831447) (xy -3.733077 5.829687)
(xy -4.075389 5.827796) (xy -4.380439 5.825788) (xy -4.645347 5.823678) (xy -4.867232 5.821480) (xy -5.043214 5.819207) (xy -5.170410 5.816875) (xy -5.245941 5.814497) (xy -5.266077 5.812913)
(xy -5.491258 5.740750) (xy -5.690423 5.620986) (xy -5.856268 5.458485) (xy -5.911083 5.383451) (xy -5.933608 5.350592) (xy -5.954232 5.321477) (xy -5.973038 5.293611) (xy -5.990111 5.264501)
(xy -6.005534 5.231654) (xy -6.019391 5.192575) (xy -6.031764 5.144771) (xy -6.042737 5.085749) (xy -6.052394 5.013016) (xy -6.060819 4.924076) (xy -6.068093 4.816438) (xy -6.074302 4.687607)
(xy -6.079529 4.535089) (xy -6.083857 4.356392) (xy -6.087369 4.149022) (xy -6.090149 3.910484) (xy -6.092281 3.638287) (xy -6.093847 3.329935) (xy -6.094932 2.982935) (xy -6.095619 2.594794)
(xy -6.095991 2.163018) (xy -6.096131 1.685114) (xy -6.096124 1.158588) (xy -6.096053 0.580947) (xy -6.096001 -0.050304) (xy -6.096000 -0.141111) (xy -6.096043 -0.779900) (xy -6.096116 -1.364739)
(xy -6.096137 -1.898120) (xy -6.096052 -2.256360) (xy -5.814193 -2.256360) (xy -5.814125 -1.757197) (xy -5.813966 -1.208271) (xy -5.813819 -0.607124) (xy -5.813777 -0.141111) (xy -5.813854 0.499116)
(xy -5.814015 1.085355) (xy -5.814159 1.620064) (xy -5.814184 2.105699) (xy -5.813989 2.544718) (xy -5.813470 2.939576) (xy -5.812526 3.292731) (xy -5.811055 3.606639) (xy -5.808956 3.883758)
(xy -5.806125 4.126544) (xy -5.802462 4.337453) (xy -5.797865 4.518944) (xy -5.792230 4.673472) (xy -5.785457 4.803495) (xy -5.777444 4.911469) (xy -5.768088 4.999850) (xy -5.757287 5.071097)
(xy -5.744940 5.127665) (xy -5.730944 5.172012) (xy -5.715199 5.206594) (xy -5.697600 5.233868) (xy -5.678048 5.256290) (xy -5.656439 5.276319) (xy -5.632672 5.296410) (xy -5.606645 5.319020)
(xy -5.586384 5.338304) (xy -5.561771 5.364561) (xy -5.541081 5.388626) (xy -5.521883 5.410597) (xy -5.501747 5.430569) (xy -5.478242 5.448637) (xy -5.448937 5.464897) (xy -5.411403 5.479446)
(xy -5.363209 5.492377) (xy -5.301924 5.503789) (xy -5.225118 5.513775) (xy -5.130361 5.522432) (xy -5.015222 5.529855) (xy -4.877271 5.536141) (xy -4.714078 5.541384) (xy -4.523212 5.545681)
(xy -4.302242 5.549127) (xy -4.048739 5.551819) (xy -3.760271 5.553851) (xy -3.434409 5.555319) (xy -3.068722 5.556320) (xy -2.660779 5.556948) (xy -2.208151 5.557300) (xy -1.708406 5.557471)
(xy -1.159115 5.557557) (xy -0.557847 5.557654) (xy -0.012178 5.557812) (xy 0.631245 5.558012) (xy 1.220601 5.558088) (xy 1.758268 5.558023) (xy 2.246624 5.557799) (xy 2.688045 5.557398)
(xy 3.084909 5.556803) (xy 3.439595 5.555995) (xy 3.754479 5.554958) (xy 4.031940 5.553673) (xy 4.274354 5.552123) (xy 4.484100 5.550290) (xy 4.663554 5.548156) (xy 4.815095 5.545704)
(xy 4.941100 5.542915) (xy 5.043947 5.539772) (xy 5.126012 5.536258) (xy 5.189674 5.532355) (xy 5.237311 5.528044) (xy 5.271300 5.523308) (xy 5.293600 5.518255) (xy 5.468036 5.437528)
(xy 5.619157 5.309399) (xy 5.722084 5.169645) (xy 5.799667 5.037667) (xy 5.799667 -5.319888) (xy 5.722084 -5.451866) (xy 5.654063 -5.548879) (xy 5.572372 -5.640625) (xy 5.538639 -5.671399)
(xy 5.514868 -5.692021) (xy 5.493943 -5.710917) (xy 5.473421 -5.728161) (xy 5.450859 -5.743829) (xy 5.423815 -5.757996) (xy 5.389844 -5.770737) (xy 5.346504 -5.782127) (xy 5.291352 -5.792243)
(xy 5.221946 -5.801158) (xy 5.135842 -5.808948) (xy 5.030596 -5.815689) (xy 4.903768 -5.821456) (xy 4.752912 -5.826324) (xy 4.575587 -5.830368) (xy 4.369349 -5.833663) (xy 4.131755 -5.836285)
(xy 3.860363 -5.838309) (xy 3.552729 -5.839811) (xy 3.206411 -5.840864) (xy 2.818965 -5.841546) (xy 2.387948 -5.841930) (xy 1.910918 -5.842093) (xy 1.385432 -5.842109) (xy 0.809046 -5.842054)
(xy 0.179318 -5.842003) (xy 0.000000 -5.842000) (xy -0.647201 -5.842068) (xy -1.240388 -5.842208) (xy -1.781990 -5.842324) (xy -2.274439 -5.842319) (xy -2.720163 -5.842096) (xy -3.121593 -5.841560)
(xy -3.481159 -5.840613) (xy -3.801291 -5.839160) (xy -4.084419 -5.837103) (xy -4.332972 -5.834346) (xy -4.549381 -5.830793) (xy -4.736077 -5.826347) (xy -4.895488 -5.820912) (xy -5.030045 -5.814390)
(xy -5.142178 -5.806687) (xy -5.234316 -5.797705) (xy -5.308891 -5.787347) (xy -5.368331 -5.775518) (xy -5.415068 -5.762121) (xy -5.451530 -5.747058) (xy -5.480148 -5.730235) (xy -5.503352 -5.711554)
(xy -5.523572 -5.690918) (xy -5.543238 -5.668232) (xy -5.564779 -5.643398) (xy -5.586748 -5.620162) (xy -5.614426 -5.594245) (xy -5.639774 -5.572614) (xy -5.662894 -5.552810) (xy -5.683888 -5.532378)
(xy -5.702857 -5.508859) (xy -5.719902 -5.479799) (xy -5.735127 -5.442739) (xy -5.748633 -5.395223) (xy -5.760521 -5.334795) (xy -5.770893 -5.258997) (xy -5.779852 -5.165373) (xy -5.787498 -5.051467)
(xy -5.793934 -4.914820) (xy -5.799262 -4.752978) (xy -5.803583 -4.563482) (xy -5.806999 -4.343877) (xy -5.809612 -4.091705) (xy -5.811524 -3.804509) (xy -5.812836 -3.479834) (xy -5.813650 -3.115222)
(xy -5.814069 -2.708216) (xy -5.814193 -2.256360) (xy -6.096052 -2.256360) (xy -6.096021 -2.382538) (xy -6.095685 -2.820485) (xy -6.095047 -3.214456) (xy -6.094021 -3.566944) (xy -6.092526 -3.880442)
(xy -6.090477 -4.157444) (xy -6.087792 -4.400443) (xy -6.084386 -4.611933) (xy -6.080176 -4.794408) (xy -6.075080 -4.950361) (xy -6.069013 -5.082285) (xy -6.061892 -5.192675) (xy -6.053634 -5.284023)
(xy -6.044156 -5.358823) (xy -6.033373 -5.419569) (xy -6.021202 -5.468754) (xy -6.007561 -5.508872) (xy -5.992366 -5.542416) (xy -5.975533 -5.571880) (xy -5.956978 -5.599757) (xy -5.936619 -5.628541)
(xy -5.914372 -5.660725) (xy -5.911207 -5.665485) (xy -5.776472 -5.825354) (xy -5.604536 -5.962390) (xy -5.418666 -6.059831) (xy -5.400964 -6.065986) (xy -5.378659 -6.071628) (xy -5.349305 -6.076783)
(xy -5.310456 -6.081478) (xy -5.259665 -6.085739) (xy -5.194485 -6.089592) (xy -5.112469 -6.093065) (xy -5.011172 -6.096183) (xy -4.888146 -6.098973) (xy -4.740946 -6.101462) (xy -4.567124 -6.103675)
(xy -4.364234 -6.105640) (xy -4.129829 -6.107382) (xy -3.861462 -6.108929) (xy -3.556688 -6.110306) (xy -3.213060 -6.111541) (xy -2.828131 -6.112659) (xy -2.399454 -6.113686) (xy -1.924583 -6.114651)
(xy -1.401071 -6.115578) (xy -0.826472 -6.116494) (xy -0.198339 -6.117426) (xy -0.072960 -6.117607) (xy 0.577063 -6.118577) (xy 1.173088 -6.119493) (xy 1.717563 -6.120284) (xy 2.212933 -6.120878)
(xy 2.661648 -6.121204) (xy 3.066152 -6.121191) )(layer F.SilkS) (width 0.010000)
)
(fp_poly (pts (xy 0.388056 -5.224861) (xy 0.926284 -5.151909) (xy 1.442169 -5.030009) (xy 1.931989 -4.860185) (xy 2.269161 -4.707442) (xy 2.385467 -4.646290) (xy 2.515386 -4.573424) (xy 2.649910 -4.494458)
(xy 2.780026 -4.415003) (xy 2.896725 -4.340672) (xy 2.990997 -4.277077) (xy 3.053830 -4.229830) (xy 3.076223 -4.204760) (xy 3.054679 -4.181883) (xy 2.996572 -4.134523) (xy 2.911693 -4.070406)
(xy 2.843389 -4.020972) (xy 2.588378 -3.819391) (xy 2.327603 -3.576761) (xy 2.072524 -3.305783) (xy 1.834598 -3.019161) (xy 1.625286 -2.729598) (xy 1.505020 -2.537285) (xy 1.380316 -2.322904)
(xy 1.142496 -2.442260) (xy 0.832858 -2.574342) (xy 0.519563 -2.658740) (xy 0.184960 -2.699984) (xy 0.127000 -2.702934) (xy -0.253898 -2.695011) (xy -0.612890 -2.637152) (xy -0.957530 -2.527568)
(xy -1.290385 -2.367282) (xy -1.454436 -2.258755) (xy -1.632699 -2.113583) (xy -1.812300 -1.944640) (xy -1.980365 -1.764801) (xy -2.124018 -1.586940) (xy -2.226171 -1.431496) (xy -2.390141 -1.085856)
(xy -2.501199 -0.729720) (xy -2.559954 -0.368118) (xy -2.567011 -0.006082) (xy -2.522977 0.351358) (xy -2.428460 0.699171) (xy -2.284065 1.032326) (xy -2.090401 1.345792) (xy -1.857529 1.624740)
(xy -1.581126 1.879192) (xy -1.286102 2.083481) (xy -0.963395 2.243070) (xy -0.657253 2.348609) (xy -0.558411 2.374336) (xy -0.462583 2.392205) (xy -0.355847 2.403564) (xy -0.224279 2.409764)
(xy -0.053956 2.412154) (xy 0.000000 2.412321) (xy 0.240604 2.407938) (xy 0.442234 2.391658) (xy 0.621727 2.360022) (xy 0.795921 2.309569) (xy 0.981650 2.236841) (xy 1.089842 2.188395)
(xy 1.296608 2.092863) (xy 1.385999 2.252932) (xy 1.674923 2.720001) (xy 1.994558 3.141962) (xy 2.343638 3.517301) (xy 2.702425 3.830121) (xy 2.796896 3.907276) (xy 2.869966 3.973160)
(xy 2.913014 4.019593) (xy 2.920358 4.036818) (xy 2.890949 4.061096) (xy 2.824331 4.106288) (xy 2.731997 4.164778) (xy 2.673266 4.200547) (xy 2.185366 4.462492) (xy 1.685599 4.669552)
(xy 1.174901 4.821510) (xy 0.654210 4.918150) (xy 0.124462 4.959255) (xy -0.413406 4.944609) (xy -0.507003 4.936422) (xy -1.021420 4.859022) (xy -1.521966 4.728701) (xy -2.004900 4.548065)
(xy -2.466482 4.319721) (xy -2.902970 4.046276) (xy -3.310625 3.730336) (xy -3.685705 3.374508) (xy -4.024470 2.981398) (xy -4.323179 2.553614) (xy -4.573789 2.102556) (xy -4.783501 1.612640)
(xy -4.939426 1.111284) (xy -5.042121 0.602317) (xy -5.092138 0.089570) (xy -5.090033 -0.423127) (xy -5.036358 -0.931945) (xy -4.931668 -1.433053) (xy -4.776518 -1.922622) (xy -4.571461 -2.396821)
(xy -4.317052 -2.851821) (xy -4.013845 -3.283791) (xy -3.749271 -3.596340) (xy -3.382862 -3.955827) (xy -2.981063 -4.275414) (xy -2.549031 -4.553070) (xy -2.091924 -4.786766) (xy -1.614902 -4.974470)
(xy -1.123122 -5.114152) (xy -0.621743 -5.203781) (xy -0.115923 -5.241328) (xy 0.388056 -5.224861) )(layer F.SilkS) (width 0.010000)
)
(fp_poly (pts (xy 3.871625 -3.467031) (xy 3.936780 -3.388271) (xy 4.011992 -3.292079) (xy 4.090056 -3.188391) (xy 4.163767 -3.087143) (xy 4.225919 -2.998272) (xy 4.269307 -2.931714) (xy 4.286725 -2.897407)
(xy 4.286321 -2.895141) (xy 4.256882 -2.877822) (xy 4.194588 -2.844925) (xy 4.158744 -2.826659) (xy 3.950167 -2.701112) (xy 3.732023 -2.533119) (xy 3.515113 -2.332872) (xy 3.310237 -2.110568)
(xy 3.128198 -1.876398) (xy 3.084732 -1.813015) (xy 2.876739 -1.451909) (xy 2.720513 -1.075306) (xy 2.615119 -0.687924) (xy 2.559623 -0.294477) (xy 2.553090 0.100317) (xy 2.594586 0.491743)
(xy 2.683176 0.875084) (xy 2.817926 1.245625) (xy 2.997901 1.598649) (xy 3.222167 1.929440) (xy 3.489789 2.233281) (xy 3.799833 2.505457) (xy 3.963878 2.623760) (xy 4.057511 2.688520)
(xy 4.130173 2.741777) (xy 4.171370 2.775690) (xy 4.176889 2.782893) (xy 4.159358 2.818264) (xy 4.112213 2.884836) (xy 4.043629 2.972966) (xy 3.961777 3.073010) (xy 3.874832 3.175325)
(xy 3.790967 3.270269) (xy 3.718356 3.348198) (xy 3.665171 3.399470) (xy 3.641219 3.414889) (xy 3.607900 3.400100) (xy 3.542981 3.361487) (xy 3.467445 3.312042) (xy 3.101674 3.029765)
(xy 2.770771 2.705500) (xy 2.477816 2.343901) (xy 2.225892 1.949622) (xy 2.018078 1.527317) (xy 1.857455 1.081641) (xy 1.773671 0.753207) (xy 1.740101 0.543137) (xy 1.718323 0.295285)
(xy 1.708507 0.027101) (xy 1.710821 -0.243961) (xy 1.725435 -0.500449) (xy 1.752517 -0.724913) (xy 1.758994 -0.762000) (xy 1.856772 -1.162283) (xy 1.999581 -1.564167) (xy 2.180636 -1.952063)
(xy 2.393154 -2.310382) (xy 2.496438 -2.456741) (xy 2.663059 -2.660010) (xy 2.863628 -2.872909) (xy 3.082493 -3.080547) (xy 3.304004 -3.268031) (xy 3.501693 -3.413279) (xy 3.765487 -3.589728)
(xy 3.871625 -3.467031) )(layer F.SilkS) (width 0.010000)
)
(fp_poly (pts (xy 4.708743 -2.093743) (xy 4.715703 -2.086271) (xy 4.732652 -2.047799) (xy 4.761169 -1.970683) (xy 4.797375 -1.866741) (xy 4.837394 -1.747787) (xy 4.877349 -1.625636) (xy 4.913364 -1.512106)
(xy 4.941562 -1.419010) (xy 4.958066 -1.358165) (xy 4.960324 -1.340693) (xy 4.934857 -1.323406) (xy 4.877100 -1.284341) (xy 4.826000 -1.249815) (xy 4.607190 -1.069768) (xy 4.431450 -0.857898)
(xy 4.300458 -0.620760) (xy 4.215893 -0.364908) (xy 4.179433 -0.096895) (xy 4.192756 0.176724) (xy 4.257542 0.449397) (xy 4.340061 0.647631) (xy 4.405102 0.752448) (xy 4.500803 0.875917)
(xy 4.613103 1.002252) (xy 4.727941 1.115669) (xy 4.831254 1.200380) (xy 4.834353 1.202538) (xy 4.913261 1.257086) (xy 4.810446 1.552466) (xy 4.751037 1.717503) (xy 4.699070 1.850800)
(xy 4.657218 1.946047) (xy 4.628156 1.996937) (xy 4.619134 2.003778) (xy 4.593095 1.989948) (xy 4.533783 1.954143) (xy 4.473461 1.916380) (xy 4.335424 1.815149) (xy 4.183457 1.681269)
(xy 4.033324 1.530091) (xy 3.900793 1.376964) (xy 3.848574 1.307997) (xy 3.668412 1.009181) (xy 3.537673 0.689345) (xy 3.456452 0.354911) (xy 3.424846 0.012297) (xy 3.442951 -0.332076)
(xy 3.510863 -0.671788) (xy 3.628678 -1.000421) (xy 3.796493 -1.311553) (xy 3.809056 -1.330900) (xy 3.897570 -1.452007) (xy 4.004725 -1.577172) (xy 4.123758 -1.700762) (xy 4.247908 -1.817143)
(xy 4.370412 -1.920682) (xy 4.484510 -2.005745) (xy 4.583439 -2.066698) (xy 4.660437 -2.097909) (xy 4.708743 -2.093743) )(layer F.SilkS) (width 0.010000)
)
)

File diff suppressed because it is too large Load Diff

View File

@ -1,75 +0,0 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "All Layers",
"auto_track_width": false,
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"ratsnest_display_mode": 0,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": true,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"meta": {
"filename": "magnetkarte.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@ -1,440 +0,0 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.049999999999999996,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": true,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.15,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": true,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.12,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": true,
"zones": {
"45_degree_only": false,
"min_clearance": 0.508
}
},
"diff_pair_dimensions": [
{
"gap": 0.0,
"via_gap": 0.0,
"width": 0.0
}
],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint_type_mismatch": "error",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
"rule_severitieslegacy_courtyards_overlap": true,
"rule_severitieslegacy_no_courtyard_defined": false,
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.0,
"min_copper_edge_clearance": 0.01,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_silk_clearance": 0.0,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0,
"solder_paste_clearance": 0.0,
"solder_paste_margin_ratio": -0.0,
"use_height_for_length_calcs": true
},
"track_widths": [
0.0,
0.25,
0.4,
0.6
],
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
}
],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "magnetkarte.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.25,
"pin_symbol_size": 0.0,
"text_offset_ratio": 0.08
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Pcbnew",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"b78e3980-fa91-4747-8504-806b364bf4af",
""
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,75 +0,0 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "All Layers",
"auto_track_width": false,
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"ratsnest_display_mode": 0,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": true,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"meta": {
"filename": "simkarte.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@ -1,436 +0,0 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.049999999999999996,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.12,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"45_degree_only": false,
"min_clearance": 0.508
}
},
"diff_pair_dimensions": [
{
"gap": 0.0,
"via_gap": 0.0,
"width": 0.0
}
],
"drc_exclusions": [],
"meta": {
"filename": "board_design_settings.json",
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint_type_mismatch": "error",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
"rule_severitieslegacy_courtyards_overlap": true,
"rule_severitieslegacy_no_courtyard_defined": false,
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.0,
"min_copper_edge_clearance": 0.024999999999999998,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_silk_clearance": 0.0,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"use_height_for_length_calcs": true
},
"track_widths": [
0.0,
0.25,
0.4
],
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
}
],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "simkarte.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.25,
"pin_symbol_size": 0.0,
"text_offset_ratio": 0.08
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Pcbnew",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"d4e970ed-dbe6-470b-b0b4-94ae90c6a705",
""
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
(module SIM-Pads (layer F.Cu) (tedit 62963936)
(fp_text reference REF** (at 0 0.5) (layer F.SilkS) hide
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value SIM-Pads (at 0 -0.5) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 85.6 3) (end 85.6 50.98) (layer B.SilkS) (width 0.12))
(fp_line (start 82.6 53.98) (end 3 53.98) (layer B.SilkS) (width 0.12))
(fp_line (start 3 0) (end 82.55 0) (layer B.SilkS) (width 0.12))
(fp_line (start 0 50.98) (end 0 3) (layer B.SilkS) (width 0.12))
(fp_line (start 30.957107 29.187107) (end 28.957107 31.187107) (layer B.SilkS) (width 0.12))
(fp_line (start 3 0) (end 82.55 0) (layer F.SilkS) (width 0.12))
(fp_line (start 85.6 3) (end 85.6 50.98) (layer F.SilkS) (width 0.12))
(fp_line (start 82.6 53.98) (end 3 53.98) (layer F.SilkS) (width 0.12))
(fp_line (start 0 50.98) (end 0 3) (layer F.SilkS) (width 0.12))
(fp_line (start 30.957107 29.187107) (end 28.957107 31.187107) (layer F.SilkS) (width 0.12))
(fp_line (start 31.25 28.48) (end 31.25 17.48) (layer F.SilkS) (width 0.12))
(fp_line (start 7.25 16.48) (end 30.25 16.48) (layer F.SilkS) (width 0.12))
(fp_line (start 6.25 30.48) (end 6.25 17.48) (layer F.SilkS) (width 0.12))
(fp_line (start 7.25 31.48) (end 28.25 31.48) (layer F.SilkS) (width 0.12))
(fp_line (start 7.25 16.48) (end 30.25 16.48) (layer B.SilkS) (width 0.12))
(fp_line (start 6.25 30.48) (end 6.25 17.48) (layer B.SilkS) (width 0.12))
(fp_line (start 7.25 31.48) (end 28.25 31.48) (layer B.SilkS) (width 0.12))
(fp_line (start 31.25 28.48) (end 31.25 17.48) (layer B.SilkS) (width 0.12))
(fp_arc (start 82.6 3) (end 82.6 0) (angle 90) (layer B.SilkS) (width 0.12))
(fp_arc (start 82.6 50.98) (end 85.6 50.98) (angle 90) (layer B.SilkS) (width 0.12))
(fp_arc (start 3 50.98) (end 3 53.98) (angle 90) (layer B.SilkS) (width 0.12))
(fp_arc (start 28.25 30.48) (end 28.25 31.48) (angle -45) (layer B.SilkS) (width 0.12))
(fp_arc (start 30.25 28.48) (end 31.25 28.48) (angle 45) (layer B.SilkS) (width 0.12))
(fp_arc (start 30.25 17.48) (end 30.25 16.48) (angle 90) (layer B.SilkS) (width 0.12))
(fp_arc (start 3 3) (end 0 3) (angle 90) (layer B.SilkS) (width 0.12))
(fp_arc (start 28.25 30.48) (end 28.25 31.48) (angle -45) (layer F.SilkS) (width 0.12))
(fp_arc (start 30.25 28.48) (end 31.25 28.48) (angle 45) (layer F.SilkS) (width 0.12))
(fp_arc (start 30.25 17.48) (end 30.25 16.48) (angle 90) (layer F.SilkS) (width 0.12))
(fp_arc (start 7.25 30.48) (end 7.25 31.48) (angle 90) (layer F.SilkS) (width 0.12))
(fp_arc (start 7.25 17.48) (end 6.25 17.48) (angle 90) (layer F.SilkS) (width 0.12))
(fp_arc (start 82.6 50.98) (end 85.6 50.98) (angle 90) (layer F.SilkS) (width 0.12))
(fp_arc (start 82.6 3) (end 82.6 0) (angle 90) (layer F.SilkS) (width 0.12))
(fp_arc (start 3 50.98) (end 3 53.98) (angle 90) (layer F.SilkS) (width 0.12))
(fp_arc (start 3 3) (end 0 3) (angle 90) (layer F.SilkS) (width 0.12))
(fp_arc (start 7.25 17.48) (end 6.25 17.48) (angle 90) (layer B.SilkS) (width 0.12))
(fp_arc (start 7.25 30.48) (end 7.25 31.48) (angle 90) (layer B.SilkS) (width 0.12))
(pad 8 smd rect (at 18.87 27.7) (size 2 1.7) (layers F.Cu F.Paste F.Mask))
(pad 7 smd rect (at 18.87 25.16) (size 2 1.7) (layers F.Cu F.Paste F.Mask))
(pad 6 smd rect (at 18.87 22.62) (size 2 1.7) (layers F.Cu F.Paste F.Mask))
(pad 5 smd rect (at 18.87 20.08) (size 2 1.7) (layers F.Cu F.Paste F.Mask))
(pad 4 smd rect (at 11.25 27.7) (size 2 1.7) (layers F.Cu F.Paste F.Mask))
(pad 3 smd rect (at 11.25 25.16) (size 2 1.7) (layers F.Cu F.Paste F.Mask))
(pad 2 smd rect (at 11.25 22.62) (size 2 1.7) (layers F.Cu F.Paste F.Mask))
(pad 1 smd rect (at 11.25 20.08) (size 2 1.7) (layers F.Cu F.Paste F.Mask))
)

View File

@ -1,50 +0,0 @@
(footprint "SO-8_falschrum" (version 20211014) (generator pcbnew)
(layer "F.Cu")
(tedit 5EA5315B)
(descr "SO, 8 Pin (https://www.ti.com/lit/ml/msop001a/msop001a.pdf), generated with kicad-footprint-generator ipc_gullwing_generator.py")
(tags "SO SO")
(attr smd)
(fp_text reference "REF**" (at 0 -4.05) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp e6d2e267-164d-4afc-8b48-cd1aff90b7d4)
)
(fp_text value "SO-8_falschrum" (at 0 4.05) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp c06efada-401e-4dfe-b3d2-3a3e07849a0a)
)
(fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp f6b8865c-5ba6-45e6-a65d-a1b68be210e7)
)
(fp_line (start -2.76 -2.465) (end -4.45 -2.465) (layer "F.SilkS") (width 0.12) (tstamp 74239588-025d-4278-bb20-8aaa7c3084df))
(fp_line (start 2.76 3.21) (end 2.76 2.465) (layer "F.SilkS") (width 0.12) (tstamp 782bb1cd-d060-47ff-abe3-37addae7ab1b))
(fp_line (start 0 -3.21) (end -2.76 -3.21) (layer "F.SilkS") (width 0.12) (tstamp a37ee151-4fcc-4d66-943d-e5b1c2e17868))
(fp_line (start -2.76 3.21) (end -2.76 2.465) (layer "F.SilkS") (width 0.12) (tstamp af41f2a4-51e3-4dbb-b929-81c444ac7fff))
(fp_line (start 0 3.21) (end 2.76 3.21) (layer "F.SilkS") (width 0.12) (tstamp c79336f7-374b-471c-a2b2-c23ba36a59b5))
(fp_line (start 0 -3.21) (end 2.76 -3.21) (layer "F.SilkS") (width 0.12) (tstamp cf87a8a5-e65f-4d3a-8572-2d19d388ce69))
(fp_line (start 0 3.21) (end -2.76 3.21) (layer "F.SilkS") (width 0.12) (tstamp d48ee01a-e5c2-4b22-aaa6-a1cb107fbac3))
(fp_line (start -2.76 -3.21) (end -2.76 -2.465) (layer "F.SilkS") (width 0.12) (tstamp d861ecda-fd97-4619-9c2d-6c4f7c60cca0))
(fp_line (start 2.76 -3.21) (end 2.76 -2.465) (layer "F.SilkS") (width 0.12) (tstamp dc7ef0e4-bd3f-4bae-b16a-6091a2fbe1a5))
(fp_line (start 4.7 -3.35) (end -4.7 -3.35) (layer "F.CrtYd") (width 0.05) (tstamp 5f316919-0561-48cc-af6d-627207b632ec))
(fp_line (start -4.7 3.35) (end 4.7 3.35) (layer "F.CrtYd") (width 0.05) (tstamp 6020986c-655c-453e-a057-f214cc9d30ae))
(fp_line (start -4.7 -3.35) (end -4.7 3.35) (layer "F.CrtYd") (width 0.05) (tstamp 6794d844-873d-41de-8a23-157904a72b2b))
(fp_line (start 4.7 3.35) (end 4.7 -3.35) (layer "F.CrtYd") (width 0.05) (tstamp d7967734-f1e1-4546-a5ab-b7258f5f3f2a))
(fp_line (start -2.65 -2.1) (end -1.65 -3.1) (layer "F.Fab") (width 0.1) (tstamp 48790e43-f2fc-44b0-8322-5388cb8e0681))
(fp_line (start 2.65 3.1) (end -2.65 3.1) (layer "F.Fab") (width 0.1) (tstamp 7c60e013-b5db-4162-a3bc-3c3e55a92637))
(fp_line (start -1.65 -3.1) (end 2.65 -3.1) (layer "F.Fab") (width 0.1) (tstamp 89f17c59-8ae8-458d-9e98-a1d8017d430e))
(fp_line (start 2.65 -3.1) (end 2.65 3.1) (layer "F.Fab") (width 0.1) (tstamp d0cb6892-437f-41c0-a652-f027fe7a96eb))
(fp_line (start -2.65 3.1) (end -2.65 -2.1) (layer "F.Fab") (width 0.1) (tstamp ea99ab82-687a-410b-9f25-f99eecf53974))
(pad "1" smd roundrect (at 3.5 -1.905) (size 1.9 0.6) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 3ef16b5b-8b97-445d-864d-105eb1aa6c46))
(pad "2" smd roundrect (at 3.5 -0.635) (size 1.9 0.6) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp e4871953-02b6-4389-a5ea-7cc4f8748acd))
(pad "3" smd roundrect (at 3.5 0.635) (size 1.9 0.6) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 9a059f78-4982-44b4-9c5e-072b9705c642))
(pad "4" smd roundrect (at 3.5 1.905) (size 1.9 0.6) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp c02f2849-6a0e-4f4d-bf38-717a4b6fd135))
(pad "5" smd roundrect (at -3.5 1.905) (size 1.9 0.6) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp b4cd1ee4-67da-4549-8e85-46e00c6d8f0b))
(pad "6" smd roundrect (at -3.5 0.635) (size 1.9 0.6) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 5515138e-0099-4ddf-8a64-f565476c169d))
(pad "7" smd roundrect (at -3.5 -0.635) (size 1.9 0.6) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 697f93e2-a0be-4cf3-b7ec-1bdeabd8a6ad))
(pad "8" smd roundrect (at -3.5 -1.905) (size 1.9 0.6) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 8018f35d-7a92-4135-8a83-0670bf6a5459))
(model "${KICAD6_3DMODEL_DIR}/Package_SO.3dshapes/SO-8_5.3x6.2mm_P1.27mm.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@ -1,87 +0,0 @@
(module LOGO (layer F.Cu)
(at 0 0)
(fp_text reference "G***" (at 0 0) (layer F.SilkS) hide
(effects (font (thickness 0.3)))
)
(fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide
(effects (font (thickness 0.3)))
)
(fp_poly (pts (xy 3.066152 -6.121191) (xy 3.428893 -6.120766) (xy 3.752319 -6.119859) (xy 4.038875 -6.118399) (xy 4.291009 -6.116313) (xy 4.511168 -6.113530) (xy 4.701799 -6.109980) (xy 4.865348 -6.105590)
(xy 5.004263 -6.100290) (xy 5.120991 -6.094008) (xy 5.217978 -6.086672) (xy 5.297671 -6.078211) (xy 5.362518 -6.068554) (xy 5.414965 -6.057629) (xy 5.457458 -6.045365) (xy 5.492446 -6.031691)
(xy 5.522375 -6.016535) (xy 5.549692 -5.999825) (xy 5.576844 -5.981491) (xy 5.606277 -5.961461) (xy 5.621560 -5.951464) (xy 5.802237 -5.806446) (xy 5.943182 -5.626144) (xy 6.008480 -5.504621)
(xy 6.081889 -5.348111) (xy 6.081889 5.065889) (xy 6.008480 5.222399) (xy 5.886481 5.426964) (xy 5.729099 5.591065) (xy 5.622219 5.668819) (xy 5.590776 5.689726) (xy 5.562762 5.708887)
(xy 5.535715 5.726375) (xy 5.507170 5.742266) (xy 5.474661 5.756634) (xy 5.435724 5.769553) (xy 5.387896 5.781099) (xy 5.328710 5.791346) (xy 5.255703 5.800368) (xy 5.166409 5.808240)
(xy 5.058365 5.815037) (xy 4.929106 5.820832) (xy 4.776167 5.825702) (xy 4.597084 5.829720) (xy 4.389392 5.832960) (xy 4.150626 5.835498) (xy 3.878322 5.837408) (xy 3.570016 5.838765)
(xy 3.223242 5.839643) (xy 2.835536 5.840116) (xy 2.404434 5.840260) (xy 1.927471 5.840149) (xy 1.402182 5.839857) (xy 0.826103 5.839459) (xy 0.196769 5.839030) (xy 0.001126 5.838908)
(xy -0.535567 5.838462) (xy -1.058045 5.837786) (xy -1.563427 5.836894) (xy -2.048833 5.835799) (xy -2.511382 5.834517) (xy -2.948193 5.833062) (xy -3.356385 5.831447) (xy -3.733077 5.829687)
(xy -4.075389 5.827796) (xy -4.380439 5.825788) (xy -4.645347 5.823678) (xy -4.867232 5.821480) (xy -5.043214 5.819207) (xy -5.170410 5.816875) (xy -5.245941 5.814497) (xy -5.266077 5.812913)
(xy -5.491258 5.740750) (xy -5.690423 5.620986) (xy -5.856268 5.458485) (xy -5.911083 5.383451) (xy -5.933608 5.350592) (xy -5.954232 5.321477) (xy -5.973038 5.293611) (xy -5.990111 5.264501)
(xy -6.005534 5.231654) (xy -6.019391 5.192575) (xy -6.031764 5.144771) (xy -6.042737 5.085749) (xy -6.052394 5.013016) (xy -6.060819 4.924076) (xy -6.068093 4.816438) (xy -6.074302 4.687607)
(xy -6.079529 4.535089) (xy -6.083857 4.356392) (xy -6.087369 4.149022) (xy -6.090149 3.910484) (xy -6.092281 3.638287) (xy -6.093847 3.329935) (xy -6.094932 2.982935) (xy -6.095619 2.594794)
(xy -6.095991 2.163018) (xy -6.096131 1.685114) (xy -6.096124 1.158588) (xy -6.096053 0.580947) (xy -6.096001 -0.050304) (xy -6.096000 -0.141111) (xy -6.096043 -0.779900) (xy -6.096116 -1.364739)
(xy -6.096137 -1.898120) (xy -6.096052 -2.256360) (xy -5.814193 -2.256360) (xy -5.814125 -1.757197) (xy -5.813966 -1.208271) (xy -5.813819 -0.607124) (xy -5.813777 -0.141111) (xy -5.813854 0.499116)
(xy -5.814015 1.085355) (xy -5.814159 1.620064) (xy -5.814184 2.105699) (xy -5.813989 2.544718) (xy -5.813470 2.939576) (xy -5.812526 3.292731) (xy -5.811055 3.606639) (xy -5.808956 3.883758)
(xy -5.806125 4.126544) (xy -5.802462 4.337453) (xy -5.797865 4.518944) (xy -5.792230 4.673472) (xy -5.785457 4.803495) (xy -5.777444 4.911469) (xy -5.768088 4.999850) (xy -5.757287 5.071097)
(xy -5.744940 5.127665) (xy -5.730944 5.172012) (xy -5.715199 5.206594) (xy -5.697600 5.233868) (xy -5.678048 5.256290) (xy -5.656439 5.276319) (xy -5.632672 5.296410) (xy -5.606645 5.319020)
(xy -5.586384 5.338304) (xy -5.561771 5.364561) (xy -5.541081 5.388626) (xy -5.521883 5.410597) (xy -5.501747 5.430569) (xy -5.478242 5.448637) (xy -5.448937 5.464897) (xy -5.411403 5.479446)
(xy -5.363209 5.492377) (xy -5.301924 5.503789) (xy -5.225118 5.513775) (xy -5.130361 5.522432) (xy -5.015222 5.529855) (xy -4.877271 5.536141) (xy -4.714078 5.541384) (xy -4.523212 5.545681)
(xy -4.302242 5.549127) (xy -4.048739 5.551819) (xy -3.760271 5.553851) (xy -3.434409 5.555319) (xy -3.068722 5.556320) (xy -2.660779 5.556948) (xy -2.208151 5.557300) (xy -1.708406 5.557471)
(xy -1.159115 5.557557) (xy -0.557847 5.557654) (xy -0.012178 5.557812) (xy 0.631245 5.558012) (xy 1.220601 5.558088) (xy 1.758268 5.558023) (xy 2.246624 5.557799) (xy 2.688045 5.557398)
(xy 3.084909 5.556803) (xy 3.439595 5.555995) (xy 3.754479 5.554958) (xy 4.031940 5.553673) (xy 4.274354 5.552123) (xy 4.484100 5.550290) (xy 4.663554 5.548156) (xy 4.815095 5.545704)
(xy 4.941100 5.542915) (xy 5.043947 5.539772) (xy 5.126012 5.536258) (xy 5.189674 5.532355) (xy 5.237311 5.528044) (xy 5.271300 5.523308) (xy 5.293600 5.518255) (xy 5.468036 5.437528)
(xy 5.619157 5.309399) (xy 5.722084 5.169645) (xy 5.799667 5.037667) (xy 5.799667 -5.319888) (xy 5.722084 -5.451866) (xy 5.654063 -5.548879) (xy 5.572372 -5.640625) (xy 5.538639 -5.671399)
(xy 5.514868 -5.692021) (xy 5.493943 -5.710917) (xy 5.473421 -5.728161) (xy 5.450859 -5.743829) (xy 5.423815 -5.757996) (xy 5.389844 -5.770737) (xy 5.346504 -5.782127) (xy 5.291352 -5.792243)
(xy 5.221946 -5.801158) (xy 5.135842 -5.808948) (xy 5.030596 -5.815689) (xy 4.903768 -5.821456) (xy 4.752912 -5.826324) (xy 4.575587 -5.830368) (xy 4.369349 -5.833663) (xy 4.131755 -5.836285)
(xy 3.860363 -5.838309) (xy 3.552729 -5.839811) (xy 3.206411 -5.840864) (xy 2.818965 -5.841546) (xy 2.387948 -5.841930) (xy 1.910918 -5.842093) (xy 1.385432 -5.842109) (xy 0.809046 -5.842054)
(xy 0.179318 -5.842003) (xy 0.000000 -5.842000) (xy -0.647201 -5.842068) (xy -1.240388 -5.842208) (xy -1.781990 -5.842324) (xy -2.274439 -5.842319) (xy -2.720163 -5.842096) (xy -3.121593 -5.841560)
(xy -3.481159 -5.840613) (xy -3.801291 -5.839160) (xy -4.084419 -5.837103) (xy -4.332972 -5.834346) (xy -4.549381 -5.830793) (xy -4.736077 -5.826347) (xy -4.895488 -5.820912) (xy -5.030045 -5.814390)
(xy -5.142178 -5.806687) (xy -5.234316 -5.797705) (xy -5.308891 -5.787347) (xy -5.368331 -5.775518) (xy -5.415068 -5.762121) (xy -5.451530 -5.747058) (xy -5.480148 -5.730235) (xy -5.503352 -5.711554)
(xy -5.523572 -5.690918) (xy -5.543238 -5.668232) (xy -5.564779 -5.643398) (xy -5.586748 -5.620162) (xy -5.614426 -5.594245) (xy -5.639774 -5.572614) (xy -5.662894 -5.552810) (xy -5.683888 -5.532378)
(xy -5.702857 -5.508859) (xy -5.719902 -5.479799) (xy -5.735127 -5.442739) (xy -5.748633 -5.395223) (xy -5.760521 -5.334795) (xy -5.770893 -5.258997) (xy -5.779852 -5.165373) (xy -5.787498 -5.051467)
(xy -5.793934 -4.914820) (xy -5.799262 -4.752978) (xy -5.803583 -4.563482) (xy -5.806999 -4.343877) (xy -5.809612 -4.091705) (xy -5.811524 -3.804509) (xy -5.812836 -3.479834) (xy -5.813650 -3.115222)
(xy -5.814069 -2.708216) (xy -5.814193 -2.256360) (xy -6.096052 -2.256360) (xy -6.096021 -2.382538) (xy -6.095685 -2.820485) (xy -6.095047 -3.214456) (xy -6.094021 -3.566944) (xy -6.092526 -3.880442)
(xy -6.090477 -4.157444) (xy -6.087792 -4.400443) (xy -6.084386 -4.611933) (xy -6.080176 -4.794408) (xy -6.075080 -4.950361) (xy -6.069013 -5.082285) (xy -6.061892 -5.192675) (xy -6.053634 -5.284023)
(xy -6.044156 -5.358823) (xy -6.033373 -5.419569) (xy -6.021202 -5.468754) (xy -6.007561 -5.508872) (xy -5.992366 -5.542416) (xy -5.975533 -5.571880) (xy -5.956978 -5.599757) (xy -5.936619 -5.628541)
(xy -5.914372 -5.660725) (xy -5.911207 -5.665485) (xy -5.776472 -5.825354) (xy -5.604536 -5.962390) (xy -5.418666 -6.059831) (xy -5.400964 -6.065986) (xy -5.378659 -6.071628) (xy -5.349305 -6.076783)
(xy -5.310456 -6.081478) (xy -5.259665 -6.085739) (xy -5.194485 -6.089592) (xy -5.112469 -6.093065) (xy -5.011172 -6.096183) (xy -4.888146 -6.098973) (xy -4.740946 -6.101462) (xy -4.567124 -6.103675)
(xy -4.364234 -6.105640) (xy -4.129829 -6.107382) (xy -3.861462 -6.108929) (xy -3.556688 -6.110306) (xy -3.213060 -6.111541) (xy -2.828131 -6.112659) (xy -2.399454 -6.113686) (xy -1.924583 -6.114651)
(xy -1.401071 -6.115578) (xy -0.826472 -6.116494) (xy -0.198339 -6.117426) (xy -0.072960 -6.117607) (xy 0.577063 -6.118577) (xy 1.173088 -6.119493) (xy 1.717563 -6.120284) (xy 2.212933 -6.120878)
(xy 2.661648 -6.121204) (xy 3.066152 -6.121191) )(layer F.SilkS) (width 0.010000)
)
(fp_poly (pts (xy 0.388056 -5.224861) (xy 0.926284 -5.151909) (xy 1.442169 -5.030009) (xy 1.931989 -4.860185) (xy 2.269161 -4.707442) (xy 2.385467 -4.646290) (xy 2.515386 -4.573424) (xy 2.649910 -4.494458)
(xy 2.780026 -4.415003) (xy 2.896725 -4.340672) (xy 2.990997 -4.277077) (xy 3.053830 -4.229830) (xy 3.076223 -4.204760) (xy 3.054679 -4.181883) (xy 2.996572 -4.134523) (xy 2.911693 -4.070406)
(xy 2.843389 -4.020972) (xy 2.588378 -3.819391) (xy 2.327603 -3.576761) (xy 2.072524 -3.305783) (xy 1.834598 -3.019161) (xy 1.625286 -2.729598) (xy 1.505020 -2.537285) (xy 1.380316 -2.322904)
(xy 1.142496 -2.442260) (xy 0.832858 -2.574342) (xy 0.519563 -2.658740) (xy 0.184960 -2.699984) (xy 0.127000 -2.702934) (xy -0.253898 -2.695011) (xy -0.612890 -2.637152) (xy -0.957530 -2.527568)
(xy -1.290385 -2.367282) (xy -1.454436 -2.258755) (xy -1.632699 -2.113583) (xy -1.812300 -1.944640) (xy -1.980365 -1.764801) (xy -2.124018 -1.586940) (xy -2.226171 -1.431496) (xy -2.390141 -1.085856)
(xy -2.501199 -0.729720) (xy -2.559954 -0.368118) (xy -2.567011 -0.006082) (xy -2.522977 0.351358) (xy -2.428460 0.699171) (xy -2.284065 1.032326) (xy -2.090401 1.345792) (xy -1.857529 1.624740)
(xy -1.581126 1.879192) (xy -1.286102 2.083481) (xy -0.963395 2.243070) (xy -0.657253 2.348609) (xy -0.558411 2.374336) (xy -0.462583 2.392205) (xy -0.355847 2.403564) (xy -0.224279 2.409764)
(xy -0.053956 2.412154) (xy 0.000000 2.412321) (xy 0.240604 2.407938) (xy 0.442234 2.391658) (xy 0.621727 2.360022) (xy 0.795921 2.309569) (xy 0.981650 2.236841) (xy 1.089842 2.188395)
(xy 1.296608 2.092863) (xy 1.385999 2.252932) (xy 1.674923 2.720001) (xy 1.994558 3.141962) (xy 2.343638 3.517301) (xy 2.702425 3.830121) (xy 2.796896 3.907276) (xy 2.869966 3.973160)
(xy 2.913014 4.019593) (xy 2.920358 4.036818) (xy 2.890949 4.061096) (xy 2.824331 4.106288) (xy 2.731997 4.164778) (xy 2.673266 4.200547) (xy 2.185366 4.462492) (xy 1.685599 4.669552)
(xy 1.174901 4.821510) (xy 0.654210 4.918150) (xy 0.124462 4.959255) (xy -0.413406 4.944609) (xy -0.507003 4.936422) (xy -1.021420 4.859022) (xy -1.521966 4.728701) (xy -2.004900 4.548065)
(xy -2.466482 4.319721) (xy -2.902970 4.046276) (xy -3.310625 3.730336) (xy -3.685705 3.374508) (xy -4.024470 2.981398) (xy -4.323179 2.553614) (xy -4.573789 2.102556) (xy -4.783501 1.612640)
(xy -4.939426 1.111284) (xy -5.042121 0.602317) (xy -5.092138 0.089570) (xy -5.090033 -0.423127) (xy -5.036358 -0.931945) (xy -4.931668 -1.433053) (xy -4.776518 -1.922622) (xy -4.571461 -2.396821)
(xy -4.317052 -2.851821) (xy -4.013845 -3.283791) (xy -3.749271 -3.596340) (xy -3.382862 -3.955827) (xy -2.981063 -4.275414) (xy -2.549031 -4.553070) (xy -2.091924 -4.786766) (xy -1.614902 -4.974470)
(xy -1.123122 -5.114152) (xy -0.621743 -5.203781) (xy -0.115923 -5.241328) (xy 0.388056 -5.224861) )(layer F.SilkS) (width 0.010000)
)
(fp_poly (pts (xy 3.871625 -3.467031) (xy 3.936780 -3.388271) (xy 4.011992 -3.292079) (xy 4.090056 -3.188391) (xy 4.163767 -3.087143) (xy 4.225919 -2.998272) (xy 4.269307 -2.931714) (xy 4.286725 -2.897407)
(xy 4.286321 -2.895141) (xy 4.256882 -2.877822) (xy 4.194588 -2.844925) (xy 4.158744 -2.826659) (xy 3.950167 -2.701112) (xy 3.732023 -2.533119) (xy 3.515113 -2.332872) (xy 3.310237 -2.110568)
(xy 3.128198 -1.876398) (xy 3.084732 -1.813015) (xy 2.876739 -1.451909) (xy 2.720513 -1.075306) (xy 2.615119 -0.687924) (xy 2.559623 -0.294477) (xy 2.553090 0.100317) (xy 2.594586 0.491743)
(xy 2.683176 0.875084) (xy 2.817926 1.245625) (xy 2.997901 1.598649) (xy 3.222167 1.929440) (xy 3.489789 2.233281) (xy 3.799833 2.505457) (xy 3.963878 2.623760) (xy 4.057511 2.688520)
(xy 4.130173 2.741777) (xy 4.171370 2.775690) (xy 4.176889 2.782893) (xy 4.159358 2.818264) (xy 4.112213 2.884836) (xy 4.043629 2.972966) (xy 3.961777 3.073010) (xy 3.874832 3.175325)
(xy 3.790967 3.270269) (xy 3.718356 3.348198) (xy 3.665171 3.399470) (xy 3.641219 3.414889) (xy 3.607900 3.400100) (xy 3.542981 3.361487) (xy 3.467445 3.312042) (xy 3.101674 3.029765)
(xy 2.770771 2.705500) (xy 2.477816 2.343901) (xy 2.225892 1.949622) (xy 2.018078 1.527317) (xy 1.857455 1.081641) (xy 1.773671 0.753207) (xy 1.740101 0.543137) (xy 1.718323 0.295285)
(xy 1.708507 0.027101) (xy 1.710821 -0.243961) (xy 1.725435 -0.500449) (xy 1.752517 -0.724913) (xy 1.758994 -0.762000) (xy 1.856772 -1.162283) (xy 1.999581 -1.564167) (xy 2.180636 -1.952063)
(xy 2.393154 -2.310382) (xy 2.496438 -2.456741) (xy 2.663059 -2.660010) (xy 2.863628 -2.872909) (xy 3.082493 -3.080547) (xy 3.304004 -3.268031) (xy 3.501693 -3.413279) (xy 3.765487 -3.589728)
(xy 3.871625 -3.467031) )(layer F.SilkS) (width 0.010000)
)
(fp_poly (pts (xy 4.708743 -2.093743) (xy 4.715703 -2.086271) (xy 4.732652 -2.047799) (xy 4.761169 -1.970683) (xy 4.797375 -1.866741) (xy 4.837394 -1.747787) (xy 4.877349 -1.625636) (xy 4.913364 -1.512106)
(xy 4.941562 -1.419010) (xy 4.958066 -1.358165) (xy 4.960324 -1.340693) (xy 4.934857 -1.323406) (xy 4.877100 -1.284341) (xy 4.826000 -1.249815) (xy 4.607190 -1.069768) (xy 4.431450 -0.857898)
(xy 4.300458 -0.620760) (xy 4.215893 -0.364908) (xy 4.179433 -0.096895) (xy 4.192756 0.176724) (xy 4.257542 0.449397) (xy 4.340061 0.647631) (xy 4.405102 0.752448) (xy 4.500803 0.875917)
(xy 4.613103 1.002252) (xy 4.727941 1.115669) (xy 4.831254 1.200380) (xy 4.834353 1.202538) (xy 4.913261 1.257086) (xy 4.810446 1.552466) (xy 4.751037 1.717503) (xy 4.699070 1.850800)
(xy 4.657218 1.946047) (xy 4.628156 1.996937) (xy 4.619134 2.003778) (xy 4.593095 1.989948) (xy 4.533783 1.954143) (xy 4.473461 1.916380) (xy 4.335424 1.815149) (xy 4.183457 1.681269)
(xy 4.033324 1.530091) (xy 3.900793 1.376964) (xy 3.848574 1.307997) (xy 3.668412 1.009181) (xy 3.537673 0.689345) (xy 3.456452 0.354911) (xy 3.424846 0.012297) (xy 3.442951 -0.332076)
(xy 3.510863 -0.671788) (xy 3.628678 -1.000421) (xy 3.796493 -1.311553) (xy 3.809056 -1.330900) (xy 3.897570 -1.452007) (xy 4.004725 -1.577172) (xy 4.123758 -1.700762) (xy 4.247908 -1.817143)
(xy 4.370412 -1.920682) (xy 4.484510 -2.005745) (xy 4.583439 -2.066698) (xy 4.660437 -2.097909) (xy 4.708743 -2.093743) )(layer F.SilkS) (width 0.010000)
)
)

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
(module tp_for_sim (layer F.Cu) (tedit 62960959)
(fp_text reference REF** (at 0 0.5) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value tp_for_sim (at 0 -0.5) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(pad 1 smd roundrect (at 0 0) (size 1 1) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
)

View File

@ -15,8 +15,6 @@ SUBDIRS = \
libhagelbarger \
libdtmf \
libtimer \
libselect \
libph_socket \
libsamplerate \
libscrambler \
libemphasis \
@ -50,21 +48,21 @@ SUBDIRS += \
cnetz \
nmt \
amps \
tacs \
jtacs \
r2000 \
imts \
mpt1327 \
jolly \
eurosignal \
pocsag \
golay \
fuenf \
tv \
radio \
zeitansage \
sim \
magnetic \
fuvst \
dcf77
fuvst
if HAVE_ALSA
if HAVE_FUSE

View File

@ -1,30 +1,29 @@
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
bin_PROGRAMS = \
amps tacs jtacs
amps
noinst_LIBRARIES = libamps.a libusatone.a
libamps_a_SOURCES = \
main_common.c \
amps_tacs_main.c \
amps.c \
transaction.c \
frame.c \
dsp.c \
sysinfo.c \
esn.c
sysinfo.c
libusatone_a_SOURCES = \
usa_tones.c \
usa_noanswer.c \
usa_outoforder.c \
usa_invalidnumber.c \
usa_congestion.c
tones.c \
noanswer.c \
outoforder.c \
invalidnumber.c \
congestion.c
amps_SOURCES = \
amps_stations.c \
amps_image.c \
amps_main.c
stations.c \
image.c \
main.c
amps_LDADD = \
$(COMMON_LA) \
@ -39,7 +38,6 @@ amps_LDADD = \
$(top_builddir)/src/libgoertzel/libgoertzel.a \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfm/libfm.a \
@ -65,92 +63,3 @@ amps_LDADD += \
$(SOAPY_LIBS)
endif
tacs_SOURCES = \
tacs_tones.c \
tacs_outoforder.c \
tacs_stations.c \
tacs_image.c \
tacs_main.c
tacs_LDADD = \
$(COMMON_LA) \
libamps.a \
$(top_builddir)/src/liboptions/liboptions.a \
$(top_builddir)/src/libdebug/libdebug.a \
$(top_builddir)/src/libmobile/libmobile.a \
$(top_builddir)/src/libosmocc/libosmocc.a \
$(top_builddir)/src/libdisplay/libdisplay.a \
$(top_builddir)/src/libcompandor/libcompandor.a \
$(top_builddir)/src/libgoertzel/libgoertzel.a \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfm/libfm.a \
$(top_builddir)/src/libfilter/libfilter.a \
$(top_builddir)/src/libwave/libwave.a \
$(top_builddir)/src/libsample/libsample.a \
$(top_builddir)/src/libg711/libg711.a \
$(top_builddir)/src/libaaimage/libaaimage.a \
-lm
if HAVE_ALSA
tacs_LDADD += \
$(top_builddir)/src/libsound/libsound.a \
$(ALSA_LIBS)
endif
if HAVE_SDR
tacs_LDADD += \
$(top_builddir)/src/libsdr/libsdr.a \
$(top_builddir)/src/libam/libam.a \
$(top_builddir)/src/libfft/libfft.a \
$(UHD_LIBS) \
$(SOAPY_LIBS)
endif
jtacs_SOURCES = \
jtacs_tones.c \
jtacs_stations.c \
jtacs_image.c \
jtacs_main.c
jtacs_LDADD = \
$(COMMON_LA) \
libamps.a \
$(top_builddir)/src/liboptions/liboptions.a \
$(top_builddir)/src/libdebug/libdebug.a \
$(top_builddir)/src/libmobile/libmobile.a \
$(top_builddir)/src/libosmocc/libosmocc.a \
$(top_builddir)/src/libdisplay/libdisplay.a \
$(top_builddir)/src/libcompandor/libcompandor.a \
$(top_builddir)/src/libgoertzel/libgoertzel.a \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfm/libfm.a \
$(top_builddir)/src/libfilter/libfilter.a \
$(top_builddir)/src/libwave/libwave.a \
$(top_builddir)/src/libsample/libsample.a \
$(top_builddir)/src/libg711/libg711.a \
$(top_builddir)/src/libaaimage/libaaimage.a \
-lm
if HAVE_ALSA
jtacs_LDADD += \
$(top_builddir)/src/libsound/libsound.a \
$(ALSA_LIBS)
endif
if HAVE_SDR
jtacs_LDADD += \
$(top_builddir)/src/libsdr/libsdr.a \
$(top_builddir)/src/libam/libam.a \
$(top_builddir)/src/libfft/libfft.a \
$(UHD_LIBS) \
$(SOAPY_LIBS)
endif

View File

@ -51,7 +51,6 @@
#include "dsp.h"
#include "frame.h"
#include "stations.h"
#include "esn.h"
#include "main.h"
/* Uncomment this to test SAT via loopback */
@ -62,9 +61,7 @@
#define PAGE_TRIES 2 /* how many times to page the phone */
#define PAGE_TO1 8.0 /* max time to wait for paging reply */
#define PAGE_TO2 4.0 /* max time to wait for last paging reply */
#define ALERT_TRIES 3 /* how many times to alert the phone */
#define ALERT_TO 0.6 /* max time to wait for alert confirm */
#define ANSWER_TO 60.0 /* max time to wait for answer */
#define ALERT_TO 60.0 /* max time to wait for answer */
#define RELEASE_TIMER 5.0 /* max time to send release messages */
/* Convert channel number to frequency number of base station.
@ -74,7 +71,6 @@ double amps_channel2freq(int channel, int uplink)
double freq;
if (!tacs) {
/* AMPS */
if (uplink == 2)
return -45.000 * 1e6;
@ -90,7 +86,6 @@ double amps_channel2freq(int channel, int uplink)
if (uplink)
freq -= 45.000;
} else if (!jtacs) {
/* TACS */
if (uplink == 2)
return -45.000 * 1e6;
@ -103,23 +98,14 @@ double amps_channel2freq(int channel, int uplink)
if (uplink)
freq -= 45.000;
} else {
/* JTACS */
/* see "ARIB_STD-T64-C.S0057-0v1.0.pdf" */
if (uplink == 2)
return 55.000 * 1e6;
return -55.000 * 1e6;
/* 799 channels */
if (channel >= 1 && channel <= 799)
freq = 860.0125 + (channel - 1) * 0.0125;
else if (channel >= 801 && channel <= 1039)
freq = 843.0125 + (channel - 801) * 0.0125;
else if (channel >= 1041 && channel <= 1199)
freq = 832.0125 + (channel - 1041) * 0.0125;
else if (channel >= 1201 && channel <= 1600)
freq = 838.0125 + (channel - 1201) * 0.0125;
else
if (channel < 1 || channel > 799)
return 0;
freq = 860.0125 + (channel - 1) * 0.025;
if (uplink)
freq += 55.000;
@ -131,19 +117,13 @@ double amps_channel2freq(int channel, int uplink)
enum amps_chan_type amps_channel2type(int channel)
{
if (!tacs) {
/* AMPS */
if (channel >= 313 && channel <= 354)
return CHAN_TYPE_CC;
} else if (!jtacs) {
/* TACS */
} else {
if (channel >= 23 && channel <= 43)
return CHAN_TYPE_CC;
if (channel >= 323 && channel <= 343)
return CHAN_TYPE_CC;
} else {
/* JTACS */
if (channel >= 418 && channel <= 456)
return CHAN_TYPE_CC;
}
return CHAN_TYPE_VC;
@ -152,7 +132,6 @@ enum amps_chan_type amps_channel2type(int channel)
const char *amps_channel2band(int channel)
{
if (!tacs) {
/* AMPS */
if (channel >= 991 && channel <= 1023)
return "A''";
if (channel >= 1 && channel <= 333)
@ -163,15 +142,11 @@ const char *amps_channel2band(int channel)
return "A'";
if (channel >= 717 && channel <= 799)
return "B'";
} else if (!jtacs) {
/* TACS */
} else {
if (channel >= 1 && channel <= 300)
return "A";
if (channel >= 301 && channel <= 600)
return "B";
} else {
/* JTACS */
return "A";
}
return "<invalid>";
@ -225,12 +200,12 @@ void amps_number2min(const char *number, uint32_t *min1, uint16_t *min2)
}
if (!tacs) {
/* MIN1 (amps) */
/* MIN1 */
*min1 = ((uint32_t)(digit2binary(number[0]) * 100 + digit2binary(number[1]) * 10 + digit2binary(number[2]) - 111)) << 14;
*min1 |= digit2binary(number[3]) << 10;
*min1 |= digit2binary(number[4]) * 100 + digit2binary(number[5]) * 10 + digit2binary(number[6]) - 111;
} else {
/* MIN1 (tacs/jtacs) */
/* MIN1 */
*min1 = digit2binary(number[0]) << 20;
*min1 |= (digit2binary(number[1]) * 100 + digit2binary(number[2]) * 10 + digit2binary(number[3]) - 111) << 10;
*min1 |= digit2binary(number[4]) * 100 + digit2binary(number[5]) * 10 + digit2binary(number[6]) - 111;
@ -241,8 +216,6 @@ void amps_number2min(const char *number, uint32_t *min1, uint16_t *min2)
*/
/* TACS: convert MIN1 and MIN2 to AREA-XXXXXXX
*/
/* JTACS: convert MIN1 and MIN2 to NET-XXXXXXX (NET = mobile network code, always 440)
*/
const char *amps_min22number(uint16_t min2)
{
static char number[4];
@ -265,7 +238,7 @@ const char *amps_min12number(uint32_t min1)
static char number[8];
if (!tacs) {
/* MIN1 (amps) */
/* MIN1 */
if ((min1 >> 14) > 999)
strcpy(number, "???");
else {
@ -285,7 +258,7 @@ const char *amps_min12number(uint32_t min1)
number[6] = binary2digit(((min1 & 0x3ff) % 10) + 1);
}
} else {
/* MIN1 (tacs/jtacs) */
/* MIN1 */
if ((min1 >> 20) < 1 || (min1 >> 20) > 10)
number[0] = '?';
else
@ -518,7 +491,7 @@ static amps_t *search_pc(void)
}
/* Create transceiver instance and link to a list. */
int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, amps_si *si, uint16_t sid, uint8_t sat, int polarity, int send_callerid, int tolerant, int loopback)
int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, amps_si *si, uint16_t sid, uint8_t sat, int polarity, int tolerant, int loopback)
{
sender_t *sender;
amps_t *amps;
@ -529,8 +502,6 @@ int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *de
/* check for channel number */
if (amps_channel2freq(atoi(kanal), 0) == 0) {
PDEBUG(DAMPS, DEBUG_ERROR, "Channel number %s invalid.\n", kanal);
if (jtacs)
PDEBUG(DAMPS, DEBUG_ERROR, "Try an even channel number, like 440.\n");
return -EINVAL;
}
@ -560,11 +531,6 @@ int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *de
PDEBUG(DAMPS, DEBUG_ERROR, "Channel number %s belongs to a voice channel, but your channel type '%s' requires to be on a control channel number. Please use correct channel.\n", kanal, chan_type_long_name(chan_type));
return -EINVAL;
}
/* only even channels */
if (jtacs && chan_type != CHAN_TYPE_VC && (atoi(kanal) & 1)) {
PDEBUG(DAMPS, DEBUG_ERROR, "Control channel on JTACS system seem not to work with odd channel numbers. Please use even channel number.\n");
return -EINVAL;
}
/* check if sid machtes channel band */
band = amps_channel2band(atoi(kanal));
@ -605,12 +571,12 @@ int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *de
amps->chan_type = chan_type;
memcpy(&amps->si, si, sizeof(amps->si));
amps->sat = sat;
amps->send_callerid = send_callerid;
if (polarity < 0)
amps->flip_polarity = 1;
amps->pre_emphasis = pre_emphasis;
amps->de_emphasis = de_emphasis;
/* the AMPS uses a frequency rage of 300..3000 Hz, but we still use the default low pass filter, which is not too far above */
rc = init_emphasis(&amps->estate, samplerate, CUT_OFF_EMPHASIS_DEFAULT, CUT_OFF_HIGHPASS_DEFAULT, CUT_OFF_LOWPASS_DEFAULT);
if (rc < 0)
@ -711,13 +677,14 @@ static void amps_release(transaction_t *trans, uint8_t cause)
trans->callref = 0;
}
/* change DSP mode to transmit release */
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX || amps->dsp_mode == DSP_MODE_AUDIO_RX_SILENCE_TX || amps->dsp_mode == DSP_MODE_OFF)
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX || amps->dsp_mode == DSP_MODE_OFF)
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_FRAME_TX, 0);
}
/*
* receive signaling
*/
void amps_rx_signaling_tone(amps_t *amps, int tone, double quality)
{
transaction_t *trans = amps->trans_list;
@ -732,7 +699,6 @@ void amps_rx_signaling_tone(amps_t *amps, int tone, double quality)
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Lost Signaling Tone signal\n");
switch (trans->state) {
case TRANS_CALL_MO_ASSIGN_CONFIRM: // should not happen
case TRANS_CALL:
if (!tone)
break;
@ -746,19 +712,16 @@ void amps_rx_signaling_tone(amps_t *amps, int tone, double quality)
destroy_transaction(trans);
amps_go_idle(amps);
break;
case TRANS_CALL_MT_ASSIGN_CONFIRM: // should not happen
case TRANS_CALL_MT_ALERT: // should not happen
case TRANS_CALL_MT_ALERT_SEND: // should not happen
case TRANS_CALL_MT_ALERT_CONFIRM:
case TRANS_CALL_MT_ALERT:
if (tone) {
timer_stop(&trans->timer);
call_up_alerting(trans->callref);
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_AUDIO_TX, 0);
trans_new_state(trans, TRANS_CALL_MT_ANSWER_WAIT);
timer_start(&trans->timer, ANSWER_TO);
trans_new_state(trans, TRANS_CALL_MT_ALERT_SEND);
timer_start(&trans->timer, ALERT_TO);
}
break;
case TRANS_CALL_MT_ANSWER_WAIT:
case TRANS_CALL_MT_ALERT_SEND:
if (!tone) {
timer_stop(&trans->timer);
if (!trans->sat_detected)
@ -779,20 +742,13 @@ void amps_rx_sat(amps_t *amps, int tone, double quality)
PDEBUG_CHAN(DAMPS, DEBUG_ERROR, "SAT signal without transaction, please fix!\n");
return;
}
/* irgnoring SAT loss on release */
if (trans->state == TRANS_CALL_RELEASE
|| trans->state == TRANS_CALL_RELEASE_SEND)
return;
/* only SAT with these states */
if (trans->state != TRANS_CALL_MO_ASSIGN_CONFIRM
&& trans->state != TRANS_CALL_MT_ASSIGN_CONFIRM
if (trans->state != TRANS_CALL
&& trans->state != TRANS_CALL_MT_ALERT
&& trans->state != TRANS_CALL_MT_ALERT_SEND
&& trans->state != TRANS_CALL_MT_ALERT_CONFIRM
&& trans->state != TRANS_CALL_MT_ANSWER_WAIT
&& trans->state != TRANS_CALL) {
&& trans->state != TRANS_CALL_MT_ALERT_SEND) {
PDEBUG_CHAN(DAMPS, DEBUG_ERROR, "SAT signal without active call, please fix!\n");
return;
}
@ -805,20 +761,10 @@ void amps_rx_sat(amps_t *amps, int tone, double quality)
trans->sat_detected = 0;
}
/* initial SAT received */
if (tone && trans->state == TRANS_CALL_MO_ASSIGN_CONFIRM) {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Confirm from mobile (SAT) received\n");
timer_stop(&trans->timer);
trans_new_state(trans, TRANS_CALL);
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_AUDIO_TX, 0);
}
if (tone && trans->state == TRANS_CALL_MT_ASSIGN_CONFIRM) {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Confirm from mobile (SAT) received\n");
timer_stop(&trans->timer);
trans->alert_retry = 1;
trans_new_state(trans, TRANS_CALL_MT_ALERT);
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_FRAME_TX, 0);
}
/* no SAT during alerting */
if (trans->state == TRANS_CALL_MT_ALERT
|| trans->state == TRANS_CALL_MT_ALERT_SEND)
return;
if (tone) {
timer_stop(&trans->timer);
@ -833,6 +779,20 @@ void amps_rx_sat(amps_t *amps, int tone, double quality)
return;
}
static void timeout_sat(amps_t *amps, double duration)
{
if (!amps->trans_list) {
PDEBUG_CHAN(DAMPS, DEBUG_ERROR, "SAT timeout, but no transaction, please fix!\n");
return;
}
if (duration == SAT_TO1)
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Timeout after %.0f seconds not receiving SAT signal.\n", duration);
else
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Timeout after %.0f seconds loosing SAT signal.\n", duration);
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Release call towards network.\n");
amps_release(amps->trans_list, CAUSE_TEMPFAIL);
}
/* receive message from phone on RECC */
void amps_rx_recc(amps_t *amps, uint8_t scm, uint8_t mpci, uint32_t esn, uint32_t min1, uint16_t min2, uint8_t msg_type, uint8_t ordq, uint8_t order, const char *dialing)
{
@ -848,7 +808,7 @@ void amps_rx_recc(amps_t *amps, uint8_t scm, uint8_t mpci, uint32_t esn, uint32_
}
if (order == 13 && (ordq == 0 || ordq == 1 || ordq == 2 || ordq == 3) && msg_type == 0) {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Registration %s (ESN = %s, %s, %s)\n", callerid, esn_to_string(esn), amps_scm(scm), amps_mpci(mpci));
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Registration %s (ESN = %08x, %s, %s)\n", callerid, esn, amps_scm(scm), amps_mpci(mpci));
_register:
numbering(callerid, &carrier, &country, &national_number);
if (carrier)
@ -864,14 +824,14 @@ _register:
}
} else
if (order == 13 && ordq == 3 && msg_type == 1) {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Registration - Power Down %s (ESN = %s, %s, %s)\n", callerid, esn_to_string(esn), amps_scm(scm), amps_mpci(mpci));
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Registration - Power Down %s (ESN = %08x, %s, %s)\n", callerid, esn, amps_scm(scm), amps_mpci(mpci));
goto _register;
} else
if (order == 0 && ordq == 0 && msg_type == 0) {
if (!dialing)
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Paging reply %s (ESN = %s, %s, %s)\n", callerid, esn_to_string(esn), amps_scm(scm), amps_mpci(mpci));
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Paging reply %s (ESN = %08x, %s, %s)\n", callerid, esn, amps_scm(scm), amps_mpci(mpci));
else
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Call %s -> %s (ESN = %s, %s, %s)\n", callerid, dialing, esn_to_string(esn), amps_scm(scm), amps_mpci(mpci));
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Call %s -> %s (ESN = %08x, %s, %s)\n", callerid, dialing, esn, amps_scm(scm), amps_mpci(mpci));
trans = search_transaction_number(amps, min1, min2);
if (!trans && !dialing) {
PDEBUG(DAMPS, DEBUG_NOTICE, "Paging reply, but call is already gone, rejecting call\n");
@ -979,11 +939,6 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
}
trans->callref = callref;
trans->page_retry = 1;
if (caller_type == TYPE_INTERNATIONAL) {
trans->caller_id[0] = '+';
strncpy(trans->caller_id + 1, caller_id, sizeof(trans->caller_id) - 2);
} else
strncpy(trans->caller_id, caller_id, sizeof(trans->caller_id) - 1);
return 0;
}
@ -1022,11 +977,8 @@ void call_down_disconnect(int callref, int cause)
switch (amps->dsp_mode) {
case DSP_MODE_AUDIO_RX_AUDIO_TX:
case DSP_MODE_AUDIO_RX_FRAME_TX:
if (trans->state == TRANS_CALL_MT_ASSIGN_CONFIRM
|| trans->state == TRANS_CALL_MT_ALERT
|| trans->state == TRANS_CALL_MT_ALERT_SEND
|| trans->state == TRANS_CALL_MT_ALERT_CONFIRM
|| trans->state == TRANS_CALL_MT_ANSWER_WAIT) {
if (trans->state == TRANS_CALL_MT_ALERT
|| trans->state == TRANS_CALL_MT_ALERT_SEND) {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Call control disconnect on voice channel while alerting, releasing towards mobile station.\n");
amps_release(trans, cause);
}
@ -1065,7 +1017,6 @@ void call_down_release(int callref, int cause)
trans->callref = 0;
switch (amps->dsp_mode) {
case DSP_MODE_AUDIO_RX_SILENCE_TX:
case DSP_MODE_AUDIO_RX_AUDIO_TX:
case DSP_MODE_AUDIO_RX_FRAME_TX:
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Call control releases on voice channel, releasing towards mobile station.\n");
@ -1079,7 +1030,7 @@ void call_down_release(int callref, int cause)
}
/* Receive audio from call instance. */
void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_t ssrc, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
amps_t *amps;
@ -1093,30 +1044,24 @@ void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_
return;
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX) {
sample_t up[(int)((double)count * amps->sender.srstate.factor + 0.5) + 10];
compress_audio(&amps->cstate, samples, count);
jitter_save(&amps->sender.dejitter, samples, count, 1, sequence, timestamp, ssrc);
count = samplerate_upsample(&amps->sender.srstate, samples, count, up);
jitter_save(&amps->sender.dejitter, up, count);
}
}
void call_down_clock(void) {}
/* Timeout handling */
void transaction_timeout(void *data)
void transaction_timeout(struct timer *timer)
{
transaction_t *trans = data;
transaction_t *trans = (transaction_t *)timer->priv;
amps_t *amps = trans->amps;
switch (trans->state) {
case TRANS_CALL_MO_ASSIGN_CONFIRM:
case TRANS_CALL_MT_ASSIGN_CONFIRM:
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Timeout after %.0f seconds not receiving initial SAT signal.\n", trans->timer.duration);
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Release call towards network.\n");
amps_release(amps->trans_list, CAUSE_TEMPFAIL);
break;
case TRANS_CALL:
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Timeout after %.0f seconds loosing SAT signal.\n", trans->timer.duration);
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Release call towards network.\n");
amps_release(amps->trans_list, CAUSE_TEMPFAIL);
timeout_sat(amps, timer->duration);
break;
case TRANS_CALL_RELEASE:
case TRANS_CALL_RELEASE_SEND:
@ -1124,18 +1069,10 @@ void transaction_timeout(void *data)
destroy_transaction(trans);
amps_go_idle(amps);
break;
case TRANS_CALL_MT_ALERT_SEND:
case TRANS_CALL_MT_ALERT_CONFIRM:
if (trans->alert_retry++ == ALERT_TRIES) {
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Phone does not respond to alert order, destroying transaction\n");
amps_release(trans, CAUSE_TEMPFAIL);
} else {
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Phone does not respond to alert order, retrying\n");
trans_new_state(trans, TRANS_CALL_MT_ALERT);
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_FRAME_TX, 0);
}
case TRANS_CALL_MT_ALERT:
amps_release(trans, CAUSE_TEMPFAIL);
break;
case TRANS_CALL_MT_ANSWER_WAIT:
case TRANS_CALL_MT_ALERT_SEND:
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Alerting timeout, destroying transaction\n");
amps_release(trans, CAUSE_NOANSWER);
break;
@ -1225,9 +1162,8 @@ again:
vc = assign_voice_channel(trans);
if (vc) {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Assignment complete, voice connected\n");
/* timer and other things are processed at assign_voice_channel() */
trans_new_state(trans, TRANS_CALL_MO_ASSIGN_CONFIRM);
amps_set_dsp_mode(vc, DSP_MODE_AUDIO_RX_SILENCE_TX, 0);
trans_new_state(trans, TRANS_CALL);
amps_set_dsp_mode(vc, DSP_MODE_AUDIO_RX_AUDIO_TX, 0);
}
return NULL;
case TRANS_CALL_MT_ASSIGN:
@ -1237,10 +1173,13 @@ again:
case TRANS_CALL_MT_ASSIGN_SEND:
vc = assign_voice_channel(trans);
if (vc) {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Assignment complete, waiting for SAT on VC\n");
/* timer and other things are processed at assign_voice_channel() */
trans_new_state(trans, TRANS_CALL_MT_ASSIGN_CONFIRM);
amps_set_dsp_mode(vc, DSP_MODE_AUDIO_RX_SILENCE_TX, 0);
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Assignment complete, next: sending alerting on VC\n");
trans->chan = 0;
trans->msg_type = 0;
trans->ordq = 0;
trans->order = 1;
trans_new_state(trans, TRANS_CALL_MT_ALERT);
amps_set_dsp_mode(vc, DSP_MODE_AUDIO_RX_FRAME_TX, 0);
}
return NULL;
case TRANS_PAGE:
@ -1273,25 +1212,8 @@ transaction_t *amps_tx_frame_fvc(amps_t *amps)
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Release call was sent, continue sending release\n");
return trans;
case TRANS_CALL_MT_ALERT:
trans->chan = 0;
trans->msg_type = 0;
trans->ordq = 0;
// "Alert with caller ID" causes older phones to interrupt the connection for some reason, therefore we don't use order 17 when no caller ID is set
if (amps->send_callerid && trans->alert_retry == 1 && trans->caller_id[0]) {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Sending alerting with caller ID\n");
trans->order = 17;
} else {
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Sending alerting\n");
trans->order = 1;
}
trans_new_state(trans, TRANS_CALL_MT_ALERT_SEND);
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Sending alerting\n");
return trans;
case TRANS_CALL_MT_ALERT_SEND:
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Alerting was sent, continue waiting for ST or timeout\n");
timer_start(&trans->timer, ALERT_TO);
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_SILENCE_TX, 0);
trans_new_state(trans, TRANS_CALL_MT_ALERT_CONFIRM);
return NULL;
default:
return NULL;
}

View File

@ -10,7 +10,6 @@ enum dsp_mode {
DSP_MODE_OFF, /* channel not active (VC) */
DSP_MODE_AUDIO_RX_AUDIO_TX, /* stream audio */
DSP_MODE_AUDIO_RX_FRAME_TX, /* stream audio, send frames */
DSP_MODE_AUDIO_RX_SILENCE_TX, /* stream audio, send silence */
DSP_MODE_FRAME_RX_FRAME_TX, /* send and decode frames */
};
@ -57,7 +56,6 @@ struct amps {
/* system info */
amps_si si;
int send_callerid; /* if set, caller ID is transmitted */
/* cell nr selection */
int cell_auto; /* if set, cell_nr is selected automatically */
@ -135,19 +133,12 @@ struct amps {
uint8_t tx_focc_order;
int tx_focc_word_count; /* counts transmitted words in a multi word message */
int tx_focc_word_repeat; /* counts repeats of multi word message */
int tx_focc_debugged; /* indicator to prevent debugging all SI/filler frames */
/* FVC frame states */
int tx_fvc_send; /* if set, send message words */
int tx_fvc_chan; /* channel to assign for voice call */
uint8_t tx_fvc_msg_type; /* message (3 values) */
uint8_t tx_fvc_ordq;
uint8_t tx_fvc_order;
char tx_fvc_callerid[34]; /* caller ID */
int tx_fvc_callerid_present;/* presentation of caller ID */
int tx_fvc_callerid_screen; /* screening of caller ID */
int tx_fvc_callerid_signal; /* signal to send in conjunction with caller ID */
int tx_fvc_word_count; /* counts transmitted words in a muli word message */
int tx_fvc_word_repeat; /* counts repeats of mulit word message */
/* SAT tone */
int sat; /* use SAT tone 0..2 */
int sat_samples; /* number of samples in buffer for supervisory detection */
@ -182,10 +173,8 @@ const char *amps_min22number(uint16_t min2);
const char *amps_min12number(uint32_t min1);
void amps_number2min(const char *number, uint32_t *min1, uint16_t *min2);
const char *amps_min2number(uint32_t min1, uint16_t min2);
void amps_encode_esn(uint32_t *esn, uint8_t mfr, uint32_t serial);
void amps_decode_esn(uint32_t esn, uint8_t *mfr, uint32_t *serial);
const char *amps_scm(uint8_t scm);
int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, amps_si *si, uint16_t sid, uint8_t sat, int polarity, int send_callerid, int tolerant, int loopback);
int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, amps_si *si, uint16_t sid, uint8_t sat, int polarity, int tolerant, int loopback);
void amps_destroy(sender_t *sender);
void amps_go_idle(amps_t *amps);
void amps_rx_signaling_tone(amps_t *amps, int tone, double quality);

View File

@ -38,10 +38,7 @@
int num_chan_type = 0;
enum amps_chan_type chan_type[MAX_SENDER] = { CHAN_TYPE_CC_PC_VC };
const char *flip_polarity = "";
int ms_power = 4;
int dtx = 0;
int send_callerid = 0;
int dcc = 0, scc = 0, sid = 0, regh = 1, regr = 1, pureg = 0, pdreg = 0, locaid = -1, regincr = 300, bis = 0;
int ms_power = 4, dtx = 0, dcc = 0, scc = 0, sid = 0, regh = 1, regr = 1, pureg = 0, pdreg = 0, locaid = -1, regincr = 300, bis = 0;
int tolerant = 0;
void print_help(const char *arg0)
@ -60,24 +57,12 @@ void print_help(const char *arg0)
printf(" If the phone shows 'NoSrv', try the other way.\n");
printf(" -P --ms-power <power level>\n");
printf(" Give power level of the mobile station 0..7. (default = '%d')\n", ms_power);
if (!tacs) {
printf(" 0 = 4 W; 1 = 1.6 W; 2 = 630 mW; 3 = 250 mW;\n");
printf(" 4 = 100 mW; 5 = 40 mW; 6 = 16 mW; 7 = 6.3 mW\n");
} else {
/* tacs, not jtacs: https://www.academia.edu/8265916/Total_Access_Communication_System?email_work_card=view-paper */
printf(" 0 = 2.28 W; 1 = 1.12 W; 2 = 447 mW; 3 = 178 mW;\n");
printf(" 4 = 70.8 mW; 5 = 28.2 mW; 6 = 11.2 mW; 7 = 4.5 mW\n");
}
printf(" 0 = %2d W; 1 = 1.6 W; 2 = 630 mW; 3 = 250 mW;\n", (tacs) ? 10 : 4);
printf(" 4 = 100 mW; 5 = 40 mW; 6 = 16 mW; 7 = 6.3 mW\n");
printf(" -D --dtx <parameter>\n");
printf(" Give DTX parameter for Discontinuous Transmission. (default = '%d')\n", dtx);
printf(" 0 = disable DTX; 1 = reserved;\n");
printf(" 2 = 8 dB attenuation in low state; 3 = transmitter off\n");
printf(" -I --caller-id 1 | 0\n");
printf(" If set, the caller ID is sent while ringing the phone. (default = '%d')\n", send_callerid);
printf(" Note that this does not work as documented in the specs. If the phone\n");
printf(" does not support caller ID, it will abort connection on receiving\n");
printf(" caller ID for some unknown reason. Therefore use caller ID only with\n");
printf(" phones that support it.\n");
if (!tacs) {
printf(" -S --sysinfo sid=<System ID> | sid=list\n");
printf(" Give system ID of cell broadcast\n");
@ -125,7 +110,6 @@ static void add_options(void)
option_add('F', "flip-polarity", 1);
option_add('P', "ms-power", 1);
option_add('D', "dtx", 1);
option_add('I', "caller-id", 1);
option_add('S', "sysinfo", 1);
option_add('O', "tolerant", 0);
}
@ -172,9 +156,6 @@ static int handle_options(int short_option, int argi, char **argv)
if (dtx < 0)
dtx = 0;
break;
case 'I':
send_callerid = atoi(argv[argi]);
break;
case 'S':
p = strchr(argv[argi], '=');
if (!p) {
@ -245,7 +226,10 @@ static int handle_options(int short_option, int argi, char **argv)
return 1;
}
extern const struct number_lengths number_lengths[];
static const struct number_lengths number_lengths[] = {
{ 10, "AMPS number" },
{ 0, NULL }
};
int main_amps_tacs(const char *name, int argc, char *argv[])
{
@ -254,10 +238,6 @@ int main_amps_tacs(const char *name, int argc, char *argv[])
int polarity;
int i;
/* jtacs has only system A, so there are only odd AIDs */
if (jtacs)
sid = 1;
/* override default */
dsp_samplerate = 96000;
@ -287,7 +267,7 @@ int main_amps_tacs(const char *name, int argc, char *argv[])
}
if (!num_kanal) {
printf("No channel (\"Kanal\") is specified, I suggest channel %d.\n\n", (!tacs) ? 333 : ((!jtacs) ? 323 : 418));
printf("No channel (\"Kanal\") is specified, I suggest channel %d.\n\n", (!tacs) ? 333 : 323);
print_help(argv[0]);
return 0;
}
@ -404,7 +384,7 @@ int main_amps_tacs(const char *name, int argc, char *argv[])
amps_si si;
init_sysinfo(&si, ms_power, ms_power, dtx, dcc, sid >> 1, regh, regr, pureg, pdreg, locaid, regincr, bis);
rc = amps_create(kanal[i], chan_type[i], dsp_device[i], use_sdr, dsp_samplerate, rx_gain, tx_gain, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, &si, sid, scc, polarity, send_callerid, tolerant, loopback);
rc = amps_create(kanal[i], chan_type[i], dsp_device[i], use_sdr, dsp_samplerate, rx_gain, tx_gain, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, &si, sid, scc, polarity, tolerant, loopback);
if (rc < 0) {
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
goto fail;

View File

@ -125,7 +125,7 @@
#define SIG_LOST_COUNT 4 /* number of measures to loose Signaling Tone */
#define CUT_OFF_HIGHPASS 300.0 /* cut off frequency for high pass filter to remove dc level from sound card / sample */
#define BEST_QUALITY 0.68 /* Best possible RX quality */
#define COMFORT_NOISE 0.02 /* audio level of comfort noise (relative to speech level) */
#define COMFORT_NOISE 0.02 /* audio level of comfort noise (relative to ISDN level) */
static sample_t ramp_up[256], ramp_down[256];
@ -162,8 +162,6 @@ void dsp_init(void)
}
dsp_sync_check[0x712] = 0x00; /* no bit error */
dsp_sync_check[0x0ed] = 0x80; /* no bit error */
compandor_init();
}
static void dsp_init_ramp(amps_t *amps)
@ -196,7 +194,7 @@ int dsp_init_sender(amps_t *amps, int tolerant)
int half;
/* attack (3ms) and recovery time (13.5ms) according to amps specs */
setup_compandor(&amps->cstate, 8000, 3.0, 13.5);
init_compandor(&amps->cstate, 8000, 3.0, 13.5);
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init DSP for transceiver.\n");
@ -255,7 +253,6 @@ int dsp_init_sender(amps_t *amps, int tolerant)
PDEBUG(DDSP, DEBUG_ERROR, "No memory!\n");
return -ENOMEM;
}
PDEBUG(DDSP, DEBUG_DEBUG, "Sat detection interval is %d ms.\n", amps->sat_samples * 1000 / amps->sender.samplerate);
amps->sat_filter_spl = spl;
/* count SAT tones */
@ -402,8 +399,8 @@ again:
rc = amps_encode_frame_fvc(amps, amps->fsk_tx_frame);
else
rc = amps_encode_frame_focc(amps, amps->fsk_tx_frame);
/* check if we have no bit string (change to tx audio / silence)
* we may not store fsk_tx_buffer_pos, because is was reset on a mode change */
/* check if we have not bit string (change to tx audio)
* we may not store fsk_tx_buffer_pos, because is was reset on a mode achange */
if (rc)
return count;
amps->fsk_tx_frame_pos = 0;
@ -476,7 +473,7 @@ static void sat_encode(amps_t *amps, sample_t *samples, int length)
void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length)
{
amps_t *amps = (amps_t *) sender;
int count, input_num;
int count;
again:
switch (amps->dsp_mode) {
@ -486,19 +483,11 @@ again:
break;
case DSP_MODE_AUDIO_RX_AUDIO_TX:
memset(power, 1, length);
input_num = samplerate_upsample_input_num(&sender->srstate, length);
jitter_load(&sender->dejitter, samples, input_num);
samplerate_upsample(&sender->srstate, samples, input_num, samples, length);
jitter_load(&amps->sender.dejitter, samples, length);
/* pre-emphasis */
if (amps->pre_emphasis)
pre_emphasis(&amps->estate, samples, length);
/* encode SAT during call */
sat_encode(amps, samples, length);
break;
case DSP_MODE_AUDIO_RX_SILENCE_TX:
memset(power, 1, length);
memset(samples, 0, sizeof(*samples) * length);
/* encode SAT while waiting for alert response or answer */
/* encode sat */
sat_encode(amps, samples, length);
break;
case DSP_MODE_AUDIO_RX_FRAME_TX:
@ -507,7 +496,6 @@ again:
* stopped, process again for rest of stream. */
count = fsk_frame(amps, samples, length);
memset(power, 1, count);
// no SAT during frame transmission, according to specs
samples += count;
power += count;
length -= count;
@ -843,7 +831,7 @@ static void sat_decode(amps_t *amps, sample_t *samples, int length)
static void sender_receive_audio(amps_t *amps, sample_t *samples, int length)
{
transaction_t *trans = amps->trans_list;
sample_t *spl, s;
sample_t *spl;
int max, pos;
int i;
@ -852,10 +840,7 @@ static void sender_receive_audio(amps_t *amps, sample_t *samples, int length)
spl = amps->sat_filter_spl;
pos = amps->sat_filter_pos;
for (i = 0; i < length; i++) {
/* unmute: use buffer, to delay audio, so we do not miss that chunk when SAT is detected */
s = spl[pos];
spl[pos++] = samples[i];
samples[i] = s;
if (pos == max) {
pos = 0;
sat_decode(amps, spl, max);
@ -909,7 +894,6 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double __at
break;
case DSP_MODE_AUDIO_RX_AUDIO_TX:
case DSP_MODE_AUDIO_RX_FRAME_TX:
case DSP_MODE_AUDIO_RX_SILENCE_TX:
sender_receive_audio(amps, samples, length);
break;
}
@ -936,16 +920,15 @@ void amps_set_dsp_mode(amps_t *amps, enum dsp_mode mode, int frame_length)
/* reset SAT detection */
sat_reset(amps, "Change to FOCC");
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Change mode to FOCC\n");
amps->tx_focc_debugged = 0;
}
if (amps->dsp_mode == DSP_MODE_FRAME_RX_FRAME_TX
&& (mode == DSP_MODE_AUDIO_RX_AUDIO_TX || mode == DSP_MODE_AUDIO_RX_FRAME_TX || mode == DSP_MODE_AUDIO_RX_SILENCE_TX)) {
&& (mode == DSP_MODE_AUDIO_RX_AUDIO_TX || mode == DSP_MODE_AUDIO_RX_FRAME_TX)) {
/* reset SAT detection */
sat_reset(amps, "Change from FOCC to FVC");
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Change mode from FOCC to FVC\n");
}
if (amps->dsp_mode == DSP_MODE_OFF
&& (mode == DSP_MODE_AUDIO_RX_AUDIO_TX || mode == DSP_MODE_AUDIO_RX_FRAME_TX || mode == DSP_MODE_AUDIO_RX_SILENCE_TX)) {
&& (mode == DSP_MODE_AUDIO_RX_AUDIO_TX || mode == DSP_MODE_AUDIO_RX_FRAME_TX)) {
/* reset SAT detection */
sat_reset(amps, "Enable FVC");
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Change mode from OFF to FVC\n");
@ -956,8 +939,6 @@ void amps_set_dsp_mode(amps_t *amps, enum dsp_mode mode, int frame_length)
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Change mode from FVC to OFF\n");
}
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Reset FSK frame transmitter, due to setting dsp mode.\n");
amps->dsp_mode = mode;
if (frame_length)
amps->fsk_rx_frame_length = frame_length;

View File

@ -1,152 +0,0 @@
/* AMPS ESN specification
*
* (C) 2023 by Andreas Eversberg <jolly@eversberg.eu>
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <pthread.h>
#include "../libsample/sample.h"
#include "../libdebug/debug.h"
#include "../libmobile/call.h"
#include "../libmobile/cause.h"
#include "../libosmocc/message.h"
#include "amps.h"
#include "esn.h"
const char *amps_manufacturer[256] = {
[129] = "Oki",
[130] = "Motorola, Inc.",
[131] = "E.F. Johnson",
[132] = "Hitachi",
[133] = "Fujitsu",
[134] = "Mitsubishi",
[135] = "NEC America, Inc.",
[136] = "Matsushita (Panasonic)",
[137] = "Harris",
[138] = "Toshiba",
[139] = "Kokusai",
[140] = "Clarion Company, Ltd.",
[141] = "GoldStar Products Co.,Ltd.",
[142] = "International Systcom (Novatel)",
[143] = "Ericsson, Inc.",
[144] = "Murata Machinery, Ltd.",
[145] = "DI-BAR Electronics, Inc.",
[146] = "Ericsson Inc. (formerly assigned to General Electric)",
[147] = "Gateway Telephone, Inc.",
[148] = "Robert Bosch Corporation (Blaupunkt)",
[149] = "Universal Cellular, Inc.",
[150] = "Alpine Electronics of America, Inc.",
[151] = "Verma Laboratories",
[152] = "Japan Radio Co.,Ltd.",
[153] = "CM Communications Incorporated",
[154] = "Sony Corporation (Japan)",
[155] = "Tama Denki Company, Ltd.",
[156] = "Mobira (Nokia-Kinex)",
[157] = "Ericsson GE Mobile Communications, Inc.",
[158] = "AT&T Technologies, Inc.",
[159] = "QUALCOMM, Incorporated",
[160] = "Hyundai",
[161] = "Satellite Technology Services, Inc.",
[162] = "Technophone Limited",
[163] = "Yupiteru Industries Company Ltd.",
[164] = "Hughes Network Systems",
[165] = "TMC Company Limited (Nokia)",
[166] = "Clarion Manufacturing Corporation of America",
[167] = "Mansoor Electronics Limited",
[168] = "Motorola International",
[169] = "Otron Corporation",
[170] = "Philips Telecom Equipment Corporation",
[171] = "Philips Circuit Assemblies",
[172] = "Uniden Corporation of America",
[173] = "Uniden Corporation - Japan",
[174] = "Shintom West Corporation of America",
[175] = "Tottori Sanyo Electric Co. Ltd.",
[176] = "Samsung Communications",
[177] = "INFA Telecom Canada, Inc.",
[178] = "Emptel Electronics Company Ltd.",
[179] = "**Unassigned**",
[180] = "ASCNet",
[181] = "Yaesu USA",
[182] = "Tecom Co. Ltd.",
[183] = "Omni Telecommunications, Inc. (formerly assigned to Valor Electronics, Inc.)",
[184] = "Royal Information Electronics Co. Ltd.",
[185] = "Tele Digital Development, Inc. (formerly assigned to Cumulus Corporation.)",
[186] = "DNC",
[187] = "**Unassigned**",
[188] = "Myday Technology, Ltd.",
[189] = "NEC America, Inc.",
[190] = "Kyocera Corporation",
[191] = "Digital Security Controls",
[192] = "CTCELL Digital, Inc.",
[193] = "Matsushita Communication Industrial Corporation of America",
[194] = "HS Electronics Corporation",
[195] = "Motorola, Inc.",
[196] = "Pacific Communication Sciences, Inc.",
[197] = "Maxon Systems, Inc., (London) Ltd.",
[198] = "Hongsheng Electronics Co., Ltd.",
[199] = "M/ACOM",
[200] = "CHANNLE LINK Incorporation",
[201] = "L.G. Information & Communications (formerly assigned to Goldstar Information & Communications, Ltd.)",
[202] = "Intel Corporation",
[203] = "Air Communications, Inc.",
[204] = "Ericsson GE Mobile Communications Inc.",
[205] = "Goldtron RF PTE Ltd.",
[206] = "Sierra Wireless Inc.",
[207] = "Mitsubishi International Corp.",
[208] = "JRC International, Inc.",
[209] = "Sapura Holdings SDN. BHD.",
[210] = "Inex Technologies, Inc.",
[211] = "Sony Electronics (U.S.A.)",
[212] = "Motorola, Inc.",
[213] = "Motorola, Inc.",
[214] = "Philips Semiconductors",
[215] = "Carillon Corp.",
[216] = "Nippondenso America, Inc.",
[217] = "International Business Machines Corporation",
[218] = "Nokia (Hong Kong)",
[219] = "Nokia (TMC Co. Ltd.)",
[220] = "TEMIC",
[221] = "Northern Telecom",
[222] = "Telrad Telecommunications Ltd.",
[223] = "Motorola, Inc.",
[224] = "Motorola, Inc.",
[225] = "Telital s.r.l.",
[226] = "Nokia (Manau, Brazil)",
[227] = "Stanilite Pacific",
[228] = "Philips Consumer Communications",
[229] = "NEC America, Inc.",
[230] = "TELLULAR Corporation",
[231] = "Ericsson Inc.",
};
const char *esn_to_string(uint32_t esn)
{
uint8_t mfr;
uint32_t serial;
static char esn_string[256];
amps_decode_esn(esn, &mfr, &serial);
if (amps_manufacturer[mfr])
snprintf(esn_string, sizeof(esn_string), "0x%08x or %d-%06d (%s)", esn, mfr, serial, amps_manufacturer[mfr]);
else
snprintf(esn_string, sizeof(esn_string), "0x%08x or %d-%06d", esn, mfr, serial);
return esn_string;
}

View File

@ -1,3 +0,0 @@
const char *esn_to_string(uint32_t esn);

View File

@ -2707,7 +2707,7 @@ static uint64_t amps_encode_word(frame_t *frame, struct def_word *w, int debug)
int i, t4 = 0;
#ifdef DEBUG_ALL_MESSAGES
debug = 1;
debug=1;
#endif
memset(spaces, ' ', ie_desc_max_len);
@ -2718,8 +2718,7 @@ static uint64_t amps_encode_word(frame_t *frame, struct def_word *w, int debug)
for (i = 0; w->ie[i].name; i++)
sum_bits += w->ie[i].bits;
if (debug)
PDEBUG(DFRAME, DEBUG_INFO, "Transmit: %s\n", w->name);
PDEBUG(DFRAME, (debug >= 0) ? DEBUG_INFO : DEBUG_DEBUG, "Transmit: %s\n", w->name);
word = 0;
for (i = 0; w->ie[i].name; i++) {
bits = w->ie[i].bits;
@ -2728,7 +2727,7 @@ static uint64_t amps_encode_word(frame_t *frame, struct def_word *w, int debug)
else
value = frame->ie[w->ie[i].ie];
word = (word << bits) | (value & cut_bits[bits]);
if (debug) {
if (debug >= 0) {
if (amps_ie_desc[w->ie[i].ie].decoder)
PDEBUG(DFRAME, DEBUG_DEBUG, " %s%s: %" PRIu64 " = %s (%s)\n", spaces + strlen(w->ie[i].name), w->ie[i].name, value, amps_ie_desc[w->ie[i].ie].decoder(value), amps_ie_desc[w->ie[i].ie].desc);
else
@ -2739,7 +2738,7 @@ static uint64_t amps_encode_word(frame_t *frame, struct def_word *w, int debug)
t4++;
if (t4 == 3) {
t4 = 0;
if (debug)
if (debug >= 0)
PDEBUG(DFRAME, DEBUG_DEBUG, " %s--> %s\n", spaces, amps_table4_name(frame->ie[AMPS_IE_LOCAL_MSG_TYPE], frame->ie[AMPS_IE_ORDQ], frame->ie[AMPS_IE_ORDER]));
}
}
@ -2747,7 +2746,7 @@ static uint64_t amps_encode_word(frame_t *frame, struct def_word *w, int debug)
return word;
}
static uint64_t amps_encode_control_filler(amps_t *amps, uint8_t dcc, uint8_t cmac, uint8_t sdcc1, uint8_t sdcc2, uint8_t wfom, int debug)
static uint64_t amps_encode_control_filler(amps_t *amps, uint8_t dcc, uint8_t cmac, uint8_t sdcc1, uint8_t sdcc2, uint8_t wfom)
{
frame_t frame;
@ -2768,10 +2767,10 @@ static uint64_t amps_encode_control_filler(amps_t *amps, uint8_t dcc, uint8_t cm
} else
frame.ie[AMPS_IE_1111] = 15;
frame.ie[AMPS_IE_OHD] = 1;
return amps_encode_word(&frame, &control_filler, debug);
return amps_encode_word(&frame, &control_filler, -1);
}
uint64_t amps_encode_word1_system(uint8_t dcc, uint16_t sid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc, int debug)
uint64_t amps_encode_word1_system(uint8_t dcc, uint16_t sid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc)
{
frame_t frame;
@ -2784,10 +2783,10 @@ uint64_t amps_encode_word1_system(uint8_t dcc, uint16_t sid1, uint8_t ep, uint8_
frame.ie[AMPS_IE_PCI] = pci;
frame.ie[AMPS_IE_NAWC] = nawc;
frame.ie[AMPS_IE_OHD] = 6;
return amps_encode_word(&frame, &amps_word1_system_parameter_overhead, debug);
return amps_encode_word(&frame, &amps_word1_system_parameter_overhead, -1);
}
uint64_t tacs_encode_word1_system(uint8_t dcc, uint16_t aid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc, int debug)
uint64_t tacs_encode_word1_system(uint8_t dcc, uint16_t aid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc)
{
frame_t frame;
@ -2800,10 +2799,10 @@ uint64_t tacs_encode_word1_system(uint8_t dcc, uint16_t aid1, uint8_t ep, uint8_
frame.ie[AMPS_IE_PCI] = pci;
frame.ie[AMPS_IE_NAWC] = nawc;
frame.ie[AMPS_IE_OHD] = 6;
return amps_encode_word(&frame, &tacs_word1_system_parameter_overhead, debug);
return amps_encode_word(&frame, &tacs_word1_system_parameter_overhead, -1);
}
uint64_t amps_encode_word2_system(uint8_t dcc, uint8_t s, uint8_t e, uint8_t regh, uint8_t regr, uint8_t dtx, uint8_t n_1, uint8_t rcf, uint8_t cpa, uint8_t cmax_1, uint8_t end, int debug)
uint64_t amps_encode_word2_system(uint8_t dcc, uint8_t s, uint8_t e, uint8_t regh, uint8_t regr, uint8_t dtx, uint8_t n_1, uint8_t rcf, uint8_t cpa, uint8_t cmax_1, uint8_t end)
{
frame_t frame;
@ -2821,10 +2820,10 @@ uint64_t amps_encode_word2_system(uint8_t dcc, uint8_t s, uint8_t e, uint8_t reg
frame.ie[AMPS_IE_CMAX_1] = cmax_1;
frame.ie[AMPS_IE_END] = end;
frame.ie[AMPS_IE_OHD] = 7;
return amps_encode_word(&frame, &word2_system_parameter_overhead, debug);
return amps_encode_word(&frame, &word2_system_parameter_overhead, -1);
}
uint64_t amps_encode_registration_id(uint8_t dcc, uint32_t regid, uint8_t end, int debug)
uint64_t amps_encode_registration_id(uint8_t dcc, uint32_t regid, uint8_t end)
{
frame_t frame;
@ -2834,10 +2833,10 @@ uint64_t amps_encode_registration_id(uint8_t dcc, uint32_t regid, uint8_t end, i
frame.ie[AMPS_IE_REGID] = regid;
frame.ie[AMPS_IE_END] = end;
frame.ie[AMPS_IE_OHD] = 0;
return amps_encode_word(&frame, &registration_id, debug);
return amps_encode_word(&frame, &registration_id, -1);
}
uint64_t amps_encode_registration_increment(uint8_t dcc, uint16_t regincr, uint8_t end, int debug)
uint64_t amps_encode_registration_increment(uint8_t dcc, uint16_t regincr, uint8_t end)
{
frame_t frame;
@ -2848,10 +2847,10 @@ uint64_t amps_encode_registration_increment(uint8_t dcc, uint16_t regincr, uint8
frame.ie[AMPS_IE_REGINCR] = regincr;
frame.ie[AMPS_IE_END] = end;
frame.ie[AMPS_IE_OHD] = 4;
return amps_encode_word(&frame, &registration_increment_global_action, debug);
return amps_encode_word(&frame, &registration_increment_global_action, -1);
}
uint64_t amps_encode_location_area(uint8_t dcc, uint8_t pureg, uint8_t pdreg, uint8_t lreg, uint16_t locaid, uint8_t end, int debug)
uint64_t amps_encode_location_area(uint8_t dcc, uint8_t pureg, uint8_t pdreg, uint8_t lreg, uint16_t locaid, uint8_t end)
{
frame_t frame;
@ -2865,10 +2864,10 @@ uint64_t amps_encode_location_area(uint8_t dcc, uint8_t pureg, uint8_t pdreg, ui
frame.ie[AMPS_IE_LOCAID] = locaid;
frame.ie[AMPS_IE_END] = end;
frame.ie[AMPS_IE_OHD] = 4;
return amps_encode_word(&frame, &location_area_global_action, debug);
return amps_encode_word(&frame, &location_area_global_action, -1);
}
uint64_t amps_encode_new_access_channel_set(uint8_t dcc, uint16_t newacc, uint8_t end, int debug)
uint64_t amps_encode_new_access_channel_set(uint8_t dcc, uint16_t newacc, uint8_t end)
{
frame_t frame;
@ -2879,10 +2878,10 @@ uint64_t amps_encode_new_access_channel_set(uint8_t dcc, uint16_t newacc, uint8_
frame.ie[AMPS_IE_NEWACC] = newacc;
frame.ie[AMPS_IE_END] = end;
frame.ie[AMPS_IE_OHD] = 4;
return amps_encode_word(&frame, &new_access_channel_set_global_action, debug);
return amps_encode_word(&frame, &new_access_channel_set_global_action, -1);
}
uint64_t amps_encode_overload_control(uint8_t dcc, uint8_t *olc, uint8_t end, int debug)
uint64_t amps_encode_overload_control(uint8_t dcc, uint8_t *olc, uint8_t end)
{
frame_t frame;
@ -2908,10 +2907,10 @@ uint64_t amps_encode_overload_control(uint8_t dcc, uint8_t *olc, uint8_t end, in
frame.ie[AMPS_IE_OLC_15] = olc[15];
frame.ie[AMPS_IE_END] = end;
frame.ie[AMPS_IE_OHD] = 4;
return amps_encode_word(&frame, &overload_control_global_action, debug);
return amps_encode_word(&frame, &overload_control_global_action, -1);
}
uint64_t amps_encode_access_type(uint8_t dcc, uint8_t bis, uint8_t pci_home, uint8_t pci_roam, uint8_t bspc, uint8_t bscap, uint8_t end, int debug)
uint64_t amps_encode_access_type(uint8_t dcc, uint8_t bis, uint8_t pci_home, uint8_t pci_roam, uint8_t bspc, uint8_t bscap, uint8_t end)
{
frame_t frame;
@ -2926,10 +2925,10 @@ uint64_t amps_encode_access_type(uint8_t dcc, uint8_t bis, uint8_t pci_home, uin
frame.ie[AMPS_IE_BSCAP] = bscap;
frame.ie[AMPS_IE_END] = end;
frame.ie[AMPS_IE_OHD] = 4;
return amps_encode_word(&frame, &access_type_parameters_global_action, debug);
return amps_encode_word(&frame, &access_type_parameters_global_action, -1);
}
uint64_t amps_encode_access_attempt(uint8_t dcc, uint8_t maxbusy_pgr, uint8_t maxsztr_pgr, uint8_t maxbusy_other, uint8_t maxsztr_other, uint8_t end, int debug)
uint64_t amps_encode_access_attempt(uint8_t dcc, uint8_t maxbusy_pgr, uint8_t maxsztr_pgr, uint8_t maxbusy_other, uint8_t maxsztr_other, uint8_t end)
{
frame_t frame;
@ -2943,7 +2942,7 @@ uint64_t amps_encode_access_attempt(uint8_t dcc, uint8_t maxbusy_pgr, uint8_t ma
frame.ie[AMPS_IE_MAXSZTR_OTHER] = maxsztr_other;
frame.ie[AMPS_IE_END] = end;
frame.ie[AMPS_IE_OHD] = 4;
return amps_encode_word(&frame, &access_attempt_parameters_global_action, debug);
return amps_encode_word(&frame, &access_attempt_parameters_global_action, -1);
}
static uint64_t amps_encode_word1_abbreviated_address_word(uint8_t dcc, uint32_t min1, int multiple)
@ -2957,7 +2956,7 @@ static uint64_t amps_encode_word1_abbreviated_address_word(uint8_t dcc, uint32_t
frame.ie[AMPS_IE_T1T2] = 0;
frame.ie[AMPS_IE_DCC] = dcc;
frame.ie[AMPS_IE_MIN1] = min1;
return amps_encode_word(&frame, &word1_abbreviated_address_word, 1);
return amps_encode_word(&frame, &word1_abbreviated_address_word, DEBUG_INFO);
}
static uint64_t amps_encode_word2_extended_address_word_a(uint16_t min2, uint8_t msg_type, uint8_t ordq, uint8_t order)
@ -2972,7 +2971,7 @@ static uint64_t amps_encode_word2_extended_address_word_a(uint16_t min2, uint8_t
frame.ie[AMPS_IE_LOCAL_MSG_TYPE] = msg_type;
frame.ie[AMPS_IE_ORDQ] = ordq;
frame.ie[AMPS_IE_ORDER] = order;
return amps_encode_word(&frame, &word2_extended_address_word_a, 1);
return amps_encode_word(&frame, &word2_extended_address_word_a, DEBUG_INFO);
}
static uint64_t amps_encode_word2_extended_address_word_b(uint8_t scc, uint16_t min2, uint8_t vmac, uint16_t chan)
@ -2985,7 +2984,7 @@ static uint64_t amps_encode_word2_extended_address_word_b(uint8_t scc, uint16_t
frame.ie[AMPS_IE_MIN2] = min2;
frame.ie[AMPS_IE_VMAC] = vmac;
frame.ie[AMPS_IE_CHAN] = chan;
return amps_encode_word(&frame, &word2_extended_address_word_b, 1);
return amps_encode_word(&frame, &word2_extended_address_word_b, DEBUG_INFO);
}
static uint64_t amps_encode_mobile_station_control_message_word1_a(uint8_t pscc, uint8_t msg_type, uint8_t ordq, uint8_t order)
@ -3000,7 +2999,7 @@ static uint64_t amps_encode_mobile_station_control_message_word1_a(uint8_t pscc,
frame.ie[AMPS_IE_LOCAL_MSG_TYPE] = msg_type;
frame.ie[AMPS_IE_ORDQ] = ordq;
frame.ie[AMPS_IE_ORDER] = order;
return amps_encode_word(&frame, &mobile_station_control_message_word1_a, 1);
return amps_encode_word(&frame, &mobile_station_control_message_word1_a, DEBUG_INFO);
}
static uint64_t amps_encode_mobile_station_control_message_word1_b(uint8_t scc, uint8_t pscc, uint8_t dtx, uint8_t pvi, uint8_t mem, uint8_t vmac, uint16_t chan)
@ -3017,38 +3016,7 @@ static uint64_t amps_encode_mobile_station_control_message_word1_b(uint8_t scc,
frame.ie[AMPS_IE_MEM] = mem;
frame.ie[AMPS_IE_VMAC] = vmac;
frame.ie[AMPS_IE_CHAN] = chan;
return amps_encode_word(&frame, &mobile_station_control_message_word1_b, 1);
}
static uint64_t amps_encode_word2_first_alert_with_info_word(uint8_t rl_w, uint8_t signal, uint8_t cpn_rl, uint8_t pi, uint8_t si)
{
frame_t frame;
memset(&frame, 0, sizeof(frame));
frame.ie[AMPS_IE_T1T2] = 1;
frame.ie[AMPS_IE_RL_W] = rl_w;
frame.ie[AMPS_IE_SIGNAL] = signal;
frame.ie[AMPS_IE_CPN_RL] = cpn_rl;
frame.ie[AMPS_IE_PI] = pi;
frame.ie[AMPS_IE_SI] = si;
return amps_encode_word(&frame, &word2_first_alert_with_info_word, 1);
}
static uint64_t amps_encode_wordn_n_minus_1th_alert_with_info_word(const char *character)
{
frame_t frame;
memset(&frame, 0, sizeof(frame));
frame.ie[AMPS_IE_T1T2] = 1;
if (character[0]) {
frame.ie[AMPS_IE_CHARACTER_1] = character[0];
if (character[1]) {
frame.ie[AMPS_IE_CHARACTER_2] = character[1];
if (character[2])
frame.ie[AMPS_IE_CHARACTER_3] = character[2];
}
}
return amps_encode_word(&frame, &wordn_n_minus_1th_alert_with_info_word, 1);
return amps_encode_word(&frame, &mobile_station_control_message_word1_b, DEBUG_INFO);
}
/* decoder function of a word */
@ -3377,7 +3345,7 @@ static void amps_encode_focc_bits(uint64_t word_a, uint64_t word_b, char *bits)
memcpy(bits + 0, dotting, 10);
bits[10] = 'i';
memcpy(bits + 11, sync_word, 11);
strcpy(bits + 11, sync_word);
bits[22] = 'i';
k = 23;
for (i = 0; i < 5; i++) {
@ -3397,22 +3365,22 @@ static void amps_encode_focc_bits(uint64_t word_a, uint64_t word_b, char *bits)
if (k != 463)
abort();
bits[k] = '\0';
bits[463] = '\0';
#ifdef BIT_DEBUGGING
if (debuglevel == DEBUG_DEBUG) {
char text[64];
strncpy(text, bits, 23);
text[23] = '\0';
#ifdef BIT_DEBUGGING
PDEBUG(DFRAME, DEBUG_INFO, "TX FOCC: %s\n", text);
for (i = 0; i < 10; i++) {
strncpy(text, bits + 23 + i * 44, 44);
text[44] = '\0';
PDEBUG(DFRAME, DEBUG_DEBUG, " word %c - %s\n", (i & 1) ? 'b' : 'a', text);
}
}
#endif
}
}
static void amps_encode_fvc_bits(uint64_t word_a, char *bits)
@ -3429,15 +3397,15 @@ static void amps_encode_fvc_bits(uint64_t word_a, char *bits)
memcpy(bits + k, dotting, 37);
k += 37;
}
memcpy(bits + k, sync_word, 11);
strcpy(bits + k, sync_word);
k += 11;
for (j = 39; j >= 0; j--)
bits[k++] = ((word_a >> j) & 1) + '0';
}
if (k != 1032)
abort();
bits[k] = '\0';
bits[1032] = '\0';
#ifdef BIT_DEBUGGING
if (debuglevel == DEBUG_DEBUG) {
@ -3449,14 +3417,13 @@ static void amps_encode_fvc_bits(uint64_t word_a, char *bits)
int amps_encode_frame_focc(amps_t *amps, char *bits)
{
uint64_t word;
int debug = !amps->tx_focc_debugged;
/* init overhead train */
if (amps->tx_focc_frame_count == 0)
prepare_sysinfo(&amps->si);
/* send overhead train */
if (amps->si.num) {
word = get_sysinfo(&amps->si, debug);
word = get_sysinfo(&amps->si);
if (++amps->tx_focc_frame_count >= amps->si.overhead_repeat)
amps->tx_focc_frame_count = 0;
goto send;
@ -3507,12 +3474,9 @@ int amps_encode_frame_focc(amps_t *amps, char *bits)
}
/* send filler */
word = amps_encode_control_filler(amps, amps->si.dcc, amps->si.filler.cmac, amps->si.filler.sdcc1, amps->si.filler.sdcc2, amps->si.filler.wfom, debug);
word = amps_encode_control_filler(amps, amps->si.dcc, amps->si.filler.cmac, amps->si.filler.sdcc1, amps->si.filler.sdcc2, amps->si.filler.wfom);
if (++amps->tx_focc_frame_count >= amps->si.overhead_repeat)
amps->tx_focc_frame_count = 0;
if (debug)
PDEBUG_CHAN(DFRAME, DEBUG_INFO, "Subsequent system/filler frames are not show, to prevent flooding the output.\n");
amps->tx_focc_debugged = 1;
send:
amps_encode_focc_bits(word, word, bits);
@ -3533,16 +3497,7 @@ int amps_encode_frame_fvc(amps_t *amps, char *bits)
amps->tx_fvc_ordq = trans->ordq;
amps->tx_fvc_order = trans->order;
amps->tx_fvc_chan = trans->chan;
strncpy(amps->tx_fvc_callerid, trans->caller_id, sizeof(amps->tx_fvc_callerid) - 1);
amps->tx_fvc_callerid_signal = 1;
amps->tx_fvc_callerid_screen = 3;
if (trans->caller_id[0])
amps->tx_fvc_callerid_present = 0;
else
amps->tx_fvc_callerid_signal = 1;
amps->tx_fvc_send = 1;
amps->tx_fvc_word_count = 0;
amps->tx_fvc_word_repeat = 0;
}
/* on change of dsp mode */
if (amps->dsp_mode != DSP_MODE_AUDIO_RX_FRAME_TX)
@ -3551,32 +3506,11 @@ int amps_encode_frame_fvc(amps_t *amps, char *bits)
/* send scheduled mobile control message */
if (amps->tx_fvc_send) {
if (amps->tx_fvc_word_count == 0) {
if (amps->tx_fvc_chan)
word = amps_encode_mobile_station_control_message_word1_b(amps->sat, amps->sat, (amps->si.word2.dtx) ? 1 : 0, 0, 0, amps->si.vmac, amps->tx_fvc_chan);
else
word = amps_encode_mobile_station_control_message_word1_a(amps->sat, amps->tx_fvc_msg_type, amps->tx_fvc_ordq, amps->tx_fvc_order);
/* done, if we don't have ALERTING with info */
if (amps->tx_fvc_order != 17)
amps->tx_fvc_send = 0;
} else if (amps->tx_fvc_word_count == 1) {
int cpn_rl, rl_w;
/* number of characters */
cpn_rl = strlen(amps->tx_fvc_callerid);
/* number of frames that are required to hold number of characters */
rl_w = (cpn_rl + 2) / 3;
word = amps_encode_word2_first_alert_with_info_word(rl_w, amps->tx_fvc_callerid_signal, cpn_rl, amps->tx_fvc_callerid_present, amps->tx_fvc_callerid_screen);
if (cpn_rl == 0)
amps->tx_fvc_send = 0;
} else {
const char *callerid;
/* chunk of caller ID */
callerid = amps->tx_fvc_callerid + (amps->tx_fvc_word_count - 2) * 3;
word = amps_encode_wordn_n_minus_1th_alert_with_info_word(callerid);
if (strlen(callerid) <= 3)
amps->tx_fvc_send = 0;
}
amps->tx_fvc_word_count++;
amps->tx_fvc_send = 0;
if (amps->tx_fvc_chan)
word = amps_encode_mobile_station_control_message_word1_b(amps->sat, amps->sat, (amps->si.word2.dtx) ? 1 : 0, 0, 0, amps->si.vmac, amps->tx_fvc_chan);
else
word = amps_encode_mobile_station_control_message_word1_a(amps->sat, amps->tx_fvc_msg_type, amps->tx_fvc_ordq, amps->tx_fvc_order);
} else
return 1;

View File

@ -211,16 +211,16 @@ typedef struct amps_frame {
} frame_t;
void init_frame(void);
uint64_t amps_encode_word1_system(uint8_t dcc, uint16_t sid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc, int debug);
uint64_t tacs_encode_word1_system(uint8_t dcc, uint16_t aid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc, int debug);
uint64_t amps_encode_word2_system(uint8_t dcc, uint8_t s, uint8_t e, uint8_t regh, uint8_t regr, uint8_t dtx, uint8_t n_1, uint8_t rcf, uint8_t cpa, uint8_t cmax_1, uint8_t end, int debug);
uint64_t amps_encode_registration_id(uint8_t dcc, uint32_t regid, uint8_t end, int debug);
uint64_t amps_encode_registration_increment(uint8_t dcc, uint16_t regincr, uint8_t end, int debug);
uint64_t amps_encode_location_area(uint8_t dcc, uint8_t pureg, uint8_t pdreg, uint8_t lreg, uint16_t locaid, uint8_t end, int debug);
uint64_t amps_encode_new_access_channel_set(uint8_t dcc, uint16_t newacc, uint8_t end, int debug);
uint64_t amps_encode_overload_control(uint8_t dcc, uint8_t *olc, uint8_t end, int debug);
uint64_t amps_encode_access_type(uint8_t dcc, uint8_t bis, uint8_t pci_home, uint8_t pci_roam, uint8_t bspc, uint8_t bscap, uint8_t end, int debug);
uint64_t amps_encode_access_attempt(uint8_t dcc, uint8_t maxbusy_pgr, uint8_t maxsztr_pgr, uint8_t maxbusy_other, uint8_t maxsztr_other, uint8_t end, int debug);
uint64_t amps_encode_word1_system(uint8_t dcc, uint16_t sid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc);
uint64_t tacs_encode_word1_system(uint8_t dcc, uint16_t aid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc);
uint64_t amps_encode_word2_system(uint8_t dcc, uint8_t s, uint8_t e, uint8_t regh, uint8_t regr, uint8_t dtx, uint8_t n_1, uint8_t rcf, uint8_t cpa, uint8_t cmax_1, uint8_t end);
uint64_t amps_encode_registration_id(uint8_t dcc, uint32_t regid, uint8_t end);
uint64_t amps_encode_registration_increment(uint8_t dcc, uint16_t regincr, uint8_t end);
uint64_t amps_encode_location_area(uint8_t dcc, uint8_t pureg, uint8_t pdreg, uint8_t lreg, uint16_t locaid, uint8_t end);
uint64_t amps_encode_new_access_channel_set(uint8_t dcc, uint16_t newacc, uint8_t end);
uint64_t amps_encode_overload_control(uint8_t dcc, uint8_t *olc, uint8_t end);
uint64_t amps_encode_access_type(uint8_t dcc, uint8_t bis, uint8_t pci_home, uint8_t pci_roam, uint8_t bspc, uint8_t bscap, uint8_t end);
uint64_t amps_encode_access_attempt(uint8_t dcc, uint8_t maxbusy_pgr, uint8_t maxsztr_pgr, uint8_t maxbusy_other, uint8_t maxsztr_other, uint8_t end);
int amps_encode_frame_focc(amps_t *amps, char *bits);
int amps_encode_frame_fvc(amps_t *amps, char *bits);
int amps_decode_frame(amps_t *amps, const char *bits, int count, double level, double quality, int negative);

View File

@ -5,16 +5,10 @@
#include "outoforder.h"
#include "invalidnumber.h"
#include "congestion.h"
#include "../libmobile/main_mobile.h"
const int tacs = 0;
const int jtacs = 0;
const struct number_lengths number_lengths[] = {
{ 10, "AMPS number (NPA-XXX-XXXX)" },
{ 0, NULL }
};
const char *number_prefixes[] = {
"1xxxxxxxxxx",
"+1xxxxxxxxxx",

View File

@ -150,7 +150,7 @@ void prepare_sysinfo(amps_si *si)
}
}
uint64_t get_sysinfo(amps_si *si, int debug)
uint64_t get_sysinfo(amps_si *si)
{
int count, nawc, end = 0;
time_t ti = time(NULL);
@ -166,27 +166,27 @@ uint64_t get_sysinfo(amps_si *si, int debug)
case SYSINFO_WORD1:
nawc = si->num - 1;
if (!tacs)
return amps_encode_word1_system(si->dcc, si->word1.sid1, si->word1.ep, si->word1.auth, si->word1.pci, nawc, debug);
return amps_encode_word1_system(si->dcc, si->word1.sid1, si->word1.ep, si->word1.auth, si->word1.pci, nawc);
else
return tacs_encode_word1_system(si->dcc, si->word1.sid1, si->word1.ep, si->word1.auth, si->word1.pci, nawc, debug);
return tacs_encode_word1_system(si->dcc, si->word1.sid1, si->word1.ep, si->word1.auth, si->word1.pci, nawc);
case SYSINFO_WORD2:
return amps_encode_word2_system(si->dcc, si->word2.s, si->word2.e, si->word2.regh, si->word2.regr, si->word2.dtx, si->word2.n_1, si->word2.rcf, si->word2.cpa, si->word2.cmax_1, end, debug);
return amps_encode_word2_system(si->dcc, si->word2.s, si->word2.e, si->word2.regh, si->word2.regr, si->word2.dtx, si->word2.n_1, si->word2.rcf, si->word2.cpa, si->word2.cmax_1, end);
case SYSINFO_REG_ID:
/* use time stamp to generate regid */
si->reg_id.regid = ti & 0xfffff;
return amps_encode_registration_id(si->dcc, si->reg_id.regid, end, debug);
return amps_encode_registration_id(si->dcc, si->reg_id.regid, end);
case SYSINFO_REG_INCR:
return amps_encode_registration_increment(si->dcc, si->reg_incr.regincr, end, debug);
return amps_encode_registration_increment(si->dcc, si->reg_incr.regincr, end);
case SYSINFO_LOC_AREA:
return amps_encode_location_area(si->dcc, si->loc_area.pureg, si->loc_area.pdreg, si->loc_area.lreg, si->loc_area.locaid, end, debug);
return amps_encode_location_area(si->dcc, si->loc_area.pureg, si->loc_area.pdreg, si->loc_area.lreg, si->loc_area.locaid, end);
case SYSINFO_NEW_ACC:
return amps_encode_new_access_channel_set(si->dcc, si->new_acc.newacc, end, debug);
return amps_encode_new_access_channel_set(si->dcc, si->new_acc.newacc, end);
case SYSINFO_OVERLOAD:
return amps_encode_overload_control(si->dcc, si->overload.olc, end, debug);
return amps_encode_overload_control(si->dcc, si->overload.olc, end);
case SYSINFO_ACC_TYPE:
return amps_encode_access_type(si->dcc, si->acc_type.bis, si->acc_type.pci_home, si->acc_type.pci_roam, si->acc_type.bspc, si->acc_type.bscap, end, debug);
return amps_encode_access_type(si->dcc, si->acc_type.bis, si->acc_type.pci_home, si->acc_type.pci_roam, si->acc_type.bspc, si->acc_type.bscap, end);
case SYSINFO_ACC_ATTEMPT:
return amps_encode_access_attempt(si->dcc, si->acc_attempt.maxbusy_pgr, si->acc_attempt.maxsztr_pgr, si->acc_attempt.maxbusy_other, si->acc_attempt.maxsztr_other, end, debug);
return amps_encode_access_attempt(si->dcc, si->acc_attempt.maxbusy_pgr, si->acc_attempt.maxsztr_pgr, si->acc_attempt.maxbusy_other, si->acc_attempt.maxsztr_other, end);
}
fprintf(stderr, "get_sysinfo unknown type, please fix!\n");

View File

@ -112,5 +112,5 @@ typedef struct system_information {
void init_sysinfo(amps_si *si, int cmac, int vmac, int dtx, int dcc, int sid1, int regh, int regr, int pureg, int pdreg, int locaid, int regincr, int bis);
void prepare_sysinfo(amps_si *si);
uint64_t get_sysinfo(amps_si *si, int debug);
uint64_t get_sysinfo(amps_si *si);

View File

@ -37,25 +37,17 @@ static const char *trans_state_name(int state)
case TRANS_REGISTER_ACK_SEND:
return "REGISTER ACK SEND";
case TRANS_CALL_MO_ASSIGN:
return "MO CALL ASSIGNMENT";
return "CALL ASSIGN MOBILE ORIGINATING";
case TRANS_CALL_MO_ASSIGN_SEND:
return "MO CALL ASSIGNMENT SENDING";
case TRANS_CALL_MO_ASSIGN_CONFIRM:
return "MO CALL ASSIGNMENT WAIT CONFIRM";
return "CALL ASSIGN MOBILE ORIGINATING SEND";
case TRANS_CALL_MT_ASSIGN:
return "MT CALL ASSIGNMENT";
return "CALL ASSIGN MOBILE TERMINATING";
case TRANS_CALL_MT_ASSIGN_SEND:
return "MT CALL ASSIGNMENT SENDING";
case TRANS_CALL_MT_ASSIGN_CONFIRM:
return "MT CALL ASSIGNMENT WAIT CONFIRM";
return "CALL ASSIGN MOBILE TERMINATING SEND";
case TRANS_CALL_MT_ALERT:
return "MT CALL ALERT";
return "CALL ALERT MOBILE TERMINATING";
case TRANS_CALL_MT_ALERT_SEND:
return "MT CALL ALERT SENDING";
case TRANS_CALL_MT_ALERT_CONFIRM:
return "MT CALL ALERT WAIT CONFIRM";
case TRANS_CALL_MT_ANSWER_WAIT:
return "MT CALL ANSWER WAIT";
return "CALL ALERT MOBILE TERMINATING SEND";
case TRANS_CALL_REJECT:
return "CALL REJECT";
case TRANS_CALL_REJECT_SEND:
@ -87,15 +79,11 @@ const char *trans_short_state_name(int state)
return "REGISTER";
case TRANS_CALL_MO_ASSIGN:
case TRANS_CALL_MO_ASSIGN_SEND:
case TRANS_CALL_MO_ASSIGN_CONFIRM:
case TRANS_CALL_MT_ASSIGN:
case TRANS_CALL_MT_ASSIGN_SEND:
case TRANS_CALL_MT_ASSIGN_CONFIRM:
return "ASSIGN";
case TRANS_CALL_MT_ALERT:
case TRANS_CALL_MT_ALERT_SEND:
case TRANS_CALL_MT_ALERT_CONFIRM:
case TRANS_CALL_MT_ANSWER_WAIT:
return "ALERT";
case TRANS_CALL_REJECT:
case TRANS_CALL_REJECT_SEND:

View File

@ -5,14 +5,10 @@ enum amps_trans_state {
TRANS_REGISTER_ACK_SEND, /* attach request received, sending ack */
TRANS_CALL_MO_ASSIGN, /* assigning channel, waiting to send */
TRANS_CALL_MO_ASSIGN_SEND, /* assigning channel, sending assignment */
TRANS_CALL_MO_ASSIGN_CONFIRM, /* assignment sent, waiting for confirm (SAT) */
TRANS_CALL_MT_ASSIGN, /* assigning channel, waiting to send */
TRANS_CALL_MT_ASSIGN_SEND, /* assigning channel, sending assignment */
TRANS_CALL_MT_ASSIGN_CONFIRM, /* assignment sent, waiting for confirm (SAT) */
TRANS_CALL_MT_ALERT, /* ringing the phone, waiting to send alert */
TRANS_CALL_MT_ALERT_SEND, /* ringing the phone, sending alert */
TRANS_CALL_MT_ALERT_CONFIRM, /* ringing the phone, signaling tone is received */
TRANS_CALL_MT_ANSWER_WAIT, /* ringing the phone, waiting for the phone to answer */
TRANS_CALL_MT_ALERT, /* ringing the phone, sending alert order until signaling tone is received */
TRANS_CALL_MT_ALERT_SEND, /* ringing the phone, signaling tone is received */
TRANS_CALL_REJECT, /* rejecting channel, waiting to send */
TRANS_CALL_REJECT_SEND, /* rejecting channel, sending reject */
TRANS_CALL, /* active call */
@ -35,8 +31,6 @@ typedef struct transaction {
uint8_t ordq;
uint8_t order;
uint16_t chan; /* channel to assign */
int alert_retry; /* current number of alter order (re)try */
char caller_id[33]; /* id of calling phone */
char dialing[33]; /* number dialed by the phone */
enum amps_trans_state state; /* state of transaction */
struct timer timer; /* for varous timeouts */
@ -53,6 +47,6 @@ transaction_t *search_transaction_number(amps_t *amps, uint32_t min1, uint16_t m
transaction_t *search_transaction_callref(amps_t *amps, int callref);
void trans_new_state(transaction_t *trans, int state);
void amps_flush_other_transactions(amps_t *amps, transaction_t *trans);
void transaction_timeout(void *data);
void transaction_timeout(struct timer *timer);
const char *trans_short_state_name(int state);

View File

@ -27,7 +27,6 @@ anetz_LDADD = \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libsquelch/libsquelch.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfm/libfm.a \

View File

@ -186,7 +186,7 @@ int anetz_init(void)
return 0;
}
static void anetz_timeout(void *data);
static void anetz_timeout(struct timer *timer);
static void anetz_go_idle(anetz_t *anetz);
/* Create transceiver instance and link to a list. */
@ -362,9 +362,9 @@ void anetz_receive_tone(anetz_t *anetz, int tone)
}
/* Timeout handling */
static void anetz_timeout(void *data)
static void anetz_timeout(struct timer *timer)
{
anetz_t *anetz = data;
anetz_t *anetz = (anetz_t *)timer->priv;
switch (anetz->state) {
case ANETZ_ANRUF:
@ -513,7 +513,7 @@ void call_down_release(int callref, __attribute__((unused)) int cause)
}
/* Receive audio from call instance. */
void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_t ssrc, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
anetz_t *anetz;
@ -526,8 +526,11 @@ void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_
if (!sender)
return;
if (anetz->dsp_mode == DSP_MODE_AUDIO)
jitter_save(&anetz->sender.dejitter, samples, count, 1, sequence, timestamp, ssrc);
if (anetz->dsp_mode == DSP_MODE_AUDIO) {
sample_t up[(int)((double)count * anetz->sender.srstate.factor + 0.5) + 10];
count = samplerate_upsample(&anetz->sender.srstate, samples, count, up);
jitter_save(&anetz->sender.dejitter, up, count);
}
}
void call_down_clock(void) {}

View File

@ -357,7 +357,6 @@ static void fsk_tone(anetz_t *anetz, sample_t *samples, int length)
void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length)
{
anetz_t *anetz = (anetz_t *) sender;
int input_num;
memset(power, 1, length);
@ -366,9 +365,7 @@ void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length
memset(samples, 0, length * sizeof(*samples));
break;
case DSP_MODE_AUDIO:
input_num = samplerate_upsample_input_num(&sender->srstate, length);
jitter_load(&sender->dejitter, samples, input_num);
samplerate_upsample(&sender->srstate, samples, input_num, samples, length);
jitter_load(&anetz->sender.dejitter, samples, length);
break;
case DSP_MODE_TONE:
fsk_tone(anetz, samples, length);

View File

@ -23,7 +23,6 @@ bnetz_LDADD = \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libsquelch/libsquelch.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfsk/libfsk.a \

View File

@ -150,7 +150,7 @@ int bnetz_init(void)
return 0;
}
static void bnetz_timeout(void *data);
static void bnetz_timeout(struct timer *timer);
static void bnetz_go_idle(bnetz_t *bnetz);
/* Create transceiver instance and link to a list. */
@ -631,9 +631,9 @@ lets see, if noise will not generate a release signal....
}
/* Timeout handling */
static void bnetz_timeout(void *data)
static void bnetz_timeout(struct timer *timer)
{
bnetz_t *bnetz = data;
bnetz_t *bnetz = (bnetz_t *)timer->priv;
switch (bnetz->state) {
case BNETZ_WAHLABRUF:
@ -816,7 +816,7 @@ void call_down_release(int callref, int __attribute__((unused)) cause)
}
/* Receive audio from call instance. */
void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_t ssrc, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
bnetz_t *bnetz;
@ -831,7 +831,9 @@ void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_
if (bnetz->dsp_mode == DSP_MODE_AUDIO
|| bnetz->dsp_mode == DSP_MODE_AUDIO_METER) {
jitter_save(&bnetz->sender.dejitter, samples, count, 1, sequence, timestamp, ssrc);
sample_t up[(int)((double)count * bnetz->sender.srstate.factor + 0.5) + 10];
count = samplerate_upsample(&bnetz->sender.srstate, samples, count, up);
jitter_save(&bnetz->sender.dejitter, up, count);
}
}

View File

@ -361,7 +361,7 @@ static void metering_tone(bnetz_t *bnetz, sample_t *samples, int length)
void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length)
{
bnetz_t *bnetz = (bnetz_t *) sender;
int count, input_num;
int count;
memset(power, 1, length);
@ -372,9 +372,7 @@ again:
break;
case DSP_MODE_AUDIO:
case DSP_MODE_AUDIO_METER:
input_num = samplerate_upsample_input_num(&sender->srstate, length);
jitter_load(&sender->dejitter, samples, input_num);
samplerate_upsample(&sender->srstate, samples, input_num, samples, length);
jitter_load(&bnetz->sender.dejitter, samples, length);
if (bnetz->dsp_mode == DSP_MODE_AUDIO_METER)
metering_tone(bnetz, samples, length);
break;
@ -420,7 +418,7 @@ void bnetz_set_dsp_mode(bnetz_t *bnetz, enum dsp_mode mode)
/* reset telegramm */
if (mode == DSP_MODE_TELEGRAMM && bnetz->dsp_mode != mode) {
bnetz->tx_telegramm = 0;
fsk_mod_reset(&bnetz->fsk_mod);
fsk_mod_tx_reset(&bnetz->fsk_mod);
}
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "DSP mode %s -> %s\n", bnetz_dsp_mode_name(bnetz->dsp_mode), bnetz_dsp_mode_name(mode));

View File

@ -31,7 +31,6 @@ cnetz_LDADD = \
$(top_builddir)/src/libcompandor/libcompandor.a \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libscrambler/libscrambler.a \
$(top_builddir)/src/libemphasis/libemphasis.a \

View File

@ -159,12 +159,6 @@
#define CUT_OFF_EMPHASIS_CNETZ 796.0 /* 200 uS time constant */
/* OgK list of alternative channels, NOT including 131 */
cnetz_t *ogk_list[16];
int ogk_list_count = 0;
int ogk_list_index = 0;
/* Convert channel number to frequency number of base station.
Set 'unterband' to 1 to get frequency of mobile station. */
double cnetz_kanal2freq(int kanal, int unterband)
@ -292,38 +286,42 @@ int cnetz_init(void)
}
/* Create transceiver instance and link to a list. */
int cnetz_create(const char *kanal_name, enum cnetz_chan_type chan_type, const char *device, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, double tx_gain, int challenge_valid, uint64_t challenge, int response_valid, uint64_t response, int warteschlange, int metering, double speech_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback)
int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *device, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, double tx_gain, int challenge_valid, uint64_t challenge, int response_valid, uint64_t response, int warteschlange, int metering, double speech_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback)
{
sender_t *sender;
cnetz_t *cnetz;
int kanal;
int rc;
kanal = atoi(kanal_name);
if ((kanal & 1) && (kanal < 3 || kanal > 1147)) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Channel ('Kanal') number %d invalid. For odd channel numbers, use channel 3 ... 1147.\n", kanal);
if ((atoi(kanal) & 1) && (atoi(kanal) < 3 || atoi(kanal) > 1147)) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Channel ('Kanal') number %s invalid. For odd channel numbers, use channel 3 ... 1147.\n", kanal);
return -EINVAL;
}
if ((kanal & 1) && kanal > 947) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "You defined an extended frequency channel %d, only newer phones support this!\n", kanal);
if ((atoi(kanal) & 1) && atoi(kanal) > 947) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "You defined an extended frequency channel %s, only newer phones support this!\n", kanal);
}
if (!(kanal & 1) && (kanal < 4 || kanal > 918)) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Channel ('Kanal') number %d invalid. For even channel numbers, use channel 4 ... 918.\n", kanal);
if (!(atoi(kanal) & 1) && (atoi(kanal) < 4 || atoi(kanal) > 918)) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Channel ('Kanal') number %s invalid. For even channel numbers, use channel 4 ... 918.\n", kanal);
return -EINVAL;
}
if (!(kanal & 1) && kanal > 758) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "You defined an extended frequency channel %d, only newer phones support this!\n", kanal);
if (!(atoi(kanal) & 1) && atoi(kanal) > 758) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "You defined an extended frequency %s, only newer phones support this!\n", kanal);
}
/* OgK must be on channel 131 */
if ((chan_type == CHAN_TYPE_OGK || chan_type == CHAN_TYPE_OGK_SPK) && atoi(kanal) != CNETZ_OGK_KANAL) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "You must use channel %d for calling channel ('Orga-Kanal') or for combined calling + traffic channel!\n", CNETZ_OGK_KANAL);
return -EINVAL;
}
/* SpK must be on channel other than 131 */
if (chan_type == CHAN_TYPE_SPK && kanal == CNETZ_STD_OGK_KANAL) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "You must not use channel %d for traffic channel!\n", CNETZ_STD_OGK_KANAL);
if (chan_type == CHAN_TYPE_SPK && atoi(kanal) == CNETZ_OGK_KANAL) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "You must not use channel %d for traffic channel!\n", CNETZ_OGK_KANAL);
return -EINVAL;
}
/* warn if we combine SpK and OgK, this is not supported by standard */
if (chan_type == CHAN_TYPE_OGK_SPK) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "You selected channel %d ('Orga-Kanal') for combined control + traffic channel. Some phones will reject this.\n", kanal);
PDEBUG(DCNETZ, DEBUG_NOTICE, "You selected channel %d ('Orga-Kanal') for combined calling + traffic channel. Some phones will reject this.\n", CNETZ_OGK_KANAL);
}
for (sender = sender_head; sender; sender = sender->next) {
@ -340,21 +338,11 @@ int cnetz_create(const char *kanal_name, enum cnetz_chan_type chan_type, const c
return -ENOMEM;
}
PDEBUG(DCNETZ, DEBUG_DEBUG, "Creating 'C-Netz' instance for 'Kanal' = %d (sample rate %d).\n", kanal, samplerate);
cnetz->kanal = kanal;
if ((chan_type == CHAN_TYPE_OGK || chan_type == CHAN_TYPE_OGK_SPK) && kanal != CNETZ_STD_OGK_KANAL) {
if (ogk_list_count == 16) {
PDEBUG(DCNETZ, DEBUG_ERROR, "No more than 16 non-standard OGK are allowed!\n");
rc = -EINVAL;
goto error;
}
ogk_list[ogk_list_count++] = cnetz;
}
PDEBUG(DCNETZ, DEBUG_DEBUG, "Creating 'C-Netz' instance for 'Kanal' = %s (sample rate %d).\n", kanal, samplerate);
/* init general part of transceiver */
/* do not enable emphasis, since it is done by cnetz code, not by common sender code */
rc = sender_create(&cnetz->sender, kanal_name, cnetz_kanal2freq(kanal, 0), cnetz_kanal2freq(kanal, 1), device, use_sdr, samplerate, rx_gain, tx_gain, 0, 0, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback, PAGING_SIGNAL_NONE);
rc = sender_create(&cnetz->sender, kanal, cnetz_kanal2freq(atoi(kanal), 0), cnetz_kanal2freq(atoi(kanal), 1), device, use_sdr, samplerate, rx_gain, tx_gain, 0, 0, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback, PAGING_SIGNAL_NONE);
if (rc < 0) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to init transceiver process!\n");
goto error;
@ -415,13 +403,13 @@ int cnetz_create(const char *kanal_name, enum cnetz_chan_type chan_type, const c
cnetz_go_idle(cnetz);
#ifdef DEBUG_SPK
transaction_t *trans = create_transaction(cnetz, TRANS_DS, 2, 2, 22002, -1, -1, NAN);
transaction_t *trans = create_transaction(cnetz, TRANS_DS, 2, 2, 22002, -1, -1);
trans->mo_call = 1;
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, (cnetz->sched_ts + 2) & 31);
#else
/* create transaction for speech channel loopback */
if (loopback && chan_type == CHAN_TYPE_SPK) {
transaction_t *trans = create_transaction(cnetz, TRANS_VHQ_K, 2, 2, 22002, -1, -1, NAN);
transaction_t *trans = create_transaction(cnetz, TRANS_VHQ_K, 2, 2, 22002, -1, -1);
trans->mo_call = 1;
cnetz_set_dsp_mode(cnetz, DSP_MODE_SPK_K);
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, (cnetz->sched_ts + 1) & 31);
@ -431,23 +419,23 @@ int cnetz_create(const char *kanal_name, enum cnetz_chan_type chan_type, const c
#if 0
/* debug flushing transactions */
transaction_t *trans1, *trans2;
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1, NAN);
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
destroy_transaction(trans1);
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1, NAN);
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
destroy_transaction(trans1);
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1, NAN);
trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1, NAN);
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1);
unlink_transaction(trans1);
link_transaction(trans1, cnetz);
cnetz_flush_other_transactions(cnetz, trans1);
trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1, NAN);
trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1);
cnetz_flush_other_transactions(cnetz, trans2);
#endif
PDEBUG(DCNETZ, DEBUG_NOTICE, "Created 'Kanal' #%d of type '%s' = %s\n", kanal, chan_type_short_name(chan_type), chan_type_long_name(chan_type));
const char *name, *long_name;
name = get_station_name(si.fuz_nat, si.fuz_fuvst, si.fuz_rest, &long_name);
PDEBUG(DCNETZ, DEBUG_NOTICE, " -> Using cell ID: Nat=%d FuVst=%d Rest=%d Name='%s' Long Name='%s'\n", si.fuz_nat, si.fuz_fuvst, si.fuz_rest, name, long_name);
PDEBUG(DCNETZ, DEBUG_NOTICE, "Created 'Kanal' #%s of type '%s' = %s\n", kanal, chan_type_short_name(chan_type), chan_type_long_name(chan_type));
const char *name, *station;
name = get_station_name(si.fuz_nat, si.fuz_fuvst, si.fuz_rest, &station);
PDEBUG(DNMT, DEBUG_NOTICE, " -> Using cell ID: Nat=%d FuVst=%d Rest=%d Name='%s' (%s)\n", si.fuz_nat, si.fuz_fuvst, si.fuz_rest, name, station);
return 0;
@ -485,9 +473,9 @@ static cnetz_t *search_free_spk(int extended)
cnetz = (cnetz_t *) sender;
/* ignore extended frequency, if not supported */
if (!extended) {
if ((cnetz->kanal & 1) && cnetz->kanal > 947)
if ((atoi(sender->kanal) & 1) && atoi(sender->kanal) > 947)
continue;
if (!(cnetz->kanal & 1) && cnetz->kanal > 758)
if (!(atoi(sender->kanal) & 1) && atoi(sender->kanal) > 758)
continue;
}
/* ignore busy channel */
@ -504,7 +492,7 @@ static cnetz_t *search_free_spk(int extended)
return ogk_spk;
}
static cnetz_t *search_ogk(int kanal)
static cnetz_t *search_ogk(void)
{
sender_t *sender;
cnetz_t *cnetz;
@ -514,8 +502,6 @@ static cnetz_t *search_ogk(int kanal)
/* ignore busy channel */
if (cnetz->state != CNETZ_IDLE)
continue;
if (cnetz->kanal != kanal)
continue;
if (cnetz->chan_type == CHAN_TYPE_OGK)
return cnetz;
if (cnetz->chan_type == CHAN_TYPE_OGK_SPK)
@ -528,6 +514,7 @@ static cnetz_t *search_ogk(int kanal)
/* Abort connection, if any and send idle broadcast */
void cnetz_go_idle(cnetz_t *cnetz)
{
cnetz_t *ogk;
transaction_t *trans;
if (cnetz->state == CNETZ_IDLE)
@ -542,26 +529,25 @@ void cnetz_go_idle(cnetz_t *cnetz)
PDEBUG(DCNETZ, DEBUG_INFO, "Entering IDLE state on channel %s.\n", cnetz->sender.kanal);
cnetz_new_state(cnetz, CNETZ_IDLE);
cnetz->sched_lr_debugged = 0;
cnetz->sched_mlr_debugged = 0;
/* set scheduler to OgK or turn off SpK */
if (cnetz->dsp_mode == DSP_MODE_SPK_K || cnetz->dsp_mode == DSP_MODE_SPK_V) {
/* switch next frame after distributed signaling boundary (multiple of 8 slots) */
cnetz_set_sched_dsp_mode(cnetz, (cnetz->chan_type == CHAN_TYPE_OGK || cnetz->chan_type == CHAN_TYPE_OGK_SPK) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 8) & 24);
cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 8) & 24);
} else {
/* switch next frame */
cnetz_set_sched_dsp_mode(cnetz, (cnetz->chan_type == CHAN_TYPE_OGK || cnetz->chan_type == CHAN_TYPE_OGK_SPK) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 1) & 31);
cnetz_set_dsp_mode(cnetz, (cnetz->chan_type == CHAN_TYPE_OGK || cnetz->chan_type == CHAN_TYPE_OGK_SPK) ? DSP_MODE_OGK : DSP_MODE_OFF);
cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 1) & 31);
cnetz_set_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF);
}
/* check for first phone in queue and trigger completion of call (becoming idle means that SpK is now available) */
trans = search_transaction_queue();
ogk = search_ogk();
trans = search_transaction(ogk, TRANS_MT_QUEUE | TRANS_MO_QUEUE);
if (trans) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Now channel is available for queued subscriber '%s'.\n", transaction2rufnummer(trans));
PDEBUG(DCNETZ, DEBUG_NOTICE, "Now channel available for queued subscriber '%s'.\n", transaction2rufnummer(trans));
trans_new_state(trans, (trans->state == TRANS_MT_QUEUE) ? TRANS_MT_DELAY : TRANS_MO_DELAY);
timer_stop(&trans->timer);
timer_start(&trans->timer, 3.0); /* Wait at least one frame cycles until timeout */
timer_start(&trans->timer, 2.0);
}
}
@ -576,7 +562,7 @@ static void cnetz_release(transaction_t *trans, uint8_t cause)
}
/* Receive audio from call instance. */
void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_t ssrc, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
cnetz_t *cnetz;
@ -591,7 +577,7 @@ void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_
if (cnetz->dsp_mode == DSP_MODE_SPK_V) {
/* store as is, since we convert rate when processing FSK frames */
jitter_save(&cnetz->sender.dejitter, samples, count, 1, sequence, timestamp, ssrc);
jitter_save(&cnetz->sender.dejitter, samples, count);
}
}
@ -599,14 +585,14 @@ void call_down_clock(void) {}
int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
{
cnetz_t *ogk, *spk;
sender_t *sender;
cnetz_t *cnetz, *spk;
int rc;
int extended;
transaction_t *trans;
uint8_t futln_nat;
uint8_t futln_fuvst;
int futln_rest; /* use int for checking size > 65535 */
int ogk_kanal;
/* 1. split number into elements */
futln_nat = dialing[0] - '0';
@ -619,22 +605,28 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
}
/* 2. check if the subscriber is attached */
rc = find_db(futln_nat, futln_fuvst, futln_rest, &ogk_kanal, NULL, &extended);
rc = find_db(futln_nat, futln_fuvst, futln_rest, NULL, &extended);
if (rc < 0) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call to not attached subscriber, rejecting!\n");
return -CAUSE_OUTOFORDER;
}
/* 3. check if given number is already in a call, return BUSY */
trans = search_transaction_number_global(futln_nat, futln_fuvst, futln_rest);
if (trans) {
for (sender = sender_head; sender; sender = sender->next) {
cnetz = (cnetz_t *) sender;
/* search transaction for this number */
trans = search_transaction_number(cnetz, futln_nat, futln_fuvst, futln_rest);
if (trans)
break;
}
if (sender) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call to busy number, rejecting!\n");
return -CAUSE_BUSY;
}
/* 4. check if we have no OgK, return NOCHANNEL */
ogk = search_ogk(ogk_kanal);
if (!ogk) {
cnetz = search_ogk();
if (!cnetz) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call, but OgK is currently busy, rejecting!\n");
return -CAUSE_NOCHANNEL;
}
@ -642,17 +634,17 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
/* 5. check if all senders are busy, return NOCHANNEL */
spk = search_free_spk(extended);
if (!spk) {
if (!ogk->warteschlange) {
if (!cnetz->warteschlange) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call, but no free channel, rejecting!\n");
return -CAUSE_NOCHANNEL;
} else
PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call, but no free channel, queuing call!\n");
}
PDEBUG(DCNETZ, DEBUG_INFO, "Call to mobile station, paging station id '%s'\n", dialing);
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Call to mobile station, paging station id '%s'\n", dialing);
/* 6. trying to page mobile station */
trans = create_transaction(ogk, (spk) ? TRANS_VAK : TRANS_WSK, futln_nat, futln_fuvst, futln_rest, -1, -1, NAN);
trans = create_transaction(cnetz, (spk) ? TRANS_VAK : TRANS_WSK, futln_nat, futln_fuvst, futln_rest, -1, -1);
if (!trans) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
return -CAUSE_TEMPFAIL;
@ -758,17 +750,17 @@ void call_down_release(int callref, int cause)
}
}
int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal)
int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest)
{
cnetz_t *cnetz;
transaction_t *trans;
cnetz = search_ogk(ogk_kanal);
cnetz = search_ogk();
if (!cnetz) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "'Meldeaufruf', but OgK is currently busy!\n");
return -CAUSE_NOCHANNEL;
}
trans = create_transaction(cnetz, TRANS_MA, futln_nat, futln_fuvst, futln_rest, -1, -1, NAN);
trans = create_transaction(cnetz, TRANS_MA, futln_nat, futln_fuvst, futln_rest, -1, -1);
if (!trans) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
return -CAUSE_TEMPFAIL;
@ -835,12 +827,21 @@ const char *chan_type_long_name(enum cnetz_chan_type chan_type)
}
/* Timeout handling */
void transaction_timeout(void *data)
void transaction_timeout(struct timer *timer)
{
transaction_t *trans = data;
transaction_t *trans = (transaction_t *)timer->priv;
cnetz_t *cnetz = trans->cnetz;
switch (trans->state) {
case TRANS_WAF:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after dialing request 'Wahlaufforderung'\n");
if (trans->try == N) {
trans_new_state(trans, TRANS_WBN);
break;
}
trans->try++;
trans_new_state(trans, TRANS_VWG);
break;
case TRANS_MT_QUEUE:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Phone in queue, but still no channel available, releasing call!\n");
call_up_release(trans->callref, CAUSE_NOCHANNEL);
@ -908,6 +909,12 @@ void transaction_timeout(void *data)
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_MFT:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after keepalive order 'Meldeaufruf'\n");
/* no response to availability check */
trans->page_failed = 1;
destroy_transaction(trans);
break;
default:
PDEBUG_CHAN(DCNETZ, DEBUG_ERROR, "Timeout unhandled in state %" PRIu64 "\n", trans->state);
}
@ -977,7 +984,6 @@ const telegramm_t *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz)
telegramm.fuz_fuvst_nr = si.fuz_fuvst;
telegramm.fuz_rest_nr = si.fuz_rest;
telegramm.kennung_fufst = si.kennung_fufst;
telegramm.bahn_bs = si.bahn_bs;
telegramm.nachbarschafts_prioritaets_bit = si.nachbar_prio;
telegramm.bewertung_nach_pegel_und_entfernung = si.bewertung;
telegramm.entfernungsangabe_der_fufst = si.entfernung;
@ -986,7 +992,7 @@ const telegramm_t *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz)
telegramm.grenzwert_fuer_umschalten = si.grenz_umschalten;
telegramm.grenze_fuer_ausloesen = si.grenz_ausloesen;
trans = search_transaction(cnetz, TRANS_EM | TRANS_UM | TRANS_WBN | TRANS_WBP | TRANS_VAG | TRANS_VAK | TRANS_ATQ | TRANS_ATQ_IDLE | TRANS_VA | TRANS_WSK);
trans = search_transaction(cnetz, TRANS_EM | TRANS_UM | TRANS_WBN | TRANS_WBP | TRANS_VAG | TRANS_VAK | TRANS_ATQ | TRANS_VA | TRANS_WSK);
if (trans) {
telegramm.futln_nationalitaet = trans->futln_nat;
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
@ -1051,14 +1057,14 @@ vak:
break;
}
if (spk == cnetz) {
PDEBUG(DCNETZ, DEBUG_INFO, "Staying on combined control + traffic channel %s\n", spk->sender.kanal);
PDEBUG(DCNETZ, DEBUG_INFO, "Staying on combined calling + traffic channel %s\n", spk->sender.kanal);
} else {
PDEBUG(DCNETZ, DEBUG_INFO, "Assigning phone to traffic channel %s\n", spk->sender.kanal);
/* sync RX time to current OgK time */
fsk_copy_sync(&spk->fsk_demod, &cnetz->fsk_demod);
}
/* set channel */
telegramm.frequenz_nr = spk->kanal;
telegramm.frequenz_nr = atoi(spk->sender.kanal);
/* change state to busy */
cnetz_new_state(spk, CNETZ_BUSY);
/* schedule switching two slots ahead */
@ -1070,7 +1076,6 @@ vak:
cnetz_flush_other_transactions(spk, trans);
break;
case TRANS_ATQ:
case TRANS_ATQ_IDLE:
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledgment 'Quittung fuer Ausloesen des FuTelG im OgK-Betrieb' to release request.\n");
telegramm.opcode = OPCODE_ATQ_R;
destroy_transaction(trans);
@ -1109,32 +1114,15 @@ const telegramm_t *cnetz_transmit_telegramm_meldeblock(cnetz_t *cnetz)
memset(&telegramm, 0, sizeof(telegramm));
telegramm.opcode = OPCODE_MLR_M;
telegramm.max_sendeleistung = cnetz_power2bits(cnetz->ms_power);
telegramm.ogk_verkehrsanteil = 0; /* must be 0 or some phone might not respond to messages in different slots */
telegramm.ogk_verkehrsanteil = 0; /* must be 0 or phone might not respond to messages in different slot */
telegramm.teilnehmergruppensperre = si.teilnehmergruppensperre;
telegramm.anzahl_gesperrter_teilnehmergruppen = si.anzahl_gesperrter_teilnehmergruppen;
if (ogk_list_count) {
/* if we have alternative OGKs, we cycle through the list and indicate their channels */
telegramm.ogk_vorschlag = ogk_list[ogk_list_index]->kanal;
if (++ogk_list_index == ogk_list_count)
ogk_list_index = 0;
} else
telegramm.ogk_vorschlag = CNETZ_STD_OGK_KANAL;
telegramm.ogk_vorschlag = CNETZ_OGK_KANAL;
telegramm.fuz_rest_nr = si.fuz_rest;
next_candidate:
trans = search_transaction(cnetz, TRANS_VWG | TRANS_WAF | TRANS_MA | TRANS_MFT);
trans = search_transaction(cnetz, TRANS_VWG | TRANS_MA);
if (trans) {
switch (trans->state) {
case TRANS_WAF:
/* no response to dial request (try again or drop connection) */
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after dialing request 'Wahlaufforderung'\n");
if (trans->try == N) {
trans_new_state(trans, TRANS_WBN);
goto next_candidate;
}
trans->try++;
trans_new_state(trans, TRANS_VWG);
/* FALLTHRU */
case TRANS_VWG:
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledgment 'Wahlaufforderung' to outging call\n");
telegramm.opcode = OPCODE_WAF_M;
@ -1142,6 +1130,7 @@ next_candidate:
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
trans_new_state(trans, TRANS_WAF);
timer_start(&trans->timer, 1.0); /* Wait two slot cycles until resending */
break;
case TRANS_MA:
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending keepalive request 'Meldeaufruf'\n");
@ -1150,13 +1139,8 @@ next_candidate:
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
trans_new_state(trans, TRANS_MFT);
timer_start(&trans->timer, 1.0); /* Wait two slot cycles until timeout */
break;
case TRANS_MFT:
/* no response to availability check */
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after keepalive order 'Meldeaufruf'\n");
trans->page_failed = 1;
destroy_transaction(trans);
goto next_candidate;
default:
; /* MLR */
}
@ -1187,12 +1171,11 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Attachment from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
break;
}
trans = create_transaction(cnetz, TRANS_EM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit, cnetz->rf_level_db);
trans = create_transaction(cnetz, TRANS_EM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit);
if (!trans) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
break;
}
cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
valid_frame = 1;
break;
case OPCODE_UM_R:
@ -1209,12 +1192,11 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Roaming from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
break;
}
trans = create_transaction(cnetz, TRANS_UM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit, cnetz->rf_level_db);
trans = create_transaction(cnetz, TRANS_UM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit);
if (!trans) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
break;
}
cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
valid_frame = 1;
break;
case OPCODE_UWG_R:
@ -1226,33 +1208,29 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
break;
case OPCODE_VWG_R:
case OPCODE_SRG_R:
case OPCODE_NUG_R:
if (!match_fuz(telegramm))
break;
rufnummer = telegramm2rufnummer(telegramm);
if (opcode == OPCODE_VWG_R)
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received outgoing Call 'Verbindungswunsch gehend' message from Subscriber '%s'\n", rufnummer);
else if (opcode == OPCODE_SRG_R)
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received outgoing emergency Call 'Sonderruf gehend' message from Subscriber '%s'\n", rufnummer);
else
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received outgoing Call 'Verbindungswunsch gehend bei Nachbarschaftsunterstuetzung' message from Subscriber '%s'\n", rufnummer);
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received outgoing emergency Call 'Sonderruf gehend' message from Subscriber '%s'\n", rufnummer);
if (cnetz->state != CNETZ_IDLE) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Call from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
break;
}
trans = create_transaction(cnetz, TRANS_VWG, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, telegramm->erweitertes_frequenzbandbit, cnetz->rf_level_db);
trans = create_transaction(cnetz, TRANS_VWG, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, telegramm->erweitertes_frequenzbandbit);
if (!trans) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
break;
}
cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
trans->try = 1;
valid_frame = 1;
break;
case OPCODE_WUE_M:
trans = search_transaction(cnetz, TRANS_WAF | TRANS_WBP | TRANS_VAG | TRANS_MO_QUEUE);
if (!trans) {
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received dialing digits 'Wahluebertragung' message without transaction (on this OgK), ignoring!\n");
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received dialing digits 'Wahluebertragung' message without transaction, ignoring!\n");
break;
}
rufnummer = transaction2rufnummer(trans);
@ -1268,30 +1246,17 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
break;
rufnummer = telegramm2rufnummer(telegramm);
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received release 'Ausloesen des FuTelG im OgK-Betrieb bei WS' message from Subscriber '%s'\n", rufnummer);
trans = search_transaction_number_global(telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
trans = search_transaction_number(cnetz, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
if (!trans) {
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "There is no transaction, so we assume that the phone did not receive previous release.\n");
/* create transaction, in case the phone repeats the release after we have acked it */
trans = create_transaction(cnetz, TRANS_ATQ_IDLE, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, -1, cnetz->rf_level_db);
trans = create_transaction(cnetz, TRANS_ATQ, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, -1);
if (!trans) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
break;
}
cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
} else {
if (cnetz == trans->cnetz) {
timer_stop(&trans->timer);
trans_new_state(trans, TRANS_ATQ);
} else
if (trans->state == TRANS_ATQ_IDLE) {
trans = create_transaction(cnetz, TRANS_ATQ_IDLE, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, -1, cnetz->rf_level_db);
if (!trans) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
break;
}
cnetz = trans->cnetz; /* cnetz may change, due to stronger reception on different OgK */
} else
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received release 'Ausloesen des FuTelG im OgK-Betrieb bei WS' message without transaction (on this OgK), ignoring!\n");
timer_stop(&trans->timer);
trans_new_state(trans, TRANS_ATQ);
}
valid_frame = 1;
break;
@ -1300,7 +1265,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
break;
trans = search_transaction_number(cnetz, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
if (!trans) {
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received acknowledge 'Meldung Funktelefonteilnehmer' message without transaction (on this OgK), ignoring!\n");
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received acknowledge 'Meldung Funktelefonteilnehmer' message without transaction, ignoring!\n");
break;
}
rufnummer = transaction2rufnummer(trans);
@ -1330,9 +1295,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
{
static telegramm_t telegramm;
transaction_t *trans = cnetz->trans_list;
int ogk_kanal;
cnetz_t *ogk;
int rc;
if (!trans)
return NULL;
@ -1348,10 +1311,9 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
telegramm.futln_nationalitaet = trans->futln_nat;
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
telegramm.frequenz_nr = cnetz->kanal;
telegramm.frequenz_nr = atoi(cnetz->sender.kanal);
telegramm.bedingte_genauigkeit_der_fufst = si.genauigkeit;
telegramm.zufallszahl = cnetz->challenge;
telegramm.bahn_bs = si.bahn_bs;
switch (trans->state) {
case TRANS_BQ:
@ -1464,15 +1426,9 @@ no_auth:
/* idle channel */
cnetz_go_idle(cnetz);
/* alloc ogk again */
rc = find_db(trans->futln_nat, trans->futln_fuvst, trans->futln_rest, &ogk_kanal, NULL, NULL);
if (rc < 0) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Cannot find subscriber in database anymore, releasing!\n");
goto no_ogk;
}
ogk = search_ogk(ogk_kanal);
ogk = search_ogk();
if (!ogk) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Cannot retry, because currently no OgK available (busy)\n");
no_ogk:
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
if (trans->callref)
call_up_release(trans->callref, CAUSE_NOCHANNEL);
@ -1678,7 +1634,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
telegramm.futln_nationalitaet = trans->futln_nat;
telegramm.futln_heimat_fuvst_nr = trans->futln_fuvst;
telegramm.futln_rest_nr = trans->futln_rest;
telegramm.frequenz_nr = cnetz->kanal;
telegramm.frequenz_nr = atoi(cnetz->sender.kanal);
telegramm.entfernung = si.entfernung;
telegramm.bedingte_genauigkeit_der_fufst = si.genauigkeit;
telegramm.gueltigkeit_des_gebuehrenstandes = 0;

View File

@ -6,7 +6,7 @@ typedef struct cnetz cnetz_t;
#include "fsk_demod.h"
#include "transaction.h"
#define CNETZ_STD_OGK_KANAL 131
#define CNETZ_OGK_KANAL 131
/* dsp modes of transmission */
enum dsp_mode {
@ -66,7 +66,6 @@ struct clock_speed {
/* instance of cnetz sender */
struct cnetz {
sender_t sender;
int kanal; /* channel number */
enum cnetz_chan_type chan_type; /* channel type */
scrambler_t scrambler_tx; /* mirror what we transmit to MS */
scrambler_t scrambler_rx; /* mirror what we receive from MS */
@ -97,12 +96,9 @@ struct cnetz {
int sched_r_m; /* Rufblock (0) / Meldeblock (1) */
enum dsp_mode sched_dsp_mode; /* what mode shall be switched to */
int sched_dsp_mode_ts; /* time slot when to switch mode (-1 = don't switch) */
int sched_lr_debugged; /* indicator to prevent debugging all idle frames */
int sched_mlr_debugged; /* indicator to prevent debugging all idle frames */
/* dsp states */
enum dsp_mode dsp_mode; /* current mode: audio, "Telegramm", .... */
double rf_level_db; /* current RF level or nan, if not applicable */
iir_filter_t lp; /* low pass filter to eliminate noise above 5280 Hz */
fsk_fm_demod_t fsk_demod; /* demod process */
double fsk_deviation; /* deviation of FSK signal on sound card */
@ -127,8 +123,8 @@ struct cnetz {
double frame_last_phase; /* master's bit phase of last frame sync */
/* audio offset removal */
double offset_last; /* last sample value of last frame */
int offset_range; /* range of samples to ramp the offset */
double offset_factor; /* filer alpha of high-pass filter */
double offset_y_last; /* last stored sample */
/* measurements */
int measure_speed; /* measure clock speed */
@ -148,7 +144,7 @@ int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *
void cnetz_destroy(sender_t *sender);
void cnetz_go_idle(cnetz_t *cnetz);
void cnetz_sync_frame(cnetz_t *cnetz, double sync, int ts);
int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal);
int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
const struct telegramm *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz);
const struct telegramm *cnetz_transmit_telegramm_meldeblock(cnetz_t *cnetz);
void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, struct telegramm *telegramm, int block);

View File

@ -25,18 +25,18 @@
#include "../libdebug/debug.h"
#include "cnetz.h"
#include "database.h"
#include "sysinfo.h"
/* the network specs say: check every 1 - 6.5 minutes for availability
* remove from database after 3 subsequent failures
* the phone will register 20 minutes after no call / no paging from network.
*/
#define MELDE_WIEDERHOLUNG 60.0 /* when busy */
#define MELDE_INTERVAL 120.0
#define MELDE_WIEDERHOLUNG 60.0
#define MELDE_MAXIMAL 3
typedef struct cnetz_database {
struct cnetz_database *next;
int ogk_kanal; /* available on which channel */
uint8_t futln_nat; /* who ... */
uint8_t futln_fuvst;
uint16_t futln_rest;
@ -51,17 +51,6 @@ typedef struct cnetz_database {
cnetz_db_t *cnetz_db_head;
static const char *print_meldeaufrufe(int versuche)
{
static char text[32];
if (versuche <= 0)
return "infinite";
sprintf(text, "%d", versuche);
return text;
}
/* destroy transaction */
static void remove_db(cnetz_db_t *db)
{
@ -85,26 +74,26 @@ static void remove_db(cnetz_db_t *db)
}
/* Timeout handling */
static void db_timeout(void *data)
static void db_timeout(struct timer *timer)
{
cnetz_db_t *db = data;
cnetz_db_t *db = (cnetz_db_t *)timer->priv;
int rc;
PDEBUG(DDB, DEBUG_INFO, "Check, if subscriber '%d,%d,%05d' is still available.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
rc = cnetz_meldeaufruf(db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal);
rc = cnetz_meldeaufruf(db->futln_nat, db->futln_fuvst, db->futln_rest);
if (rc < 0) {
/* OgK is used for speech, but this never happens in a real
* network. We just assume that the phone has responded and
* assume we had a response. */
PDEBUG(DDB, DEBUG_INFO, "OgK busy, so we assume a positive response.\n");
timer_start(&db->timer, si.meldeinterval); /* when to check avaiability again */
timer_start(&db->timer, MELDE_INTERVAL); /* when to check avaiability again */
db->retry = 0;
}
}
/* create/update db entry */
int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal, int *futelg_bit, int *extended, int busy, int failed)
int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended, int busy, int failed)
{
cnetz_db_t *db, **dbp;
@ -139,9 +128,6 @@ int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int o
PDEBUG(DDB, DEBUG_INFO, "Adding subscriber '%d,%d,%05d' to database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
}
if (ogk_kanal)
db->ogk_kanal = ogk_kanal;
if (futelg_bit && *futelg_bit >= 0)
db->futelg_bit = *futelg_bit;
@ -150,23 +136,23 @@ int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int o
db->busy = busy;
if (busy) {
PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%05d' on OGK channel #%d is busy now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal);
PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%05d' busy now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
timer_stop(&db->timer);
} else if (!failed) {
PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%05d' on OGK channel #%d is idle now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal);
timer_start(&db->timer, si.meldeinterval); /* when to check avaiability (again) */
PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%05d' idle now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
timer_start(&db->timer, MELDE_INTERVAL); /* when to check avaiability (again) */
db->retry = 0;
db->eingebucht = 1;
db->last_seen = get_time();
} else {
db->retry++;
PDEBUG(DDB, DEBUG_NOTICE, "Paging subscriber '%d,%d,%05d' on OGK channel #%d failed (try %d of %s).\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->ogk_kanal, db->retry, print_meldeaufrufe(si.meldeaufrufe));
if (si.meldeaufrufe && db->retry == si.meldeaufrufe) {
PDEBUG(DDB, DEBUG_NOTICE, "Paging subscriber '%d,%d,%05d' failed (try %d of %d).\n", db->futln_nat, db->futln_fuvst, db->futln_rest, db->retry, MELDE_MAXIMAL);
if (db->retry == MELDE_MAXIMAL) {
PDEBUG(DDB, DEBUG_INFO, "Marking subscriber as gone.\n");
db->eingebucht = 0;
return db->extended;
}
timer_start(&db->timer, (si.meldeinterval < MELDE_WIEDERHOLUNG) ? si.meldeinterval : MELDE_WIEDERHOLUNG); /* when to do retry */
timer_start(&db->timer, MELDE_WIEDERHOLUNG); /* when to do retry */
}
if (futelg_bit)
@ -176,7 +162,7 @@ int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int o
return 0;
}
int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *ogk_kanal, int *futelg_bit, int *extended)
int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended)
{
cnetz_db_t *db = cnetz_db_head;
@ -185,8 +171,6 @@ int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *og
&& db->futln_nat == futln_nat
&& db->futln_fuvst == futln_fuvst
&& db->futln_rest == futln_rest) {
if (ogk_kanal)
*ogk_kanal = db->ogk_kanal;
if (futelg_bit)
*futelg_bit = db->futelg_bit;
if (extended)
@ -209,7 +193,6 @@ void dump_db(void)
cnetz_db_t *db = cnetz_db_head;
double now = get_time();
int last;
char attached[16];
PDEBUG(DDB, DEBUG_NOTICE, "Dump of subscriber database:\n");
if (!db) {
@ -221,8 +204,7 @@ void dump_db(void)
PDEBUG(DDB, DEBUG_NOTICE, "-------------------------------------------------------------------------------\n");
while (db) {
last = (db->busy) ? 0 : (uint32_t)(now - db->last_seen);
sprintf(attached, "YES (OGK %d)", db->ogk_kanal);
PDEBUG(DDB, DEBUG_NOTICE, "%d,%d,%05d\t%s\t%s\t\t%02d:%02d:%02d \t%d/%s\n", db->futln_nat, db->futln_fuvst, db->futln_rest, (db->eingebucht) ? attached : "-no-\t", (db->busy) ? "YES" : "-no-", last / 3600, (last / 60) % 60, last % 60, db->retry, print_meldeaufrufe(si.meldeaufrufe));
PDEBUG(DDB, DEBUG_NOTICE, "%d,%d,%05d\t%s\t\t%s\t\t%02d:%02d:%02d \t%d/%d\n", db->futln_nat, db->futln_fuvst, db->futln_rest, (db->eingebucht) ? "YES" : "-no-", (db->busy) ? "YES" : "-no-", last / 3600, (last / 60) % 60, last % 60, db->retry, MELDE_MAXIMAL);
db = db->next;
}
}

View File

@ -1,6 +1,6 @@
int update_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int ogk_kanal, int *futelg_bit, int *extended, int busy, int failed);
int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *ogk_kanal, int *futelg_bit, int *extended);
int update_db(cnetz_t *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended, int busy, int failed);
int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended);
void flush_db(void);
void dump_db(void);

View File

@ -46,6 +46,7 @@
#define MAX_DISPLAY 1.4 /* something above speech level, no emphasis */
#define BITRATE 5280.0 /* bits per second */
#define BLOCK_BITS 198 /* duration of one time slot including pause at beginning and end */
#define CUT_OFF_OFFSET 300.0 /* cut off frequency for offset filter (level correction between subsequent audio chunks) */
#ifdef TEST_SCRAMBLE
jitter_t scrambler_test_jb;
@ -76,7 +77,6 @@ const char *cnetz_dsp_mode_name(enum dsp_mode mode)
void dsp_init(void)
{
compandor_init();
}
static void dsp_init_ramp(cnetz_t *cnetz)
@ -103,6 +103,7 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
{
int rc = 0;
double size;
double RC, dt;
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init FSK for 'Sender'.\n");
@ -149,7 +150,7 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
}
/* reinit the sample rate to shrink/expand audio */
init_samplerate(&cnetz->sender.srstate, 8000.0, (double)cnetz->sender.samplerate / (1.1 / (1.0 + clock_speed[0] / 1000000.0)), 3300.0); /* 66 <-> 60 */
init_samplerate(&cnetz->sender.srstate, 8000.0, (double)cnetz->sender.samplerate / 1.1, 3300.0); /* 66 <-> 60 */
rc = fsk_fm_init(&cnetz->fsk_demod, cnetz, cnetz->sender.samplerate, (double)BITRATE / (1.0 + clock_speed[0] / 1000000.0), demod);
if (rc < 0)
@ -159,15 +160,23 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
scrambler_setup(&cnetz->scrambler_tx, (double)cnetz->sender.samplerate / 1.1);
scrambler_setup(&cnetz->scrambler_rx, (double)cnetz->sender.samplerate / 1.1);
/* reinit jitter buffer for 8000 kHz */
jitter_destroy(&cnetz->sender.dejitter);
rc = jitter_create(&cnetz->sender.dejitter, 8000 / 5);
if (rc < 0)
goto error;
/* init compandor, according to C-Netz specs, attack and recovery time
* shall not exceed according to ITU G.162 */
setup_compandor(&cnetz->cstate, 8000, 5.0, 22.5);
init_compandor(&cnetz->cstate, 8000, 5.0, 22.5);
/* use duration of one bit to ramp level of last frame to current frame */
cnetz->offset_range = ceil(cnetz->fsk_bitduration);
/* use this filter to compensate level changes between two subsequent audio chunks */
RC = 1.0 / (CUT_OFF_OFFSET * 2.0 *3.14);
dt = 1.0 / cnetz->sender.samplerate;
cnetz->offset_factor = RC / (RC + dt);
#ifdef TEST_SCRAMBLE
rc = jitter_create(&scrambler_test_jb, "scramble", cnetz->sender.samplerate, sizeof(sample_t), JITTER_AUDIO);
rc = jitter_create(&scrambler_test_jb, cnetz->sender.samplerate / 5);
if (rc < 0) {
PDEBUG_CHAN(DDSP, DEBUG_ERROR, "Failed to init jitter buffer for scrambler test!\n");
exit(0);
@ -559,12 +568,10 @@ static int fsk_distributed_encode(cnetz_t *cnetz, const char *bits)
/* decode samples and hut for bit changes
* use deviation to find greatest slope of the signal (bit change)
*/
void sender_receive(sender_t *sender, sample_t *samples, int length, double rf_level_db)
void sender_receive(sender_t *sender, sample_t *samples, int length, double __attribute__((unused)) rf_level_db)
{
cnetz_t *cnetz = (cnetz_t *) sender;
cnetz->rf_level_db = rf_level_db;
/* measure rx sample speed */
calc_clock_speed(cnetz, length, 0, 0);
@ -572,7 +579,7 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double rf_l
#ifdef TEST_UNSCRAMBLE
scrambler(&scrambler_test_scrambler1, samples, length);
#endif
jitter_save(&scrambler_test_jb, samples, length, 0, 0, 0, 0);
jitter_save(&scrambler_test_jb, samples, length);
return;
#endif
@ -593,8 +600,7 @@ static int shrink_speech(cnetz_t *cnetz, sample_t *speech_buffer)
/* 1. compress dynamics */
compress_audio(&cnetz->cstate, speech_buffer, 100);
/* 2. upsample */
speech_length = samplerate_upsample_output_num(&cnetz->sender.srstate, 100);
samplerate_upsample(&cnetz->sender.srstate, speech_buffer, 100, speech_buffer, speech_length);
speech_length = samplerate_upsample(&cnetz->sender.srstate, speech_buffer, 100, speech_buffer);
/* 3. scramble */
if (cnetz->scrambler)
scrambler(&cnetz->scrambler_tx, speech_buffer, speech_length);
@ -662,11 +668,19 @@ again:
switch (cnetz->dsp_mode) {
case DSP_MODE_OGK:
if (((si.timeslots >> cnetz->sched_ts) & 1)) {
/* if automatic polarity selection is used, toggle between
* two polarities (every 4 slots) until a response is received
* then continue to use the time slots of that polarity
*/
if (cnetz->auto_polarity)
cnetz->negative_polarity = (cnetz->sched_ts & 7) >> 2;
/* send on timeslots depending on the polarity:
* positive polarity: ts, ts+8, ts+16, ts+24
* negative polarity: ts+4, ts+12, ts+20, ts+28
*/
if (((cnetz->sched_ts & 7) == (si.timeslot & 7) && cnetz->negative_polarity == 0)
|| ((cnetz->sched_ts & 7) == ((si.timeslot + 4) & 7) && cnetz->negative_polarity == 1)) {
if (cnetz->sched_r_m == 0) {
/* if automatic polarity selection is used, toggle between two polarities (every transmitted slot) until a response is received then continue to use the time slots of that polarity */
if (cnetz->auto_polarity)
cnetz->negative_polarity = (cnetz->sched_ts & 7) >> 2;
/* set last time slot, so we know to which time slot the message from mobile station belongs to */
cnetz->sched_last_ts = cnetz->sched_ts;
bits = cnetz_encode_telegramm(cnetz);
@ -813,8 +827,7 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
{
sample_t *spl;
int pos, i;
int range;
double offset;
double x, y, x_last, y_last, factor;
/* check if we still have a transaction
* this might not be true, if we just released transaction, but still
@ -823,13 +836,21 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
if (!cnetz->trans_list)
return;
/* ramp from level of last frame to level of current frame */
range = cnetz->offset_range;
offset = speech_buffer[0] - cnetz->offset_last;
for (i = 0; i < range; i++) {
speech_buffer[i] -= offset * (1.0 - (double)i / (double)range);
/* fix offset between speech blocks by using high pass filter */
/* use first sample as previous sample, so we don't have a level jump between two subsequent audio chunks */
x_last = speech_buffer[0];
y_last = cnetz->offset_y_last;
factor = cnetz->offset_factor;
for (i = 0; i < count; i++) {
/* change level */
x = speech_buffer[i];
/* high-pass to remove low level frequencies, caused by level jump between audio chunks */
y = factor * (y_last + x - x_last);
x_last = x;
y_last = y;
speech_buffer[i] = y;
}
cnetz->offset_last = speech_buffer[count - 1];
cnetz->offset_y_last = y_last;
/* 4. de-emphasis is done by cnetz code, not by common code */
/* de-emphasis is only used when scrambler is off, see FTZ 171 TR 60 Clause 4 */

View File

@ -121,10 +121,7 @@
* if debug is set to 1, debugging will start at program start
*/
//#define DEBUG_DECODER
#ifdef DEBUG_DECODER
static int debug = 0;
#endif
//static int debug = 0;
#include <stdio.h>
#include <stdint.h>
@ -185,7 +182,7 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
#ifdef DEBUG_DECODER
char debug_filename[256];
sprintf(debug_filename, "/tmp/debug_decoder_channel_%s.txt", cnetz->sender.kanal);
sprintf(debug_filename, "/tmp/debug_decoder_channel_%d.txt", cnetz->sender.kanal);
fsk->debug_fp = fopen(debug_filename, "w");
if (!fsk->debug_fp) {
fprintf(stderr, "Failed to open decoder debug file '%s'!\n", debug_filename);
@ -417,6 +414,17 @@ static inline void find_change_slope(fsk_fm_demod_t *fsk)
sample_t threshold;
int i;
#ifdef DEBUG_DECODER
/* show deviation of middle sample in windows (in a range of bandwidth) */
if (debug) {
fprintf(fsk->debug_fp, "%s",
debug_amplitude(
fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len]
)
);
}
#endif
/* get level range (level_min and level_max) and also
* get maximum slope (change_max) and where it was
* (change_at) and what direction it went (change_positive)
@ -484,6 +492,10 @@ static inline void find_change_slope(fsk_fm_demod_t *fsk)
}
fsk->next_bit -= fsk->bits_per_sample;
#ifdef DEBUG_DECODER
if (debug)
fprintf(fsk->debug_fp, "\n");
#endif
}
/* find bit change by looking at zero crossing */
@ -495,6 +507,12 @@ static inline void find_change_level(fsk_fm_demod_t *fsk)
/* get bit in the middle of the buffer */
s = fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len];
#ifdef DEBUG_DECODER
/* show deviation */
if (debug)
fprintf(fsk->debug_fp, "%s", debug_amplitude(s));
#endif
/* just sample first bit in distributed mode */
if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V && fsk->bit_count == 0) {
if (fmod(fsk->bit_time, BITS_PER_SPK_BLOCK) < 1.5)
@ -551,6 +569,10 @@ static inline void find_change_level(fsk_fm_demod_t *fsk)
fsk->next_bit -= fsk->bits_per_sample;
done:
#ifdef DEBUG_DECODER
if (debug)
fprintf(fsk->debug_fp, "\n");
#endif
return;
}
@ -558,7 +580,7 @@ done:
void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
{
int i;
double t = 0.0;
double t;
/* process signaling block, sample by sample */
for (i = 0; i < length; i++) {
@ -568,14 +590,6 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
if (fsk->bit_buffer_pos == fsk->bit_buffer_len)
fsk->bit_buffer_pos = 0;
#ifdef DEBUG_DECODER
/* show deviation of center sample in window */
if (debug)
fprintf(fsk->debug_fp, "%s", debug_amplitude(fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len]));
if (debug && fmod(fsk->bit_time - fsk->bits_per_sample, 1.0) > fmod(fsk->bit_time, 1.0))
fprintf(fsk->debug_fp, " -bitchange-");
#endif
/* for each sample process buffer */
if (fsk->cnetz->dsp_mode != DSP_MODE_SPK_V) {
if (fsk->demod_type == FSK_DEMOD_SLOPE)
@ -597,7 +611,7 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
fsk->next_bit = 1.0 - fsk->bits_per_sample;
#ifdef DEBUG_DECODER
if (debug && fsk->bit_count)
fprintf(fsk->debug_fp, "\n---- SPK(V) BLOCK START ----");
fprintf(fsk->debug_fp, "---- SPK(V) BLOCK START ----\n");
#endif
fsk->bit_count = 0;
} else
@ -608,21 +622,13 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
find_change_level(fsk);
} else
if (t >= 5.5 && t < 65.5) {
#ifdef DEBUG_DECODER
if (debug && !fsk->speech_count)
fprintf(fsk->debug_fp, " (start recording speech)");
#endif
/* get audio for the duration of 60 bits */
/* prevent overflow, if speech_size != 0 and SPK_V
* has been restarted. */
if (fsk->speech_count < fsk->speech_size)
fsk->speech_buffer[fsk->speech_count++] = fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len];
fsk->speech_buffer[fsk->speech_count++] = samples[i];
} else
if (t >= 65.5) {
#ifdef DEBUG_DECODER
if (debug && fsk->speech_count)
fprintf(fsk->debug_fp, " (stop recording speech)");
#endif
if (fsk->speech_count) {
unshrink_speech(fsk->cnetz, fsk->speech_buffer, fsk->speech_count);
fsk->speech_count = 0;
@ -635,10 +641,6 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
if (fsk->bit_time >= BITS_PER_SUPERFRAME) {
fsk->bit_time -= BITS_PER_SUPERFRAME;
}
#ifdef DEBUG_DECODER
if (debug && samples)
fprintf(fsk->debug_fp, "\n");
#endif
/* another clock is used to measure actual super frame time */
fsk->bit_time_uncorrected += fsk->bits_per_sample;
if (fsk->bit_time_uncorrected >= BITS_PER_SUPERFRAME) {

View File

@ -44,20 +44,19 @@ enum cnetz_chan_type chan_type[MAX_SENDER] = { CHAN_TYPE_OGK_SPK };
int measure_speed = 0;
double clock_speed[2] = { 0.0, 0.0 };
int set_clock_speed = 0;
const char *flip_polarity = "";
const char *flip_polarity = "auto";
int ms_power = 6; /* 1..8 */
int warteschlange = 1;
int challenge_valid;
uint64_t challenge;
int response_valid;
uint64_t response;
uint32_t timeslots = 4; /* 1 up to 8 */
uint8_t timeslot = 0;
uint8_t fuz_nat = 1;
uint8_t fuz_fuvst = 4;
uint8_t fuz_rest = 66;
const char *fuz_name = NULL;
uint8_t kennung_fufst = 1; /* normal prio */
uint8_t bahn_bs = 0; /* normal */
uint8_t authentifikationsbit = 0;
uint8_t ws_kennung = 0; /* no queue */
uint8_t fuvst_sperren = 0; /* no blocking registration/calls */
@ -73,11 +72,9 @@ uint8_t reduzierung = 0; /* factor 4 */
uint8_t nachbar_prio = 0;
int8_t futln_sperre_start = -1; /* no blocking */
int8_t futln_sperre_end = -1; /* no range */
int meldeinterval = 120; /* when to ask the phone about beeing alive */
int meldeaufrufe = 3; /* how many times to ask phone about beeing alive */
enum demod_type demod = FSK_DEMOD_AUTO;
int metering = 20;
double speech_deviation = 2400.0; /* best results with older equipment (not C5) */
double speech_deviation = 4000.0; /* best results with all my equipment */
void print_help(const char *arg0)
{
@ -85,10 +82,6 @@ void print_help(const char *arg0)
/* - - */
printf(" -T --channel-type <channel type> | list\n");
printf(" Give channel type, use 'list' to get a list. (default = '%s')\n", chan_type_short_name(chan_type[0]));
printf(" You must define at least one OgK at channel 131. This channel may be a\n");
printf(" a combined OgK+SpK channel, but this works with older phones only.\n");
printf(" You must define additionally one or more SpK, in order to make calls.\n");
printf(" You may define alternative OgK, the phones will attach to it then.\n");
printf(" -M --measure-speed\n");
printf(" Measures clock speed. THIS IS REQUIRED! See documentation!\n");
printf(" -C --clock-speed <rx ppm>,<tx ppm>\n");
@ -102,8 +95,8 @@ void print_help(const char *arg0)
printf(" generates a negative signal rather than a positive one. If auto, the\n");
printf(" base station uses double time slots with alternating polarity.\n");
printf(" Once a mobile registers, the correct polarity is selected and used.\n");
printf(" (default = %s)\n", (flip_polarity[0]) ? flip_polarity : "auto");
printf(" Note: Correct polarity is selected for SDR by default.\n");
printf(" (default = %s)\n", flip_polarity);
printf(" Note: This has no effect with SDR.\n");
printf(" -P --ms-power <power level>\n");
printf(" Give power level of the mobile station: 1, 2, 4, 6, 8 (default = '%d')\n", ms_power);
printf(" 1 = 7.5-20 W; 2 = 4-8 W; 4 = 0.5-1 W; 6 = 50-125 mW; 8 = 2-10 mW\n");
@ -125,13 +118,14 @@ void print_help(const char *arg0)
printf(" Increment metering counter every given number of seconds.\n");
printf(" To turn off, use 0. (default = %d)\n", metering);
printf(" -V --voice-deviation <2400..4000 Hz>\n");
printf(" It is unclear what the actual voice deviation is. Please increase, if\n");
printf(" mobile's earpiece is too quiet and the microphone is too loud.\n");
printf(" It is unclear what the actual voice deviation is. Please decrease, if\n");
printf(" mobile's microphone is too loud and speaker is too quiet.\n");
printf(" (default = %.0f)\n", speech_deviation);
printf(" -S --sysinfo timeslots=1|2|4|8\n");
printf(" Set number of timeslots of OgK broadcast. There are 32 time slots per\n");
printf(" frame, but only up to 8 slots can be used, because of processing\n");
printf(" delay. (default = %d)\n", timeslots);
printf(" -S --sysinfo timeslot=<0..31>\n");
printf(" Set time slot of OgK broadcast. There are 32 time slots, but every 8th\n");
printf(" slot is used. This means if you select time slot 0, also slots 8, 16\n");
printf(" and 24 will be used. If you select slot 14, also slots 6, 22 and 30\n");
printf(" will be used. (default = %d)\n", timeslot);
printf(" -S --sysinfo fuz-nat=<nat>\n");
printf(" Set country ID of base station. All IDs were used inside Germany only.\n");
printf(" (default = %d)\n", fuz_nat);
@ -151,12 +145,6 @@ void print_help(const char *arg0)
printf(" 2 = Higher priority base station.\n");
printf(" 3 = Highest priority base station.\n");
printf(" Note: Priority has no effect, because there is only one base station.\n");
printf(" -S --sysinfo bahn-bs=<value>\n");
printf(" Set special tunnel base station mode for train mobile phones only.\n");
printf(" (default = %d)\n", kennung_fufst);
printf(" 0 = Disable (every phone is allowed)\n");
printf(" 1 = Enable (only train phones are allowed)\n");
printf(" Note: Enableing this will force priority to 0 (Test base station).\n");
printf(" -S --sysinfo auth=<auth>\n");
printf(" Enable authentication flag on the base station. Since we cannot\n");
printf(" authenticate, because we don't know the secret key and the algorithm,\n");
@ -229,12 +217,6 @@ void print_help(const char *arg0)
} else {
printf(" (default = %d-%d)\n", futln_sperre_start, futln_sperre_end);
}
printf(" -S --sysinfo meldeinterval=<seconds>\n");
printf(" Time to wait until pinging the phone wether it is still available.\n");
printf(" (default = %d)\n", meldeinterval);
printf(" -S --sysinfo meldeaufrufe=<count>\n");
printf(" Number of times we try to ping mobile until we assume it is gone.\n");
printf(" Use '0' for infinite tries. (default = %d)\n", meldeaufrufe);
printf(" -D --demod auto | slope | level\n");
printf(" Adjust demodulation algorithm. Use 'slope' to detect a level change\n");
printf(" by finding the highest slope of a bit transition. It is useful, if\n");
@ -364,8 +346,8 @@ static int handle_options(int short_option, int argi, char **argv)
return -EINVAL;
}
p++;
if (!strncasecmp(argv[argi], "timeslots=", p - argv[argi])) {
timeslots = atoi_limit(p, 1, 8);
if (!strncasecmp(argv[argi], "timeslot=", p - argv[argi])) {
timeslot = atoi_limit(p, 0, 31);
} else
if (!strncasecmp(argv[argi], "fuz-nat=", p - argv[argi])) {
fuz_nat = atoi_limit(p, 0, 7);
@ -398,9 +380,6 @@ error_fuz:
if (!strncasecmp(argv[argi], "kennung-fufst=", p - argv[argi])) {
kennung_fufst = atoi_limit(p, 0, 3);
} else
if (!strncasecmp(argv[argi], "bahn-bs=", p - argv[argi])) {
bahn_bs = atoi_limit(p, 0, 1);
} else
if (!strncasecmp(argv[argi], "auth=", p - argv[argi])) {
authentifikationsbit = atoi_limit(p, 0, 1);
} else
@ -454,12 +433,6 @@ error_fuz:
futln_sperre_end = atoi(q) & 0xf;
}
} else
if (!strncasecmp(argv[argi], "meldeinterval=", p - argv[argi])) {
meldeinterval = atoi_limit(p, 1, 20 * 60);
} else
if (!strncasecmp(argv[argi], "meldeaufrufe=", p - argv[argi])) {
meldeaufrufe = atoi_limit(p, 0, 1000000);
} else
{
fprintf(stderr, "Given sysinfo parameter '%s' unknown, use '-h' for help!\n", argv[argi]);
return -EINVAL;
@ -551,7 +524,7 @@ int main(int argc, char *argv[])
}
if (!num_kanal) {
printf("No channel (\"Kanal\") is specified, I suggest channel %d.\n\n", CNETZ_STD_OGK_KANAL);
printf("No channel (\"Kanal\") is specified, I suggest channel %d.\n\n", CNETZ_OGK_KANAL);
mandatory = 1;
}
if (use_sdr) {
@ -602,13 +575,7 @@ int main(int argc, char *argv[])
}
if (anzahl_gesperrter_teilnehmergruppen)
printf("Blocked subscriber with number's last 4 bits from 0x%x to 0x%x\n", teilnehmergruppensperre, (teilnehmergruppensperre + anzahl_gesperrter_teilnehmergruppen - 1) & 0xf);
switch(timeslots) {
case 1: timeslots=0x00000001; break;
case 2: timeslots=0x00010001; break;
case 4: timeslots=0x01010101; break;
default: timeslots=0x11111111;
}
init_sysinfo(timeslots, fuz_nat, fuz_fuvst, fuz_rest, kennung_fufst, bahn_bs, authentifikationsbit, ws_kennung, fuvst_sperren, grenz_einbuchen, grenz_umschalten, grenz_ausloesen, mittel_umschalten, mittel_ausloesen, genauigkeit, bewertung, entfernung, reduzierung, nachbar_prio, teilnehmergruppensperre, anzahl_gesperrter_teilnehmergruppen, meldeinterval, meldeaufrufe);
init_sysinfo(timeslot, fuz_nat, fuz_fuvst, fuz_rest, kennung_fufst, authentifikationsbit, ws_kennung, fuvst_sperren, grenz_einbuchen, grenz_umschalten, grenz_ausloesen, mittel_umschalten, mittel_ausloesen, genauigkeit, bewertung, entfernung, reduzierung, nachbar_prio, teilnehmergruppensperre, anzahl_gesperrter_teilnehmergruppen);
dsp_init();
rc = init_telegramm();
if (rc < 0) {
@ -618,7 +585,7 @@ int main(int argc, char *argv[])
init_coding();
cnetz_init();
/* check for mandatory standard OgK */
/* check for mandatory OgK */
for (i = 0; i < num_kanal; i++) {
if (chan_type[i] == CHAN_TYPE_OGK || chan_type[i] == CHAN_TYPE_OGK_SPK)
break;
@ -662,7 +629,7 @@ int main(int argc, char *argv[])
polarity = 1; /* positive */
if (!strcmp(flip_polarity, "yes"))
polarity = -1; /* negative */
if (use_sdr && !flip_polarity[0])
if (use_sdr && polarity == 0)
polarity = 1; /* SDR is always positive */
/* demodulation algorithm */

View File

@ -7,10 +7,10 @@
/* The list of cell towers is ripped from BSA61 phone's firmware */
static struct cnetz_stations {
char long_name[32], name[8];
char standort[32], name[8];
uint8_t nat, fuvst, rest;
} cnetz_stations[] = {
/* Langer-Name Kurzer Name, Nat FuVST Rest */
/* Standort-Name Kurzer Name, Nat FuVST Rest */
{ "Oberhausen 32", "OB32", 1, 2, 1, },
{ "Oberhausen 0 <prov.>", "OB0", 1, 2, 5, },
{ "Wuppertal 18", "WUP18", 1, 2, 6, },
@ -2143,37 +2143,37 @@ void station_list(void)
char name[33];
printf("List of all base stations:\n\n");
printf("Kurz Name Nat FuVst Rest\n");
printf("Name Standort Nat FuVst Rest\n");
printf("------------------------------------------------------------\n");
for (i = 0; cnetz_stations[i].long_name[0]; i++) {
for (i = 0; cnetz_stations[i].standort[0]; i++) {
memset(name, ' ', sizeof(name));
memcpy(name, cnetz_stations[i].name, strlen(cnetz_stations[i].name));
name[8] = '\0';
printf("%s", name);
memset(name, ' ', sizeof(name));
memcpy(name, cnetz_stations[i].long_name, strlen(cnetz_stations[i].long_name));
memcpy(name, cnetz_stations[i].standort, strlen(cnetz_stations[i].standort));
name[sizeof(name) - 1] = '\0';
printf("%s%d\t%d\t%d\n", name, cnetz_stations[i].nat, cnetz_stations[i].fuvst, cnetz_stations[i].rest);
}
}
const char *get_station_name(uint8_t nat, uint8_t fuvst, uint8_t rest, const char **long_name)
const char *get_station_name(uint8_t nat, uint8_t fuvst, uint8_t rest, const char **standort)
{
int i;
for (i = 0; cnetz_stations[i].long_name[0]; i++) {
for (i = 0; cnetz_stations[i].standort[0]; i++) {
if (cnetz_stations[i].nat == nat
&& cnetz_stations[i].fuvst == fuvst
&& cnetz_stations[i].rest == rest) {
if (long_name)
*long_name = cnetz_stations[i].long_name;
if (standort)
*standort = cnetz_stations[i].standort;
return cnetz_stations[i].name;
}
}
if (long_name)
*long_name = "unknown";
return *long_name;
if (standort)
*standort = "unknown";
return *standort;
}
const char *get_station_id(const char *name, uint8_t *nat, uint8_t *fuvst, uint8_t *rest)
@ -2182,8 +2182,7 @@ const char *get_station_id(const char *name, uint8_t *nat, uint8_t *fuvst, uint8
for (i = 0; cnetz_stations[i].name[0]; i++) {
/* check for given prefix */
if (!strncasecmp(cnetz_stations[i].name, name, strlen(name))
|| !strncasecmp(cnetz_stations[i].long_name, name, strlen(name)) ) {
if (!strncasecmp(cnetz_stations[i].name, name, strlen(name))) {
/* found twice */
if (found >= 0)
return "Given station name is ambiguous, use more letters! Use '-S fuz-name=list' to get a list of all stations.";

View File

@ -4,12 +4,12 @@
cnetz_si si;
void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t bahn_bs, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen, int meldeinterval, int meldeaufrufe)
void init_sysinfo(uint8_t timeslot, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen)
{
memset(&si, 0, sizeof(si));
/* timeslot to use */
si.timeslots = timeslots;
si.timeslot = timeslot;
/* ID of base station */
si.fuz_nat = fuz_nat;
@ -37,10 +37,7 @@ void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_
/* a low value is tollerant to bad quality */
si.grenz_einbuchen = grenz_einbuchen; /* 1..7 */
if (bahn_bs)
kennung_fufst = 0;
si.kennung_fufst = kennung_fufst;
si.bahn_bs = bahn_bs;
si.authentifikationsbit = authentifikationsbit;
@ -55,8 +52,5 @@ void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_
/* deny group of subscribers. (used to balance subscribers between base stations) */
si.teilnehmergruppensperre = teilnehmergruppensperre;
si.anzahl_gesperrter_teilnehmergruppen = anzahl_gesperrter_teilnehmergruppen;
si.meldeinterval = meldeinterval;
si.meldeaufrufe = meldeaufrufe;
}

View File

@ -1,6 +1,6 @@
typedef struct system_information {
uint32_t timeslots; /* timeslot map to use */
uint8_t timeslot; /* timeslot to use */
uint8_t fuz_nat; /* national network ID */
uint8_t fuz_fuvst; /* id of switching center */
uint8_t fuz_rest; /* rest of base station id */
@ -13,7 +13,6 @@ typedef struct system_information {
uint8_t entfernung;
uint8_t grenz_einbuchen;
uint8_t kennung_fufst; /* prio of base station */
uint8_t bahn_bs; /* special train base station */
uint8_t authentifikationsbit; /* base station suppoerts authentication */
uint8_t ws_kennung; /* queue setting sof base station */
uint8_t nachbar_prio;
@ -21,11 +20,9 @@ typedef struct system_information {
uint8_t reduzierung;
int8_t teilnehmergruppensperre;
int8_t anzahl_gesperrter_teilnehmergruppen;
int meldeinterval; /* when to retry availability check */
int meldeaufrufe; /* 0 for infinite */
} cnetz_si;
extern cnetz_si si;
void init_sysinfo(uint32_t timeslots, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t bahn_bs, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen, int meldeinterval, int meldeaufrufe);
void init_sysinfo(uint8_t timeslot, uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen);

View File

@ -632,8 +632,7 @@ static char *assemble_telegramm(const telegramm_t *telegramm, int debug)
abort();
}
if (debug)
PDEBUG(DFRAME, DEBUG_INFO, "Coding %s %s\n", definition_opcode[telegramm->opcode].message_name, definition_opcode[telegramm->opcode].message_text);
PDEBUG(DFRAME, DEBUG_DEBUG, "Coding %s %s\n", definition_opcode[telegramm->opcode].message_name, definition_opcode[telegramm->opcode].message_text);
/* copy opcode */
for (i = 0; i < 6; i++)
@ -848,7 +847,7 @@ static void disassemble_telegramm(telegramm_t *telegramm, const char *bits, int
value = (value << 1) | (bits[i] == '1');
telegramm->opcode = value;
PDEBUG(DFRAME, DEBUG_INFO, "Decoding %s %s\n", definition_opcode[telegramm->opcode].message_name, definition_opcode[telegramm->opcode].message_text);
PDEBUG(DFRAME, DEBUG_DEBUG, "Decoding %s %s\n", definition_opcode[telegramm->opcode].message_name, definition_opcode[telegramm->opcode].message_text);
/* copy parameters */
if (auth && bits[1]) /* auth flag and chip card flag */
@ -1500,9 +1499,10 @@ void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, doub
return;
}
PDEBUG_CHAN(DDSP, DEBUG_INFO, "RF level: %.1f dB RX Level: %.0f%% Standard deviation: %.0f%% Sync Time: %.2f (TS %.2f) %s\n", cnetz->rf_level_db, fabs(level) / cnetz->fsk_deviation * 100.0, stddev / fabs(level) * 100.0, sync_time, sync_time / 396.0, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
if (bit_errors)
PDEBUG_CHAN(DDSP, DEBUG_INFO, " -> Frame has %d bit errors.\n", bit_errors);
PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Standard deviation: %.0f%% Sync Time: %.2f (TS %.2f) Bit errors: %d %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, stddev / fabs(level) * 100.0, sync_time, sync_time / 396.0, bit_errors, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
else
PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Standard deviation: %.0f%% Sync Time: %.2f (TS %.2f) %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, stddev / fabs(level) * 100.0, sync_time, sync_time / 396.0, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)");
disassemble_telegramm(&telegramm, bits, si.authentifikationsbit);
opcode = telegramm.opcode;
@ -1579,7 +1579,6 @@ const char *cnetz_encode_telegramm(cnetz_t *cnetz)
const telegramm_t *telegramm = NULL;
uint8_t opcode;
char *bits;
int debug = 1;
switch (cnetz->dsp_mode) {
case DSP_MODE_OGK:
@ -1602,11 +1601,7 @@ const char *cnetz_encode_telegramm(cnetz_t *cnetz)
return NULL;
opcode = telegramm->opcode;
if (opcode == OPCODE_LR_R && cnetz->sched_lr_debugged)
debug = 0;
if (opcode == OPCODE_MLR_M && cnetz->sched_mlr_debugged)
debug = 0;
bits = assemble_telegramm(telegramm, debug);
bits = assemble_telegramm(telegramm, (opcode != OPCODE_LR_R) && (opcode != OPCODE_MLR_M));
bits = encode(bits);
bits = interleave(bits);
@ -1618,13 +1613,6 @@ const char *cnetz_encode_telegramm(cnetz_t *cnetz)
bits[i] ^= 1;
}
if (opcode == OPCODE_LR_R && !cnetz->sched_lr_debugged)
cnetz->sched_lr_debugged = 1;
if (opcode == OPCODE_MLR_M && !cnetz->sched_mlr_debugged) {
cnetz->sched_mlr_debugged = 1;
PDEBUG(DFRAME, DEBUG_INFO, "Subsequent IDLE frames are not show, to prevent flooding the output.\n");
}
return bits;
}

View File

@ -20,7 +20,6 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include "../libsample/sample.h"
#include "../libdebug/debug.h"
#include "../libmobile/call.h"
@ -29,8 +28,6 @@
#include "telegramm.h"
#include "database.h"
static int new_cueue_position = 0;
const char *transaction2rufnummer(transaction_t *trans)
{
static char rufnummer[32]; /* make GCC happy (overflow check) */
@ -41,34 +38,24 @@ const char *transaction2rufnummer(transaction_t *trans)
}
/* create transaction */
transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended, double rf_level_db)
transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended)
{
transaction_t *trans;
sender_t *sender;
transaction_t *trans = NULL;
cnetz_t *search_cnetz;
trans = search_transaction_number_global(futln_nat, futln_fuvst, futln_rest);
/* search transaction for this subscriber */
for (sender = sender_head; sender; sender = sender->next) {
search_cnetz = (cnetz_t *) sender;
/* search transaction for this callref */
trans = search_transaction_number(search_cnetz, futln_nat, futln_fuvst, futln_rest);
if (trans)
break;
}
if (trans) {
const char *rufnummer = transaction2rufnummer(trans);
int old_callref = trans->callref;
cnetz_t *old_cnetz = trans->cnetz;
/* both states must be the same and one of the give selection */
if ((trans->state & state & (TRANS_EM | TRANS_UM | TRANS_VWG | TRANS_ATQ_IDLE))) {
if (!isnan(trans->rf_level_db) && !isnan(rf_level_db) && trans->cnetz->kanal != cnetz->kanal) {
if (rf_level_db > trans->rf_level_db) {
PDEBUG(DTRANS, DEBUG_NOTICE, "Found already pending transaction for subscriber '%s' on channel #%d, but this message on channel #%d is stronger, so we move to that channel!\n", rufnummer, trans->cnetz->kanal, cnetz->kanal);
trans->rf_level_db = rf_level_db;
unlink_transaction(trans);
link_transaction(trans, cnetz);
update_db(trans->futln_nat, trans->futln_fuvst, trans->futln_rest, cnetz->kanal, NULL, NULL, 1, 0);
return trans;
}
if (rf_level_db < trans->rf_level_db) {
PDEBUG(DTRANS, DEBUG_NOTICE, "Found already pending transaction for subscriber '%s' on channel #%d, but this message on channel #%d is weaker, so we ignore that channel!\n", rufnummer, trans->cnetz->kanal, cnetz->kanal);
return trans;
}
}
PDEBUG(DTRANS, DEBUG_NOTICE, "Found already pending transaction for subscriber '%s' on channel #%d, but this message on channel #%d is also received. Try to avoid multiple OgK channels!\n", rufnummer, trans->cnetz->kanal, cnetz->kanal);
return trans;
}
PDEBUG(DTRANS, DEBUG_NOTICE, "Found already pending transaction for subscriber '%s', deleting!\n", rufnummer);
destroy_transaction(trans);
if (old_cnetz) /* should be... */
@ -101,12 +88,10 @@ transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_
link_transaction(trans, cnetz);
/* update database: now busy */
update_db(futln_nat, futln_fuvst, futln_rest, cnetz->kanal, &futelg_bit, &extended, 1, 0);
update_db(cnetz, futln_nat, futln_fuvst, futln_rest, &futelg_bit, &extended, 1, 0);
trans->futelg_bit = futelg_bit;
trans->extended = extended;
trans->rf_level_db = rf_level_db;
return trans;
}
@ -114,7 +99,7 @@ transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_
void destroy_transaction(transaction_t *trans)
{
/* update database: now idle */
update_db(trans->futln_nat, trans->futln_fuvst, trans->futln_rest, 0, NULL, NULL, 0, trans->page_failed);
update_db(trans->cnetz, trans->futln_nat, trans->futln_fuvst, trans->futln_rest, NULL, NULL, 0, trans->page_failed);
unlink_transaction(trans);
@ -197,23 +182,6 @@ transaction_t *search_transaction_number(cnetz_t *cnetz, uint8_t futln_nat, uint
return NULL;
}
transaction_t *search_transaction_number_global(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest)
{
sender_t *sender;
cnetz_t *cnetz;
transaction_t *trans = NULL;
/* search transaction for this subscriber */
for (sender = sender_head; sender; sender = sender->next) {
cnetz = (cnetz_t *) sender;
/* search transaction for this callref */
trans = search_transaction_number(cnetz, futln_nat, futln_fuvst, futln_rest);
if (trans)
break;
}
return trans;
}
transaction_t *search_transaction_callref(cnetz_t *cnetz, int callref)
{
transaction_t *trans = cnetz->trans_list;
@ -233,42 +201,6 @@ transaction_t *search_transaction_callref(cnetz_t *cnetz, int callref)
return NULL;
}
/* get oldest transaction in queue:
*
* oldest means that the queue number is the smallest.
* all candidates (transactions) must be in queue state.
*/
transaction_t *search_transaction_queue(void)
{
sender_t *sender;
transaction_t *trans, *found = NULL;
cnetz_t *cnetz;
int queue_max = 0;
for (sender = sender_head; sender; sender = sender->next) {
cnetz = (cnetz_t *) sender;
trans = cnetz->trans_list;
while (trans) {
if ((trans->state & (TRANS_MO_QUEUE | TRANS_MT_QUEUE))) {
/* select if first or lower number */
if (!found || trans->queue_position < queue_max) {
queue_max = trans->queue_position;
found = trans;
}
}
trans = trans->next;
}
}
if (found) {
const char *rufnummer = transaction2rufnummer(found);
PDEBUG(DTRANS, DEBUG_DEBUG, "Found oldest transaction in queue for subscriber '%s'\n", rufnummer);
return found;
}
return NULL;
}
static const char *trans_state_name(uint64_t state)
{
switch (state) {
@ -320,8 +252,6 @@ static const char *trans_state_name(uint64_t state)
return "AT";
case TRANS_ATQ:
return "ATQ";
case TRANS_ATQ_IDLE:
return "ATQ_IDLE";
case TRANS_MO_QUEUE:
return "MO_QUEUE";
case TRANS_MT_QUEUE:
@ -371,7 +301,6 @@ const char *trans_short_state_name(uint64_t state)
case TRANS_AF:
case TRANS_AT:
case TRANS_ATQ:
case TRANS_ATQ_IDLE:
return "RELEASE";
case TRANS_MO_QUEUE:
case TRANS_MO_DELAY:
@ -388,9 +317,6 @@ void trans_new_state(transaction_t *trans, uint64_t state)
{
PDEBUG(DTRANS, DEBUG_INFO, "Transaction (%s) state %s -> %s\n", transaction2rufnummer(trans), trans_state_name(trans->state), trans_state_name(state));
trans->state = state;
/* in case of a queue, set new positon */
if (!trans->queue_position && (state == TRANS_MO_QUEUE || state == TRANS_MT_QUEUE))
trans->queue_position = ++new_cueue_position;
cnetz_display_status();
}

View File

@ -29,12 +29,11 @@
#define TRANS_AF (1 << 20) /* release connection by base station (SpK) */
#define TRANS_AT (1 << 21) /* release connection by mobile station */
#define TRANS_ATQ (1 << 22) /* acknowledge release of MO call in queue */
#define TRANS_ATQ_IDLE (1 << 23) /* repeat, if call has been released already (mobile sends again) */
/* queue */
#define TRANS_MO_QUEUE (1 << 24) /* MO queue */
#define TRANS_MT_QUEUE (1 << 25) /* MT queue */
#define TRANS_MO_DELAY (1 << 26) /* delay to be sure the channel is free again */
#define TRANS_MT_DELAY (1 << 27)
#define TRANS_MO_QUEUE (1 << 23) /* MO queue */
#define TRANS_MT_QUEUE (1 << 24) /* MT queue */
#define TRANS_MO_DELAY (1 << 25) /* delay to be sure the channel is free again */
#define TRANS_MT_DELAY (1 << 26)
typedef struct transaction {
struct transaction *next; /* pointer to next node in list */
@ -55,22 +54,18 @@ typedef struct transaction {
int mt_call; /* flags a moile terminating call */
int page_failed; /* failed to get a response from MS */
double call_start; /* when did the call start? (used for metering) */
int queue_position; /* to find next transaction in queue */
double rf_level_db; /* level of first contact, so we can detect correct channel at multiple receptions */
} transaction_t;
const char *transaction2rufnummer(transaction_t *trans);
transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended, double rf_level_db);
transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended);
void destroy_transaction(transaction_t *trans);
void link_transaction(transaction_t *trans, cnetz_t *cnetz);
void unlink_transaction(transaction_t *trans);
transaction_t *search_transaction(cnetz_t *cnetz, uint64_t state_mask);
transaction_t *search_transaction_number(cnetz_t *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
transaction_t *search_transaction_number_global(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
transaction_t *search_transaction_callref(cnetz_t *cnetz, int callref);
transaction_t *search_transaction_queue(void);
void trans_new_state(transaction_t *trans, uint64_t state);
void cnetz_flush_other_transactions(cnetz_t *cnetz, transaction_t *trans);
void transaction_timeout(void *data);
void transaction_timeout(struct timer *timer);
const char *trans_short_state_name(uint64_t state);

View File

@ -314,7 +314,7 @@ int send_sto(am791x_t *am791x, sample_t *sample, int length)
/* modulate STO */
phaseshift = am791x->sto_phaseshift65536;
while (count < length) {
while (count < length && fsk->tx_bitpos < 1.0) {
sample[count++] = fsk->sin_tab[(uint16_t)phase];
phase += phaseshift;
if (phase >= 65536.0)
@ -1066,16 +1066,16 @@ static void handle_state(am791x_t *am791x)
}
/* timeout events */
static void tx_timeout(void *data)
static void tx_timeout(struct timer *timer)
{
am791x_t *am791x = data;
am791x_t *am791x = (am791x_t *)timer->priv;
handle_tx_state(am791x);
}
static void rx_timeout(void *data)
static void rx_timeout(struct timer *timer)
{
am791x_t *am791x = data;
am791x_t *am791x = (am791x_t *)timer->priv;
handle_rx_state(am791x);
}

View File

@ -1001,7 +1001,7 @@ static ssize_t dk_ioctl_set(void *inst, int cmd, const void *buf, size_t in_bufs
break;
case TCOON:
PDEBUG(DDATENKLO, DEBUG_DEBUG, "Terminal turns on output.\n");
datenklo->output_off = 0;
datenklo->output_off = 1;
break;
case TCIOFF:
PDEBUG(DDATENKLO, DEBUG_DEBUG, "Terminal turns off input.\n");
@ -1257,9 +1257,9 @@ void sighandler(int sigset)
}
/* vtimer */
static void vtime_timeout(void *data)
static void vtime_timeout(struct timer *timer)
{
datenklo_t *datenklo = data;
datenklo_t *datenklo = (datenklo_t *)timer->priv;
/* check if there is enough data to read */
datenklo->vtimeout = 1;

View File

@ -467,7 +467,7 @@ static void *device_child(void *arg)
const char *dev_info_argv[] = { dev_name };
struct cuse_info ci;
strncat(dev_name, device->name, sizeof(dev_name) - strlen(dev_name) - 1);
strncat(dev_name, device->name, sizeof(dev_name) - strlen(device->name) - 1);
memset(&ci, 0, sizeof(ci));
ci.dev_major = device->major;
@ -520,7 +520,7 @@ void *device_init(void *inst, const char *name, int (*open)(void *inst, int flag
}
pthread_getname_np(device->thread, tname, sizeof(tname));
strncat(tname, "-device", sizeof(tname) - strlen(tname) - 1);
strncat(tname, "-device", sizeof(tname) - 7 - 1);
tname[sizeof(tname) - 1] = '\0';
pthread_setname_np(device->thread, tname);

View File

@ -1,26 +0,0 @@
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
if HAVE_ALSA
bin_PROGRAMS = \
dcf77
dcf77_SOURCES = \
dcf77.c \
weather.c \
cities.c \
image.c \
main.c
dcf77_LDADD = \
$(COMMON_LA) \
$(top_builddir)/src/liboptions/liboptions.a \
$(top_builddir)/src/libdebug/libdebug.a \
$(top_builddir)/src/libdisplay/libdisplay.a \
$(top_builddir)/src/libfilter/libfilter.a \
$(top_builddir)/src/libwave/libwave.a \
$(top_builddir)/src/libsample/libsample.a \
$(top_builddir)/src/libsound/libsound.a \
$(top_builddir)/src/libaaimage/libaaimage.a \
$(ALSA_LIBS) \
-lm
endif

View File

@ -1,633 +0,0 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include "cities.h"
static struct city_list {
int region;
const char *name;
} city_list[] = {
{ 0, "AGEN" },
{ 0, "AUCH" },
{ 0, "BORDEAUX" },
{ 0, "BRIVE LA GAILLARDE" },
{ 0, "CAHORS" },
{ 0, "MONTAUBAN" },
{ 0, "MONT MARSAN" },
{ 0, "PAU" },
{ 0, "PERIGUEUX" },
{ 0, "TARBES" },
{ 0, "TOULOUSE" },
{ 1, "ANGOULEME" },
{ 1, "LA ROCHELL" },
{ 1, "LA ROCHE S" },
{ 1, "LIMOGES" },
{ 1, "NIORT" },
{ 1, "POITIERS" },
{ 2, "ALENCON" },
{ 2, "AUXERRE" },
{ 2, "BAR LE DUC" },
{ 2, "BLOIS" },
{ 2, "BOBIGNY" },
{ 2, "BOURGES" },
{ 2, "CERGY PONT" },
{ 2, "CHARTRES" },
{ 2, "CRETEIL" },
{ 2, "EVRY" },
{ 2, "LE MANS" },
{ 2, "MELUN" },
{ 2, "NANTERRE" },
{ 2, "NEVERS" },
{ 2, "ORLEANS" },
{ 2, "PARIS" },
{ 2, "REIMS" },
{ 2, "TOURS" },
{ 2, "TROYES" },
{ 2, "VERSAILLES" },
{ 3, "ANGERS" },
{ 3, "BREST" },
{ 3, "CHERBOURG" },
{ 3, "JERSEY" },
{ 3, "LAVAL" },
{ 3, "LORIENT" },
{ 3, "NANTES" },
{ 3, "RENNES" },
{ 3, "ST BRIEUC" },
{ 4, "AURILLAC" },
{ 4, "CLERMON FERRAND" },
{ 4, "FLORAC" },
{ 4, "GUERET" },
{ 4, "MENDE" },
{ 4, "MILLAU" },
{ 4, "MONTLUCON" },
{ 4, "PUY VELAY" },
{ 4, "RODEZ" },
{ 4, "ST-ETIENNE" },
{ 4, "ST FLOUR" },
{ 5, "ALBI" },
{ 5, "BEZIERS" },
{ 5, "CARCASSONN" },
{ 5, "FOIX" },
{ 5, "MONTPELLIER" },
{ 5, "PERPIGNAN" },
{ 6, "AALST" },
{ 6, "ANTWERPEN" },
{ 6, "BOULOGNE" },
{ 6, "BRUGGE" },
{ 6, "BRUSSEL" },
{ 6, "CHARLEROI" },
{ 6, "GENK" },
{ 6, "GENT" },
{ 6, "HALLE" },
{ 6, "HASSELT" },
{ 6, "IXELLES" },
{ 6, "KNOKKE-HEIST" },
{ 6, "KORTRIJK" },
{ 6, "LEUVEN" },
{ 6, "LIEGE" },
{ 6, "LILLE" },
{ 6, "LOKEREN" },
{ 6, "MAASTRICHT" },
{ 6, "MECHELEN" },
{ 6, "MIDDELBURG" },
{ 6, "MONS" },
{ 6, "MOUSCRON" },
{ 6, "NAMUR" },
{ 6, "OOSTENDE" },
{ 6, "ROESELARE" },
{ 6, "SCHAERBEEK" },
{ 6, "TERNEUZEN" },
{ 6, "TOURNAI" },
{ 7, "CHAUMONT" },
{ 7, "DIJON" },
{ 7, "EPINAL" },
{ 7, "LONS LE S" },
{ 7, "METZ" },
{ 7, "NANCY" },
{ 7, "VESOUL" },
{ 8, "ALES" },
{ 8, "AVIGNON" },
{ 8, "MARSEILLE" },
{ 8, "MONTELIMAR" },
{ 8, "NIMES" },
{ 8, "PRIVAS" },
{ 8, "ST TROPEZ" },
{ 8, "TOULON" },
{ 9, "BOURG EN B" },
{ 9, "LYON" },
{ 9, "MACON" },
{ 9, "VALENCE" },
{ 10, "BRIANCON" },
{ 10, "CHAMBERY" },
{ 10, "DIGNE" },
{ 10, "GAP" },
{ 10, "GRENOBLE" },
{ 11, "ANNECY" },
{ 11, "BESANCON" },
{ 11, "DELEMONT" },
{ 11, "LA CHAUX-DE-FONDS" },
{ 12, "ASCHAFFENBURG" },
{ 12, "BAD HOMBURG" },
{ 12, "BAD KREUZNACH" },
{ 12, "DARMSTADT" },
{ 12, "FRANKFURT AM MAIN" },
{ 12, "HEIDELBERG" },
{ 12, "KAISERSLAUTERN" },
{ 12, "KARLSRUHE" },
{ 12, "LANDAU IN DER PFALZ" },
{ 12, "LUDWIGSHAFEN" },
{ 12, "MAINZ" },
{ 12, "MANNHEIM" },
{ 12, "PIRMASENS" },
{ 12, "WORMS" },
{ 13, "BITBURG" },
{ 13, "HAGEN" },
{ 13, "ISERLOHN" },
{ 13, "KOBLENZ" },
{ 13, "LUEDENSCHEID" },
{ 13, "LUXEMBOURG" },
{ 13, "NEUWIED" },
{ 13, "SAARBRUECKEN" },
{ 13, "SEDAN" },
{ 13, "SIEGEN" },
{ 13, "TRIER" },
{ 13, "VERVIERS" },
{ 13, "WIESBADEN" },
{ 14, "AACHEN" },
{ 14, "BIELEFELD" },
{ 14, "BOCHUM" },
{ 14, "BONN" },
{ 14, "DORTMUND" },
{ 14, "DUEREN" },
{ 14, "DUESSELDORF" },
{ 14, "DUISBURG" },
{ 14, "ESSEN" },
{ 14, "GELSENKIRCHEN" },
{ 14, "GUETERSLOH" },
{ 14, "KOELN" },
{ 14, "LINGEN" },
{ 14, "LIPPSTADT" },
{ 14, "MOENCHENGLADBACH" },
{ 14, "MUELHEIM AN DER RUHR" },
{ 14, "MUENSTER" },
{ 14, "NORDHORN" },
{ 14, "OBERHAUSEN" },
{ 14, "OSNABRUECK" },
{ 14, "RECKLINGHAUSEN" },
{ 14, "RHEINE" },
{ 14, "SOLINGEN" },
{ 14, "WESEL" },
{ 14, "WUPPERTAL" },
{ 15, "BRISTOL" },
{ 15, "CARDIFF" },
{ 15, "EXETER" },
{ 15, "HOLYHEAD" },
{ 15, "PLYMOUTH" },
{ 15, "ST DAVIDS" },
{ 15, "SWANSEA" },
{ 16, "BIRMINGHAM" },
{ 16, "BLACKPOOL" },
{ 16, "LEEDS" },
{ 16, "LEICESTER" },
{ 16, "LIVERPOOL" },
{ 16, "MANCHESTER" },
{ 16, "MIDDLESBROUGH" },
{ 16, "NEWCASTLE" },
{ 16, "NOTTINGHAM" },
{ 16, "SHEFFIELD" },
{ 17, "AMIENS" },
{ 17, "BEAUVAIS" },
{ 17, "CAEN" },
{ 17, "EVREUX" },
{ 17, "LAON" },
{ 17, "LE HAVRE" },
{ 17, "ROUEN" },
{ 18, "BOURNEMOUT" },
{ 18, "BRIGHTON" },
{ 18, "CAMBRIDGE" },
{ 18, "DOVER" },
{ 18, "IPSWICH" },
{ 18, "KINGSTON" },
{ 18, "LONDON" },
{ 18, "NORTHAMPTON" },
{ 18, "NORWICH" },
{ 18, "OXFORD" },
{ 18, "PORTSMOUTH" },
{ 18, "READING" },
{ 18, "SOUTHAMPTON" },
{ 19, "BORKUM" },
{ 19, "BREMERHAVEN" },
{ 19, "CUXHAVEN" },
{ 19, "DEN HELDER" },
{ 19, "ELMSHORN" },
{ 19, "EMDEN" },
{ 19, "GRONINGEN" },
{ 19, "HAMBURG" },
{ 19, "LEEUWARDEN" },
{ 19, "NORDERTSTEDT" },
{ 19, "SPIEKEROOG" },
{ 19, "ST PETER ORDING" },
{ 19, "SYLT" },
{ 19, "TEXEL" },
{ 19, "WILHELMSHAVEN" },
{ 20, "ALBORG" },
{ 20, "ESBJERG" },
{ 20, "FREDERIKSHAVN" },
{ 20, "HERNING" },
{ 20, "HOLSTERBRO" },
{ 20, "SKAGEN" },
{ 20, "THISTED" },
{ 20, "THYBOROEN" },
{ 20, "VIBORG" },
{ 21, "ARHUS" },
{ 21, "FREDERICIA" },
{ 21, "HORSENS" },
{ 21, "KOLDING" },
{ 21, "ODENSE" },
{ 21, "RANDERS" },
{ 21, "SILKEBORG" },
{ 21, "VEJLE" },
{ 22, "BRAUNSCHWEIG" },
{ 22, "BREMEN" },
{ 22, "CELLE" },
{ 22, "GOSLAR" },
{ 22, "HAMELN" },
{ 22, "HANNOVER" },
{ 22, "HERFORD" },
{ 22, "HILDESHEIM" },
{ 22, "LUENEBURG" },
{ 22, "MAGDEBURG" },
{ 22, "MINDEN" },
{ 22, "OLDENBURG" },
{ 22, "WOLFSBURG" },
{ 23, "HELSINGOER" },
{ 23, "KALUNDBORG" },
{ 23, "KOEBENHAVN" },
{ 23, "MALMOE" },
{ 23, "NAESTVED" },
{ 23, "ROSKILDE" },
{ 23, "SLAGELSE" },
{ 24, "FEHMARN" },
{ 24, "FLENSBURG" },
{ 24, "GREIFSWALD" },
{ 24, "KIEL" },
{ 24, "LUEBECK" },
{ 24, "ROSTOCK" },
{ 24, "RUEGEN" },
{ 24, "SCHWERIN" },
{ 24, "STRALSUND" },
{ 24, "SZCZECIN" },
{ 24, "WISMAR" },
{ 25, "AUGSBURG" },
{ 25, "DEGGENDORF" },
{ 25, "INGOLSTADT" },
{ 25, "LANDSHUT" },
{ 25, "PASSAU" },
{ 25, "REGENSBURG" },
{ 25, "ULM" },
{ 26, "BURGHAUSEN" },
{ 26, "FRIEDRICHSHAFEN" },
{ 26, "KEMPTEN" },
{ 26, "LINZ" },
{ 26, "MUENCHEN" },
{ 26, "ROSENHEIM" },
{ 26, "SIGMARINGEN" },
{ 26, "WELS" },
{ 27, "BOLZANO" },
{ 27, "MERANO" },
{ 27, "TRENTO" },
{ 28, "ANSBACH" },
{ 28, "BAMBERG" },
{ 28, "BAYREUTH" },
{ 28, "ERLANGEN" },
{ 28, "FUERTH" },
{ 28, "NUERNBERG" },
{ 28, "SCHWEINFURT" },
{ 28, "WEIDEN" },
{ 28, "WERTHEIM" },
{ 28, "WUERZBURG" },
{ 29, "ALTENBURG" },
{ 29, "BAUTZEN" },
{ 29, "CHEMNITZ" },
{ 29, "COTTBUS" },
{ 29, "DESSAU" },
{ 29, "DRESDEN" },
{ 29, "EISENHUETTENSTADT" },
{ 29, "GOERLITZ" },
{ 29, "HALLE" },
{ 29, "HOYERSWERDA" },
{ 29, "LEIPZIG" },
{ 29, "WITTENBERG" },
{ 29, "WROCLAW" },
{ 30, "EISENACH" },
{ 30, "ERFURT" },
{ 30, "GOTHA" },
{ 30, "HOF" },
{ 30, "JENA" },
{ 30, "NORDHAUSEN" },
{ 30, "PLAUEN" },
{ 30, "SUHL" },
{ 30, "WEIMAR" },
{ 30, "ZWICKAU" },
{ 31, "EVIAN" },
{ 31, "FRIBOURG" },
{ 31, "GENEVE" },
{ 31, "LAUSANNE" },
{ 31, "MONTREUX" },
{ 31, "NEUCHATEL" },
{ 32, "AARAU" },
{ 32, "BERN" },
{ 32, "BIENNE" },
{ 32, "FRAUENFELD" },
{ 32, "KONSTANZ" },
{ 32, "LUZERN" },
{ 32, "SCHAFFHAUSEN" },
{ 32, "SOLOTHURN" },
{ 32, "ZUERICH" },
{ 32, "ZUG" },
{ 33, "ADELBODEN" },
{ 33, "GRINDELWALD" },
{ 33, "INTERLAKEN" },
{ 34, "BRIG" },
{ 34, "MARTIGNY" },
{ 34, "SION" },
{ 35, "ALTDORF" },
{ 35, "GLARUS" },
{ 35, "SARNEN" },
{ 35, "SCHWYZ" },
{ 35, "STANS" },
{ 35, "ST.GALLEN" },
{ 36, "CHUR" },
{ 36, "DAVOS" },
{ 37, "FULDA" },
{ 37, "GIESSEN" },
{ 37, "GOETTINGEN" },
{ 37, "KASSEL" },
{ 37, "MARBURG" },
{ 38, "BELLINZONA" },
{ 38, "EDOLO" },
{ 38, "LOCARNO" },
{ 38, "LUGANO" },
{ 39, "AOSTA" },
{ 39, "SESTRIERE" },
{ 40, "ALESSANDRIA" },
{ 40, "BERGAMO" },
{ 40, "BRESCIA" },
{ 40, "MILANO" },
{ 40, "PARMA" },
{ 40, "PIACENZA" },
{ 40, "TORINO" },
{ 40, "VERONA" },
{ 41, "FIRENZE" },
{ 41, "PERUGIA" },
{ 41, "PISA" },
{ 41, "ROMA" },
{ 41, "SIENA" },
{ 41, "VATICANO" },
{ 42, "AMSTERDAM" },
{ 42, "ARNHEM" },
{ 42, "ASSEN" },
{ 42, "DEN HAAG" },
{ 42, "EINDHOVEN" },
{ 42, "HAARLEM" },
{ 42, "LELYSTAD" },
{ 42, "ROTTERDAM" },
{ 42, "S.HERTOGENBOSCH" },
{ 42, "UTRECHT" },
{ 42, "ZWOLLE" },
{ 43, "CANNES" },
{ 43, "GENOVA" },
{ 43, "LA SPEZIA" },
{ 43, "MONACO" },
{ 43, "NICE" },
{ 43, "SAN REMO" },
{ 44, "BOLOGNA" },
{ 44, "NOVA GORIC" },
{ 44, "RIJEKA" },
{ 44, "RIMINI" },
{ 44, "TRIESTE" },
{ 44, "UDINE" },
{ 44, "VENEZIA" },
{ 45, "BASEL" },
{ 45, "BELFORT" },
{ 45, "COLMAR" },
{ 45, "FREIBURG" },
{ 45, "LIESTAL" },
{ 45, "LOERRACH" },
{ 45, "MULHOUSE" },
{ 45, "OFFENBURG" },
{ 45, "STRASBOURG" },
{ 46, "GRAZ" },
{ 46, "KLAGENFURT" },
{ 46, "LIENZ" },
{ 46, "LJUBLJANA" },
{ 46, "MARIBOR" },
{ 46, "SEMMERING" },
{ 46, "VILLACH" },
{ 46, "ZELTWEG" },
{ 47, "BAD GASTEIN" },
{ 47, "INNSBRUCK" },
{ 47, "ISCHGL" },
{ 47, "LANDECK" },
{ 47, "SOELDEN" },
{ 47, "TUXERTAL" },
{ 48, "BAD TOELZ" },
{ 48, "BERCHTESGADEN" },
{ 48, "BISCHOFSHOFEN" },
{ 48, "BREGENZ" },
{ 48, "GARMISCH PARTENKIRCHEN" },
{ 48, "KITZBUEHEL" },
{ 48, "LINDAU" },
{ 48, "SALZBURG" },
{ 48, "SCHLADMING" },
{ 48, "STEYR" },
{ 48, "VADUZ" },
{ 49, "BRATISLAVA" },
{ 49, "EISENSTADT" },
{ 49, "GYOER" },
{ 49, "KLOSTERNEUBURG" },
{ 49, "SOPRON" },
{ 49, "SZOMBATHELY" },
{ 49, "TRENCIN" },
{ 49, "WIEN" },
{ 49, "WIENER NEUSTADT" },
{ 49, "ZALAEGERSZEG" },
{ 50, "BRNO" },
{ 50, "BUDEJOVICE" },
{ 50, "CHEB" },
{ 50, "HAVLICKAV BROD" },
{ 50, "HRADEC/KRA" },
{ 50, "JIHLAVA" },
{ 50, "KARLOVY VARY" },
{ 50, "KLADNO" },
{ 50, "MOST" },
{ 50, "OLOMOUC" },
{ 50, "OSTRAVA" },
{ 50, "PARDUBICE" },
{ 50, "PLZEN" },
{ 50, "PRAHA" },
{ 50, "PREROV" },
{ 50, "PROSTEJOV" },
{ 50, "ST POELTEN" },
{ 50, "ZWETTL" },
{ 51, "CHOMUTOV" },
{ 51, "DECIN" },
{ 51, "LIBEREC" },
{ 51, "OPAVA" },
{ 51, "PIRNA" },
{ 51, "SNIEZKA" },
{ 51, "TEPLICE" },
{ 51, "USTI NAD LABEM" },
{ 51, "WALBRZYCH" },
{ 52, "BERLIN" },
{ 52, "BRANDENBURG" },
{ 52, "FINOW" },
{ 52, "FRANKFURT AN DER ODER" },
{ 52, "GORZOW" },
{ 52, "NEUBRANDENBURG" },
{ 52, "POTSDAM" },
{ 52, "POZNAN" },
{ 52, "STENDAL" },
{ 53, "GOETEBORG" },
{ 53, "HALMSTAD" },
{ 54, "GAEVLE" },
{ 54, "NYKOPING" },
{ 54, "STOCKHOLM" },
{ 54, "UPPSALA" },
{ 54, "VAESTERAS" },
{ 55, "BORGHOLM" },
{ 55, "BORNHOLM" },
{ 55, "KALMAR" },
{ 55, "LINKOEPING" },
{ 55, "RONNE" },
{ 55, "VISBY" },
{ 56, "BORAS" },
{ 56, "JOENKOEPING" },
{ 56, "KARLSTAD" },
{ 56, "OEREBRO" },
{ 57, "BADEN-BADEN" },
{ 57, "DONAUESCHINGEN" },
{ 57, "FREUDENSTADT" },
{ 57, "VILLINGEN-SCHWENNINGEN" },
{ 58, "DRAMMEN" },
{ 58, "FREDRIKSTADEN" },
{ 58, "OSLO" },
{ 58, "TOENSBERG" },
{ 59, "AALEN" },
{ 59, "GOEPPINGEN" },
{ 59, "HEILBRONN" },
{ 59, "PFORZHEIM" },
{ 59, "REUTLINGEN" },
{ 59, "SCHWAEBISCH GMUEND" },
{ 59, "STUTTGART" },
{ 59, "TUEBINGEN" },
{ 60, "NAPOLI" },
{ 61, "ANCONA" },
{ 61, "PESCARA" },
{ 61, "SAN MARINO" },
{ 62, "BARI" },
{ 62, "FOGGIA" },
{ 62, "LECCE" },
{ 63, "BEKESCSABA" },
{ 63, "BRANSKA" },
{ 63, "BUDAPEST" },
{ 63, "DEBRECEN" },
{ 63, "DUNAIJVAROS" },
{ 63, "EGER" },
{ 63, "ERD" },
{ 63, "HODMEZOVASARHELY" },
{ 63, "KAPOSVAR" },
{ 63, "KECSKEMET" },
{ 63, "KOSICE" },
{ 63, "MISKOLC" },
{ 63, "NAGYKANIZSA" },
{ 63, "NYIREGYHAZA" },
{ 63, "OZD" },
{ 63, "PECS" },
{ 63, "SALGOTARJAN" },
{ 63, "SIOFOK" },
{ 63, "SZEGED" },
{ 63, "SZEKESFEEVAR" },
{ 63, "SZOLNOK" },
{ 63, "TATABANYA" },
{ 63, "VESZPREM" },
{ 64, "MADRID" },
{ 65, "BILBAO" },
{ 66, "CATANIA" },
{ 66, "COSENZA" },
{ 66, "MESSINA" },
{ 66, "PALERMO" },
{ 66, "REGGIO CALABRIA" },
{ 67, "IBIZA" },
{ 67, "MAHON" },
{ 67, "PALMA DE MALLORCA" },
{ 68, "VALENCIA" },
{ 69, "BARCELONA" },
{ 69, "FIGUERES" },
{ 69, "GIRONA" },
{ 69, "LLORET DE MAR" },
{ 70, "ANDORRA LA VELLA" },
{ 71, "SEVILLA" },
{ 72, "LISBOA" },
{ 73, "AJACCIO" },
{ 73, "BASTIA" },
{ 73, "CAGLIARI" },
{ 73, "SASSARI" },
{ 74, "GIJON" },
{ 75, "CORK" },
{ 75, "GALWAY" },
{ 75, "LIMERICK" },
{ 76, "BELFAST" },
{ 76, "DUBLIN" },
{ 77, "ABERDEEN" },
{ 77, "EDINBURGH" },
{ 77, "GLASGOW" },
{ 77, "ISLE OF MAN" },
{ 78, "BERGEN" },
{ 78, "STAVANGER" },
{ 79, "TRONDHEIM" },
{ 80, "SUNDSVALL" },
{ 81, "GDANSK" },
{ 81, "OLSZTYN" },
{ 81, "SLUPSK" },
{ 82, "BIALYSTOK" },
{ 82, "BYDGOSZCZ" },
{ 82, "LODZ" },
{ 82, "LUBLIN" },
{ 82, "TORUN" },
{ 82, "WARSZAWA" },
{ 83, "BIELSKO" },
{ 83, "KATOWICE" },
{ 83, "KIELCE" },
{ 83, "KRAKOW" },
{ 83, "OPOLE" },
{ 83, "RZESZOW" },
{ 83, "ZAKOPANE" },
{ 84, "UMEA" },
{ 85, "FALUN" },
{ 85, "OESTERSUND" },
{ 86, "SAMEDAN" },
{ 87, "OSIJEK" },
{ 87, "ZAGREB" },
{ 88, "ZERMATT" },
{ 89, "SPLIT" },
{ 24, "Doerphof" },
{ -1, NULL }
};
void display_city(const char *search)
{
int i;
int found = 0;
for (i = 0; city_list[i].name; i++) {
if (strcasestr(city_list[i].name, search)) {
found++;
printf("City %s is located in region %d.\n", city_list[i].name, city_list[i].region);
}
}
if (!found) {
printf("No city found for '%s', try larger city.\n", search);
}
}

View File

@ -1,3 +0,0 @@
void display_city(const char *search);

File diff suppressed because it is too large Load Diff

View File

@ -1,76 +0,0 @@
#include "../libsample/sample.h"
#include "../libfilter/iir_filter.h"
#include "../libdisplay/display.h"
#include <time.h>
typedef struct dcf77_tx {
int enable;
double phase_360;
double carrier_phase, carrier_phase_step; /* uncorrected phase */
double test_phase, test_phase_step;
double level;
int wave, waves_0, waves_1, waves_sec;
time_t timestamp;
int second;
char symbol;
uint64_t data_frame;
char data_string[100]; /* 60 digits + spaces + '\0' */
int test_tone;
int weather;
int weather_day;
int weather_night;
int extreme;
int rain;
int wind_dir;
int wind_bft;
int temperature_day;
int temperature_night;
uint64_t weather_cipher;
} dcf77_tx_t;
typedef struct dcf77_rx {
int enable;
double phase_360;
double carrier_phase, carrier_phase_step; /* uncorrected phase */
iir_filter_t carrier_lp[2]; /* filters received carrier signal */
double sample_counter, sample_step; /* when to sample */
double *delay_buffer;
int delay_size, delay_index;
int clock_count;
double value_level, value_short, value_long; /* measured values */
int data_receive, data_index;
char data_string[100]; /* 60 digits + spaces + '\0' */
int string_index;
uint64_t data_frame;
int weather_index;
uint64_t weather_cipher;
uint64_t weather_key;
} dcf77_rx_t;
typedef struct dcf77 {
dcf77_tx_t tx;
dcf77_rx_t rx;
/* measurements */
dispmeas_t dispmeas; /* display measurements */
dispmeasparam_t *dmp_input_level;
dispmeasparam_t *dmp_signal_level;
dispmeasparam_t *dmp_signal_quality;
dispmeasparam_t *dmp_current_second;
/* wave */
dispwav_t dispwav; /* display wave form */
} dcf77_t;
int dcf77_init(int _fast_math);
void dcf77_exit(void);
dcf77_t *dcf77_create(int samplerate, int use_tx, int use_rx, int test_tone);
void dcf77_destroy(dcf77_t *dcf77);
void dcf77_tx_start(dcf77_t *dcf77, time_t timestamp, double sub_sec);
void dcf77_encode(dcf77_t *dcf77, sample_t *samples, int length);
void dcf77_decode(dcf77_t *dcf77, sample_t *samples, int length);
void list_weather(void);
time_t dcf77_start_weather(time_t timestamp, int region, int offset);
void dcf77_set_weather(dcf77_t *dcf77, int weather_day, int weather_night, int extreme, int rain, int wind_dir, int wind_bft, int temperature_day, int temperature_night);

View File

@ -1,16 +0,0 @@
#include <stdio.h>
const char *aaimage[] = {
"",
"@W * DCF77 with weather info *",
"",
" @Y\\__/",
" @w_______@Y/ \\__",
" @w/ ____\\_@Y/@w_",
" \\___/@r10:08:33@w\\",
" @B/ @w\\________/",
" @B/ @W*@B/ @W*@B/ @W*@B/ @W*@B/",
" @W*@B/ @W*@B/ @W*@B/ @W*@B/",
"",
NULL
};

View File

@ -1,644 +0,0 @@
/* DCF77 main
*
* (C) 2022 by Andreas Eversberg <jolly@eversberg.eu>
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <termios.h>
#include <sched.h>
#include <time.h>
#include <math.h>
#include "../libdebug/debug.h"
#include "../liboptions/options.h"
#include "../libsample/sample.h"
#include "../libsound/sound.h"
#include "../libaaimage/aaimage.h"
#include "dcf77.h"
#include "cities.h"
int num_kanal = 1;
dcf77_t *dcf77 = NULL;
static void *soundif = NULL;
static const char *dsp_device = "";
static int dsp_samplerate = 192000;
static int dsp_buffer = 50;
static int rx = 0, tx = 0;
static double timestamp = -1;
static int weather = 0;
static int weather_day;
static int weather_night;
static int extreme;
static int rain;
static int wind_dir;
static int wind_bft;
static int temperature_day;
static int temperature_night;
static int region = -1, region_advance;
static int double_amplitude = 0;
static int test_tone = 0;
static int dsp_interval = 1; /* ms */
static int rt_prio = 1;
static int fast_math = 0;
/* not static, in case we add libtimer some day, then compiler hits an error */
double get_time(void)
{
static struct timespec tv;
clock_gettime(CLOCK_REALTIME, &tv);
return (double)tv.tv_sec + (double)tv.tv_nsec / 1000000000.0;
}
static time_t parse_time(char **argv)
{
time_t t;
struct tm *tm;
int val;
t = get_time();
tm = localtime(&t);
if (!tm)
return -1;
val = atoi(argv[0]);
if (val < 1900)
return -1;
tm->tm_year = val - 1900;
val = atoi(argv[1]);
if (val < 1 || val > 12)
return -1;
tm->tm_mon = val - 1;
val = atoi(argv[2]);
if (val < 1 || val > 31)
return -1;
tm->tm_mday = val;
val = atoi(argv[3]);
if (val < 0 || val > 23)
return -1;
tm->tm_hour = val;
val = atoi(argv[4]);
if (val < 0 || val > 59)
return -1;
tm->tm_min = val;
val = atoi(argv[5]);
if (val < 0 || val > 59)
return -1;
tm->tm_sec = val;
tm->tm_isdst = -1;
return mktime(tm);
}
static time_t feierabend_time()
{
time_t t;
struct tm *tm;
t = get_time();
tm = localtime(&t);
tm->tm_hour = 17;
tm->tm_min = 0;
tm->tm_sec = 0;
tm->tm_isdst = -1;
return mktime(tm);
}
static void print_usage(const char *app)
{
printf("Usage: %s [-a hw:0,0] [<options>]\n", app);
}
void print_help(void)
{
/* - - */
printf(" -h --help\n");
printf(" This help\n");
printf(" --config [~/]<path to config file>\n");
printf(" Give a config file to use. If it starts with '~/', path is at home dir.\n");
printf(" Each line in config file is one option, '-' or '--' must not be given!\n");
debug_print_help();
printf(" -a --audio-device hw:<card>,<device>\n");
printf(" Sound card and device number (default = '%s')\n", dsp_device);
printf(" -s --samplerate <rate>\n");
printf(" Sample rate of sound device (default = '%d')\n", dsp_samplerate);
printf(" -b --buffer <ms>\n");
printf(" How many milliseconds are processed in advance (default = '%d')\n", dsp_buffer);
printf(" A buffer below 10 ms requires low interval like 0.1 ms.\n");
printf(" -T --tx\n");
printf(" Transmit time signal (default)\n");
printf(" -R --rx\n");
printf(" Receive time signal\n");
printf(" -F --fake\n");
printf(" Use given time stamp: <year> <month> <day> <hour> <min> <sec>.\n");
printf(" All values have to be numerical. The year must have 4 digits.\n");
printf(" --feierabend\n");
printf(" --end-of-working-day\n");
printf(" Use fake time stamp that equals 5 O'Clock PM.\n");
printf(" --geburtstag\n");
printf(" --birthday\n");
printf(" Use fake time stamp that equals birth of the author.\n");
printf(" -W --weather <weather> <extreme> <rain> <wind dir> <wind bft> <temperature>\n");
printf(" Send these weather info for all regions / all days.\n");
printf(" See -L for infos on values.\n");
printf(" weather = 1..15 for common day and night weather.\n");
printf(" weather = 1..15,1..15 for specific day and night weather.\n");
printf(" extreme = 0..15 for extreme weather conditions.\n");
printf(" rain = 0..100 for rain/show probability. (closest is used)\n");
printf(" wind dir = N | NE | E | SE | S | SW | W | NW | 0 for wind direction.\n");
printf(" wind bft = <bft> for wind speed in bft. (closest is used)\n");
printf(" temerature = <celsius> for common min and max temperature.\n");
printf(" temerature = <celsius>,<celsius> for specific min and max temperature.\n");
printf(" --beach-party\n");
printf(" Beach weather, equivalent to -W 1 0 0 0 2 35,20\n");
printf(" --santa-claus\n");
printf(" --muenster-2005\n");
printf(" Deep snow, equivalent to -W 7 1 100 E 3 1,-1\n");
printf(" -A --at-region <region> <advance minutes>\n");
printf(" Alter time, so that the weather of the given region is transmitted.\n");
printf(" To allow the receiver to sync, give time to advance in minutes.\n");
printf(" -L --list\n");
printf(" List all regions / weather values.\n");
printf(" -C --city <name fragment>\n");
printf(" Search for city (case insensitive) and display its region code.\n");
printf(" -D --double-amplitude\n");
printf(" Transmit with double amplitude by using differential stereo output.\n");
printf(" --test-tone\n");
printf(" Transmit a test tone (10%% level, 1000 Hz) with the carrier.\n");
printf(" -r --realtime <prio>\n");
printf(" Set prio: 0 to disable, 99 for maximum (default = %d)\n", rt_prio);
printf(" --fast-math\n");
printf(" Use fast math approximation for slow CPU / ARM based systems.\n");
printf("\n");
printf("Press 'w' key to toggle display of RX wave form.\n");
printf("Press 'm' key to toggle display of measurement values.\n");
}
#define OPT_F1 1001
#define OPT_F2 1002
#define OPT_G1 1003
#define OPT_G2 1004
#define OPT_BEACH 1005
#define OPT_SANTA 1006
#define OPT_MUENSTER 1007
#define OPT_TEST_TONE 1008
#define OPT_FAST_MATH 1009
static void add_options(void)
{
option_add('h', "help", 0);
option_add('v', "verbose", 1);
option_add('a', "audio-device", 1);
option_add('s', "samplerate", 1);
option_add('b', "buffer", 1);
option_add('T', "tx", 0);
option_add('R', "rx", 0);
option_add('F', "fake", 6);
option_add(OPT_F1, "feierabend", 0);
option_add(OPT_F2, "end-of-working-day", 0);
option_add(OPT_G1, "geburtstag", 0);
option_add(OPT_G2, "birthday", 0);
option_add('W', "weather", 6);
option_add(OPT_BEACH, "beach-party", 0);
option_add(OPT_SANTA, "santa-claus", 0);
option_add(OPT_MUENSTER, "muenster-2005", 0);
option_add('A', "at-region", 2);
option_add('L', "list", 0);
option_add('C', "city", 1);
option_add('D', "double-amplitude", 0);
option_add(OPT_TEST_TONE, "test-tone", 0);
option_add('r', "realtime", 1);
option_add(OPT_FAST_MATH, "fast-math", 0);
}
static const char *wind_dirs[8] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW" };
static int handle_options(int short_option, int argi, char **argv)
{
char *string, *string1;
int rc, i;
switch (short_option) {
case 'h':
print_usage(argv[0]);
print_help();
return 0;
case 'v':
if (!strcasecmp(argv[argi], "list")) {
debug_list_cat();
return 0;
}
rc = parse_debug_opt(argv[argi]);
if (rc < 0) {
fprintf(stderr, "Failed to parse debug option, please use -h for help.\n");
return rc;
}
break;
case 'a':
dsp_device = options_strdup(argv[argi]);
break;
case 's':
dsp_samplerate = atoi(argv[argi]);
break;
case 'b':
dsp_buffer = atoi(argv[argi]);
break;
case 'T':
tx = 1;
break;
case 'R':
rx = 1;
break;
case 'F':
timestamp = parse_time(argv + argi);
if (timestamp < 0) {
fprintf(stderr, "Given time stamp is invalid, please use -h for help.\n");
return -EINVAL;
}
break;
case OPT_F1:
case OPT_F2:
timestamp = feierabend_time() - 70;
break;
case OPT_G1:
case OPT_G2:
timestamp = 115099200 - 70;
break;
case 'W':
if (weather) {
no_multiple_weathers:
fprintf(stderr, "You cannot define more than one weather situation.\n");
return -EINVAL;
}
weather = 1;
string = options_strdup(argv[argi++]);
string1 = strsep(&string, ",");
weather_day = atoi(string1);
if (string)
weather_night = atoi(string);
else
weather_night = weather_day;
extreme = atoi(argv[argi++]);
rain = atoi(argv[argi++]);
/* if wind is not found, wind 8 (changable) is selected */
string = options_strdup(argv[argi++]);
for (i = 0; i < 8; i++) {
if (!strcasecmp(string, wind_dirs[i]))
break;
}
wind_dir = i;
wind_bft = atoi(argv[argi++]);
string = options_strdup(argv[argi++]);
string1 = strsep(&string, ",");
temperature_day = atoi(string1);
if (string)
temperature_night = atoi(string);
else
temperature_night = temperature_day;
break;
case OPT_BEACH:
if (weather)
goto no_multiple_weathers;
weather = 1;
weather_day = 1;
weather_night = 1;
extreme = 0;
rain = 0;
wind_dir = 8;
wind_bft = 2;
temperature_day = 35;
temperature_night = 20; /* tropical night >= 20 */
break;
case OPT_SANTA:
case OPT_MUENSTER:
if (weather)
goto no_multiple_weathers;
weather = 1;
weather_day = 7;
weather_night = 7;
extreme = 0;
rain = 100;
wind_dir = 6;
wind_bft = 3;
temperature_day = 1;
temperature_night = -1; /* freezing a little */
break;
case 'A':
region = atoi(argv[argi++]);
if (region < 0 || region > 89) {
fprintf(stderr, "Given region number is is invalid, please use -L for list of valid regions.\n");
return -EINVAL;
}
region_advance = atoi(argv[argi++]);
break;
case 'L':
list_weather();
return 0;
case 'C':
display_city(argv[argi++]);
return 0;
case OPT_TEST_TONE:
test_tone = 1;
break;
case 'D':
double_amplitude = 1;
break;
case 'r':
rt_prio = atoi(argv[argi]);
break;
case OPT_FAST_MATH:
fast_math = 1;
break;
default:
return -EINVAL;
}
return 1;
}
static int quit = 0;
static void sighandler(int sigset)
{
if (sigset == SIGHUP || sigset == SIGPIPE)
return;
fprintf(stderr, "\nSignal %d received.\n", sigset);
quit = 1;
}
static int get_char()
{
struct timeval tv = {0, 0};
fd_set fds;
char c = 0;
int __attribute__((__unused__)) rc;
FD_ZERO(&fds);
FD_SET(0, &fds);
select(0+1, &fds, NULL, NULL, &tv);
if (FD_ISSET(0, &fds)) {
rc = read(0, &c, 1);
return c;
} else
return -1;
}
int soundif_open(const char *audiodev, int samplerate, int buffer_size)
{
if (!audiodev || !audiodev[0]) {
PDEBUG(DDSP, DEBUG_ERROR, "No audio device given!\n");
return -EINVAL;
}
/* open audiodev */
soundif = sound_open(audiodev, NULL, NULL, NULL, (double_amplitude) ? 2 : 1, 0.0, samplerate, buffer_size, 1.0, 1.0, 0.0, 2.0);
if (!soundif) {
PDEBUG(DDSP, DEBUG_ERROR, "Failed to open sound device!\n");
return -EIO;
}
return 0;
}
void soundif_start(void)
{
sound_start(soundif);
PDEBUG(DDSP, DEBUG_DEBUG, "Starting audio stream!\n");
}
void soundif_close(void)
{
/* close audiodev */
if (soundif) {
sound_close(soundif);
soundif = NULL;
}
}
void soundif_work(int buffer_size)
{
int count;
sample_t buff1[buffer_size], buff2[buffer_size], *samples[2] = { buff1, buff2 };
double rf_level_db[2];
int rc;
int i;
/* encode and write */
count = sound_get_tosend(soundif, buffer_size);
if (count < 0) {
PDEBUG(DDSP, DEBUG_ERROR, "Failed to get number of samples in buffer (rc = %d)!\n", count);
return;
}
if (count) {
dcf77_encode(dcf77, samples[0], count);
if (double_amplitude) {
for (i = 0; i < count; i++)
samples[1][i] = -samples[0][i];
}
rc = sound_write(soundif, samples, NULL, count, NULL, NULL, (double_amplitude) ? 2 : 1);
if (rc < 0) {
PDEBUG(DDSP, DEBUG_ERROR, "Failed to write TX data to audio device (rc = %d)\n", rc);
return;
}
}
/* read */
count = sound_read(soundif, samples, buffer_size, 1, rf_level_db);
if (count < 0) {
PDEBUG(DDSP, DEBUG_ERROR, "Failed to read from audio device (rc = %d)!\n", count);
return;
}
/* decode */
dcf77_decode(dcf77, samples[0], count);
}
int main(int argc, char *argv[])
{
int rc, argi;
int buffer_size;
struct termios term, term_orig;
double begin_time, now, sleep;
char c;
/* handle options / config file */
add_options();
rc = options_config_file(argc, argv, "~/.osmocom/dcf77/dcf77.conf", handle_options);
if (rc < 0)
return 0;
argi = options_command_line(argc, argv, handle_options);
if (argi <= 0)
return argi;
if (dsp_samplerate < 192000) {
fprintf(stderr, "The sample rate must be at least 192000 to TX or RX 77.5 kHz. Quitting!\n");
goto error;
}
/* default to TX, if --tx and --rx was not set */
if (!tx && !rx)
tx = 1;
/* inits */
dcf77_init(fast_math);
/* size of dsp buffer in samples */
buffer_size = dsp_samplerate * dsp_buffer / 1000;
rc = soundif_open(dsp_device, dsp_samplerate, buffer_size);
if (rc < 0) {
printf("Failed to open sound for DCF77, use '-h' for help.\n");
goto error;
}
dcf77 = dcf77_create(dsp_samplerate, tx, rx, test_tone);
if (!dcf77) {
fprintf(stderr, "Failed to create \"DCF77\" instance. Quitting!\n");
goto error;
}
if (weather)
dcf77_set_weather(dcf77, weather_day, weather_night, extreme, rain, wind_dir, wind_bft, temperature_day, temperature_night);
/* no time stamp given, so we use our clock */
if (tx) {
if (timestamp < 0 && region < 0)
printf("No alternative time given, so you might not notice the difference between our transmission and the real DCF77 transmission.\n");
if (timestamp < 0)
timestamp = get_time();
if (region >= 0 && weather)
timestamp = dcf77_start_weather((time_t)timestamp, region, region_advance);
}
print_aaimage();
printf("DCF77 ready.\n");
/* prepare terminal */
tcgetattr(0, &term_orig);
term = term_orig;
term.c_lflag &= ~(ISIG|ICANON|ECHO);
term.c_cc[VMIN]=1;
term.c_cc[VTIME]=2;
tcsetattr(0, TCSANOW, &term);
/* set real time prio */
if (rt_prio) {
struct sched_param schedp;
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = rt_prio;
rc = sched_setscheduler(0, SCHED_RR, &schedp);
if (rc)
fprintf(stderr, "Error setting SCHED_RR with prio %d\n", rt_prio);
}
signal(SIGINT, sighandler);
signal(SIGHUP, sighandler);
signal(SIGTERM, sighandler);
signal(SIGPIPE, sighandler);
soundif_start();
if (tx)
dcf77_tx_start(dcf77, (time_t)timestamp, fmod(timestamp, 1.0));
while (!quit) {
int w;
begin_time = get_time();
soundif_work(buffer_size);
do {
w = 0;
} while (w);
c = get_char();
switch (c) {
case 3:
printf("CTRL+c received, quitting!\n");
quit = 1;
break;
case 'w':
/* toggle wave display */
display_measurements_on(0);
display_wave_on(-1);
break;
case 'm':
/* toggle measurements display */
display_wave_on(0);
display_measurements_on(-1);
break;
default:
break;
}
display_measurements(dsp_interval / 1000.0);
now = get_time();
/* sleep interval */
sleep = ((double)dsp_interval / 1000.0) - (now - begin_time);
if (sleep > 0)
usleep(sleep * 1000000.0);
}
signal(SIGINT, SIG_DFL);
signal(SIGTSTP, SIG_DFL);
signal(SIGHUP, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
/* reset real time prio */
if (rt_prio > 0) {
struct sched_param schedp;
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = 0;
sched_setscheduler(0, SCHED_OTHER, &schedp);
}
/* reset terminal */
tcsetattr(0, TCSANOW, &term_orig);
error:
/* destroy UK0 instances */
if (dcf77)
dcf77_destroy(dcf77);
soundif_close();
dcf77_exit();
options_free();
return 0;
}

View File

@ -1,582 +0,0 @@
/* based on code found at:
https://github.com/FroggySoft/AlarmClock/blob/master/dcf77.cpp
https://github.com/tobozo/esp32-dcf77-weatherman/blob/master/dcf77.cpp
*/
#include <stdio.h>
#include <stdint.h>
#include <endian.h>
#include "../libdebug/debug.h"
#include "weather.h"
/// Container zum Konvertieren zwischen 4 Bytes und Uint.
union ByteUInt {
struct {
# if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t Byte0;
uint8_t Byte1;
uint8_t Byte2;
uint8_t Byte3;
# elif __BYTE_ORDER == __BIG_ENDIAN
uint8_t Byte3;
uint8_t Byte2;
uint8_t Byte1;
uint8_t Byte0;
# else
#error unsupported bitorder, please fix
# endif
} s;
uint32_t FullUint;
};
/// bit pattern for 0D,0E from 0B-0D
static const uint32_t mUintArrBitPattern12[12] = {
0x80000, //0b10000000000000000000 / 0D.3
0x00010, //0b00000000000000010000 / 0B.4
0x00008, //0b00000000000000001000 / 0B.3
0x00100, //0b00000000000100000000 / 0C.0
0x00080, //0b00000000000010000000 / 0B.7
0x01000, //0b00000001000000000000 / 0C.4
0x00800, //0b00000000100000000000 / 0C.3
0x10000, //0b00010000000000000000 / 0D.0
0x08000, //0b00001000000000000000 / 0C.7
0x00001, //0b00000000000000000001 / 0B.0
0x00000, //0b00000000000000000000 / xxxx
0x00000 //0b00000000000000000000 / xxxx
};
/// 12-15 from 16-19 (time)
static const uint32_t mUintArrBitPattern30_1[30] = {
0x00000200, //0b00000000000000000000001000000000 / 17.1
0x00000020, //0b00000000000000000000000000100000 / 16.5
0x02000000, //0b00000010000000000000000000000000 / 19.1
0x00000000, //0b00000000000000000000000000000000 / 1A.3
0x00000000, //0b00000000000000000000000000000000 / 1A.5
0x00000080, //0b00000000000000000000000010000000 / 16.7
0x40000000, //0b01000000000000000000000000000000 / 19.6
0x01000000, //0b00000001000000000000000000000000 / 19.0
0x04000000, //0b00000100000000000000000000000000 / 19.2
0x00000000, //0b00000000000000000000000000000000 / 1A.4
0x00010000, //0b00000000000000010000000000000000 / 18.0
0x00000000, //0b00000000000000000000000000000000 / 1A.2
0x00400000, //0b00000000010000000000000000000000 / 18.6
0x00000010, //0b00000000000000000000000000010000 / 16.4
0x00200000, //0b00000000001000000000000000000000 / 18.5
0x00080000, //0b00000000000010000000000000000000 / 18.3
0x00004000, //0b00000000000000000100000000000000 / 17.6
0x00000000, //0b00000000000000000000000000000000 / 1A.6
0x00020000, //0b00000000000000100000000000000000 / 18.1
0x00100000, //0b00000000000100000000000000000000 / 18.4
0x00008000, //0b00000000000000001000000000000000 / 17.7
0x00000040, //0b00000000000000000000000001000000 / 16.6
0x00001000, //0b00000000000000000001000000000000 / 17.4
0x00000400, //0b00000000000000000000010000000000 / 17.2
0x00000001, //0b00000000000000000000000000000001 / 16.0
0x80000000, //0b10000000000000000000000000000000 / 19.7
0x00000008, //0b00000000000000000000000000001000 / 16.3
0x00000002, //0b00000000000000000000000000000010 / 16.1
0x00040000, //0b00000000000001000000000000000000 / 18.2
0x10000000 //0b00010000000000000000000000000000 / 19.4
};
/// bit pattern for 12-15 from 1A (time2)
static const uint32_t mUintArrBitPattern30_2[30] = {
0x00, //0b00000000, /* 17.1
0x00, //0b00000000, /* 16.5
0x00, //0b00000000, /* 19.1
0x08, //0b00001000, /* 1A.3
0x20, //0b00100000, /* 1A.5
0x00, //0b00000000, /* 16.7
0x00, //0b00000000, /* 19.6
0x00, //0b00000000, /* 19.0
0x00, //0b00000000, /* 19.2
0x10, //0b00010000, /* 1A.4
0x00, //0b00000000, /* 18.0
0x04, //0b00000100, /* 1A.2
0x00, //0b00000000, /* 18.6
0x00, //0b00000000, /* 16.4
0x00, //0b00000000, /* 18.5
0x00, //0b00000000, /* 18.3
0x00, //0b00000000, /* 17.6
0x40, //0b01000000, /* 1A.6
0x00, //0b00000000, /* 18.1
0x00, //0b00000000, /* 18.4
0x00, //0b00000000, /* 17.7
0x00, //0b00000000, /* 16.6
0x00, //0b00000000, /* 17.4
0x00, //0b00000000, /* 17.2
0x00, //0b00000000, /* 16.0
0x00, //0b00000000, /* 19.7
0x00, //0b00000000, /* 16.3
0x00, //0b00000000, /* 16.1
0x00, //0b00000000, /* 18.2
0x00 //0b00000000, /* 19.4
};
/// 12-14 from 1C-1E (result from F)
static const uint32_t mUintArrBitPattern20[20] = {
0x000004, //0b000000000000000000000100 / 1C.2
0x002000, //0b000000000010000000000000 / 1E.5
0x008000, //0b000000001000000000000000 / 1E.7
0x400000, //0b010000000000000000000000 / 1D.6
0x000100, //0b000000000000000100000000 / 1E.0
0x100000, //0b000100000000000000000000 / 1D.4
0x000400, //0b000000000000010000000000 / 1E.2
0x800000, //0b100000000000000000000000 / 1D.7
0x040000, //0b000001000000000000000000 / 1D.2
0x020000, //0b000000100000000000000000 / 1D.1
0x000008, //0b000000000000000000001000 / 1C.3
0x000200, //0b000000000000001000000000 / 1E.1
0x004000, //0b000000000100000000000000 / 1E.6
0x000002, //0b000000000000000000000010 / 1C.1
0x001000, //0b000000000001000000000000 / 1E.4
0x080000, //0b000010000000000000000000 / 1D.3
0x000800, //0b000000000000100000000000 / 1E.3
0x200000, //0b001000000000000000000000 / 1D.5
0x010000, //0b000000010000000000000000 / 1D.0
0x000001 //0b000000000000000000000001 / 1C.0
};
/// bit pattern for 12-15 from 16-19 (1/3)
static const uint64_t mByteArrLookupTable1C_1[8] = {
0xBB0E22C573DFF76D, 0x90E9A1381C844A56,
0x648D280BD1BA9352, 0x1CC5A7F0E97F364E,
0xC1773DB3AAE00C6F, 0x1488F62BD2995E45,
0x1F7096D3B30BFCEE, 0x8142CA34A5582967
};
/// bit pattern for 12-15 from 16-19 (2/3)
static const uint64_t mByteArrLookupTable1C_2[8] = {
0xAB3DFC7465E60E4F, 0x9711D85983C2BA20,
0xC51BD2584937017D, 0x93FAE02F66B4AC8E,
0xB7CC43FF5866EB35, 0x822A99DD007114AE,
0x4EB1F7701852AA9F, 0xD56BCC3D0483E926
};
/// bit pattern for 12-15 from 16-19 (3/3)
static const uint64_t mByteArrLookupTable1C_3[8] = {
0x0A02000F06070D08, 0x030C0B050901040E,
0x0209050D0C0E0F08, 0x06070B01000A0403,
0x08000D0F010C0306, 0x0B0409050A07020E,
0x030D000C09060F0B, 0x010E080A02070405
};
/// Container, which contains all former global vars
typedef struct DataContainer {
/// Registers R12 to R15
union ByteUInt mByteUint1;
/// Registers R08 to R0A
union ByteUInt mByteUint2;
/// Registers R0B to R0E
union ByteUInt mByteUint3;
/// Registers R1C to R1E
union ByteUInt mByteUint4;
uint8_t mByteUpperTime2;//, mByteR1B;
uint32_t mUintLowerTime;
} DataContainer_t;
static int32_t GetWeatherFromPlain(uint8_t *PlainBytes)
{
uint32_t result;
uint32_t checkSum;
checkSum = PlainBytes[2] & 0x0f;
checkSum <<= 8;
checkSum |= PlainBytes[1];
checkSum <<= 4;
checkSum |= PlainBytes[0] >> 4;
if (checkSum != 0x2501)
return -1;
result = PlainBytes[0] & 0x0f;
result <<= 8;
result |= PlainBytes[4];
result <<= 8;
result |= PlainBytes[3];
result <<= 4;
result |= PlainBytes[2] >> 4;
return result;
}
static uint8_t *GetPlainFromWeather(uint32_t weather)
{
static uint8_t result[5];
weather <<= 4;
result[1] = 0x50;
result[2] = (weather & 0xf0) | 0x02;
weather >>= 8;
result[3] = weather & 0xff;
weather >>= 8;
result[4] = weather & 0xff;
weather >>= 8;
result[0] = (weather & 0x0f) | 0x10;
return result;
}
static void CopyTimeToByteUint(uint8_t *data, uint8_t *key, DataContainer_t *container)
{
int i;
for (i = 0; i < 4; i++)
{
container->mUintLowerTime <<= 8;
container->mUintLowerTime |= key[3 - i];
}
container->mByteUpperTime2 = key[4];
// copy R
container->mByteUint3.s.Byte0 = data[2];
container->mByteUint3.s.Byte1 = data[3];
container->mByteUint3.s.Byte2 = data[4];
container->mByteUint3.FullUint >>= 4;
// copy L
container->mByteUint2.s.Byte0 = data[0];
container->mByteUint2.s.Byte1 = data[1];
container->mByteUint2.s.Byte2 = (uint8_t)(data[2] & 0x0F);
}
static void ShiftTimeRight(int round, DataContainer_t *container)
{
int count;
uint8_t tmp;
if ((round == 16) || (round == 8) || (round == 7) || (round == 3))
count = 2;
else
count = 1;
while (count-- != 0)
{
tmp = 0;
if ((container->mUintLowerTime & 0x00100000) != 0) // save time bit 20
tmp = 1;
container->mUintLowerTime &= 0xFFEFFFFF;
if ((container->mUintLowerTime & 1) != 0)
container->mUintLowerTime |= 0x00100000; // copy time bit 0 to time bit 19
container->mUintLowerTime >>= 1; // time >>= 1
if ((container->mByteUpperTime2 & 1) != 0)
container->mUintLowerTime |= 0x80000000;
container->mByteUpperTime2 >>= 1;
if (tmp != 0)
container->mByteUpperTime2 |= 0x80; // insert time bit 20 to time bit 39
}
}
static void ShiftTimeLeft(int round, DataContainer_t *container)
{
int count;
uint8_t tmp;
if ((round == 16) || (round == 8) || (round == 7) || (round == 3))
count = 2;
else
count = 1;
while (count-- != 0)
{
tmp = 0;
if ((container->mByteUpperTime2 & 0x80) != 0)
tmp = 1;
container->mByteUpperTime2 <<= 1;
if ((container->mUintLowerTime & 0x80000000) != 0)
container->mByteUpperTime2 |= 1;
container->mUintLowerTime <<= 1;
if ((container->mUintLowerTime & 0x00100000) != 0)
container->mUintLowerTime |= 1;
container->mUintLowerTime &= 0xFFEFFFFF;
if (tmp != 0)
container->mUintLowerTime |= 0x00100000;
}
}
static void ExpandR(DataContainer_t *container)
{
uint32_t tmp;
int i;
container->mByteUint3.FullUint &= 0x000FFFFF; // clear 0D(4-7),0E
tmp = 0x00100000; // and set bits form 0B-0D(0-3)
for (i = 0; i < 12; i++)
{
if ((container->mByteUint3.FullUint & mUintArrBitPattern12[i]) != 0)
container->mByteUint3.FullUint |= tmp;
tmp <<= 1;
}
}
static void ExpandL(DataContainer_t *container)
{
uint32_t tmp;
int i;
container->mByteUint2.FullUint &= 0x000FFFFF; // clear 0D(4-7),0E
tmp = 0x00100000; // and set bits form 0B-0D(0-3)
for (i = 0; i < 12; i++)
{
if ((container->mByteUint2.FullUint & mUintArrBitPattern12[i]) != 0)
container->mByteUint2.FullUint |= tmp;
tmp <<= 1;
}
}
static void CompressKey(DataContainer_t *container)
{
uint32_t tmp;
int i;
container->mByteUint1.FullUint = 0; // clear 12-15
tmp = 0x00000001; // and set bits from 16-1A (time)
for (i = 0; i < 30; i++)
{
if ((container->mUintLowerTime & mUintArrBitPattern30_1[i]) != 0 || (container->mByteUpperTime2 & mUintArrBitPattern30_2[i]) != 0)
container->mByteUint1.FullUint |= tmp;
tmp <<= 1;
}
}
static void DoSbox(DataContainer_t *container)
{
uint8_t tmp, helper; //mByteR1B;
int i;
helper = container->mByteUint1.s.Byte3; // R1B = R15;
container->mByteUint1.s.Byte3 = container->mByteUint1.s.Byte2; // R15 = R14
// INNER LOOP
for (i = 5; i > 0; i--)
{
if ((i & 1) == 0) // round 4,2
{
tmp = (uint8_t)(container->mByteUint1.s.Byte0 >> 4); // swap R12
tmp |= (uint8_t)((container->mByteUint1.s.Byte0 & 0x0f) << 4);
container->mByteUint1.s.Byte0 = tmp;
}
container->mByteUint1.s.Byte3 &= 0xF0; // set R1C
tmp = (uint8_t)((container->mByteUint1.s.Byte0 & 0x0F) | container->mByteUint1.s.Byte3);
if ((i & 4) != 0)
tmp = mByteArrLookupTable1C_1[(tmp & 0x38) >> 3] >> (56 - (tmp & 0x07) * 8);
if ((i & 2) != 0)
tmp = mByteArrLookupTable1C_2[(tmp & 0x38) >> 3] >> (56 - (tmp & 0x07) * 8);
else if (i == 1)
tmp = mByteArrLookupTable1C_3[(tmp & 0x38) >> 3] >> (56 - (tmp & 0x07) * 8);
if ((i & 1) != 0)
container->mByteUint4.s.Byte0 = (uint8_t)(tmp & 0x0F);
else
container->mByteUint4.s.Byte0 |= (uint8_t)(tmp & 0xF0);
if ((i & 1) == 0) // copy 14->13->12, 1C->1E->1D
{
tmp = container->mByteUint1.s.Byte3;
container->mByteUint1.FullUint >>= 8;
container->mByteUint1.s.Byte3 = tmp;
container->mByteUint4.FullUint <<= 8;
}
container->mByteUint1.s.Byte3 >>= 1; // rotate R1B>R15 twice
if ((helper & 1) != 0)
container->mByteUint1.s.Byte3 |= 0x80;
helper >>= 1;
container->mByteUint1.s.Byte3 >>= 1;
if ((helper & 1) != 0)
container->mByteUint1.s.Byte3 |= 0x80;
helper >>= 1;
} // end of inner loop
}
static void DoPbox(DataContainer_t *container)
{
uint32_t tmp;
int i;
container->mByteUint1.FullUint = 0xFF000000; // clear 12-14
tmp = 0x00000001; // and set bits from 1C-1E (result from F)
for (i = 0; i < 20; i++)
{
if ((container->mByteUint4.FullUint & mUintArrBitPattern20[i]) != 0)
container->mByteUint1.FullUint |= tmp;
tmp <<= 1;
}
}
/* modified DES decrypt using strings */
static uint8_t *Decrypt(uint8_t *cipher, uint8_t *key)
{
DataContainer_t container;
int i;
static uint8_t plain[5];
CopyTimeToByteUint(cipher, key, &container);
// OUTER LOOP 1
for (i = 16; i > 0; i--)
{
ShiftTimeRight(i, &container);
ExpandR(&container);
CompressKey(&container);
// expR XOR compr.Key
container.mByteUint1.FullUint ^= container.mByteUint3.FullUint; // 12-15 XOR 0B-0E
container.mByteUint3.s.Byte2 &= 0x0F; // clear 0D(4-7)
DoSbox(&container);
DoPbox(&container);
// L XOR P-Boxed Round-Key (L')
container.mByteUint1.FullUint ^= container.mByteUint2.FullUint;
// L = R
container.mByteUint2.FullUint = container.mByteUint3.FullUint & 0x00FFFFFF;
// R = L'
container.mByteUint3.FullUint = container.mByteUint1.FullUint & 0x00FFFFFF;
} // end of outer loop 1
container.mByteUint3.FullUint <<= 4;
container.mByteUint2.s.Byte2 &= 0x0F;
container.mByteUint2.s.Byte2 |= (uint8_t)(container.mByteUint3.s.Byte0 & 0xF0);
plain[0] = container.mByteUint2.s.Byte0;
plain[1] = container.mByteUint2.s.Byte1;
plain[2] = container.mByteUint2.s.Byte2;
plain[3] = container.mByteUint3.s.Byte1;
plain[4] = container.mByteUint3.s.Byte2;
return plain;
}
/* modified DES encrypt using strings */
static uint8_t *Encrypt(uint8_t *plain, uint8_t *key)
{
static uint8_t cipher[5];
DataContainer_t container;
int i;
CopyTimeToByteUint(plain, key, &container);
// OUTER LOOP 1
for (i = 1; i < 17; i++)
{
ExpandL(&container);
CompressKey(&container);
// expR XOR compr.Key
container.mByteUint1.FullUint ^= container.mByteUint2.FullUint; // L' XOR compr.Key
container.mByteUint3.s.Byte2 &= 0x0F; // clear 0D(4-7)
DoSbox(&container);
DoPbox(&container);
// L XOR P-Boxed Round-Key (L')
container.mByteUint1.FullUint ^= container.mByteUint3.FullUint;
// L = R
container.mByteUint3.FullUint = container.mByteUint2.FullUint & 0x00FFFFFF;
// R = L'
container.mByteUint2.FullUint = container.mByteUint1.FullUint & 0x00FFFFFF;
ShiftTimeLeft(i, &container);
} // end of outer loop 1
container.mByteUint3.FullUint <<= 4;
container.mByteUint2.s.Byte2 &= 0x0F;
container.mByteUint2.s.Byte2 |= (uint8_t)(container.mByteUint3.s.Byte0 & 0xF0);
cipher[0] = container.mByteUint2.s.Byte0;
cipher[1] = container.mByteUint2.s.Byte1;
cipher[2] = container.mByteUint2.s.Byte2;
cipher[3] = container.mByteUint3.s.Byte1;
cipher[4] = container.mByteUint3.s.Byte2;
return cipher;
}
//#define DEBUG_CIPER
/* decode given crypted frame and key
* return the weather info or -1 on checksum error
*/
int32_t weather_decode(uint64_t cipher, uint64_t key)
{
uint8_t CipherBytes[5];
uint8_t KeyBytes[5];
uint8_t *PlainBytes;
int32_t weather;
int i;
for (i = 0; i < 5; i++)
CipherBytes[i] = cipher >> (i * 8);
for (i = 0; i < 5; i++)
KeyBytes[i] = key >> (i * 8);
PlainBytes = Decrypt(CipherBytes, KeyBytes);
weather = GetWeatherFromPlain(PlainBytes);
#ifdef DEBUG_CIPER
printf("cipher=%s\n", debug_hex(CipherBytes, 5));
printf("key =%s\n", debug_hex(KeyBytes, 5));
printf("plain =%s\n", debug_hex(PlainBytes, 5));
if (weather < 0)
printf("weather=error\n");
else
printf("weather=%06x\n", weather);
weather_encode(weather, key);
#endif
return weather;
}
/* encode given weather info and key
* return crypted frame
*/
uint64_t weather_encode(uint32_t weather, uint64_t key)
{
uint8_t KeyBytes[5];
uint8_t *PlainBytes;
uint8_t *CipherBytes;
uint64_t cipher = 0;
int i;
PlainBytes = GetPlainFromWeather(weather);
for (i = 0; i < 5; i++)
KeyBytes[i] = key >> (i * 8);
CipherBytes = Encrypt(PlainBytes, KeyBytes);
#ifdef DEBUG_CIPER
printf("plain =%s\n", debug_hex(PlainBytes, 5));
printf("key =%s\n", debug_hex(KeyBytes, 5));
printf("cipher=%s\n", debug_hex(CipherBytes, 5));
#endif
for (i = 0; i < 5; i++)
cipher |= (uint64_t)(CipherBytes[i]) << (i * 8);
return cipher;
}

View File

@ -1,3 +0,0 @@
int32_t weather_decode(uint64_t cipher, uint64_t key);
uint64_t weather_encode(uint32_t weather, uint64_t key);

View File

@ -22,7 +22,6 @@ eurosignal_LDADD = \
$(top_builddir)/src/libdisplay/libdisplay.a \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfsk/libfsk.a \

View File

@ -234,7 +234,7 @@ void euro_exit(void)
flush_id();
}
static void call_timeout(void *data);
static void call_timeout(struct timer *timer);
/* Create transceiver instance and link to a list. */
int euro_create(const char *kanal, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, int fm, int tx, int rx, int repeat, int degraded, int random, uint32_t scan_from, uint32_t scan_to, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback)
@ -506,7 +506,7 @@ static void call_play_announcement(euro_call_t *call)
else
chunk[i] = 0.0;
}
int16_to_samples_speech(spl, chunk, 160);
int16_to_samples(spl, chunk, 160);
call_up_audio(call->callref, spl, 160);
}
@ -549,9 +549,9 @@ void call_down_clock(void)
}
/* Timeout handling */
static void call_timeout(void *data)
static void call_timeout(struct timer *timer)
{
euro_call_t *call = data;
euro_call_t *call = (euro_call_t *)timer->priv;
switch (call->state) {
case EURO_CALL_ANSWER:
@ -760,7 +760,7 @@ void call_down_release(int callref, int cause)
}
/* Receive audio from call instance. */
void call_down_audio(int __attribute__((unused)) callref, uint16_t __attribute__((unused)) sequence, uint32_t __attribute__((unused)) timestamp, uint32_t __attribute__((unused)) ssrc, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) count)
void call_down_audio(int __attribute__((unused)) callref, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) count)
{
}

View File

@ -19,7 +19,6 @@ bin_PROGRAMS = \
$(top_builddir)/src/libgoertzel/libgoertzel.a \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfm/libfm.a \

View File

@ -595,17 +595,15 @@ void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length
fuenf_t *fuenf = (fuenf_t *) sender;
sample_t *orig_samples = samples;
int orig_length = length;
int count, input_num;
int count;
sample_t *spl;
int pos;
int i;
/* speak through */
if (fuenf->state == FUENF_STATE_DURCHSAGE && fuenf->callref) {
jitter_load(&fuenf->sender.dejitter, samples, length);
memset(power, 1, length);
input_num = samplerate_upsample_input_num(&sender->srstate, length);
jitter_load(&sender->dejitter, samples, input_num);
samplerate_upsample(&sender->srstate, samples, input_num, samples, length);
} else {
/* send if something has to be sent. else turn transmitter off */
while ((count = encode(fuenf, samples, length))) {

View File

@ -390,7 +390,7 @@ void call_down_release(int callref, int cause)
}
/* Receive audio from call instance. */
void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_t ssrc, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
fuenf_t *fuenf;
@ -403,8 +403,11 @@ void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_
if (!sender)
return;
if (fuenf->state == FUENF_STATE_DURCHSAGE)
jitter_save(&fuenf->sender.dejitter, samples, count, 1, sequence, timestamp, ssrc);
if (fuenf->state == FUENF_STATE_DURCHSAGE) {
sample_t up[(int)((double)count * fuenf->sender.srstate.factor + 0.5) + 10];
count = samplerate_upsample(&fuenf->sender.srstate, samples, count, up);
jitter_save(&fuenf->sender.dejitter, up, count);
}
}
void dump_info(void) {}

View File

@ -48,9 +48,9 @@ void print_help(const char *arg0)
main_mobile_print_help(arg0, "-k <kanal> | -k list");
/* - - */
printf(" -T --tx\n");
printf(" Transmit 5-tones on given channel, to page a receiver. (default)\n");
printf(" Transmit Eurosignal on given channel, to page a receiver. (default)\n");
printf(" -R --rx\n");
printf(" Receive 5-tones on given channel, so we are the receiver.\n");
printf(" Receive Eurosignal on given channel, so we are the receiver.\n");
printf(" If none of the options -T nor -R is given, only transmitter is enabled.\n");
printf(" -D --deviation <KHz>\n");
printf(" Choose deviation of FM signal (default %.0f KHz).\n", signal_deviation / 1000.0);

View File

@ -22,8 +22,8 @@ fuvst_LDADD = \
$(top_builddir)/src/libcompandor/libcompandor.a \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libscrambler/libscrambler.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfm/libfm.a \
$(top_builddir)/src/libv27/libv27.a \
@ -49,8 +49,8 @@ fuvst_sniffer_LDADD = \
$(top_builddir)/src/libcompandor/libcompandor.a \
$(top_builddir)/src/libjitter/libjitter.a \
$(top_builddir)/src/libtimer/libtimer.a \
$(top_builddir)/src/libselect/libselect.a \
$(top_builddir)/src/libsamplerate/libsamplerate.a \
$(top_builddir)/src/libscrambler/libscrambler.a \
$(top_builddir)/src/libemphasis/libemphasis.a \
$(top_builddir)/src/libfm/libfm.a \
$(top_builddir)/src/libv27/libv27.a \

View File

@ -591,9 +591,9 @@ static void destroy_transaction(transaction_t *trans)
}
/* Timeout handling */
void trans_timeout(void *data)
void trans_timeout(struct timer *timer)
{
transaction_t *trans = data;
transaction_t *trans = (transaction_t *)timer->priv;
PDEBUG(DTRANS, DEBUG_NOTICE, "Releasing transaction due to timeout.\n");
if (trans->callref)
@ -1240,17 +1240,13 @@ void fuvst_destroy(sender_t *sender)
void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length)
{
fuvst_t *fuvst = (fuvst_t *) sender;
int input_num;
memset(power, 1, length);
if (fuvst->chan_type == CHAN_TYPE_ZZK)
v27_modem_send(&fuvst->modem, samples, length);
else {
input_num = samplerate_upsample_input_num(&sender->srstate, length);
jitter_load(&sender->dejitter, samples, input_num);
samplerate_upsample(&sender->srstate, samples, input_num, samples, length);
}
else
jitter_load(&fuvst->sender.dejitter, samples, length);
}
void sender_receive(sender_t *sender, sample_t *samples, int length, double __attribute__((unused)) rf_level_db)
@ -1284,7 +1280,7 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double __at
}
/* Receive audio from call instance. */
void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_t ssrc, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
fuvst_t *fuvst;
@ -1297,8 +1293,11 @@ void call_down_audio(int callref, uint16_t sequence, uint32_t timestamp, uint32_
if (!sender)
return;
if (fuvst->callref)
jitter_save(&fuvst->sender.dejitter, samples, count, 1, sequence, timestamp, ssrc);
if (fuvst->callref) {
sample_t up[(int)((double)count * fuvst->sender.srstate.factor + 0.5) + 10];
count = samplerate_upsample(&fuvst->sender.srstate, samples, count, up);
jitter_save(&fuvst->sender.dejitter, up, count);
}
}
void call_down_clock(void) {}

View File

@ -1,4 +1,5 @@
#include "../libmobile/sender.h"
#include "../libscrambler/scrambler.h"
#include "../libv27/modem.h"
#include "../libmtp/mtp.h"
#include "mup.h"

View File

@ -255,7 +255,7 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double __at
v27_modem_receive(&sniffer->modem, samples, length);
}
void call_down_audio(int __attribute__((unused)) callref, uint16_t __attribute__((unused)) sequence, uint32_t __attribute__((unused)) timestamp, uint32_t __attribute__((unused)) ssrc, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) count) { }
void call_down_audio(int __attribute__((unused)) callref, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) count) { }
void call_down_clock(void) {}

View File

@ -1,261 +0,0 @@
/* GSC signal processing
*
* (C) 2022 by Andreas Eversberg <jolly@eversberg.eu>
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define CHAN gsc->sender.kanal
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <sys/param.h>
#include "../libsample/sample.h"
#include "../libdebug/debug.h"
#include "golay.h"
#include "dsp.h"
#define MAX_DISPLAY 1.4 /* something above speech level, no emphasis */
#define VOICE_BANDWIDTH 3000 /* just guessing */
static void dsp_init_ramp(gsc_t *gsc)
{
double c;
int i;
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Generating cosine shaped ramp table.\n");
for (i = 0; i < 256; i++) {
/* This is mathematically incorrect... */
if (i < 64)
c = 1.0;
else if (i >= 192)
c = -1.0;
else
c = cos((double)(i - 64) / 128.0 * M_PI);
gsc->fsk_ramp_down[i] = c * gsc->fsk_deviation * gsc->fsk_polarity;
gsc->fsk_ramp_up[i] = -gsc->fsk_ramp_down[i];
}
}
/* Init transceiver instance. */
int dsp_init_sender(gsc_t *gsc, int samplerate, double deviation, double polarity)
{
int rc;
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init DSP for transceiver.\n");
/* set modulation parameters */
// NOTE: baudrate equals modulation, because we have a raised cosine ramp of beta = 0.5
sender_set_fm(&gsc->sender, deviation, 600.0, deviation, MAX_DISPLAY);
gsc->fsk_bitduration = (double)samplerate / 600.0;
gsc->fsk_bitstep = 1.0 / gsc->fsk_bitduration;
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Use %.4f samples for one bit duration @ %d.\n", gsc->fsk_bitduration, gsc->sender.samplerate);
gsc->fsk_tx_buffer_size = gsc->fsk_bitduration + 10; /* 1 bit, add some extra to prevent short buffer due to rounding */
gsc->fsk_tx_buffer = calloc(sizeof(sample_t), gsc->fsk_tx_buffer_size);
if (!gsc->fsk_tx_buffer) {
PDEBUG_CHAN(DDSP, DEBUG_ERROR, "No memory!\n");
rc = -ENOMEM;
goto error;
}
/* create deviation and ramp */
gsc->fsk_deviation = 1.0; // equals what we st at sender_set_fm()
gsc->fsk_polarity = polarity;
dsp_init_ramp(gsc);
return 0;
error:
dsp_cleanup_sender(gsc);
return -rc;
}
/* Cleanup transceiver instance. */
void dsp_cleanup_sender(gsc_t *gsc)
{
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Cleanup DSP for transceiver.\n");
if (gsc->fsk_tx_buffer) {
free(gsc->fsk_tx_buffer);
gsc->fsk_tx_buffer = NULL;
}
}
/* encode one bit into samples
* input: bit
* output: samples
* return number of samples */
static int fsk_bit_encode(gsc_t *gsc, uint8_t bit)
{
/* alloc samples, add 1 in case there is a rest */
sample_t *spl;
double phase, bitstep, devpol;
int count;
uint8_t lastbit;
devpol = gsc->fsk_deviation * gsc->fsk_polarity;
spl = gsc->fsk_tx_buffer;
phase = gsc->fsk_tx_phase;
lastbit = gsc->fsk_tx_lastbit;
bitstep = gsc->fsk_bitstep * 256.0;
if (lastbit) {
if (bit) {
/* stay up */
do {
*spl++ = devpol;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
} else {
/* ramp down */
do {
*spl++ = gsc->fsk_ramp_down[(uint8_t)phase];
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
lastbit = 0;
}
} else {
if (bit) {
/* ramp up */
do {
*spl++ = gsc->fsk_ramp_up[(uint8_t)phase];
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
lastbit = 1;
} else {
/* stay down */
do {
*spl++ = -devpol;
phase += bitstep;
} while (phase < 256.0);
phase -= 256.0;
}
}
/* depending on the number of samples, return the number */
count = ((uintptr_t)spl - (uintptr_t)gsc->fsk_tx_buffer) / sizeof(*spl);
gsc->fsk_tx_phase = phase;
gsc->fsk_tx_lastbit = lastbit;
return count;
}
/* Process received audio stream from radio unit. */
void sender_receive(sender_t __attribute__((unused)) *sender, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) length, double __attribute__((unused)) rf_level_db)
{
}
/* Provide stream of audio toward radio unit */
void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length)
{
gsc_t *gsc = (gsc_t *) sender;
int rc;
again:
/* play 2 seconds of pause */
if (gsc->wait_2_sec) {
int tosend = MIN(length, gsc->wait_2_sec);
memset(power, 1, tosend);
memset(samples, 0, sizeof(samples) * tosend);
power += tosend;
samples += tosend;
gsc->wait_2_sec -= tosend;
if (gsc->wait_2_sec)
return;
}
/* play wave file, if open */
if (gsc->wave_tx_play.left) {
int wave_num, s;
wave_num = samplerate_upsample_input_num(&gsc->wave_tx_upsample, length);
sample_t buffer[wave_num * 2], *wave_samples[2] = { buffer, buffer + wave_num };
wave_read(&gsc->wave_tx_play, wave_samples, wave_num);
if (gsc->wave_tx_channels == 2) {
for (s = 0; s < wave_num; s++) {
wave_samples[0][s] += wave_samples[1][s];
}
}
samplerate_upsample(&gsc->wave_tx_upsample, wave_samples[0], wave_num, samples, length);
if (!gsc->wave_tx_play.left) {
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Voice message sent.\n");
wave_destroy_playback(&gsc->wave_tx_play);
return;
}
return;
}
/* get FSK bits or start playing wave file */
if (!gsc->fsk_tx_buffer_length) {
int8_t bit = get_bit(gsc);
/* bit == 2 means voice transmission. */
if (bit == 2) {
if (gsc->wave_tx_filename[0]) {
gsc->wave_tx_samplerate = gsc->wave_tx_channels = 0;
rc = wave_create_playback(&gsc->wave_tx_play, gsc->wave_tx_filename, &gsc->wave_tx_samplerate, &gsc->wave_tx_channels, gsc->fsk_deviation);
if (rc < 0) {
gsc->wave_tx_play.left = 0;
PDEBUG_CHAN(DDSP, DEBUG_ERROR, "Failed to open wave file '%s' for voice message.\n", gsc->wave_tx_filename);
} else {
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Sending wave file '%s' for voice message after 2 seconds.\n", gsc->wave_tx_filename);
init_samplerate(&gsc->wave_tx_upsample, gsc->wave_tx_samplerate, gsc->sender.samplerate, VOICE_BANDWIDTH);
}
}
gsc->wait_2_sec = gsc->sender.samplerate * 2.0;
goto again;
}
/* no message, power is off */
if (bit < 0) {
memset(samples, 0, sizeof(samples) * length);
memset(power, 0, length);
return;
}
/* encode */
gsc->fsk_tx_buffer_length = fsk_bit_encode(gsc, bit);
gsc->fsk_tx_buffer_pos = 0;
}
/* send encoded bit until end of source or destination buffer is reached */
while (length) {
*power++ = 1;
*samples++ = gsc->fsk_tx_buffer[gsc->fsk_tx_buffer_pos++];
length--;
if (gsc->fsk_tx_buffer_pos == gsc->fsk_tx_buffer_length) {
gsc->fsk_tx_buffer_length = 0;
break;
}
}
/* do again, if destination buffer is not yet full */
if (length)
goto again;
}

View File

@ -1,4 +0,0 @@
int dsp_init_sender(gsc_t *gsc, int samplerate, double deviation, double polarity);
void dsp_cleanup_sender(gsc_t *gsc);

View File

@ -1,877 +0,0 @@
/* Golay/GSC transcoding (encoding only - maybe)
*
* (C) 2022 by Andreas Eversberg <jolly@eversberg.eu>
* All Rights Reserved
*
* Inspired by GSC code written by Brandon Creighton <cstone@pobox.com>.
*
* Inspired by GOLAY code written by Robert Morelos-Zaragoza
* <robert@spectra.eng.hawaii.edu>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Golay code was is use since 1973, the GSC extension was used after 1982.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include "../libsample/sample.h"
#include "../libdebug/debug.h"
#include "../libmobile/call.h"
#include "../libmobile/main_mobile.h"
#include "../libmobile/cause.h"
#include "golay.h"
#include "dsp.h"
/* Create transceiver instance and link to a list. */
int golay_create(const char *kanal, double frequency, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, double deviation, double polarity, const char *message, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback)
{
gsc_t *gsc;
int rc;
gsc = calloc(1, sizeof(*gsc));
if (!gsc) {
PDEBUG(DGOLAY, DEBUG_ERROR, "No memory!\n");
return -ENOMEM;
}
PDEBUG(DGOLAY, DEBUG_DEBUG, "Creating 'GOLAY' instance for frequency = %s (sample rate %d).\n", kanal, samplerate);
/* init general part of transceiver */
rc = sender_create(&gsc->sender, kanal, frequency, frequency, device, use_sdr, samplerate, rx_gain, tx_gain, 0, 0, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback, PAGING_SIGNAL_NONE);
if (rc < 0) {
PDEBUG(DGOLAY, DEBUG_ERROR, "Failed to init transceiver process!\n");
goto error;
}
/* init audio processing */
rc = dsp_init_sender(gsc, samplerate, deviation, polarity);
if (rc < 0) {
PDEBUG(DGOLAY, DEBUG_ERROR, "Failed to init audio processing!\n");
goto error;
}
gsc->tx = 1;
gsc->default_message = message;
PDEBUG(DGOLAY, DEBUG_NOTICE, "Created transmitter for frequency %s\n", kanal);
return 0;
error:
golay_destroy(&gsc->sender);
return rc;
}
static void golay_msg_destroy(gsc_t *gsc, gsc_msg_t *msg);
/* Destroy transceiver instance and unlink from list. */
void golay_destroy(sender_t *sender)
{
gsc_t *gsc = (gsc_t *) sender;
PDEBUG(DGOLAY, DEBUG_DEBUG, "Destroying 'GOLAY' instance for frequency = %s.\n", sender->kanal);
while (gsc->msg_list)
golay_msg_destroy(gsc, gsc->msg_list);
dsp_cleanup_sender(gsc);
sender_destroy(&gsc->sender);
free(gsc);
}
/* Create message and add to queue */
static gsc_msg_t *golay_msg_create(gsc_t *gsc, const char *address, const char *text, enum gsc_msg_type type)
{
gsc_msg_t *msg, **msgp;
if (strlen(address) != sizeof(msg->address) - 1) {
PDEBUG(DGOLAY, DEBUG_NOTICE, "Address has incorrect length, cannot page!\n");
return NULL;
}
if (strlen(text) > sizeof(msg->data) - 1) {
PDEBUG(DGOLAY, DEBUG_NOTICE, "Given test is too long, cannot page!\n");
return NULL;
}
/* get type from last digit, if automatic type is given */
if (type == TYPE_AUTO) {
switch (address[6]) {
case '1': type = TYPE_VOICE; break;
case '2': type = TYPE_VOICE; break;
case '3': type = TYPE_VOICE; break;
case '4': type = TYPE_VOICE; break;
case '5': type = TYPE_ALPHA; break;
case '6': type = TYPE_ALPHA; break;
case '7': type = TYPE_ALPHA; break;
case '8': type = TYPE_ALPHA; break;
case '9': type = TYPE_TONE; break;
case '0': type = TYPE_TONE; break;
default:
PDEBUG(DGOLAY, DEBUG_NOTICE, "Illegal function suffix '%c' in last address digit.\n", address[6]);
return NULL;
}
} else
PDEBUG(DGOLAY, DEBUG_INFO, "Overriding message type as defined by sender.\n");
PDEBUG(DGOLAY, DEBUG_INFO, "Creating msg instance to page address '%s'.\n", address);
/* create */
msg = calloc(1, sizeof(*msg));
if (!msg) {
PDEBUG(DGOLAY, DEBUG_ERROR, "No mem!\n");
abort();
}
/* init */
memcpy(msg->address, address, MIN(sizeof(msg->address) - 1, strlen(address) + 1));
msg->type = type;
memcpy(msg->data, text, MIN(sizeof(msg->data) - 1, strlen(text) + 1));
/* link */
msgp = &gsc->msg_list;
while ((*msgp))
msgp = &(*msgp)->next;
(*msgp) = msg;
return msg;
}
/* Remove and destroy msg from queue */
static void golay_msg_destroy(gsc_t *gsc, gsc_msg_t *msg)
{
gsc_msg_t **msgp;
/* unlink */
msgp = &gsc->msg_list;
while ((*msgp) != msg)
msgp = &(*msgp)->next;
(*msgp) = msg->next;
/* destroy */
free(msg);
}
/* uncomment this for showing encoder tables ("<parity> <information>", LSB is the right most bit) */
//#define DEBUG_TABLE
static uint32_t golay_table[4096];
#define X22 0x00400000
#define X11 0x00000800
#define MASK12 0xfffff800
#define GEN_GOL 0x00000c75
/* generate golay encoding table. the redundancy is shifted 12 bits */
void init_golay(void)
{
uint32_t syndrome, aux;
int data;
for (data = 0; data < 4096; data++) {
syndrome = data << 11;
/* calculate syndrome */
aux = X22;
if (syndrome >= X11) {
while (syndrome & MASK12) {
while (!(aux & syndrome))
aux = aux >> 1;
syndrome ^= (aux / X11) * GEN_GOL;
}
}
golay_table[data] = data | (syndrome << 12);
#ifdef DEBUG_TABLE
printf("Golay %4d: ", data);
for (int i = 22; i >= 0; i--) {
if (i == 11)
printf(" ");
printf("%d", (golay_table[data] >> i) & 1);
}
printf("\n");
#endif
}
}
static uint16_t bch_table[128];
#define X14 0x4000
#define X8 0x0100
#define MASK7 0xff00
#define GEN_BCH 0x00000117
/* generate bch encoding table. the redundancy is shifted 7 bits */
void init_bch(void)
{
uint16_t syndrome, aux;
int data;
for (data = 0; data < 128; data++) {
syndrome = data << 8;
/* calculate syndrome */
aux = X14;
if (syndrome >= X8) {
while (syndrome & MASK7) {
while (!(aux & syndrome))
aux = aux >> 1;
syndrome ^= (aux / X8) * GEN_BCH;
}
}
bch_table[data] = data | (syndrome << 7);
#ifdef DEBUG_TABLE
printf("BCH %3d: ", data);
for (int i = 14; i >= 0; i--) {
if (i == 6)
printf(" ");
printf("%d", (bch_table[data] >> i) & 1);
}
printf("\n");
#endif
}
}
static inline uint32_t calc_golay(uint16_t data)
{
return golay_table[data & 0xfff];
}
static inline uint16_t calc_bch(uint16_t data)
{
return bch_table[data & 0x7f];
}
static const uint16_t preamble_values[] = {
2030, 1628, 3198, 647, 191, 3315, 1949, 2540, 1560, 2335,
};
static const uint32_t start_code = 713;
static const uint32_t activation_code = 2563;
/* Rep. 900-2 Table VI */
static const uint16_t word1s[50] = {
721, 2731, 2952, 1387, 1578, 1708, 2650, 1747, 2580, 1376,
2692, 696, 1667, 3800, 3552, 3424, 1384, 3595, 876, 3124,
2285, 2608, 899, 3684, 3129, 2124, 1287, 2616, 1647, 3216,
375, 1232, 2824, 1840, 408, 3127, 3387, 882, 3468, 3267,
1575, 3463, 3152, 2572, 1252, 2592, 1552, 835, 1440, 160,
};
/* Rep. 900-2 Table VII (left column) */
static char encode_alpha(char c)
{
if (c >= 'a' && c <= 'z')
c = c - 'a' + 'A';
switch (c) {
case 0x0a:
case 0x0d:
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> CR/LF character.\n");
c = 0x3c;
break;
case '{':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> '%c' character.\n", c);
c = 0x3b;
break;
case '}':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> '%c' character.\n", c);
c = 0x3d;
break;
case '\\':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> '%c' character.\n", c);
c = 0x20;
break;
default:
if (c < 0x20 || c > 0x5d) {
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> ' ' character.\n");
c = 0x20;
} else {
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> '%c' character.\n", c);
c = c - 0x20;
}
}
return c;
}
/* Rep. 900-2 Table VII (right columns) */
static char encode_numeric(char c)
{
switch (c) {
case 'u':
case 'U':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'U' character.\n");
c = 0xb;
break;
case ' ':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> '%c' character.\n", c);
c = 0xc;
break;
case '-':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> '%c' character.\n", c);
c = 0xd;
break;
case '=':
case '*':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> '*' character.\n");
c = 0xe;
break;
case 'a':
case 'A':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'A' character.\n");
c = 0xf0;
break;
case 'b':
case 'B':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'B' character.\n");
c = 0xf1;
break;
case 'c':
case 'C':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'C' character.\n");
c = 0xf2;
break;
case 'd':
case 'D':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'D' character.\n");
c = 0xf3;
break;
case 'e':
case 'E':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'E' character.\n");
c = 0xf4;
break;
case 'f':
case 'F':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'F' character.\n");
c = 0xf6;
break;
case 'g':
case 'G':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'G' character.\n");
c = 0xf7;
break;
case 'h':
case 'H':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'H' character.\n");
c = 0xf8;
break;
case 'j':
case 'J':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'J' character.\n");
c = 0xf9;
break;
case 'l':
case 'L':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'L' character.\n");
c = 0xfb;
break;
case 'n':
case 'N':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'N' character.\n");
c = 0xfc;
break;
case 'p':
case 'P':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'P' character.\n");
c = 0xfd;
break;
case 'r':
case 'R':
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> 'r' character.\n");
c = 0xfe;
break;
default:
if (c >= '0' && c <= '9') {
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> '%c' character.\n", c);
c = c - '0';
} else {
PDEBUG(DGOLAY, DEBUG_DEBUG, " -> ' ' character.\n");
c = 0xc;
}
}
return c;
}
static int encode_address(const char *code, int *preamble, uint16_t *word1, uint16_t *word2)
{
static const uint16_t illegal_low[16] = { 0, 25, 51, 103, 206, 340, 363, 412, 445, 530, 642, 726, 782, 810, 825, 877 };
static const uint16_t illegal_high[7] = { 0, 292, 425, 584, 631, 841, 851 };
int idx, g0, g1, a0, a1, a2, ap0, ap, ap1, ap2, ap3, b1b0, b3b2, g1g0, a2a1a0;
int i;
for (i = 0; i < 7; i++) {
if (code[i] < '0' || code[i] > '9')
break;
}
if (code[i]) {
PDEBUG(DGOLAY, DEBUG_NOTICE, "Invalid functional address character. Only 0..9 are allowed.\n");
return -EINVAL;
}
idx = code[0] - '0';
g1 = code[1] - '0';
g0 = code[2] - '0';
a2 = code[3] - '0';
a1 = code[4] - '0';
a0 = code[5] - '0';
*preamble = (idx + g0) % 10;
ap = a2 * 200 + a1 * 20 + a0 * 2;
ap3 = ap / 1000;
ap2 = (ap / 100) % 10;
ap1 = (ap / 10) % 10;
ap0 = ap % 10;
b1b0 = (ap1 * 10 + ap0) / 2;
b3b2 = (ap3 * 10 + ap2);
g1g0 = (g1 * 10 + g0);
if (g1g0 >= 50) {
*word1 = word1s[g1g0 - 50];
*word2 = b3b2 * 100 + b1b0 + 50;
} else {
*word1 = word1s[g1g0];
*word2 = b3b2 * 100 + b1b0;
}
a2a1a0 = a2 * 100 + a1 * 10 + a0;
if (g1g0 < 50) {
for (i = 0; i < 16; i++) {
if (a2a1a0 == illegal_low[i])
break;
}
if (i < 16) {
PDEBUG(DGOLAY, DEBUG_NOTICE, "Functional address has invlid value '%03d' for last three characters.\n", a2a1a0);
return -EINVAL;
}
} else {
for (i = 0; i < 7; i++) {
if (a2a1a0 == illegal_high[i])
break;
}
if (i < 7) {
PDEBUG(DGOLAY, DEBUG_NOTICE, "Functional address has invlid value '%03d' for last three characters.\n", a2a1a0);
return -EINVAL;
}
}
return 0;
}
static inline void queue_reset(gsc_t *gsc)
{
gsc->bit_index = 0;
gsc->bit_num = 0;
gsc->bit_ac = 0;
gsc->bit_overflow = 0;
}
static inline void queue_bit(gsc_t *gsc, int bit)
{
if (gsc->bit_num == sizeof(gsc->bit))
gsc->bit_overflow = 1;
if (gsc->bit_overflow) {
gsc->bit_num++;
return;
}
gsc->bit[gsc->bit_num++] = bit;
}
static inline void queue_dup(gsc_t *gsc, uint32_t data, int len)
{
int i;
for (i = 0; i < len; i++) {
queue_bit(gsc, (data >> i) & 1);
queue_bit(gsc, (data >> i) & 1);
}
}
static inline void queue_comma(gsc_t *gsc, int bits, uint8_t polarity)
{
int i;
for (i = 0; i < bits; i++) {
queue_bit(gsc, polarity);
polarity = !polarity;
}
}
static int queue_batch(gsc_t *gsc, const char *address, enum gsc_msg_type type, const char *message)
{
int preamble;
uint16_t word1, word2;
uint8_t function;
uint32_t golay;
uint16_t bch[8];
uint8_t msg[12], digit, shifted, contbit, checksum;
int i, j, k;
int rc;
queue_reset(gsc);
/* check address length */
if (!address || strlen(address) != 7) {
PDEBUG(DGOLAY, DEBUG_NOTICE, "Invalid functional address '%s' size. Only 7 digits are allowed.\n", address);
return -EINVAL;
}
/* calculate address */
rc = encode_address(address, &preamble, &word1, &word2);
if (rc < 0)
return rc;
/* get function from last digit */
switch (address[6]) {
case '1': function = 0; break;
case '2': function = 1; break;
case '3': function = 2; break;
case '4': function = 3; break;
case '5': function = 0; break;
case '6': function = 1; break;
case '7': function = 2; break;
case '8': function = 3; break;
case '9': function = 0; break;
case '0': function = 1; break;
default:
PDEBUG(DGOLAY, DEBUG_NOTICE, "Illegal function suffix '%c' in last address digit.\n", address[6]);
return -EINVAL;
}
switch (type) {
case TYPE_ALPHA:
case TYPE_NUMERIC:
PDEBUG(DGOLAY, DEBUG_INFO, "Coding text message for functional address '%s' and message '%s'.\n", address, message);
break;
case TYPE_VOICE:
PDEBUG(DGOLAY, DEBUG_INFO, "Coding voice message for functional address %s with wave file '%s'.\n", address, message);
break;
default:
PDEBUG(DGOLAY, DEBUG_INFO, "Coding tone only message for functional address %s.\n", address);
}
/* encode preamble and store */
PDEBUG(DGOLAY, DEBUG_DEBUG, "Encoding preamble '%d'.\n", preamble);
golay = calc_golay(preamble_values[preamble]);
queue_comma(gsc, 28, golay & 1);
for (i = 0; i < 18; i++) {
queue_dup(gsc, golay, 23);
}
/* encode start code and store */
PDEBUG(DGOLAY, DEBUG_DEBUG, "Encoding start code.\n");
golay = calc_golay(start_code);
queue_comma(gsc, 28, golay & 1);
queue_dup(gsc, golay, 23);
golay ^= 0x7fffff;
queue_bit(gsc, (golay & 1) ^ 1);
queue_dup(gsc, golay, 23);
/* encode address and store */
PDEBUG(DGOLAY, DEBUG_DEBUG, "Encoding address words '%d' and '%d'.\n", word1, word2);
golay = calc_golay(word1);
if (function & 0x2)
golay ^= 0x7fffff;
queue_comma(gsc, 28, golay & 1);
queue_dup(gsc, golay, 23);
golay = calc_golay(word2);
if (function & 0x1)
golay ^= 0x7fffff;
queue_bit(gsc, (golay & 1) ^ 1);
queue_dup(gsc, golay, 23);
/* encode message */
switch (type) {
case TYPE_ALPHA:
PDEBUG(DGOLAY, DEBUG_DEBUG, "Encoding %d alphanumeric digits.\n", (int)strlen(message));
for (i = 0; *message; i++) {
if (i == MAX_ADB) {
PDEBUG(DGOLAY, DEBUG_NOTICE, "Message overflows %d characters, cropping message.\n", MAX_ADB * 8);
}
for (j = 0; *message && j < 8; j++) {
msg[j] = encode_alpha(*message++);
}
/* fill empty characters with NULL */
while (j < 8)
msg[j++] = 0x3e;
/* 8 characters + continue-bit */
bch[0] = calc_bch((msg[0] | (msg[1] << 6)) & 0x7f);
bch[1] = calc_bch(((msg[1] >> 1) | (msg[2] << 5)) & 0x7f);
bch[2] = calc_bch(((msg[2] >> 2) | (msg[3] << 4)) & 0x7f);
bch[3] = calc_bch(((msg[3] >> 3) | (msg[4] << 3)) & 0x7f);
bch[4] = calc_bch(((msg[4] >> 4) | (msg[5] << 2)) & 0x7f);
bch[5] = calc_bch(((msg[5] >> 5) | (msg[6] << 1)) & 0x7f);
if (*message && i < MAX_ADB)
contbit = 1;
else
contbit = 0;
bch[6] = calc_bch((contbit << 6) | msg[7]);
/* checksum */
checksum = bch[0] + bch[1] + bch[2] + bch[3] + bch[4] + bch[5] + bch[6];
bch[7] = calc_bch(checksum & 0x7f);
/* store comma bit */
queue_bit(gsc, (bch[0] & 1) ^ 1); // inverted first bit
/* store interleaved bits */
for (j = 0; j < 15; j++) {
for (k = 0; k < 8; k++)
queue_bit(gsc, (bch[k] >> j) & 1);
}
}
break;
case TYPE_NUMERIC:
PDEBUG(DGOLAY, DEBUG_DEBUG, "Encoding %d numeric digits.\n", (int)strlen(message));
shifted = 0;
for (i = 0; *message; i++) {
if (i == MAX_NDB) {
PDEBUG(DGOLAY, DEBUG_NOTICE, "Message overflows %d characters, cropping message.\n", MAX_NDB * 12);
}
for (j = 0; *message && j < 12; j++) {
/* get next digit or shifted digit */
if (shifted) {
digit = shifted & 0xf;
shifted = 0;
} else
digit = encode_numeric(*message);
/* if digit is extended, use the shifted code and later the digit itself */
if (digit > 0xf) {
shifted = digit;
msg[j] = digit >> 4;
} else {
msg[j] = digit;
message++;
}
}
/* fill empty digits with NULL */
while (j < 12)
msg[j++] = 0xa;
/* 8 digits + continue-bit */
bch[0] = calc_bch((msg[0] | (msg[1] << 4)) & 0x7f);
bch[1] = calc_bch(((msg[1] >> 3) | (msg[2] << 1) | (msg[3] << 5)) & 0x7f);
bch[2] = calc_bch(((msg[3] >> 2) | (msg[4] << 2) | (msg[5] << 6)) & 0x7f);
bch[3] = calc_bch(((msg[5] >> 1) | (msg[6] << 3)) & 0x7f);
bch[4] = calc_bch((msg[7] | (msg[8] << 4)) & 0x7f);
bch[5] = calc_bch(((msg[8] >> 3) | (msg[9] << 1) | (msg[10] << 5)) & 0x7f);
if (*message && i < MAX_NDB)
contbit = 1;
else
contbit = 0;
bch[6] = calc_bch((contbit << 6) | (msg[10] >> 2) | (msg[11] << 2));
/* checksum */
checksum = bch[0] + bch[1] + bch[2] + bch[3] + bch[4] + bch[5] + bch[6];
bch[7] = calc_bch(checksum & 0x7f);
/* store comma bit */
queue_bit(gsc, (bch[0] & 1) ^ 1); // inverted first bit
/* store interleaved bits */
for (j = 0; j < 15; j++) {
for (k = 0; k < 8; k++)
queue_bit(gsc, (bch[k] >> j) & 1);
}
}
break;
case TYPE_VOICE:
/* store wave file name */
memcpy(gsc->wave_tx_filename, message, MIN(sizeof(gsc->wave_tx_filename) - 1, strlen(message) + 1));
/* store bit number for activation code. this is used to play the AC again after voice message. */
gsc->bit_ac = gsc->bit_num;
/* encode activation code and store */
PDEBUG(DGOLAY, DEBUG_DEBUG, "Encoding activation code.\n");
golay = calc_golay(activation_code);
queue_comma(gsc, 28, golay & 1);
queue_dup(gsc, golay, 23);
golay ^= 0x7fffff;
queue_bit(gsc, (golay & 1) ^ 1);
queue_dup(gsc, golay, 23);
break;
default:
/* encode comma after message and store */
PDEBUG(DGOLAY, DEBUG_DEBUG, "Encoding 'comma' sequence after message.\n");
queue_comma(gsc, 121 * 8, 1);
}
/* check overflow */
if (gsc->bit_overflow) {
PDEBUG(DGOLAY, DEBUG_ERROR, "Bit stream (%d bits) overflows bit buffer size (%d bits), please fix!\n", gsc->bit_num, (int)sizeof(gsc->bit));
return -EOVERFLOW;
}
return 0;
}
/* get next bit
*
* if there is no message, return -1, so that the transmitter is turned off.
*
* if there is a message, return next bit to be transmitted.
*
* if there is a message in the queue, encode message and return its first bit.
*
* if there is a voice message, return 2 at the end, to tell the DSP to send voice.
*/
int8_t get_bit(gsc_t *gsc)
{
gsc_msg_t *msg;
int rc;
/* if currently transmiting message, send next bit */
if (gsc->bit_num) {
/* Transmission complete. */
if (gsc->bit_index == gsc->bit_num) {
/* on voice message... */
if (gsc->bit_ac) {
/* rewind to play the AC again after voice transmission */
gsc->bit_index = gsc->bit_ac;
gsc->bit_ac = 0;
/* indicate voice message to DSP */
return 2;
}
queue_reset(gsc);
PDEBUG(DGOLAY, DEBUG_INFO, "Done transmitting message.\n");
goto next_msg;
}
return gsc->bit[gsc->bit_index++];
}
next_msg:
msg = gsc->msg_list;
/* no message pending, turn transmitter off */
if (!msg)
return -1;
/* encode first message in queue */
rc = queue_batch(gsc, msg->address, msg->type, msg->data);
if (rc >= 0)
PDEBUG(DGOLAY, DEBUG_INFO, "Transmitting message to address '%s'.\n", msg->address);
golay_msg_destroy(gsc, msg);
if (rc < 0)
goto next_msg;
/* return first bit */
return gsc->bit[gsc->bit_index++];
}
void golay_msg_send(const char *text)
{
char buffer[strlen(text) + 1], *p = buffer, *address_string, *message;
gsc_t *gsc;
enum gsc_msg_type type = TYPE_AUTO;
strcpy(buffer, text);
address_string = strsep(&p, ",");
message = p;
switch ((message[0] << 8) | message[1]) {
case ('a' << 8) | ',':
type = TYPE_ALPHA;
message += 2;
break;
case ('n' << 8) | ',':
type = TYPE_NUMERIC;
message += 2;
break;
case ('v' << 8) | ',':
type = TYPE_VOICE;
message += 2;
break;
default:
message = "";
}
gsc = (gsc_t *) sender_head;
golay_msg_create(gsc, address_string, message, type);
}
void call_down_clock(void)
{
}
/* Call control starts call towards paging network. */
int call_down_setup(int __attribute__((unused)) callref, const char *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
{
char channel = '\0';
sender_t *sender;
gsc_t *gsc;
const char *address;
const char *message;
gsc_msg_t *msg;
/* find transmitter */
for (sender = sender_head; sender; sender = sender->next) {
/* skip channels that are different than requested */
if (channel && sender->kanal[0] != channel)
continue;
gsc = (gsc_t *) sender;
/* check if base station cannot transmit */
if (!gsc->tx)
continue;
break;
}
if (!sender) {
if (channel)
PDEBUG(DGOLAY, DEBUG_NOTICE, "Cannot page, because given station not available, rejecting!\n");
else
PDEBUG(DGOLAY, DEBUG_NOTICE, "Cannot page, no trasmitting station available, rejecting!\n");
return -CAUSE_NOCHANNEL;
}
/* get address */
address = dialing;
/* get message */
if (caller_id[0])
message = caller_id;
else
message = gsc->default_message;
/* create call process to page station */
msg = golay_msg_create(gsc, address, message, TYPE_AUTO);
if (!msg)
return -CAUSE_INVALNUMBER;
return -CAUSE_NORMAL;
}
void call_down_answer(int __attribute__((unused)) callref)
{
}
static void _release(int __attribute__((unused)) callref, int __attribute__((unused)) cause)
{
PDEBUG(DGOLAY, DEBUG_INFO, "Call has been disconnected by network.\n");
}
void call_down_disconnect(int callref, int cause)
{
_release(callref, cause);
call_up_release(callref, cause);
}
/* Call control releases call toward mobile station. */
void call_down_release(int callref, int cause)
{
_release(callref, cause);
}
/* Receive audio from call instance. */
void call_down_audio(int __attribute__((unused)) callref, uint16_t __attribute__((unused)) sequence, uint32_t __attribute__((unused)) timestamp, uint32_t __attribute__((unused)) ssrc, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) count)
{
}
void dump_info(void) {}

View File

@ -1,67 +0,0 @@
#include "../libmobile/sender.h"
enum gsc_msg_type {
TYPE_AUTO = 0, /* Defined by 7th digit */
TYPE_TONE, /* TONE only */
TYPE_VOICE, /* TONE + VOICE */
TYPE_ALPHA, /* TONE + DATA */
TYPE_NUMERIC, /* TONE + DATA */
};
#define MAX_ADB 10 /* 80 characters */
#define MAX_NDB 2 /* 24 digits */
/* instance of outgoing message */
typedef struct gsc_msg {
struct gsc_msg *next;
char address[8]; /* 7 digits + EOL */
enum gsc_msg_type type; /* type of message */
char data[256]; /* message to be transmitted */
} gsc_msg_t;
typedef struct gsc {
sender_t sender;
int tx;
gsc_msg_t *msg_list; /* queue of messages */
const char *default_message;
/* current trasmitting message */
uint8_t bit[4096];
int bit_num;
int bit_ac; /* where activation code starts (voice only). */
int bit_index; /* when playing out */
int bit_overflow;
/* dsp states */
double fsk_deviation; /* deviation of FSK signal on sound card */
double fsk_polarity; /* polarity of FSK signal (-1.0 = bit '1' is down) */
sample_t fsk_ramp_up[256]; /* samples of upward ramp shape */
sample_t fsk_ramp_down[256]; /* samples of downward ramp shape */
double fsk_bitduration; /* duration of a bit in samples */
double fsk_bitstep; /* fraction of a bit each sample */
sample_t *fsk_tx_buffer; /* tx buffer for one data block */
int fsk_tx_buffer_size; /* size of tx buffer (in samples) */
int fsk_tx_buffer_length; /* usage of buffer (in samples) */
int fsk_tx_buffer_pos; /* current position sending buffer */
double fsk_tx_phase; /* current bit position */
uint8_t fsk_tx_lastbit; /* last bit of last message, to correctly ramp */
/* voice message */
int wait_2_sec; /* counter to wait 2 seconds before playback */
char wave_tx_filename[256];
int wave_tx_samplerate;
int wave_tx_channels;
wave_play_t wave_tx_play; /* wave playback */
samplerate_t wave_tx_upsample; /* wave upsampler */
} gsc_t;
int golay_create(const char *kanal, double frequency, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, double deviation, double polarity, const char *message, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback);
void golay_destroy(sender_t *sender);
void init_golay(void);
void init_bch(void);
int8_t get_bit(gsc_t *gsc);
void golay_msg_send(const char *buffer);

View File

@ -1,6 +0,0 @@
#include <stdio.h>
const char *aaimage[] = {
NULL
};

Some files were not shown because too many files have changed in this diff Show More