mirror of
https://github.com/svpcom/wfb-ng.git
synced 2025-03-14 10:33:58 -03:00
1. Add WFB-NG std draft.
2. Fix frame format. 3. Add multiple links support 4. Add missing libsodium init. Warn if not enough entropy is available 5. Add project logo
This commit is contained in:
parent
3ff62387e6
commit
73af6d7cfa
2
Makefile
2
Makefile
@ -13,7 +13,7 @@ all: all_bin gs.key test
|
||||
|
||||
env:
|
||||
virtualenv env --python=$(PYTHON)
|
||||
./env/bin/pip install --upgrade pip==20.2.3 setuptools==44.1.1 stdeb
|
||||
./env/bin/pip install --upgrade pip setuptools stdeb
|
||||
|
||||
all_bin: wfb_rx wfb_tx wfb_keygen
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
WFB-NG
|
||||
=============
|
||||

|
||||
|
||||
This is the next generation of long-range **packet** radio link based on **raw WiFi radio**
|
||||
|
||||
|
||||
|
4
doc/Makefile
Normal file
4
doc/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
all: wfb-ng-std-draft.html
|
||||
|
||||
%.html: %.md
|
||||
pandoc --self-contained -V include-before='<style>body {max-width:unset!important}</style>' --from markdown $^ -o $@
|
BIN
doc/logo-big-1280x640.png
Normal file
BIN
doc/logo-big-1280x640.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
442
doc/logo-big.eps
Normal file
442
doc/logo-big.eps
Normal file
@ -0,0 +1,442 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: cairo 1.15.10 (http://cairographics.org)
|
||||
%%CreationDate: Wed Sep 7 10:35:40 2022
|
||||
%%Pages: 1
|
||||
%%DocumentData: Clean7Bit
|
||||
%%LanguageLevel: 2
|
||||
%%BoundingBox: 22 0 794 261
|
||||
%%EndComments
|
||||
%%BeginProlog
|
||||
50 dict begin
|
||||
/q { gsave } bind def
|
||||
/Q { grestore } bind def
|
||||
/cm { 6 array astore concat } bind def
|
||||
/w { setlinewidth } bind def
|
||||
/J { setlinecap } bind def
|
||||
/j { setlinejoin } bind def
|
||||
/M { setmiterlimit } bind def
|
||||
/d { setdash } bind def
|
||||
/m { moveto } bind def
|
||||
/l { lineto } bind def
|
||||
/c { curveto } bind def
|
||||
/h { closepath } bind def
|
||||
/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
|
||||
0 exch rlineto 0 rlineto closepath } bind def
|
||||
/S { stroke } bind def
|
||||
/f { fill } bind def
|
||||
/f* { eofill } bind def
|
||||
/n { newpath } bind def
|
||||
/W { clip } bind def
|
||||
/W* { eoclip } bind def
|
||||
/BT { } bind def
|
||||
/ET { } bind def
|
||||
/BDC { mark 3 1 roll /BDC pdfmark } bind def
|
||||
/EMC { mark /EMC pdfmark } bind def
|
||||
/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
|
||||
/Tj { show currentpoint cairo_store_point } bind def
|
||||
/TJ {
|
||||
{
|
||||
dup
|
||||
type /stringtype eq
|
||||
{ show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
|
||||
} forall
|
||||
currentpoint cairo_store_point
|
||||
} bind def
|
||||
/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
|
||||
cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
|
||||
/Tf { pop /cairo_font exch def /cairo_font_matrix where
|
||||
{ pop cairo_selectfont } if } bind def
|
||||
/Td { matrix translate cairo_font_matrix matrix concatmatrix dup
|
||||
/cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
|
||||
/cairo_font where { pop cairo_selectfont } if } bind def
|
||||
/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
|
||||
cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
|
||||
/g { setgray } bind def
|
||||
/rg { setrgbcolor } bind def
|
||||
/d1 { setcachedevice } bind def
|
||||
/cairo_data_source {
|
||||
CairoDataIndex CairoData length lt
|
||||
{ CairoData CairoDataIndex get /CairoDataIndex CairoDataIndex 1 add def }
|
||||
{ () } ifelse
|
||||
} def
|
||||
/cairo_flush_ascii85_file { cairo_ascii85_file status { cairo_ascii85_file flushfile } if } def
|
||||
/cairo_image { image cairo_flush_ascii85_file } def
|
||||
/cairo_imagemask { imagemask cairo_flush_ascii85_file } def
|
||||
%%EndProlog
|
||||
%%BeginSetup
|
||||
%%BeginResource: font GOST-2.304-81typeB
|
||||
11 dict begin
|
||||
/FontType 42 def
|
||||
/FontName /GOST-2.304-81typeB def
|
||||
/PaintType 0 def
|
||||
/FontMatrix [ 1 0 0 1 0 0 ] def
|
||||
/FontBBox [ 0 0 0 0 ] def
|
||||
/Encoding 256 array def
|
||||
0 1 255 { Encoding exch /.notdef put } for
|
||||
Encoding 45 /hyphen put
|
||||
Encoding 66 /B put
|
||||
Encoding 68 /D put
|
||||
Encoding 70 /F put
|
||||
Encoding 76 /L put
|
||||
Encoding 87 /W put
|
||||
Encoding 97 /a put
|
||||
Encoding 103 /g put
|
||||
Encoding 105 /i put
|
||||
Encoding 107 /k put
|
||||
Encoding 110 /n put
|
||||
Encoding 116 /t put
|
||||
/CharStrings 13 dict dup begin
|
||||
/.notdef 0 def
|
||||
/W 1 def
|
||||
/F 2 def
|
||||
/B 3 def
|
||||
/hyphen 4 def
|
||||
/n 5 def
|
||||
/g 6 def
|
||||
/D 7 def
|
||||
/a 8 def
|
||||
/t 9 def
|
||||
/L 10 def
|
||||
/i 11 def
|
||||
/k 12 def
|
||||
end readonly def
|
||||
/sfnts [
|
||||
<000100000009008000030010637674200403004500000528000000146670676dc960b19b0000
|
||||
053c00000153676c79662c7c13ec0000009c0000048c68656164cf259b670000069000000036
|
||||
6868656108a904db000006c800000024686d747818a3034f000006ec000000346c6f63610762
|
||||
0888000007200000001c6d617870021f01c30000073c0000002070726570e9ab85350000075c
|
||||
0000002f0002001f000001d50379000300070018400d040002070300060603030207032b2b00
|
||||
3f2b10dc303133211121012111211f01b6fe4a0197fe8801780379fca6033b00000000010044
|
||||
ffff02ac02ac0022000001363534262322070b01262322070b01262322061514171316333236
|
||||
371b011633323702ab01160e1a0670600a16160a616f061b0d160189061b0a1204696909171a
|
||||
07028202060f131bfe0c01091c1cfef701f41b130e0702fd991c0d0b011ffee1181c00000001
|
||||
00440000019a02ac001a00001335333236353426232122151114163332363511333236353426
|
||||
2389ef10121111feef23150e0f13ef10121111019bcc150d0f1423fd99101211110134150e0f
|
||||
130000030044000001de02ac0015001f0029000001363d013427262b01221511143b01323736
|
||||
3d013426053332161d0114062b011323353332161d011406019d1f282739cd2323ef39272822
|
||||
fecdcd1c28281ccdababab1c2828018625334539282823fd992227283a88263d1e281d881d28
|
||||
0156cd271d451c280001004400cd019a0111000d000025323635342623212206151416330178
|
||||
10121111feef11121310cd150d0f13140e0e14000000000100440000019a01de001a00002511
|
||||
3427262b012215111416333236351133321615111416333236019a28273aaa23150e0f13881d
|
||||
28140e0f1322013439282722fe66101211110178281cfecc10121100000000020044ff33019a
|
||||
01de000900260000252322263d0134363b01111514062b0122061514163b013237363511342b
|
||||
0122061d01141716330156891d27271d89281d8811111210883a282722ab395028283944281d
|
||||
cd1c28fe66441d28140e0e1428273a0200225038cd3a282700020044000001de02ac000f0019
|
||||
000025113427262b01221511143b013237362714062b01113332161501de282739ef2323ef39
|
||||
272844281ccdcd1c2889019a39282823fd992227283a1d280223271d00020044ffff01df01de
|
||||
000c002800002514062b0122263d0134363b01131617163332363534272e013511342b012206
|
||||
1d011417163b0132360156281d441d27271d8921152307070f1316151a22ab3950282839441e
|
||||
36891d28281dcd1c28fe931b0f04160e15090a27170133225038cd3a28271900000000010044
|
||||
0000015602ac001f0000133534262322061d012322061514163b011114163332363511333236
|
||||
35342623cd140e0e14221112131022140e0f13671012111101deab11121310ab140e0e14fe88
|
||||
101211110178150d0f130000000100440000019a02ac001100002132363534262b0111342623
|
||||
220615111433017810121111ef150d0f1423150d0f13024511121310fd992200000000020044
|
||||
0000008902ac000d001900003711342623220615111416333236031416333236353426232206
|
||||
89150d0f14150e0f1345140f0e14140e0f1422019a11111210fe6610121102780e14140e0f14
|
||||
1400000000010044ffff019b02ac0021000013113426232206151114163332363d0137171633
|
||||
323635342f01373635342623220789150d0f14150e0f1321b30a100e1608b2ab0f150d0c0a01
|
||||
34015511121310fd9910121111bc19e90f150d0b0be9810a110d16070044004501df000002ad
|
||||
000000000000ff330000b800002c4bb800095058b101018e59b801ff85b800441db900090003
|
||||
5f5e2db800012c2020456944b001602db800022cb800012a212db800032c2046b00325465258
|
||||
2359208a208a49648a204620686164b004254620686164525823658a592f20b00053586920b0
|
||||
00545821b040591b6920b000545821b0406559593a2db800042c2046b00425465258238a5920
|
||||
46206a6164b0042546206a61645258238a592ffd2db800052c4b20b0032650585158b080441b
|
||||
b04044591b21212045b0c05058b0c0441b2159592db800062c2020456944b001602020457d69
|
||||
1844b001602db800072cb800062a2db800082c4b20b003265358b0801bb040598a8a20b00326
|
||||
5358b0022621b0c08a8a1b8a235920b0032653582321b801008a8a1b8a235920b80003265358
|
||||
b0032545b8014050582321b8014023211bb003254523212321591b2159442db800092c4b5358
|
||||
45441b2121592d00000100000001199941d5b0175f0f3cf5001903e800000000b5729f210000
|
||||
0000b5729f21ffbcff3305570379000000030002000000000000000100000379ff33001a059b
|
||||
ffbcffff055700010000000000000000000000000000000d01f4001f02f0004401de00440223
|
||||
004401de004401de004401de00440223004401de0044019a004401de004400cd004401de0044
|
||||
00000022005c008400c000da0104013a0162019e01cc01ea0214024600010000000d006d0007
|
||||
00000000000200000000000a00000200015300000001bb00000002000200002b2bbd00010042
|
||||
00330025001600082bbd0000004300340025001700082bba0002000400072b0000>
|
||||
] def
|
||||
/f-0-0 currentdict end definefont pop
|
||||
%%EndResource
|
||||
%%EndSetup
|
||||
%%Page: 1 1
|
||||
%%BeginPageSetup
|
||||
%%PageBoundingBox: 22 0 794 261
|
||||
%%EndPageSetup
|
||||
q 22 0 772 261 rectclip
|
||||
1 0 0 -1 0 261 cm q
|
||||
1 g
|
||||
538.793 0 m 786.434 0 l 790.102 0 793.051 2.949 793.051 6.617 c 793.051
|
||||
254.258 l 793.051 257.922 790.102 260.875 786.434 260.875 c 538.793 260.875
|
||||
l 535.129 260.875 532.18 257.922 532.18 254.258 c 532.18 6.617 l 532.18
|
||||
2.949 535.129 0 538.793 0 c h
|
||||
538.793 0 m f
|
||||
0 0.560784 0 rg
|
||||
750.832 65.785 m 750.52 66.793 l 750.203 67.801 l 749.949 68.746 l 749.699
|
||||
69.691 l 749.508 70.512 l 749.32 71.332 l 749.258 71.836 l 749.133 72.277
|
||||
l 749.07 72.781 l 749.07 74.672 l 749.133 75.488 l 749.195 76.371 l 749.383
|
||||
77.441 l 749.574 78.578 l 749.824 79.836 l 750.078 81.285 l 750.453 82.863
|
||||
l 750.895 84.625 l 751.336 86.453 l 751.902 88.469 l 752.473 90.676 l 753.102
|
||||
93.008 l 753.859 95.527 l 754.613 98.301 l 755.055 99.875 l 755.559 101.578
|
||||
l 756.125 103.34 l 756.629 105.23 l 757.199 107.184 l 757.828 109.203 l
|
||||
758.457 111.281 l 759.086 113.488 l 759.719 115.691 l 760.41 118.023 l
|
||||
761.168 120.418 l 761.859 122.875 l 762.617 125.395 l 763.371 127.98 l 764.129
|
||||
130.562 l 764.887 133.148 l 765.641 135.855 l 766.398 138.504 l 767.152
|
||||
141.148 l 767.91 143.797 l 768.664 146.441 l 769.422 149.09 l 770.18 151.672
|
||||
l 770.871 154.191 l 771.562 156.715 l 772.195 159.109 l 772.824 161.504
|
||||
l 773.453 163.832 l 774.023 166.039 l 774.59 168.246 l 775.094 170.324
|
||||
l 775.598 172.34 l 776.102 174.23 l 776.543 176.121 l 776.922 177.887 l
|
||||
777.297 179.586 l 777.867 182.297 l 778.309 184.754 l 778.746 187.148 l
|
||||
779.062 189.355 l 779.379 191.496 l 779.566 193.449 l 779.691 195.34 l 779.82
|
||||
197.168 l 779.82 198.805 l 779.758 200.32 l 779.691 201.77 l 779.566 203.027
|
||||
l 779.379 204.227 l 779.125 205.359 l 778.875 206.305 l 778.621 207.188
|
||||
l 778.309 208.008 l 777.93 208.699 l 777.613 209.328 l 777.234 209.961
|
||||
l 776.855 210.465 l 776.543 211.031 l 775.785 211.914 l 775.094 212.859
|
||||
l 774.336 213.738 l 773.582 214.559 l 772.762 215.316 l 772.004 216.07 l
|
||||
771.25 216.641 l 770.555 217.145 l 769.926 217.586 l 769.422 217.836 l
|
||||
768.918 217.961 l 768.539 218.023 l 768.16 217.898 l 767.91 217.586 l 767.656
|
||||
217.145 l 767.469 216.512 l 767.344 215.758 l 767.215 214.938 l 767.09
|
||||
213.992 l 766.902 213.047 l 766.711 212.039 l 766.461 211.094 l 766.27 210.336
|
||||
l 765.957 209.645 l 765.641 208.824 l 765.262 208.008 l 764.316 206.117
|
||||
l 763.75 205.109 l 763.184 204.035 l 762.555 202.965 l 761.859 201.77 l
|
||||
761.168 200.633 l 760.473 199.438 l 759.719 198.176 l 758.961 196.914 l
|
||||
758.457 195.969 l 757.891 195.023 l 757.262 193.953 l 756.629 192.883 l
|
||||
756 191.75 l 755.242 190.488 l 754.551 189.227 l 753.793 187.906 l 753.039
|
||||
186.582 l 752.219 185.133 l 751.398 183.746 l 750.582 182.297 l 749.762
|
||||
180.91 l 748.941 179.461 l 748.188 178.074 l 747.367 176.688 l 746.609
|
||||
175.367 l 745.793 173.98 l 745.035 172.719 l 744.281 171.395 l 743.586 170.199
|
||||
l 742.895 169 l 742.199 167.805 l 741.445 166.605 l 740.688 165.348 l 739.934
|
||||
164.086 l 739.176 162.762 l 738.418 161.504 l 737.602 160.18 l 736.781
|
||||
158.855 l 736.023 157.531 l 735.207 156.211 l 734.449 154.949 l 733.695
|
||||
153.688 l 732.938 152.492 l 732.18 151.293 l 731.488 150.16 l 730.793 149.027
|
||||
l 730.164 148.02 l 729.535 147.008 l 728.906 146 l 728.273 145.055 l 727.52
|
||||
143.797 l 726.699 142.535 l 725.879 141.34 l 725.125 140.078 l 724.305
|
||||
138.879 l 723.547 137.684 l 722.73 136.484 l 721.973 135.352 l 721.281 134.219
|
||||
l 720.523 133.211 l 719.895 132.266 l 719.262 131.32 l 718.633 130.5 l
|
||||
718.129 129.742 l 717.562 129.051 l 717.121 128.359 l 716.492 127.539 l
|
||||
715.859 126.781 l 715.293 126.027 l 714.664 125.332 l 714.098 124.641 l
|
||||
713.531 124.008 l 712.961 123.441 l 711.449 121.93 l 710.945 121.488 l 710.504
|
||||
121.109 l 710 120.605 l 709.434 120.164 l 708.805 119.66 l 708.172 119.156
|
||||
l 707.48 118.652 l 706.852 118.211 l 706.156 117.77 l 705.465 117.332 l
|
||||
704.832 116.953 l 703.574 116.32 l 702.941 116.07 l 702.188 115.754 l 701.43
|
||||
115.504 l 700.676 115.25 l 699.918 115.062 l 699.164 114.871 l 698.469
|
||||
114.684 l 697.84 114.559 l 697.207 114.496 l 696.516 114.367 l 695.758 114.242
|
||||
l 694.941 114.18 l 694.184 114.18 l 693.492 114.117 l 690.465 114.117 l
|
||||
689.332 113.992 l 688.703 113.926 l 688.199 113.801 l 687.695 113.613 l
|
||||
687.191 113.422 l 686.75 113.172 l 686.246 112.793 l 685.676 112.414 l
|
||||
685.109 111.91 l 684.605 111.469 l 684.039 110.965 l 683.535 110.461 l 683.094
|
||||
109.957 l 682.59 109.516 l 682.086 109.012 l 681.078 107.879 l 680.637
|
||||
107.375 l 680.195 106.809 l 679.879 106.305 l 679.566 105.863 l 679.375
|
||||
105.359 l 679.188 104.855 l 679.062 104.285 l 679 103.719 l 678.934 103.152
|
||||
l 678.871 102.523 l 678.871 99.562 l 678.809 98.805 l 678.809 98.047 l
|
||||
678.746 97.293 l 678.621 96.535 l 678.559 95.844 l 678.43 95.211 l 678.18
|
||||
93.828 l 677.988 93.133 l 677.738 92.379 l 677.484 91.621 l 677.234 90.863
|
||||
l 676.98 90.109 l 676.668 89.477 l 676.414 88.848 l 676.035 88.156 l 675.66
|
||||
87.523 l 675.281 86.895 l 674.84 86.203 l 674.336 85.508 l 673.832 84.879
|
||||
l 673.328 84.184 l 672.887 83.617 l 671.879 82.484 l 671.5 82.043 l 671.059
|
||||
81.602 l 670.617 81.098 l 669.609 80.09 l 668.98 79.523 l 668.348 78.957
|
||||
l 667.656 78.324 l 666.961 77.758 l 666.27 77.191 l 665.449 76.562 l 664.695
|
||||
75.93 l 664 75.426 l 663.309 74.922 l 662.551 74.418 l 661.668 73.789 l
|
||||
660.789 73.156 l 659.844 72.527 l 658.77 71.773 l 657.699 71.078 l 656.504
|
||||
70.324 l 655.367 69.504 l 654.172 68.746 l 652.91 67.93 l 651.715 67.172
|
||||
l 650.453 66.352 l 649.191 65.535 l 647.934 64.777 l 646.988 64.148 l 646.043
|
||||
63.516 l 645.035 62.887 l 643.965 62.258 l 642.828 61.562 l 641.695 60.871
|
||||
l 640.559 60.113 l 639.301 59.359 l 638.039 58.602 l 636.781 57.848 l 635.457
|
||||
57.027 l 634.133 56.27 l 632.809 55.453 l 631.488 54.633 l 630.227 53.875
|
||||
l 628.902 53.121 l 627.641 52.301 l 626.383 51.609 l 625.184 50.852 l 623.988
|
||||
50.16 l 622.789 49.465 l 621.594 48.773 l 620.27 48.016 l 619.008 47.262
|
||||
l 617.625 46.441 l 616.301 45.684 l 614.914 44.867 l 613.527 44.047 l 612.078
|
||||
43.227 l 610.691 42.406 l 609.242 41.59 l 607.855 40.832 l 606.406 40.012
|
||||
l 605.082 39.195 l 603.762 38.438 l 602.5 37.746 l 601.238 37.051 l 600.105
|
||||
36.359 l 599.035 35.727 l 597.965 35.16 l 596.074 34.027 l 594.812 33.27
|
||||
l 593.551 32.578 l 592.355 31.82 l 591.223 31.129 l 590.023 30.5 l 588.953
|
||||
29.867 l 587.883 29.238 l 586.875 28.734 l 585.863 28.23 l 584.984 27.789
|
||||
l 584.164 27.41 l 583.344 27.094 l 582.652 26.781 l 581.895 26.59 l 580.949
|
||||
26.34 l 579.941 26.152 l 578.996 25.961 l 578.051 25.836 l 577.23 25.711
|
||||
l 576.477 25.582 l 575.848 25.395 l 575.406 25.141 l 575.09 24.891 l 575.027
|
||||
24.512 l 575.027 24.133 l 575.152 23.629 l 575.469 23.125 l 575.848 22.496
|
||||
l 576.352 21.801 l 576.98 21.047 l 577.672 20.289 l 578.492 19.473 l 579.312
|
||||
18.715 l 580.195 17.957 l 581.074 17.266 l 582.02 16.574 l 582.59 16.195
|
||||
l 583.094 15.816 l 583.723 15.438 l 584.352 15.125 l 585.047 14.746 l 585.863
|
||||
14.43 l 586.746 14.18 l 587.691 13.926 l 588.828 13.676 l 589.961 13.484
|
||||
l 591.285 13.359 l 592.734 13.297 l 594.246 13.234 l 595.883 13.234 l 597.711
|
||||
13.359 l 599.602 13.484 l 601.555 13.676 l 603.699 13.988 l 605.902 14.305
|
||||
l 608.297 14.746 l 610.754 15.188 l 613.465 15.754 l 615.164 16.133 l 616.93
|
||||
16.508 l 618.82 16.949 l 620.711 17.453 l 622.727 17.957 l 624.809 18.461
|
||||
l 627.012 19.031 l 629.219 19.598 l 631.551 20.227 l 633.945 20.855 l 636.34
|
||||
21.488 l 638.859 22.18 l 641.379 22.875 l 643.965 23.629 l 646.609 24.387
|
||||
l 649.258 25.141 l 651.902 25.898 l 654.551 26.656 l 657.195 27.41 l 659.906
|
||||
28.168 l 662.488 28.922 l 665.074 29.68 l 667.656 30.434 l 670.176 31.191
|
||||
l 672.633 31.883 l 675.027 32.641 l 677.359 33.332 l 679.566 33.965 l 681.77
|
||||
34.594 l 683.852 35.223 l 685.867 35.855 l 687.82 36.422 l 689.711 36.926
|
||||
l 691.477 37.492 l 693.176 37.934 l 694.75 38.438 l 697.523 39.195 l 700.043
|
||||
39.949 l 702.375 40.582 l 704.582 41.148 l 706.598 41.715 l 708.426 42.156
|
||||
l 710.191 42.598 l 711.766 42.91 l 713.215 43.227 l 714.473 43.48 l 715.609
|
||||
43.668 l 716.68 43.793 l 717.562 43.922 l 718.383 43.984 l 719.703 43.984
|
||||
l 720.273 43.922 l 720.777 43.855 l 721.219 43.793 l 721.723 43.668 l 722.539
|
||||
43.543 l 723.359 43.289 l 724.305 43.102 l 725.25 42.848 l 726.258 42.535
|
||||
l 728.273 41.902 l 729.281 41.527 l 730.289 41.211 l 731.234 40.895 l 732.117
|
||||
40.582 l 733 40.266 l 733.82 39.949 l 734.641 39.637 l 735.52 39.258 l
|
||||
736.402 38.941 l 737.285 38.629 l 738.168 38.312 l 738.988 37.996 l 739.867
|
||||
37.684 l 740.625 37.43 l 741.383 37.242 l 742.074 37.051 l 742.766 36.926
|
||||
l 743.523 36.801 l 744.344 36.672 l 745.16 36.609 l 746.738 36.609 l 747.492
|
||||
36.672 l 748.188 36.738 l 748.816 36.863 l 749.383 36.988 l 749.887 37.176
|
||||
l 750.453 37.367 l 751.023 37.617 l 751.527 37.934 l 751.969 38.25 l 752.41
|
||||
38.562 l 752.785 38.941 l 753.164 39.258 l 753.48 39.57 l 753.793 39.887
|
||||
l 754.109 40.266 l 754.488 40.645 l 754.805 41.086 l 755.117 41.527 l 755.434
|
||||
42.031 l 755.684 42.598 l 755.938 43.164 l 756.062 43.668 l 756.188 44.234
|
||||
l 756.316 44.867 l 756.379 45.559 l 756.441 46.316 l 756.441 47.891 l 756.379
|
||||
48.711 l 756.254 49.527 l 756.125 50.285 l 756 50.977 l 755.812 51.672
|
||||
l 755.621 52.426 l 755.371 53.184 l 755.055 54.066 l 754.738 54.883 l 754.426
|
||||
55.766 l 754.109 56.648 l 753.73 57.531 l 753.418 58.414 l 753.102 59.23
|
||||
l 752.785 60.051 l 752.473 60.934 l 752.156 61.816 l 751.84 62.762 l 751.465
|
||||
63.77 l h
|
||||
750.832 65.785 m f
|
||||
0.504104 w
|
||||
0 J
|
||||
2 j
|
||||
[] 0.0 d
|
||||
4 M q 1 0 0 1 0 0 cm
|
||||
750.832 65.785 m 750.52 66.793 l 750.203 67.801 l 749.949 68.746 l 749.699
|
||||
69.691 l 749.508 70.512 l 749.32 71.332 l 749.258 71.836 l 749.133 72.277
|
||||
l 749.07 72.781 l 749.07 74.672 l 749.133 75.488 l 749.195 76.371 l 749.383
|
||||
77.441 l 749.574 78.578 l 749.824 79.836 l 750.078 81.285 l 750.453 82.863
|
||||
l 750.895 84.625 l 751.336 86.453 l 751.902 88.469 l 752.473 90.676 l 753.102
|
||||
93.008 l 753.859 95.527 l 754.613 98.301 l 755.055 99.875 l 755.559 101.578
|
||||
l 756.125 103.34 l 756.629 105.23 l 757.199 107.184 l 757.828 109.203 l
|
||||
758.457 111.281 l 759.086 113.488 l 759.719 115.691 l 760.41 118.023 l
|
||||
761.168 120.418 l 761.859 122.875 l 762.617 125.395 l 763.371 127.98 l 764.129
|
||||
130.562 l 764.887 133.148 l 765.641 135.855 l 766.398 138.504 l 767.152
|
||||
141.148 l 767.91 143.797 l 768.664 146.441 l 769.422 149.09 l 770.18 151.672
|
||||
l 770.871 154.191 l 771.562 156.715 l 772.195 159.109 l 772.824 161.504
|
||||
l 773.453 163.832 l 774.023 166.039 l 774.59 168.246 l 775.094 170.324
|
||||
l 775.598 172.34 l 776.102 174.23 l 776.543 176.121 l 776.922 177.887 l
|
||||
777.297 179.586 l 777.867 182.297 l 778.309 184.754 l 778.746 187.148 l
|
||||
779.062 189.355 l 779.379 191.496 l 779.566 193.449 l 779.691 195.34 l 779.82
|
||||
197.168 l 779.82 198.805 l 779.758 200.32 l 779.691 201.77 l 779.566 203.027
|
||||
l 779.379 204.227 l 779.125 205.359 l 778.875 206.305 l 778.621 207.188
|
||||
l 778.309 208.008 l 777.93 208.699 l 777.613 209.328 l 777.234 209.961
|
||||
l 776.855 210.465 l 776.543 211.031 l 775.785 211.914 l 775.094 212.859
|
||||
l 774.336 213.738 l 773.582 214.559 l 772.762 215.316 l 772.004 216.07 l
|
||||
771.25 216.641 l 770.555 217.145 l 769.926 217.586 l 769.422 217.836 l
|
||||
768.918 217.961 l 768.539 218.023 l 768.16 217.898 l 767.91 217.586 l 767.656
|
||||
217.145 l 767.469 216.512 l 767.344 215.758 l 767.215 214.938 l 767.09
|
||||
213.992 l 766.902 213.047 l 766.711 212.039 l 766.461 211.094 l 766.27 210.336
|
||||
l 765.957 209.645 l 765.641 208.824 l 765.262 208.008 l 764.316 206.117
|
||||
l 763.75 205.109 l 763.184 204.035 l 762.555 202.965 l 761.859 201.77 l
|
||||
761.168 200.633 l 760.473 199.438 l 759.719 198.176 l 758.961 196.914 l
|
||||
758.457 195.969 l 757.891 195.023 l 757.262 193.953 l 756.629 192.883 l
|
||||
756 191.75 l 755.242 190.488 l 754.551 189.227 l 753.793 187.906 l 753.039
|
||||
186.582 l 752.219 185.133 l 751.398 183.746 l 750.582 182.297 l 749.762
|
||||
180.91 l 748.941 179.461 l 748.188 178.074 l 747.367 176.688 l 746.609
|
||||
175.367 l 745.793 173.98 l 745.035 172.719 l 744.281 171.395 l 743.586 170.199
|
||||
l 742.895 169 l 742.199 167.805 l 741.445 166.605 l 740.688 165.348 l 739.934
|
||||
164.086 l 739.176 162.762 l 738.418 161.504 l 737.602 160.18 l 736.781
|
||||
158.855 l 736.023 157.531 l 735.207 156.211 l 734.449 154.949 l 733.695
|
||||
153.688 l 732.938 152.492 l 732.18 151.293 l 731.488 150.16 l 730.793 149.027
|
||||
l 730.164 148.02 l 729.535 147.008 l 728.906 146 l 728.273 145.055 l 727.52
|
||||
143.797 l 726.699 142.535 l 725.879 141.34 l 725.125 140.078 l 724.305
|
||||
138.879 l 723.547 137.684 l 722.73 136.484 l 721.973 135.352 l 721.281 134.219
|
||||
l 720.523 133.211 l 719.895 132.266 l 719.262 131.32 l 718.633 130.5 l
|
||||
718.129 129.742 l 717.562 129.051 l 717.121 128.359 l 716.492 127.539 l
|
||||
715.859 126.781 l 715.293 126.027 l 714.664 125.332 l 714.098 124.641 l
|
||||
713.531 124.008 l 712.961 123.441 l 711.449 121.93 l 710.945 121.488 l 710.504
|
||||
121.109 l 710 120.605 l 709.434 120.164 l 708.805 119.66 l 708.172 119.156
|
||||
l 707.48 118.652 l 706.852 118.211 l 706.156 117.77 l 705.465 117.332 l
|
||||
704.832 116.953 l 703.574 116.32 l 702.941 116.07 l 702.188 115.754 l 701.43
|
||||
115.504 l 700.676 115.25 l 699.918 115.062 l 699.164 114.871 l 698.469
|
||||
114.684 l 697.84 114.559 l 697.207 114.496 l 696.516 114.367 l 695.758 114.242
|
||||
l 694.941 114.18 l 694.184 114.18 l 693.492 114.117 l 690.465 114.117 l
|
||||
689.332 113.992 l 688.703 113.926 l 688.199 113.801 l 687.695 113.613 l
|
||||
687.191 113.422 l 686.75 113.172 l 686.246 112.793 l 685.676 112.414 l
|
||||
685.109 111.91 l 684.605 111.469 l 684.039 110.965 l 683.535 110.461 l 683.094
|
||||
109.957 l 682.59 109.516 l 682.086 109.012 l 681.078 107.879 l 680.637
|
||||
107.375 l 680.195 106.809 l 679.879 106.305 l 679.566 105.863 l 679.375
|
||||
105.359 l 679.188 104.855 l 679.062 104.285 l 679 103.719 l 678.934 103.152
|
||||
l 678.871 102.523 l 678.871 99.562 l 678.809 98.805 l 678.809 98.047 l
|
||||
678.746 97.293 l 678.621 96.535 l 678.559 95.844 l 678.43 95.211 l 678.18
|
||||
93.828 l 677.988 93.133 l 677.738 92.379 l 677.484 91.621 l 677.234 90.863
|
||||
l 676.98 90.109 l 676.668 89.477 l 676.414 88.848 l 676.035 88.156 l 675.66
|
||||
87.523 l 675.281 86.895 l 674.84 86.203 l 674.336 85.508 l 673.832 84.879
|
||||
l 673.328 84.184 l 672.887 83.617 l 671.879 82.484 l 671.5 82.043 l 671.059
|
||||
81.602 l 670.617 81.098 l 669.609 80.09 l 668.98 79.523 l 668.348 78.957
|
||||
l 667.656 78.324 l 666.961 77.758 l 666.27 77.191 l 665.449 76.562 l 664.695
|
||||
75.93 l 664 75.426 l 663.309 74.922 l 662.551 74.418 l 661.668 73.789 l
|
||||
660.789 73.156 l 659.844 72.527 l 658.77 71.773 l 657.699 71.078 l 656.504
|
||||
70.324 l 655.367 69.504 l 654.172 68.746 l 652.91 67.93 l 651.715 67.172
|
||||
l 650.453 66.352 l 649.191 65.535 l 647.934 64.777 l 646.988 64.148 l 646.043
|
||||
63.516 l 645.035 62.887 l 643.965 62.258 l 642.828 61.562 l 641.695 60.871
|
||||
l 640.559 60.113 l 639.301 59.359 l 638.039 58.602 l 636.781 57.848 l 635.457
|
||||
57.027 l 634.133 56.27 l 632.809 55.453 l 631.488 54.633 l 630.227 53.875
|
||||
l 628.902 53.121 l 627.641 52.301 l 626.383 51.609 l 625.184 50.852 l 623.988
|
||||
50.16 l 622.789 49.465 l 621.594 48.773 l 620.27 48.016 l 619.008 47.262
|
||||
l 617.625 46.441 l 616.301 45.684 l 614.914 44.867 l 613.527 44.047 l 612.078
|
||||
43.227 l 610.691 42.406 l 609.242 41.59 l 607.855 40.832 l 606.406 40.012
|
||||
l 605.082 39.195 l 603.762 38.438 l 602.5 37.746 l 601.238 37.051 l 600.105
|
||||
36.359 l 599.035 35.727 l 597.965 35.16 l 596.074 34.027 l 594.812 33.27
|
||||
l 593.551 32.578 l 592.355 31.82 l 591.223 31.129 l 590.023 30.5 l 588.953
|
||||
29.867 l 587.883 29.238 l 586.875 28.734 l 585.863 28.23 l 584.984 27.789
|
||||
l 584.164 27.41 l 583.344 27.094 l 582.652 26.781 l 581.895 26.59 l 580.949
|
||||
26.34 l 579.941 26.152 l 578.996 25.961 l 578.051 25.836 l 577.23 25.711
|
||||
l 576.477 25.582 l 575.848 25.395 l 575.406 25.141 l 575.09 24.891 l 575.027
|
||||
24.512 l 575.027 24.133 l 575.152 23.629 l 575.469 23.125 l 575.848 22.496
|
||||
l 576.352 21.801 l 576.98 21.047 l 577.672 20.289 l 578.492 19.473 l 579.312
|
||||
18.715 l 580.195 17.957 l 581.074 17.266 l 582.02 16.574 l 582.59 16.195
|
||||
l 583.094 15.816 l 583.723 15.438 l 584.352 15.125 l 585.047 14.746 l 585.863
|
||||
14.43 l 586.746 14.18 l 587.691 13.926 l 588.828 13.676 l 589.961 13.484
|
||||
l 591.285 13.359 l 592.734 13.297 l 594.246 13.234 l 595.883 13.234 l 597.711
|
||||
13.359 l 599.602 13.484 l 601.555 13.676 l 603.699 13.988 l 605.902 14.305
|
||||
l 608.297 14.746 l 610.754 15.188 l 613.465 15.754 l 615.164 16.133 l 616.93
|
||||
16.508 l 618.82 16.949 l 620.711 17.453 l 622.727 17.957 l 624.809 18.461
|
||||
l 627.012 19.031 l 629.219 19.598 l 631.551 20.227 l 633.945 20.855 l 636.34
|
||||
21.488 l 638.859 22.18 l 641.379 22.875 l 643.965 23.629 l 646.609 24.387
|
||||
l 649.258 25.141 l 651.902 25.898 l 654.551 26.656 l 657.195 27.41 l 659.906
|
||||
28.168 l 662.488 28.922 l 665.074 29.68 l 667.656 30.434 l 670.176 31.191
|
||||
l 672.633 31.883 l 675.027 32.641 l 677.359 33.332 l 679.566 33.965 l 681.77
|
||||
34.594 l 683.852 35.223 l 685.867 35.855 l 687.82 36.422 l 689.711 36.926
|
||||
l 691.477 37.492 l 693.176 37.934 l 694.75 38.438 l 697.523 39.195 l 700.043
|
||||
39.949 l 702.375 40.582 l 704.582 41.148 l 706.598 41.715 l 708.426 42.156
|
||||
l 710.191 42.598 l 711.766 42.91 l 713.215 43.227 l 714.473 43.48 l 715.609
|
||||
43.668 l 716.68 43.793 l 717.562 43.922 l 718.383 43.984 l 719.703 43.984
|
||||
l 720.273 43.922 l 720.777 43.855 l 721.219 43.793 l 721.723 43.668 l 722.539
|
||||
43.543 l 723.359 43.289 l 724.305 43.102 l 725.25 42.848 l 726.258 42.535
|
||||
l 728.273 41.902 l 729.281 41.527 l 730.289 41.211 l 731.234 40.895 l 732.117
|
||||
40.582 l 733 40.266 l 733.82 39.949 l 734.641 39.637 l 735.52 39.258 l
|
||||
736.402 38.941 l 737.285 38.629 l 738.168 38.312 l 738.988 37.996 l 739.867
|
||||
37.684 l 740.625 37.43 l 741.383 37.242 l 742.074 37.051 l 742.766 36.926
|
||||
l 743.523 36.801 l 744.344 36.672 l 745.16 36.609 l 746.738 36.609 l 747.492
|
||||
36.672 l 748.188 36.738 l 748.816 36.863 l 749.383 36.988 l 749.887 37.176
|
||||
l 750.453 37.367 l 751.023 37.617 l 751.527 37.934 l 751.969 38.25 l 752.41
|
||||
38.562 l 752.785 38.941 l 753.164 39.258 l 753.48 39.57 l 753.793 39.887
|
||||
l 754.109 40.266 l 754.488 40.645 l 754.805 41.086 l 755.117 41.527 l 755.434
|
||||
42.031 l 755.684 42.598 l 755.938 43.164 l 756.062 43.668 l 756.188 44.234
|
||||
l 756.316 44.867 l 756.379 45.559 l 756.441 46.316 l 756.441 47.891 l 756.379
|
||||
48.711 l 756.254 49.527 l 756.125 50.285 l 756 50.977 l 755.812 51.672
|
||||
l 755.621 52.426 l 755.371 53.184 l 755.055 54.066 l 754.738 54.883 l 754.426
|
||||
55.766 l 754.109 56.648 l 753.73 57.531 l 753.418 58.414 l 753.102 59.23
|
||||
l 752.785 60.051 l 752.473 60.934 l 752.156 61.816 l 751.84 62.762 l 751.465
|
||||
63.77 l h
|
||||
750.832 65.785 m S Q
|
||||
17.958715 w
|
||||
1 J
|
||||
0 j
|
||||
q 1 0 0 1 0 0 cm
|
||||
583.219 238.188 m 582.852 222.684 570.367 210.199 554.863 209.832 c S Q
|
||||
q 1 0 0 1 0 0 cm
|
||||
625.754 238.188 m 625.836 219.363 618.395 201.281 605.082 187.969 c 591.77
|
||||
174.656 573.688 167.215 554.863 167.301 c S Q
|
||||
q 1 0 0 1 0 0 cm
|
||||
668.285 238.188 m 668.301 208.102 656.359 179.242 635.082 157.969 c 613.809
|
||||
136.695 584.949 124.75 554.863 124.766 c S Q
|
||||
q 1 0 0 1 0 0 cm
|
||||
710.82 238.188 m 710.68 152.113 640.938 82.371 554.863 82.23 c S Q
|
||||
0 0.501961 0.501961 rg
|
||||
BT
|
||||
144.000001 0 0 -144.000001 12.326648 108.318331 Tm
|
||||
/f-0-0 1 Tf
|
||||
[(WFB-ng)]TJ
|
||||
0 -1 Td
|
||||
[(DataLink)]TJ
|
||||
ET
|
||||
Q Q
|
||||
showpage
|
||||
%%Trailer
|
||||
end
|
||||
%%EOF
|
BIN
doc/logo-big.png
Normal file
BIN
doc/logo-big.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
130
doc/logo-big.svg
Normal file
130
doc/logo-big.svg
Normal file
@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Creator: fig2dev Version 3.2.6a -->
|
||||
|
||||
<!-- CreationDate: 2022-09-07 09:58:42 -->
|
||||
|
||||
<!-- Magnification: 1.05 -->
|
||||
|
||||
<svg
|
||||
width="793.05176pt"
|
||||
height="260.87396pt"
|
||||
viewBox="5489 719 12585.519 4139.9998"
|
||||
version="1.1"
|
||||
id="svg16"
|
||||
sodipodi:docname="logo-big.svg"
|
||||
inkscape:version="1.2.1 (9c6d41e, 2022-07-14)"
|
||||
inkscape:export-filename="logo-big.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata22">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs20" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1147"
|
||||
id="namedview18"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.67816092"
|
||||
inkscape:cx="92.161017"
|
||||
inkscape:cy="168.83898"
|
||||
inkscape:window-x="1366"
|
||||
inkscape:window-y="31"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg16"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="pt" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2285.24px;line-height:100%;font-family:'GOST type B';-inkscape-font-specification:'GOST type B';letter-spacing:0px;word-spacing:0px;fill:#008080;fill-opacity:1;stroke:none;stroke-width:11.9023px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="5807.4766"
|
||||
y="2437.9829"
|
||||
id="text26"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan24"
|
||||
x="5807.4766"
|
||||
y="2437.9829"
|
||||
style="font-size:2285.24px;fill:#008080;stroke-width:11.9023px">WFB-ng</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="5807.4766"
|
||||
y="4723.2227"
|
||||
style="font-size:2285.24px;fill:#008080;stroke-width:11.9023px"
|
||||
id="tspan28">DataLink</tspan></text>
|
||||
<g
|
||||
fill="none"
|
||||
id="g28"
|
||||
transform="matrix(1.0726947,0,0,1.0726947,8125.3361,-436.134)">
|
||||
<!-- Line -->
|
||||
<rect
|
||||
x="5490"
|
||||
y="1125"
|
||||
width="3735"
|
||||
height="3735"
|
||||
rx="105"
|
||||
fill="#ffffff"
|
||||
id="rect16" />
|
||||
<!-- Line -->
|
||||
<polygon
|
||||
points="8656,2003 8655,2010 8655,2017 8655,2026 8655,2036 8656,2047 8658,2061 8660,2076 8664,2094 8668,2115 8674,2138 8680,2163 8687,2191 8696,2222 8705,2256 8716,2293 8722,2315 8729,2338 8736,2362 8743,2387 8751,2413 8759,2441 8768,2470 8777,2500 8786,2532 8796,2564 8805,2597 8815,2631 8825,2666 8835,2701 8846,2736 8856,2771 8866,2806 8876,2841 8885,2875 8894,2909 8903,2942 8912,2974 8920,3005 8928,3034 8936,3063 8942,3091 8949,3117 8955,3142 8960,3166 8965,3189 8973,3224 8979,3257 8984,3288 8988,3317 8990,3344 8992,3369 8993,3392 8993,3413 8992,3432 8990,3450 8987,3465 8984,3479 8980,3491 8976,3502 8971,3511 8967,3519 8962,3527 8957,3534 8947,3546 8938,3558 8928,3569 8917,3580 8907,3589 8897,3597 8888,3604 8880,3608 8874,3610 8869,3611 8864,3609 8860,3604 8858,3596 8856,3586 8854,3574 8852,3561 8850,3548 8846,3534 8843,3525 8840,3516 8835,3505 8830,3494 8824,3482 8817,3469 8809,3455 8801,3441 8792,3426 8783,3411 8774,3395 8764,3379 8757,3367 8750,3355 8743,3342 8735,3329 8727,3314 8718,3299 8709,3283 8699,3266 8690,3249 8680,3232 8670,3215 8660,3197 8650,3180 8640,3163 8630,3146 8621,3130 8612,3114 8602,3098 8593,3082 8584,3066 8574,3049 8564,3033 8554,3016 8543,2998 8533,2980 8522,2963 8511,2945 8501,2927 8490,2910 8480,2894 8470,2878 8461,2862 8451,2848 8443,2834 8434,2820 8426,2808 8416,2792 8406,2776 8396,2761 8386,2745 8376,2730 8367,2715 8357,2701 8348,2687 8339,2674 8331,2662 8323,2651 8316,2641 8309,2632 8303,2624 8295,2613 8287,2603 8279,2594 8271,2585 8264,2576 8256,2569 8249,2562 8243,2555 8237,2550 8231,2544 8223,2538 8215,2531 8207,2524 8197,2517 8188,2511 8179,2505 8170,2500 8162,2495 8153,2491 8143,2487 8133,2483 8123,2480 8112,2477 8102,2474 8093,2472 8085,2471 8074,2469 8063,2468 8051,2468 8041,2467 8031,2467 8023,2467 8014,2467 8006,2467 7997,2466 7989,2465 7981,2462 7974,2460 7967,2455 7960,2450 7951,2443 7943,2436 7936,2429 7929,2422 7922,2415 7914,2407 7907,2399 7900,2391 7894,2384 7890,2377 7887,2369 7885,2362 7883,2353 7882,2344 7882,2336 7882,2328 7882,2319 7882,2310 7881,2299 7881,2288 7880,2277 7878,2266 7877,2257 7875,2248 7873,2238 7870,2228 7866,2217 7863,2207 7859,2198 7855,2189 7850,2180 7845,2171 7839,2162 7833,2153 7826,2143 7819,2135 7812,2127 7806,2119 7800,2113 7795,2107 7788,2101 7781,2094 7773,2086 7765,2079 7756,2071 7746,2063 7736,2055 7726,2047 7717,2041 7708,2034 7698,2027 7687,2019 7675,2011 7662,2002 7649,1993 7634,1983 7619,1974 7604,1964 7589,1954 7573,1944 7558,1934 7542,1924 7529,1916 7516,1907 7502,1899 7487,1889 7472,1880 7456,1870 7439,1860 7422,1849 7405,1839 7387,1828 7369,1817 7351,1807 7334,1796 7317,1786 7300,1776 7284,1766 7268,1757 7252,1748 7236,1738 7220,1729 7204,1720 7187,1710 7170,1700 7153,1690 7135,1680 7118,1670 7101,1660 7084,1651 7067,1641 7051,1632 7036,1623 7021,1615 7008,1607 6995,1600 6983,1593 6971,1586 6955,1576 6939,1567 6924,1558 6909,1549 6895,1541 6881,1533 6868,1526 6856,1520 6845,1515 6834,1510 6825,1507 6816,1504 6802,1500 6789,1498 6776,1496 6764,1494 6754,1492 6746,1490 6741,1486 6739,1481 6740,1476 6742,1470 6747,1462 6753,1453 6761,1443 6771,1433 6781,1422 6793,1412 6804,1403 6817,1393 6824,1388 6831,1383 6840,1379 6849,1374 6860,1370 6872,1366 6886,1363 6901,1360 6919,1358 6938,1357 6959,1357 6982,1358 7007,1360 7034,1362 7063,1366 7094,1371 7127,1377 7163,1385 7185,1390 7209,1395 7234,1401 7260,1408 7288,1414 7317,1422 7346,1430 7377,1438 7409,1447 7442,1456 7476,1465 7510,1474 7545,1484 7580,1494 7615,1504 7650,1515 7685,1525 7720,1535 7754,1545 7787,1554 7819,1564 7850,1573 7881,1582 7910,1591 7938,1599 7964,1607 7989,1614 8013,1621 8036,1628 8058,1634 8095,1645 8129,1654 8159,1663 8187,1670 8213,1676 8236,1682 8256,1686 8274,1690 8290,1692 8303,1694 8315,1695 8325,1696 8333,1695 8340,1695 8347,1694 8354,1693 8364,1690 8376,1687 8388,1684 8401,1681 8415,1676 8428,1672 8442,1668 8455,1663 8466,1659 8478,1655 8489,1651 8500,1646 8512,1642 8523,1638 8535,1633 8546,1629 8557,1626 8567,1622 8576,1620 8585,1618 8596,1616 8607,1615 8618,1614 8629,1614 8640,1615 8649,1616 8657,1618 8664,1620 8672,1623 8680,1627 8687,1632 8693,1637 8698,1642 8703,1647 8708,1652 8713,1657 8718,1663 8723,1670 8727,1678 8730,1686 8732,1693 8734,1701 8735,1710 8736,1721 8736,1732 8735,1743 8734,1754 8732,1765 8730,1774 8728,1783 8725,1793 8721,1804 8717,1815 8713,1827 8709,1838 8704,1850 8700,1861 8696,1872 8692,1884 8687,1895 8683,1908 8678,1922 8674,1935 8670,1949 8666,1962 8663,1974 8660,1986 8658,1997 "
|
||||
fill="#008f00"
|
||||
stroke="#008f00"
|
||||
stroke-width="8px"
|
||||
stroke-linejoin="bevel"
|
||||
id="polygon18" />
|
||||
<!-- Arc -->
|
||||
<path
|
||||
d="M 6300,4500 A 461,461 0 0 0 5850,4050"
|
||||
stroke="#008f00"
|
||||
stroke-width="285px"
|
||||
stroke-linecap="round"
|
||||
id="path20" />
|
||||
<!-- Arc -->
|
||||
<path
|
||||
d="M 6975,4500 A 1120,1120 0 0 0 5850,3375"
|
||||
stroke="#008f00"
|
||||
stroke-width="285px"
|
||||
stroke-linecap="round"
|
||||
id="path22" />
|
||||
<!-- Arc -->
|
||||
<path
|
||||
d="M 7650,4500 A 1799,1799 0 0 0 5850,2700"
|
||||
stroke="#008f00"
|
||||
stroke-width="285px"
|
||||
stroke-linecap="round"
|
||||
id="path24" />
|
||||
<!-- Arc -->
|
||||
<path
|
||||
d="M 8325,4500 A 2479,2479 0 0 0 5850,2025"
|
||||
stroke="#008f00"
|
||||
stroke-width="285px"
|
||||
stroke-linecap="round"
|
||||
id="path26" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.1 KiB |
197
doc/logo.eps
Normal file
197
doc/logo.eps
Normal file
@ -0,0 +1,197 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Title: logo.fig
|
||||
%%Creator: fig2dev Version 3.2.6a
|
||||
%%CreationDate: 2022-09-07 17:34:11
|
||||
%%BoundingBox: 0 0 236 236
|
||||
%Magnification: 1.0000
|
||||
%%EndComments
|
||||
%%BeginProlog
|
||||
/$F2psDict 200 dict def
|
||||
$F2psDict begin
|
||||
$F2psDict /mtrx matrix put
|
||||
/col-1 {0 setgray} bind def
|
||||
/col7 {1.000 1.000 1.000 srgb} bind def
|
||||
/col12 {0.000 0.560 0.000 srgb} bind def
|
||||
|
||||
end
|
||||
|
||||
/cp {closepath} bind def
|
||||
/ef {eofill} bind def
|
||||
/gr {grestore} bind def
|
||||
/gs {gsave} bind def
|
||||
/sa {save} bind def
|
||||
/rs {restore} bind def
|
||||
/l {lineto} bind def
|
||||
/m {moveto} bind def
|
||||
/rm {rmoveto} bind def
|
||||
/n {newpath} bind def
|
||||
/s {stroke} bind def
|
||||
/sh {show} bind def
|
||||
/slc {setlinecap} bind def
|
||||
/slj {setlinejoin} bind def
|
||||
/slw {setlinewidth} bind def
|
||||
/srgb {setrgbcolor} bind def
|
||||
/rot {rotate} bind def
|
||||
/sc {scale} bind def
|
||||
/sd {setdash} bind def
|
||||
/ff {findfont} bind def
|
||||
/sf {setfont} bind def
|
||||
/scf {scalefont} bind def
|
||||
/sw {stringwidth} bind def
|
||||
/tr {translate} bind def
|
||||
/tnt {dup dup currentrgbcolor
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
|
||||
bind def
|
||||
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
|
||||
4 -2 roll mul srgb} bind def
|
||||
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
|
||||
/$F2psEnd {$F2psEnteredState restore end} def
|
||||
|
||||
/pageheader {
|
||||
save
|
||||
newpath 0 236 moveto 0 0 lineto 236 0 lineto 236 236 lineto closepath clip newpath
|
||||
-345.8 306.2 translate
|
||||
1 -1 scale
|
||||
$F2psBegin
|
||||
10 setmiterlimit
|
||||
0 slj 0 slc
|
||||
0.06299 0.06299 sc
|
||||
} bind def
|
||||
/pagefooter {
|
||||
$F2psEnd
|
||||
restore
|
||||
} bind def
|
||||
%%EndProlog
|
||||
pageheader
|
||||
%
|
||||
% Fig objects follow
|
||||
%
|
||||
%
|
||||
% here starts figure with depth 50
|
||||
% Polyline
|
||||
0 slj
|
||||
0 slc
|
||||
0.000 slw
|
||||
n 5595 1125 m 5490 1125 5490 4755 105 arcto 4 {pop} repeat
|
||||
5490 4860 9120 4860 105 arcto 4 {pop} repeat
|
||||
9225 4860 9225 1230 105 arcto 4 {pop} repeat
|
||||
9225 1125 5595 1125 105 arcto 4 {pop} repeat
|
||||
cp gs col7 1.00 shd ef gr
|
||||
% Polyline
|
||||
2 slj
|
||||
7.500 slw
|
||||
n 8696 1872 m 8692 1884 l 8687 1895 l 8683 1908 l 8678 1922 l 8674 1935 l
|
||||
8670 1949 l 8666 1962 l 8663 1974 l 8660 1986 l 8658 1997 l
|
||||
8656 2003 l 8655 2010 l 8655 2017 l 8655 2026 l 8655 2036 l
|
||||
8656 2047 l 8658 2061 l 8660 2076 l 8664 2094 l 8668 2115 l
|
||||
8674 2138 l 8680 2163 l 8687 2191 l 8696 2222 l 8705 2256 l
|
||||
8716 2293 l 8722 2315 l 8729 2338 l 8736 2362 l 8743 2387 l
|
||||
8751 2413 l 8759 2441 l 8768 2470 l 8777 2500 l 8786 2532 l
|
||||
8796 2564 l 8805 2597 l 8815 2631 l 8825 2666 l 8835 2701 l
|
||||
8846 2736 l 8856 2771 l 8866 2806 l 8876 2841 l 8885 2875 l
|
||||
8894 2909 l 8903 2942 l 8912 2974 l 8920 3005 l 8928 3034 l
|
||||
8936 3063 l 8942 3091 l 8949 3117 l 8955 3142 l 8960 3166 l
|
||||
8965 3189 l 8973 3224 l 8979 3257 l 8984 3288 l 8988 3317 l
|
||||
8990 3344 l 8992 3369 l 8993 3392 l 8993 3413 l 8992 3432 l
|
||||
8990 3450 l 8987 3465 l 8984 3479 l 8980 3491 l 8976 3502 l
|
||||
8971 3511 l 8967 3519 l 8962 3527 l 8957 3534 l 8947 3546 l
|
||||
8938 3558 l 8928 3569 l 8917 3580 l 8907 3589 l 8897 3597 l
|
||||
8888 3604 l 8880 3608 l 8874 3610 l 8869 3611 l 8864 3609 l
|
||||
8860 3604 l 8858 3596 l 8856 3586 l 8854 3574 l 8852 3561 l
|
||||
8850 3548 l 8846 3534 l 8843 3525 l 8840 3516 l 8835 3505 l
|
||||
8830 3494 l 8824 3482 l 8817 3469 l 8809 3455 l 8801 3441 l
|
||||
8792 3426 l 8783 3411 l 8774 3395 l 8764 3379 l 8757 3367 l
|
||||
8750 3355 l 8743 3342 l 8735 3329 l 8727 3314 l 8718 3299 l
|
||||
8709 3283 l 8699 3266 l 8690 3249 l 8680 3232 l 8670 3215 l
|
||||
8660 3197 l 8650 3180 l 8640 3163 l 8630 3146 l 8621 3130 l
|
||||
8612 3114 l 8602 3098 l 8593 3082 l 8584 3066 l 8574 3049 l
|
||||
8564 3033 l 8554 3016 l 8543 2998 l 8533 2980 l 8522 2963 l
|
||||
8511 2945 l 8501 2927 l 8490 2910 l 8480 2894 l 8470 2878 l
|
||||
8461 2862 l 8451 2848 l 8443 2834 l 8434 2820 l 8426 2808 l
|
||||
8416 2792 l 8406 2776 l 8396 2761 l 8386 2745 l 8376 2730 l
|
||||
8367 2715 l 8357 2701 l 8348 2687 l 8339 2674 l 8331 2662 l
|
||||
8323 2651 l 8316 2641 l 8309 2632 l 8303 2624 l 8295 2613 l
|
||||
8287 2603 l 8279 2594 l 8271 2585 l 8264 2576 l 8256 2569 l
|
||||
8249 2562 l 8243 2555 l 8237 2550 l 8231 2544 l 8223 2538 l
|
||||
8215 2531 l 8207 2524 l 8197 2517 l 8188 2511 l 8179 2505 l
|
||||
8170 2500 l 8162 2495 l 8153 2491 l 8143 2487 l 8133 2483 l
|
||||
8123 2480 l 8112 2477 l 8102 2474 l 8093 2472 l 8085 2471 l
|
||||
8074 2469 l 8063 2468 l 8051 2468 l 8041 2467 l 8031 2467 l
|
||||
8023 2467 l 8014 2467 l 8006 2467 l 7997 2466 l 7989 2465 l
|
||||
7981 2462 l 7974 2460 l 7967 2455 l 7960 2450 l 7951 2443 l
|
||||
7943 2436 l 7936 2429 l 7929 2422 l 7922 2415 l 7914 2407 l
|
||||
7907 2399 l 7900 2391 l 7894 2384 l 7890 2377 l 7887 2369 l
|
||||
7885 2362 l 7883 2353 l 7882 2344 l 7882 2336 l 7882 2328 l
|
||||
7882 2319 l 7882 2310 l 7881 2299 l 7881 2288 l 7880 2277 l
|
||||
7878 2266 l 7877 2257 l 7875 2248 l 7873 2238 l 7870 2228 l
|
||||
7866 2217 l 7863 2207 l 7859 2198 l 7855 2189 l 7850 2180 l
|
||||
7845 2171 l 7839 2162 l 7833 2153 l 7826 2143 l 7819 2135 l
|
||||
7812 2127 l 7806 2119 l 7800 2113 l 7795 2107 l 7788 2101 l
|
||||
7781 2094 l 7773 2086 l 7765 2079 l 7756 2071 l 7746 2063 l
|
||||
7736 2055 l 7726 2047 l 7717 2041 l 7708 2034 l 7698 2027 l
|
||||
7687 2019 l 7675 2011 l 7662 2002 l 7649 1993 l 7634 1983 l
|
||||
7619 1974 l 7604 1964 l 7589 1954 l 7573 1944 l 7558 1934 l
|
||||
7542 1924 l 7529 1916 l 7516 1907 l 7502 1899 l 7487 1889 l
|
||||
7472 1880 l 7456 1870 l 7439 1860 l 7422 1849 l 7405 1839 l
|
||||
7387 1828 l 7369 1817 l 7351 1807 l 7334 1796 l 7317 1786 l
|
||||
7300 1776 l 7284 1766 l 7268 1757 l 7252 1748 l 7236 1738 l
|
||||
7220 1729 l 7204 1720 l 7187 1710 l 7170 1700 l 7153 1690 l
|
||||
7135 1680 l 7118 1670 l 7101 1660 l 7084 1651 l 7067 1641 l
|
||||
7051 1632 l 7036 1623 l 7021 1615 l 7008 1607 l 6995 1600 l
|
||||
6983 1593 l 6971 1586 l 6955 1576 l 6939 1567 l 6924 1558 l
|
||||
6909 1549 l 6895 1541 l 6881 1533 l 6868 1526 l 6856 1520 l
|
||||
6845 1515 l 6834 1510 l 6825 1507 l 6816 1504 l 6802 1500 l
|
||||
6789 1498 l 6776 1496 l 6764 1494 l 6754 1492 l 6746 1490 l
|
||||
6741 1486 l 6739 1481 l 6740 1476 l 6742 1470 l 6747 1462 l
|
||||
6753 1453 l 6761 1443 l 6771 1433 l 6781 1422 l 6793 1412 l
|
||||
6804 1403 l 6817 1393 l 6824 1388 l 6831 1383 l 6840 1379 l
|
||||
6849 1374 l 6860 1370 l 6872 1366 l 6886 1363 l 6901 1360 l
|
||||
6919 1358 l 6938 1357 l 6959 1357 l 6982 1358 l 7007 1360 l
|
||||
7034 1362 l 7063 1366 l 7094 1371 l 7127 1377 l 7163 1385 l
|
||||
7185 1390 l 7209 1395 l 7234 1401 l 7260 1408 l 7288 1414 l
|
||||
7317 1422 l 7346 1430 l 7377 1438 l 7409 1447 l 7442 1456 l
|
||||
7476 1465 l 7510 1474 l 7545 1484 l 7580 1494 l 7615 1504 l
|
||||
7650 1515 l 7685 1525 l 7720 1535 l 7754 1545 l 7787 1554 l
|
||||
7819 1564 l 7850 1573 l 7881 1582 l 7910 1591 l 7938 1599 l
|
||||
7964 1607 l 7989 1614 l 8013 1621 l 8036 1628 l 8058 1634 l
|
||||
8095 1645 l 8129 1654 l 8159 1663 l 8187 1670 l 8213 1676 l
|
||||
8236 1682 l 8256 1686 l 8274 1690 l 8290 1692 l 8303 1694 l
|
||||
8315 1695 l 8325 1696 l 8333 1695 l 8340 1695 l 8347 1694 l
|
||||
8354 1693 l 8364 1690 l 8376 1687 l 8388 1684 l 8401 1681 l
|
||||
8415 1676 l 8428 1672 l 8442 1668 l 8455 1663 l 8466 1659 l
|
||||
8478 1655 l 8489 1651 l 8500 1646 l 8512 1642 l 8523 1638 l
|
||||
8535 1633 l 8546 1629 l 8557 1626 l 8567 1622 l 8576 1620 l
|
||||
8585 1618 l 8596 1616 l 8607 1615 l 8618 1614 l 8629 1614 l
|
||||
8640 1615 l 8649 1616 l 8657 1618 l 8664 1620 l 8672 1623 l
|
||||
8680 1627 l 8687 1632 l 8693 1637 l 8698 1642 l 8703 1647 l
|
||||
8708 1652 l 8713 1657 l 8718 1663 l 8723 1670 l 8727 1678 l
|
||||
8730 1686 l 8732 1693 l 8734 1701 l 8735 1710 l 8736 1721 l
|
||||
8736 1732 l 8735 1743 l 8734 1754 l 8732 1765 l 8730 1774 l
|
||||
8728 1783 l 8725 1793 l 8721 1804 l 8717 1815 l 8713 1827 l
|
||||
8709 1838 l 8704 1850 l 8700 1861 l
|
||||
cp gs col12 1.00 shd ef gr gs col12 s gr
|
||||
% Arc
|
||||
285.000 slw
|
||||
1 slc
|
||||
n 5838.8 4511.2 461.4 -1.3972 -88.6028 arcn
|
||||
gs col12 s gr
|
||||
|
||||
% Arc
|
||||
n 5855.1 4494.9 1119.9 0.2614 -90.2614 arcn
|
||||
gs col12 s gr
|
||||
|
||||
% Arc
|
||||
n 5850.7 4499.3 1799.3 0.0232 -90.0232 arcn
|
||||
gs col12 s gr
|
||||
|
||||
% Arc
|
||||
n 5846.3 4503.7 2478.7 -0.0860 -89.9140 arcn
|
||||
gs col12 s gr
|
||||
|
||||
% here ends figure;
|
||||
pagefooter
|
||||
showpage
|
||||
%%Trailer
|
||||
%EOF
|
30
doc/logo.fig
Normal file
30
doc/logo.fig
Normal file
@ -0,0 +1,30 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.6a
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
5 1 0 20 12 7 48 -1 -1 0.000 1 1 0 0 5838.750 4511.250 6300 4500 6165 4185 5850 4050
|
||||
5 1 0 20 12 7 48 -1 -1 0.000 1 1 0 0 5855.110 4494.890 6975 4500 6647 3703 5850 3375
|
||||
5 1 0 20 12 7 48 -1 -1 0.000 1 1 0 0 5850.730 4499.270 7650 4500 7127 3231 5850 2700
|
||||
5 1 0 20 12 7 48 -1 -1 0.000 1 1 0 0 5846.278 4503.722 8325 4500 7601 2753 5850 2025
|
||||
6 6705 1305 9045 3645
|
||||
3 1 0 1 12 12 49 -1 20 0.000 0 0 0 38
|
||||
8741 1761 8696 1867 8650 2004 8650 2096 9045 3372 8962 3547
|
||||
8847 3645 8863 3538 8779 3409 8605 3098 8415 2786 8293 2604
|
||||
8232 2543 8164 2490 8081 2467 8020 2467 7974 2467 7929 2422
|
||||
7882 2377 7882 2330 7882 2270 7860 2186 7807 2118 7746 2057
|
||||
7563 1935 7252 1745 6941 1571 6812 1487 6705 1503 6804 1388
|
||||
6979 1305 8255 1700 8346 1700 8483 1655 8589 1609 8673 1616
|
||||
8703 1647 8734 1677
|
||||
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
-6
|
||||
2 4 0 0 12 7 50 -1 20 0.000 0 0 7 0 0 5
|
||||
9225 1125 5490 1125 5490 4860 9225 4860 9225 1125
|
83
doc/logo.svg
Normal file
83
doc/logo.svg
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!-- Creator: fig2dev Version 3.2.6a -->
|
||||
<!-- CreationDate: 2022-09-07 17:33:03 -->
|
||||
<!-- Magnification: 1.05 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="236pt" height="236pt"
|
||||
viewBox="5489 1124 3737 3737">
|
||||
<g fill="none">
|
||||
<!-- Line -->
|
||||
<rect x="5490" y="1125" width="3735" height="3735" rx="105" fill="#ffffff"/>
|
||||
<!-- Line -->
|
||||
<polygon points=" 8696,1872 8692,1884 8687,1895 8683,1908 8678,1922 8674,1935 8670,1949 8666,1962
|
||||
8663,1974 8660,1986 8658,1997 8656,2003 8655,2010 8655,2017 8655,2026 8655,2036
|
||||
8656,2047 8658,2061 8660,2076 8664,2094 8668,2115 8674,2138 8680,2163 8687,2191
|
||||
8696,2222 8705,2256 8716,2293 8722,2315 8729,2338 8736,2362 8743,2387 8751,2413
|
||||
8759,2441 8768,2470 8777,2500 8786,2532 8796,2564 8805,2597 8815,2631 8825,2666
|
||||
8835,2701 8846,2736 8856,2771 8866,2806 8876,2841 8885,2875 8894,2909 8903,2942
|
||||
8912,2974 8920,3005 8928,3034 8936,3063 8942,3091 8949,3117 8955,3142 8960,3166
|
||||
8965,3189 8973,3224 8979,3257 8984,3288 8988,3317 8990,3344 8992,3369 8993,3392
|
||||
8993,3413 8992,3432 8990,3450 8987,3465 8984,3479 8980,3491 8976,3502 8971,3511
|
||||
8967,3519 8962,3527 8957,3534 8947,3546 8938,3558 8928,3569 8917,3580 8907,3589
|
||||
8897,3597 8888,3604 8880,3608 8874,3610 8869,3611 8864,3609 8860,3604 8858,3596
|
||||
8856,3586 8854,3574 8852,3561 8850,3548 8846,3534 8843,3525 8840,3516 8835,3505
|
||||
8830,3494 8824,3482 8817,3469 8809,3455 8801,3441 8792,3426 8783,3411 8774,3395
|
||||
8764,3379 8757,3367 8750,3355 8743,3342 8735,3329 8727,3314 8718,3299 8709,3283
|
||||
8699,3266 8690,3249 8680,3232 8670,3215 8660,3197 8650,3180 8640,3163 8630,3146
|
||||
8621,3130 8612,3114 8602,3098 8593,3082 8584,3066 8574,3049 8564,3033 8554,3016
|
||||
8543,2998 8533,2980 8522,2963 8511,2945 8501,2927 8490,2910 8480,2894 8470,2878
|
||||
8461,2862 8451,2848 8443,2834 8434,2820 8426,2808 8416,2792 8406,2776 8396,2761
|
||||
8386,2745 8376,2730 8367,2715 8357,2701 8348,2687 8339,2674 8331,2662 8323,2651
|
||||
8316,2641 8309,2632 8303,2624 8295,2613 8287,2603 8279,2594 8271,2585 8264,2576
|
||||
8256,2569 8249,2562 8243,2555 8237,2550 8231,2544 8223,2538 8215,2531 8207,2524
|
||||
8197,2517 8188,2511 8179,2505 8170,2500 8162,2495 8153,2491 8143,2487 8133,2483
|
||||
8123,2480 8112,2477 8102,2474 8093,2472 8085,2471 8074,2469 8063,2468 8051,2468
|
||||
8041,2467 8031,2467 8023,2467 8014,2467 8006,2467 7997,2466 7989,2465 7981,2462
|
||||
7974,2460 7967,2455 7960,2450 7951,2443 7943,2436 7936,2429 7929,2422 7922,2415
|
||||
7914,2407 7907,2399 7900,2391 7894,2384 7890,2377 7887,2369 7885,2362 7883,2353
|
||||
7882,2344 7882,2336 7882,2328 7882,2319 7882,2310 7881,2299 7881,2288 7880,2277
|
||||
7878,2266 7877,2257 7875,2248 7873,2238 7870,2228 7866,2217 7863,2207 7859,2198
|
||||
7855,2189 7850,2180 7845,2171 7839,2162 7833,2153 7826,2143 7819,2135 7812,2127
|
||||
7806,2119 7800,2113 7795,2107 7788,2101 7781,2094 7773,2086 7765,2079 7756,2071
|
||||
7746,2063 7736,2055 7726,2047 7717,2041 7708,2034 7698,2027 7687,2019 7675,2011
|
||||
7662,2002 7649,1993 7634,1983 7619,1974 7604,1964 7589,1954 7573,1944 7558,1934
|
||||
7542,1924 7529,1916 7516,1907 7502,1899 7487,1889 7472,1880 7456,1870 7439,1860
|
||||
7422,1849 7405,1839 7387,1828 7369,1817 7351,1807 7334,1796 7317,1786 7300,1776
|
||||
7284,1766 7268,1757 7252,1748 7236,1738 7220,1729 7204,1720 7187,1710 7170,1700
|
||||
7153,1690 7135,1680 7118,1670 7101,1660 7084,1651 7067,1641 7051,1632 7036,1623
|
||||
7021,1615 7008,1607 6995,1600 6983,1593 6971,1586 6955,1576 6939,1567 6924,1558
|
||||
6909,1549 6895,1541 6881,1533 6868,1526 6856,1520 6845,1515 6834,1510 6825,1507
|
||||
6816,1504 6802,1500 6789,1498 6776,1496 6764,1494 6754,1492 6746,1490 6741,1486
|
||||
6739,1481 6740,1476 6742,1470 6747,1462 6753,1453 6761,1443 6771,1433 6781,1422
|
||||
6793,1412 6804,1403 6817,1393 6824,1388 6831,1383 6840,1379 6849,1374 6860,1370
|
||||
6872,1366 6886,1363 6901,1360 6919,1358 6938,1357 6959,1357 6982,1358 7007,1360
|
||||
7034,1362 7063,1366 7094,1371 7127,1377 7163,1385 7185,1390 7209,1395 7234,1401
|
||||
7260,1408 7288,1414 7317,1422 7346,1430 7377,1438 7409,1447 7442,1456 7476,1465
|
||||
7510,1474 7545,1484 7580,1494 7615,1504 7650,1515 7685,1525 7720,1535 7754,1545
|
||||
7787,1554 7819,1564 7850,1573 7881,1582 7910,1591 7938,1599 7964,1607 7989,1614
|
||||
8013,1621 8036,1628 8058,1634 8095,1645 8129,1654 8159,1663 8187,1670 8213,1676
|
||||
8236,1682 8256,1686 8274,1690 8290,1692 8303,1694 8315,1695 8325,1696 8333,1695
|
||||
8340,1695 8347,1694 8354,1693 8364,1690 8376,1687 8388,1684 8401,1681 8415,1676
|
||||
8428,1672 8442,1668 8455,1663 8466,1659 8478,1655 8489,1651 8500,1646 8512,1642
|
||||
8523,1638 8535,1633 8546,1629 8557,1626 8567,1622 8576,1620 8585,1618 8596,1616
|
||||
8607,1615 8618,1614 8629,1614 8640,1615 8649,1616 8657,1618 8664,1620 8672,1623
|
||||
8680,1627 8687,1632 8693,1637 8698,1642 8703,1647 8708,1652 8713,1657 8718,1663
|
||||
8723,1670 8727,1678 8730,1686 8732,1693 8734,1701 8735,1710 8736,1721 8736,1732
|
||||
8735,1743 8734,1754 8732,1765 8730,1774 8728,1783 8725,1793 8721,1804 8717,1815
|
||||
8713,1827 8709,1838 8704,1850 8700,1861" fill="#008f00"
|
||||
stroke="#008f00" stroke-width="8px" stroke-linejoin="bevel"/>
|
||||
<!-- Arc -->
|
||||
<path d="M 6300,4500 A 461 461 0 0 0 5850 4050"
|
||||
stroke="#008f00" stroke-width="285px" stroke-linecap="round"/>
|
||||
<!-- Arc -->
|
||||
<path d="M 6975,4500 A 1120 1120 0 0 0 5850 3375"
|
||||
stroke="#008f00" stroke-width="285px" stroke-linecap="round"/>
|
||||
<!-- Arc -->
|
||||
<path d="M 7650,4500 A 1799 1799 0 0 0 5850 2700"
|
||||
stroke="#008f00" stroke-width="285px" stroke-linecap="round"/>
|
||||
<!-- Arc -->
|
||||
<path d="M 8325,4500 A 2479 2479 0 0 0 5850 2025"
|
||||
stroke="#008f00" stroke-width="285px" stroke-linecap="round"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.4 KiB |
174
doc/wfb-ng-std-draft.md
Normal file
174
doc/wfb-ng-std-draft.md
Normal file
@ -0,0 +1,174 @@
|
||||
% WFB-NG Data Transport Standard [Draft]
|
||||
% Vasily Evseenko <<svpcom@p2ptech.org>>
|
||||
% Aug 29, 2022
|
||||
|
||||
## Introduction
|
||||
|
||||
The purpose of this document is to standardize the data transfer protocol
|
||||
via raw wifi radio over long distances. In this context, "long distance" is the distance over which the standard 802.11 ACK mechanism does not work.
|
||||
|
||||
Many areas of robotics require an inexpensive and long-range point-to-point or point-to-multipoint communication channel.
|
||||
|
||||
The proposed solution allows you to transmit arbitrary data streams at speeds up to 8mbps (MCS # 1 modulation) over a distance of tens of kilometers
|
||||
using ordinary wifi adapters that support the transmission of "raw" packets. At the moment, these are adapters based on Realtek RTL8812AU chips.
|
||||
|
||||
## Areas of use:
|
||||
|
||||
- Communication between robots and ground station
|
||||
- Communication of amateur satellites (CUBESAT) with the earth
|
||||
- Digital radio communication on the ground
|
||||
- ...
|
||||
|
||||
## Work principles
|
||||
The main limitation of the transmission range of standard WiFi is the requirement to receive an ACK packet from the receiver in a strictly defined time interval after transmission.
|
||||
When the distance between two stations exceeds ~200m, then the receiver does not have time to confirm the receipt of the packet and data transmission becomes impossible.
|
||||
|
||||
Some WiFi adapters have a so-called "raw" mode for receiving and transmitting packets.
|
||||
In "raw" WiFi mode, the adapter can receive and transmit packets bypassing the standard 802.11 protocol stack. In particular, you can turn off the requirements for sending and receiving ACK packets.
|
||||
In this case, the limitation on the maximum range is removed (the range now depends only on the sensitivity of the receiver and the power of the transmitter).
|
||||
But requires to make own medium access control layer (MAC layer).
|
||||
|
||||
## Protocol description
|
||||
|
||||
The protocol supports point-to-point links. But each of two peers can simultaneously participate in an arbitrary number of links.
|
||||
|
||||
Each link has:
|
||||
|
||||
- Own set of encryption keys
|
||||
- Up to 256 unidirectional data streams.
|
||||
|
||||
The last four bytes of the sender's MAC address are used to set the connection membership.
|
||||
Thus the MAC address has the format: `0x57, 0x42, 0xaa, 0xbb, 0xcc, 0xdd`, where the first two bytes are the protocol header (`'W'`,`'B'`),
|
||||
then three bytes - the link id and the last byte - the number of the stream inside the link.
|
||||
First address byte `'W'`(0x57) has two lower bits set which means that address is multicast and locally administred.
|
||||
|
||||
1. The initial data transfer quantum is a UDP packet. The contents of the packet is opaque and can be any of:
|
||||
- RTP packet with video or audio.
|
||||
- Mavlink packet
|
||||
- IP tunnel data packet.
|
||||
- ...
|
||||
|
||||
2. Next, the packet stream is processed by the FEC codec (using [zfec](http://info.iet.unipi.it/~luigi/fec.html) -- Erasure codes based on Vandermonde matrices.)
|
||||
3. FEC packets are encrypted with the aead_chacha20poly1305 stream cipher using the libsodium library
|
||||
4. The result is transmitted to the air in the form of one WiFi packet.
|
||||
|
||||
|
||||
### Stream allocation scheme:
|
||||
|
||||
Down streams (vehicle to GS): 0 - 127
|
||||
|
||||
Up streams (GS to vehicle): 128 - 255
|
||||
|
||||
Stream ranges:
|
||||
|
||||
* 0 - 15: video streams, 0 is default video stream
|
||||
* 16 - 31: mavlink streams, 16 is default mavlink stream
|
||||
* 32 - 47: tunnel streams, 32 is default tunnel stream
|
||||
|
||||
All other ranges reserved for future use
|
||||
|
||||
|
||||
## Radio packets format
|
||||
|
||||
There are two packet types
|
||||
|
||||
1. Data packet (`packet_type = 1`, has encrypted and fec-encoded data)
|
||||
2. Session packet (`packet_type = 2`, has encrypted session key)
|
||||
|
||||
|
||||
``` .c
|
||||
static uint8_t ieee80211_header[] = {
|
||||
0x08, 0x01, 0x00, 0x00, // data frame, not protected, from STA to DS via an AP
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // receiver is broadcast
|
||||
0x57, 0x42, 0xaa, 0xbb, 0xcc, 0xdd, // last four bytes will be replaced by channel_id
|
||||
0x57, 0x42, 0xaa, 0xbb, 0xcc, 0xdd, // last four bytes will be replaced by channel_id
|
||||
0x00, 0x00, // (seq_num << 4) + fragment_num
|
||||
};
|
||||
```
|
||||
|
||||
```
|
||||
radiotap_header:
|
||||
ieee_80211_header:
|
||||
1. Data packet:
|
||||
wblock_hdr_t { packet_type = 1, nonce = (block_idx << 8) + fragment_idx }
|
||||
wpacket_hdr_t { flags, packet_size } #
|
||||
data #
|
||||
+-- encrypted and authenticated by session key
|
||||
2. Session packet:
|
||||
wsession_hdr_t { packet_type = 2, nonce = random() }
|
||||
wsession_data_t { epoch, channel_id, session_key } # -- encrypted and signed using crypto_box_easy(rx_publickey, tx_secretkey)
|
||||
|
||||
data nonce: 56bit block_idx + 8bit fragment_idx
|
||||
session nonce: crypto_box_NONCEBYTES of random bytes
|
||||
```
|
||||
|
||||
``` .c
|
||||
// Network packet headers. All numbers are in network (big endian) format
|
||||
// Encrypted packets can be either session key or data packet.
|
||||
|
||||
// Session key packet
|
||||
|
||||
typedef struct {
|
||||
uint8_t packet_type; // packet_type = 2
|
||||
uint8_t session_nonce[crypto_box_NONCEBYTES]; // random data
|
||||
} __attribute__ ((packed)) wsession_hdr_t;
|
||||
|
||||
typedef struct{
|
||||
uint64_t epoch; // It allow to drop session packets from old epoch
|
||||
uint32_t channel_id; // (link_id << 8) + port_number
|
||||
uint8_t session_key[crypto_aead_chacha20poly1305_KEYBYTES];
|
||||
} __attribute__ ((packed)) wsession_data_t;
|
||||
|
||||
// Data packet. Embed FEC-encoded data
|
||||
|
||||
typedef struct {
|
||||
uint8_t packet_type; // packet_type = 1
|
||||
uint64_t data_nonce; // data_nonce = (block_idx << 8) + fragment_idx
|
||||
} __attribute__ ((packed)) wblock_hdr_t;
|
||||
|
||||
// Plain data packet after FEC decode
|
||||
|
||||
typedef struct {
|
||||
uint8_t flags;
|
||||
uint16_t packet_size;
|
||||
} __attribute__ ((packed)) wpacket_hdr_t;
|
||||
|
||||
```
|
||||
|
||||
## Implementation notes
|
||||
### Reference implementation
|
||||
[wfb-ng.org](http://wfb-ng.org) -- reference implementation of WFB-NG protocol stack (C + Python/Twisted).
|
||||
|
||||
License GPLv3.
|
||||
|
||||
### Encryption
|
||||
WFB-NG encrypts data stream using libsodium.
|
||||
|
||||
When TX starts, it generates new session key, encrypts it using public key authenticated encryption (cryptobox) and announce it every SESSION_KEY_ANNOUNCE_MSEC (default 1s).
|
||||
Data packets encrypted by crypto_aead_chacha20poly1305_encrypt using session key and packet index as nonce.
|
||||
|
||||
|
||||
### RX-Ring
|
||||
Due to multiple RX radios with own internal queues incoming packets can arrive out of order and you need a method to rearrange them.
|
||||
RX-Ring is a circular buffer, where you store packets, grouped by FEC blocks. It has two parameters: *rx_ring_front* (index of the first allocated FEC block) and
|
||||
*alloc_size* -- number of allocated blocks. So rx_ring is like a queue of FEC blocks (each block can hold up to N fragments) - you append
|
||||
new fragments to block(s) in the tail and fetch them from the head.
|
||||
|
||||
When you receive a new packet it can belongs to:
|
||||
|
||||
1. New fec block - you need to allocate it in RX ring (do nothing if block was already processed)
|
||||
2. Already existing fec block - you need to add it to them (do nothing if packet already processed)
|
||||
|
||||
If you successfully decode all fragments from the block then you should yield and remove ALL unfinished blocks before it.
|
||||
|
||||
When you allocate a new block you have following choices:
|
||||
|
||||
1. Add a new block to rx ring tail.
|
||||
2. Override a block at rx ring head if rx ring is full.
|
||||
|
||||
So you can support invariant that output UDP packets will be always ordered and no duplicates will be inside.
|
||||
|
||||
### Mavlink mode
|
||||
By default WFB-NG encapsulates one source UDP packet to one WiFi packet. But mavlink packets are very small (usually less than 100 bytes) and
|
||||
send them in separate packets produces too much overhead. You can add optimized mavlink mode.
|
||||
It will pack mavlink packets into one UDP packet while size < ``MAX_PAYLOAD_SIZE`` and ``mavlink_agg_in_ms`` is not expired.
|
@ -6,11 +6,13 @@ ReloadPropagatedFrom=wifibroadcast.service
|
||||
[Service]
|
||||
Type=simple
|
||||
EnvironmentFile=/etc/default/wifibroadcast
|
||||
# Use for multi-link setup
|
||||
# Environment="WIFIBROADCAST_CFG=/etc/wifibroadcast_linkXXX.cfg"
|
||||
ExecStart=/usr/bin/wfb-server %i ${WFB_NICS}
|
||||
TimeoutStopSec=5s
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
StandardOutput=file:/var/log/wifibroadcast.log
|
||||
# Set logging to file in wifibroadcast.cfg
|
||||
StandardError=inherit
|
||||
|
||||
[Install]
|
||||
|
2
setup.py
2
setup.py
@ -80,5 +80,7 @@ setup(
|
||||
author="Vasily Evseenko",
|
||||
author_email="svpcom@p2ptech.org",
|
||||
description="The next generation of long-range packet radio link based on raw WiFi radio",
|
||||
long_description=open('README.md').read(),
|
||||
long_description_content_type='text/markdown',
|
||||
license="GPLv3",
|
||||
)
|
||||
|
36
src/keygen.c
36
src/keygen.c
@ -1,6 +1,6 @@
|
||||
/* -*- c -*-
|
||||
*/
|
||||
// Copyright (C) 2017, 2018 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
// Copyright (C) 2017 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -20,6 +20,11 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sodium.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@ -29,8 +34,33 @@ int main(void)
|
||||
unsigned char gs_secretkey[crypto_box_SECRETKEYBYTES];
|
||||
FILE *fp;
|
||||
|
||||
crypto_box_keypair(drone_publickey, drone_secretkey);
|
||||
crypto_box_keypair(gs_publickey, gs_secretkey);
|
||||
{
|
||||
int fd;
|
||||
int c;
|
||||
|
||||
if ((fd = open("/dev/random", O_RDONLY)) != -1) {
|
||||
if (ioctl(fd, RNDGETENTCNT, &c) == 0 && c < 160) {
|
||||
fprintf(stderr, "This system doesn't provide enough entropy to quickly generate high-quality random numbers.\n"
|
||||
"Installing the rng-utils/rng-tools, jitterentropy or haveged packages may help.\n"
|
||||
"On virtualized Linux environments, also consider using virtio-rng.\n"
|
||||
"The service will not start until enough entropy has been collected.\n");
|
||||
}
|
||||
(void) close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (sodium_init() < 0)
|
||||
{
|
||||
fprintf(stderr, "libsodium init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (crypto_box_keypair(drone_publickey, drone_secretkey) !=0 ||
|
||||
crypto_box_keypair(gs_publickey, gs_secretkey) != 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to generate keys\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if((fp = fopen("drone.key", "w")) == NULL)
|
||||
{
|
||||
|
117
src/rx.cpp
117
src/rx.cpp
@ -1,6 +1,6 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (C) 2017 - 2020 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
// Copyright (C) 2017 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -32,6 +32,8 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <limits.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@ -48,7 +50,7 @@ extern "C"
|
||||
using namespace std;
|
||||
|
||||
|
||||
Receiver::Receiver(const char *wlan, int wlan_idx, int radio_port, BaseAggregator *agg) : wlan_idx(wlan_idx), agg(agg)
|
||||
Receiver::Receiver(const char *wlan, int wlan_idx, uint32_t channel_id, BaseAggregator *agg) : wlan_idx(wlan_idx), agg(agg)
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
@ -60,9 +62,7 @@ Receiver::Receiver(const char *wlan, int wlan_idx, int radio_port, BaseAggregato
|
||||
|
||||
if (pcap_set_snaplen(ppcap, 4096) !=0) throw runtime_error("set_snaplen failed");
|
||||
if (pcap_set_promisc(ppcap, 1) != 0) throw runtime_error("set_promisc failed");
|
||||
//if (pcap_set_rfmon(ppcap, 1) !=0) throw runtime_error("set_rfmon failed");
|
||||
if (pcap_set_timeout(ppcap, -1) !=0) throw runtime_error("set_timeout failed");
|
||||
//if (pcap_set_buffer_size(ppcap, 2048) !=0) throw runtime_error("set_buffer_size failed");
|
||||
if (pcap_set_immediate_mode(ppcap, 1) != 0) throw runtime_error(string_format("pcap_set_immediate_mode failed: %s", pcap_geterr(ppcap)));
|
||||
if (pcap_activate(ppcap) !=0) throw runtime_error(string_format("pcap_activate failed: %s", pcap_geterr(ppcap)));
|
||||
if (pcap_setnonblock(ppcap, 1, errbuf) != 0) throw runtime_error(string_format("set_nonblock failed: %s", errbuf));
|
||||
@ -71,22 +71,12 @@ Receiver::Receiver(const char *wlan, int wlan_idx, int radio_port, BaseAggregato
|
||||
struct bpf_program bpfprogram;
|
||||
string program;
|
||||
|
||||
switch (link_encap)
|
||||
{
|
||||
case DLT_PRISM_HEADER:
|
||||
fprintf(stderr, "%s has DLT_PRISM_HEADER Encap\n", wlan);
|
||||
program = string_format("radio[0x4a:4]==0x13223344 && radio[0x4e:2] == 0x55%.2x", radio_port);
|
||||
break;
|
||||
|
||||
case DLT_IEEE802_11_RADIO:
|
||||
fprintf(stderr, "%s has DLT_IEEE802_11_RADIO Encap\n", wlan);
|
||||
program = string_format("ether[0x0a:4]==0x13223344 && ether[0x0e:2] == 0x55%.2x", radio_port);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (link_encap != DLT_IEEE802_11_RADIO) {
|
||||
throw runtime_error(string_format("unknown encapsulation on %s", wlan));
|
||||
}
|
||||
|
||||
program = string_format("ether[0x0a:2]==0x5742 && ether[0x0c:4] == 0x%08x", channel_id);
|
||||
|
||||
if (pcap_compile(ppcap, &bpfprogram, program.c_str(), 1, 0) == -1) {
|
||||
throw runtime_error(string_format("Unable to compile %s: %s", program.c_str(), pcap_geterr(ppcap)));
|
||||
}
|
||||
@ -208,9 +198,11 @@ void Receiver::loop_iter(void)
|
||||
}
|
||||
|
||||
|
||||
Aggregator::Aggregator(const string &client_addr, int client_port, int k, int n, const string &keypair) : fec_k(k), fec_n(n), seq(0), rx_ring_front(0), rx_ring_alloc(0), last_known_block((uint64_t)-1),
|
||||
count_p_all(0), count_p_dec_err(0), count_p_dec_ok(0), count_p_fec_recovered(0),
|
||||
count_p_lost(0), count_p_bad(0), count_p_override(0)
|
||||
Aggregator::Aggregator(const string &client_addr, int client_port, int k, int n, const string &keypair, uint64_t epoch, uint32_t channel_id) : \
|
||||
fec_k(k), fec_n(n), seq(0), rx_ring_front(0), rx_ring_alloc(0),
|
||||
last_known_block((uint64_t)-1), epoch(epoch), channel_id(channel_id),
|
||||
count_p_all(0), count_p_dec_err(0), count_p_dec_ok(0), count_p_fec_recovered(0),
|
||||
count_p_lost(0), count_p_bad(0), count_p_override(0)
|
||||
{
|
||||
sockfd = open_udp_socket_for_tx(client_addr, client_port);
|
||||
fec_p = fec_new(fec_k, fec_n);
|
||||
@ -423,7 +415,7 @@ void Aggregator::log_rssi(const sockaddr_in *sockaddr, uint8_t wlan_idx, const u
|
||||
|
||||
void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, const uint8_t *antenna, const int8_t *rssi, sockaddr_in *sockaddr)
|
||||
{
|
||||
uint8_t new_session_key[sizeof(session_key)];
|
||||
wsession_data_t new_session_data;
|
||||
count_p_all += 1;
|
||||
|
||||
if(size == 0) return;
|
||||
@ -447,16 +439,17 @@ void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_id
|
||||
break;
|
||||
|
||||
case WFB_PACKET_KEY:
|
||||
if(size != sizeof(wsession_key_t))
|
||||
if(size != sizeof(wsession_hdr_t) + sizeof(wsession_data_t) + crypto_box_MACBYTES)
|
||||
{
|
||||
fprintf(stderr, "invalid session key packet\n");
|
||||
count_p_bad += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(crypto_box_open_easy(new_session_key,
|
||||
((wsession_key_t*)buf)->session_key_data, sizeof(wsession_key_t::session_key_data),
|
||||
((wsession_key_t*)buf)->session_key_nonce,
|
||||
if(crypto_box_open_easy((uint8_t*)&new_session_data,
|
||||
buf + sizeof(wsession_hdr_t),
|
||||
sizeof(wsession_data_t) + crypto_box_MACBYTES,
|
||||
((wsession_hdr_t*)buf)->session_nonce,
|
||||
tx_publickey, rx_secretkey) != 0)
|
||||
{
|
||||
fprintf(stderr, "unable to decrypt session key\n");
|
||||
@ -464,12 +457,20 @@ void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_id
|
||||
return;
|
||||
}
|
||||
|
||||
count_p_dec_ok += 1;
|
||||
if (be64toh(new_session_data.epoch) < epoch || be32toh(new_session_data.channel_id) != channel_id)
|
||||
{
|
||||
fprintf(stderr, "session channel_id or epoch doesn't match\n");
|
||||
count_p_dec_err += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp(session_key, new_session_key, sizeof(session_key)) != 0)
|
||||
count_p_dec_ok += 1;
|
||||
epoch = be64toh(new_session_data.epoch);
|
||||
|
||||
if (memcmp(session_key, new_session_data.session_key, sizeof(session_key)) != 0)
|
||||
{
|
||||
fprintf(stderr, "New session detected\n");
|
||||
memcpy(session_key, new_session_key, sizeof(session_key));
|
||||
memcpy(session_key, new_session_data.session_key, sizeof(session_key));
|
||||
|
||||
rx_ring_front = 0;
|
||||
rx_ring_alloc = 0;
|
||||
@ -500,9 +501,9 @@ void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_id
|
||||
buf + sizeof(wblock_hdr_t), size - sizeof(wblock_hdr_t),
|
||||
buf,
|
||||
sizeof(wblock_hdr_t),
|
||||
(uint8_t*)(&(block_hdr->nonce)), session_key) != 0)
|
||||
(uint8_t*)(&(block_hdr->data_nonce)), session_key) != 0)
|
||||
{
|
||||
fprintf(stderr, "unable to decrypt packet #0x%" PRIx64 "\n", be64toh(block_hdr->nonce));
|
||||
fprintf(stderr, "unable to decrypt packet #0x%" PRIx64 "\n", be64toh(block_hdr->data_nonce));
|
||||
count_p_dec_err += 1;
|
||||
return;
|
||||
}
|
||||
@ -512,8 +513,8 @@ void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_id
|
||||
|
||||
assert(decrypted_len <= MAX_FEC_PAYLOAD);
|
||||
|
||||
uint64_t block_idx = be64toh(block_hdr->nonce) >> 8;
|
||||
uint8_t fragment_idx = (uint8_t)(be64toh(block_hdr->nonce) & 0xff);
|
||||
uint64_t block_idx = be64toh(block_hdr->data_nonce) >> 8;
|
||||
uint8_t fragment_idx = (uint8_t)(be64toh(block_hdr->data_nonce) & 0xff);
|
||||
|
||||
// Should never happend due to generating new session key on tx side
|
||||
if (block_idx > MAX_BLOCK_IDX)
|
||||
@ -682,7 +683,7 @@ void Aggregator::apply_fec(int ring_idx)
|
||||
fec_decode(fec_p, (const uint8_t**)in_blocks, out_blocks, index, MAX_FEC_PAYLOAD);
|
||||
}
|
||||
|
||||
void radio_loop(int argc, char* const *argv, int optind, int radio_port, shared_ptr<BaseAggregator> agg, int log_interval)
|
||||
void radio_loop(int argc, char* const *argv, int optind, uint32_t channel_id, shared_ptr<BaseAggregator> agg, int log_interval)
|
||||
{
|
||||
int nfds = min(argc - optind, MAX_RX_INTERFACES);
|
||||
uint64_t log_send_ts = 0;
|
||||
@ -693,7 +694,7 @@ void radio_loop(int argc, char* const *argv, int optind, int radio_port, shared_
|
||||
|
||||
for(int i = 0; i < nfds; i++)
|
||||
{
|
||||
rx[i] = new Receiver(argv[optind + i], i, radio_port, agg.get());
|
||||
rx[i] = new Receiver(argv[optind + i], i, channel_id, agg.get());
|
||||
fds[i].fd = rx[i]->getfd();
|
||||
fds[i].events = POLLIN;
|
||||
}
|
||||
@ -817,7 +818,9 @@ void network_loop(int srv_port, Aggregator &agg, int log_interval)
|
||||
int main(int argc, char* const *argv)
|
||||
{
|
||||
int opt;
|
||||
uint8_t k = 8, n = 12, radio_port = 1;
|
||||
uint8_t k = 8, n = 12, radio_port = 0;
|
||||
uint32_t link_id = 0;
|
||||
uint64_t epoch = 0;
|
||||
int log_interval = 1000;
|
||||
int client_port = 5600;
|
||||
int srv_port = 0;
|
||||
@ -825,7 +828,7 @@ int main(int argc, char* const *argv)
|
||||
rx_mode_t rx_mode = LOCAL;
|
||||
string keypair = "rx.key";
|
||||
|
||||
while ((opt = getopt(argc, argv, "K:fa:k:n:c:u:p:l:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "K:fa:k:n:c:u:p:l:i:e:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'K':
|
||||
keypair = optarg;
|
||||
@ -855,36 +858,64 @@ int main(int argc, char* const *argv)
|
||||
case 'l':
|
||||
log_interval = atoi(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
link_id = ((uint32_t)atoi(optarg)) & 0xffffff;
|
||||
break;
|
||||
case 'e':
|
||||
epoch = atoll(optarg);
|
||||
break;
|
||||
default: /* '?' */
|
||||
show_usage:
|
||||
fprintf(stderr, "Local receiver: %s [-K rx_key] [-k RS_K] [-n RS_N] [-c client_addr] [-u client_port] [-p radio_port] [-l log_interval] interface1 [interface2] ...\n", argv[0]);
|
||||
fprintf(stderr, "Remote (forwarder): %s -f [-c client_addr] [-u client_port] [-p radio_port] interface1 [interface2] ...\n", argv[0]);
|
||||
fprintf(stderr, "Remote (aggregator): %s -a server_port [-K rx_key] [-k RS_K] [-n RS_N] [-c client_addr] [-u client_port] [-l log_interval]\n", argv[0]);
|
||||
fprintf(stderr, "Default: K='%s', k=%d, n=%d, connect=%s:%d, radio_port=%d, log_interval=%d\n", keypair.c_str(), k, n, client_addr.c_str(), client_port, radio_port, log_interval);
|
||||
fprintf(stderr, "Local receiver: %s [-K rx_key] [-k RS_K] [-n RS_N] [-c client_addr] [-u client_port] [-p radio_port] [-l log_interval] [-e epoch] [-i link_id] interface1 [interface2] ...\n", argv[0]);
|
||||
fprintf(stderr, "Remote (forwarder): %s -f [-c client_addr] [-u client_port] [-p radio_port] [-i link_id] interface1 [interface2] ...\n", argv[0]);
|
||||
fprintf(stderr, "Remote (aggregator): %s -a server_port [-K rx_key] [-k RS_K] [-n RS_N] [-c client_addr] [-u client_port] [-l log_interval] [-p radio_port] [-e epoch] [-i link_id]\n", argv[0]);
|
||||
fprintf(stderr, "Default: K='%s', k=%d, n=%d, connect=%s:%d, link_id=0x%06x, radio_port=%u, epoch=%lu, log_interval=%d\n", keypair.c_str(), k, n, client_addr.c_str(), client_port, link_id, radio_port, epoch, log_interval);
|
||||
fprintf(stderr, "WFB-ng version " WFB_VERSION "\n");
|
||||
fprintf(stderr, "WFB-ng home page: <http://wfb-ng.org>\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int fd;
|
||||
int c;
|
||||
|
||||
if ((fd = open("/dev/random", O_RDONLY)) != -1) {
|
||||
if (ioctl(fd, RNDGETENTCNT, &c) == 0 && c < 160) {
|
||||
fprintf(stderr, "This system doesn't provide enough entropy to quickly generate high-quality random numbers.\n"
|
||||
"Installing the rng-utils/rng-tools, jitterentropy or haveged packages may help.\n"
|
||||
"On virtualized Linux environments, also consider using virtio-rng.\n"
|
||||
"The service will not start until enough entropy has been collected.\n");
|
||||
}
|
||||
(void) close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (sodium_init() < 0)
|
||||
{
|
||||
fprintf(stderr, "libsodium init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
uint32_t channel_id = (link_id << 8) + radio_port;
|
||||
if (rx_mode == LOCAL || rx_mode == FORWARDER)
|
||||
{
|
||||
if (optind >= argc) goto show_usage;
|
||||
|
||||
shared_ptr<BaseAggregator> agg;
|
||||
if(rx_mode == LOCAL){
|
||||
agg = shared_ptr<Aggregator>(new Aggregator(client_addr, client_port, k, n, keypair));
|
||||
agg = shared_ptr<Aggregator>(new Aggregator(client_addr, client_port, k, n, keypair, epoch, channel_id));
|
||||
}else{
|
||||
agg = shared_ptr<Forwarder>(new Forwarder(client_addr, client_port));
|
||||
}
|
||||
|
||||
radio_loop(argc, argv, optind, radio_port, agg, log_interval);
|
||||
radio_loop(argc, argv, optind, channel_id, agg, log_interval);
|
||||
}else if(rx_mode == AGGREGATOR)
|
||||
{
|
||||
if (optind > argc) goto show_usage;
|
||||
Aggregator agg(client_addr, client_port, k, n, keypair);
|
||||
Aggregator agg(client_addr, client_port, k, n, keypair, epoch, channel_id);
|
||||
|
||||
network_loop(srv_port, agg, log_interval);
|
||||
}else{
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (C) 2017, 2018 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
// Copyright (C) 2017 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -118,7 +118,7 @@ typedef std::unordered_map<uint64_t, antennaItem> antenna_stat_t;
|
||||
class Aggregator : public BaseAggregator
|
||||
{
|
||||
public:
|
||||
Aggregator(const std::string &client_addr, int client_port, int k, int n, const std::string &keypair);
|
||||
Aggregator(const std::string &client_addr, int client_port, int k, int n, const std::string &keypair, uint64_t epoch, uint32_t channel_id);
|
||||
~Aggregator();
|
||||
virtual void process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, const uint8_t *antenna, const int8_t *rssi, sockaddr_in *sockaddr);
|
||||
virtual void dump_stats(FILE *fp);
|
||||
@ -137,6 +137,8 @@ private:
|
||||
int rx_ring_front; // current packet
|
||||
int rx_ring_alloc; // number of allocated entries
|
||||
uint64_t last_known_block; //id of last known block
|
||||
uint64_t epoch; // current epoch
|
||||
const uint32_t channel_id; // (link_id << 8) + port_number
|
||||
|
||||
// rx->tx keypair
|
||||
uint8_t rx_secretkey[crypto_box_SECRETKEYBYTES];
|
||||
@ -156,7 +158,7 @@ private:
|
||||
class Receiver
|
||||
{
|
||||
public:
|
||||
Receiver(const char* wlan, int wlan_idx, int port, BaseAggregator* agg);
|
||||
Receiver(const char* wlan, int wlan_idx, uint32_t channel_id, BaseAggregator* agg);
|
||||
~Receiver();
|
||||
void loop_iter(void);
|
||||
int getfd(void){ return fd; }
|
||||
|
113
src/tx.cpp
113
src/tx.cpp
@ -1,6 +1,6 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (C) 2017 - 2020 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
// Copyright (C) 2017 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -27,6 +27,8 @@
|
||||
#include <sys/resource.h>
|
||||
#include <pcap/pcap.h>
|
||||
#include <assert.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
@ -42,9 +44,12 @@ extern "C"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Transmitter::Transmitter(int k, int n, const string &keypair): fec_k(k), fec_n(n), block_idx(0),
|
||||
fragment_idx(0),
|
||||
max_packet_size(0)
|
||||
Transmitter::Transmitter(int k, int n, const string &keypair, uint64_t epoch, uint32_t channel_id) : \
|
||||
fec_k(k), fec_n(n), block_idx(0),
|
||||
fragment_idx(0),
|
||||
max_packet_size(0),
|
||||
epoch(epoch),
|
||||
channel_id(channel_id)
|
||||
{
|
||||
fec_p = fec_new(fec_k, fec_n);
|
||||
|
||||
@ -88,21 +93,35 @@ Transmitter::~Transmitter()
|
||||
|
||||
void Transmitter::make_session_key(void)
|
||||
{
|
||||
// init session key
|
||||
randombytes_buf(session_key, sizeof(session_key));
|
||||
session_key_packet.packet_type = WFB_PACKET_KEY;
|
||||
randombytes_buf(session_key_packet.session_key_nonce, sizeof(session_key_packet.session_key_nonce));
|
||||
if (crypto_box_easy(session_key_packet.session_key_data, session_key, sizeof(session_key),
|
||||
session_key_packet.session_key_nonce, rx_publickey, tx_secretkey) != 0)
|
||||
|
||||
// fill packet header
|
||||
wsession_hdr_t *session_hdr = (wsession_hdr_t *)session_key_packet;
|
||||
session_hdr->packet_type = WFB_PACKET_KEY;
|
||||
|
||||
randombytes_buf(session_hdr->session_nonce, sizeof(session_hdr->session_nonce));
|
||||
|
||||
// fill packet contents
|
||||
wsession_data_t session_data = { .epoch = htobe64(epoch),
|
||||
.channel_id = htobe32(channel_id) };
|
||||
|
||||
memcpy(session_data.session_key, session_key, sizeof(session_key));
|
||||
|
||||
if (crypto_box_easy(session_key_packet + sizeof(wsession_hdr_t),
|
||||
(uint8_t*)&session_data, sizeof(session_data),
|
||||
session_hdr->session_nonce, rx_publickey, tx_secretkey) != 0)
|
||||
{
|
||||
throw runtime_error("Unable to make session key!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PcapTransmitter::PcapTransmitter(int k, int n, const string &keypair, uint8_t radio_port, const vector<string> &wlans) : Transmitter(k, n, keypair),
|
||||
radio_port(radio_port),
|
||||
current_output(0),
|
||||
ieee80211_seq(0)
|
||||
PcapTransmitter::PcapTransmitter(int k, int n, const string &keypair, uint64_t epoch, uint32_t channel_id, const vector<string> &wlans) : \
|
||||
Transmitter(k, n, keypair, epoch, channel_id),
|
||||
channel_id(channel_id),
|
||||
current_output(0),
|
||||
ieee80211_seq(0)
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
for(auto it=wlans.begin(); it!=wlans.end(); it++)
|
||||
@ -138,8 +157,13 @@ void PcapTransmitter::inject_packet(const uint8_t *buf, size_t size)
|
||||
|
||||
// ieee80211 header
|
||||
memcpy(p, ieee80211_header, sizeof(ieee80211_header));
|
||||
p[SRC_MAC_LASTBYTE] = radio_port;
|
||||
p[DST_MAC_LASTBYTE] = radio_port;
|
||||
|
||||
// channel_id
|
||||
uint32_t channel_id_be = htobe32(channel_id);
|
||||
memcpy(p + SRC_MAC_THIRD_BYTE, &channel_id_be, sizeof(uint32_t));
|
||||
memcpy(p + DST_MAC_THIRD_BYTE, &channel_id_be, sizeof(uint32_t));
|
||||
|
||||
// sequence number
|
||||
p[FRAME_SEQ_LB] = ieee80211_seq & 0xff;
|
||||
p[FRAME_SEQ_HB] = (ieee80211_seq >> 8) & 0xff;
|
||||
ieee80211_seq += 16;
|
||||
@ -172,13 +196,16 @@ void Transmitter::send_block_fragment(size_t packet_size)
|
||||
assert(packet_size <= MAX_FEC_PAYLOAD);
|
||||
|
||||
block_hdr->packet_type = WFB_PACKET_DATA;
|
||||
block_hdr->nonce = htobe64(((block_idx & BLOCK_IDX_MASK) << 8) + fragment_idx);
|
||||
block_hdr->data_nonce = htobe64(((block_idx & BLOCK_IDX_MASK) << 8) + fragment_idx);
|
||||
|
||||
// encrypted payload
|
||||
crypto_aead_chacha20poly1305_encrypt(ciphertext + sizeof(wblock_hdr_t), &ciphertext_len,
|
||||
block[fragment_idx], packet_size,
|
||||
(uint8_t*)block_hdr, sizeof(wblock_hdr_t),
|
||||
NULL, (uint8_t*)(&(block_hdr->nonce)), session_key);
|
||||
if (crypto_aead_chacha20poly1305_encrypt(ciphertext + sizeof(wblock_hdr_t), &ciphertext_len,
|
||||
block[fragment_idx], packet_size,
|
||||
(uint8_t*)block_hdr, sizeof(wblock_hdr_t),
|
||||
NULL, (uint8_t*)(&(block_hdr->data_nonce)), session_key) < 0)
|
||||
{
|
||||
throw runtime_error("Unable to encrypt packet!");
|
||||
}
|
||||
|
||||
inject_packet(ciphertext, sizeof(wblock_hdr_t) + ciphertext_len);
|
||||
}
|
||||
@ -186,7 +213,7 @@ void Transmitter::send_block_fragment(size_t packet_size)
|
||||
void Transmitter::send_session_key(void)
|
||||
{
|
||||
//fprintf(stderr, "Announce session key\n");
|
||||
inject_packet((uint8_t*)&session_key_packet, sizeof(session_key_packet));
|
||||
inject_packet((uint8_t*)session_key_packet, sizeof(session_key_packet));
|
||||
}
|
||||
|
||||
void Transmitter::send_packet(const uint8_t *buf, size_t size, uint8_t flags)
|
||||
@ -303,7 +330,9 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int poll_timeou
|
||||
int main(int argc, char * const *argv)
|
||||
{
|
||||
int opt;
|
||||
uint8_t k=8, n=12, radio_port=1;
|
||||
uint8_t k=8, n=12, radio_port=0;
|
||||
uint32_t link_id = 0x0;
|
||||
uint64_t epoch = 0;
|
||||
int udp_port=5600;
|
||||
|
||||
int bandwidth = 20;
|
||||
@ -316,7 +345,7 @@ int main(int argc, char * const *argv)
|
||||
|
||||
string keypair = "tx.key";
|
||||
|
||||
while ((opt = getopt(argc, argv, "K:k:n:u:r:p:B:G:S:L:M:D:T:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "K:k:n:u:r:p:B:G:S:L:M:D:T:i:e:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'K':
|
||||
keypair = optarg;
|
||||
@ -354,12 +383,18 @@ int main(int argc, char * const *argv)
|
||||
case 'T':
|
||||
poll_timeout = atoi(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
link_id = ((uint32_t)atoi(optarg)) & 0xffffff;
|
||||
break;
|
||||
case 'e':
|
||||
epoch = atoll(optarg);
|
||||
break;
|
||||
default: /* '?' */
|
||||
show_usage:
|
||||
fprintf(stderr, "Usage: %s [-K tx_key] [-k RS_K] [-n RS_N] [-u udp_port] [-p radio_port] [-B bandwidth] [-G guard_interval] [-S stbc] [-L ldpc] [-M mcs_index] [ -T poll_timeout ] interface1 [interface2] ...\n",
|
||||
fprintf(stderr, "Usage: %s [-K tx_key] [-k RS_K] [-n RS_N] [-u udp_port] [-p radio_port] [-B bandwidth] [-G guard_interval] [-S stbc] [-L ldpc] [-M mcs_index] [-T poll_timeout] [-e epoch] [-i link_id] interface1 [interface2] ...\n",
|
||||
argv[0]);
|
||||
fprintf(stderr, "Default: K='%s', k=%d, n=%d, udp_port=%d, radio_port=%d bandwidth=%d guard_interval=%s stbc=%d ldpc=%d mcs_index=%d, poll_timeout=%d\n",
|
||||
keypair.c_str(), k, n, udp_port, radio_port, bandwidth, short_gi ? "short" : "long", stbc, ldpc, mcs_index, poll_timeout);
|
||||
fprintf(stderr, "Default: K='%s', k=%d, n=%d, udp_port=%d, link_id=0x%06x, radio_port=%u, epoch=%lu, bandwidth=%d guard_interval=%s stbc=%d ldpc=%d mcs_index=%d, poll_timeout=%d\n",
|
||||
keypair.c_str(), k, n, udp_port, link_id, radio_port, epoch, bandwidth, short_gi ? "short" : "long", stbc, ldpc, mcs_index, poll_timeout);
|
||||
fprintf(stderr, "Radio MTU: %lu\n", (unsigned long)MAX_PAYLOAD_SIZE);
|
||||
fprintf(stderr, "WFB-ng version " WFB_VERSION "\n");
|
||||
fprintf(stderr, "WFB-ng home page: <http://wfb-ng.org>\n");
|
||||
@ -416,6 +451,28 @@ int main(int argc, char * const *argv)
|
||||
radiotap_header[MCS_FLAGS_OFF] = flags;
|
||||
radiotap_header[MCS_IDX_OFF] = mcs_index;
|
||||
}
|
||||
|
||||
{
|
||||
int fd;
|
||||
int c;
|
||||
|
||||
if ((fd = open("/dev/random", O_RDONLY)) != -1) {
|
||||
if (ioctl(fd, RNDGETENTCNT, &c) == 0 && c < 160) {
|
||||
fprintf(stderr, "This system doesn't provide enough entropy to quickly generate high-quality random numbers.\n"
|
||||
"Installing the rng-utils/rng-tools, jitterentropy or haveged packages may help.\n"
|
||||
"On virtualized Linux environments, also consider using virtio-rng.\n"
|
||||
"The service will not start until enough entropy has been collected.\n");
|
||||
}
|
||||
(void) close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (sodium_init() < 0)
|
||||
{
|
||||
fprintf(stderr, "libsodium init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
vector<int> rx_fd;
|
||||
@ -430,12 +487,14 @@ int main(int argc, char * const *argv)
|
||||
|
||||
shared_ptr<Transmitter> t;
|
||||
|
||||
uint32_t channel_id = (link_id << 8) + radio_port;
|
||||
|
||||
if(debug_port)
|
||||
{
|
||||
fprintf(stderr, "Using %lu ports from %d for wlan emulation\n", wlans.size(), debug_port);
|
||||
t = shared_ptr<UdpTransmitter>(new UdpTransmitter(k, n, keypair, "127.0.0.1", debug_port));
|
||||
t = shared_ptr<UdpTransmitter>(new UdpTransmitter(k, n, keypair, "127.0.0.1", debug_port, epoch, channel_id));
|
||||
} else {
|
||||
t = shared_ptr<PcapTransmitter>(new PcapTransmitter(k, n, keypair, radio_port, wlans));
|
||||
t = shared_ptr<PcapTransmitter>(new PcapTransmitter(k, n, keypair, epoch, channel_id, wlans));
|
||||
}
|
||||
|
||||
data_source(t, rx_fd, poll_timeout);
|
||||
|
19
src/tx.hpp
19
src/tx.hpp
@ -1,6 +1,6 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (C) 2017, 2018 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
// Copyright (C) 2017 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -32,7 +32,7 @@
|
||||
class Transmitter
|
||||
{
|
||||
public:
|
||||
Transmitter(int k, int m, const std::string &keypair);
|
||||
Transmitter(int k, int m, const std::string &keypair, uint64_t epoch, uint32_t channel_id);
|
||||
virtual ~Transmitter();
|
||||
void send_packet(const uint8_t *buf, size_t size, uint8_t flags);
|
||||
void send_session_key(void);
|
||||
@ -47,28 +47,30 @@ private:
|
||||
fec_t* fec_p;
|
||||
int fec_k; // RS number of primary fragments in block
|
||||
int fec_n; // RS total number of fragments in block
|
||||
uint64_t block_idx; //block_idx << 8 + fragment_idx = nonce (64bit)
|
||||
uint64_t block_idx; // (block_idx << 8) + fragment_idx = nonce (64bit)
|
||||
uint8_t fragment_idx;
|
||||
uint8_t** block;
|
||||
size_t max_packet_size;
|
||||
const uint64_t epoch; // Packets from old epoch will be discarded
|
||||
const uint32_t channel_id; // (link_id << 8) + port_number
|
||||
|
||||
// tx->rx keypair
|
||||
uint8_t tx_secretkey[crypto_box_SECRETKEYBYTES];
|
||||
uint8_t rx_publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t session_key[crypto_aead_chacha20poly1305_KEYBYTES];
|
||||
wsession_key_t session_key_packet;
|
||||
uint8_t session_key_packet[sizeof(wsession_hdr_t) + sizeof(wsession_data_t) + crypto_box_MACBYTES];
|
||||
};
|
||||
|
||||
|
||||
class PcapTransmitter : public Transmitter
|
||||
{
|
||||
public:
|
||||
PcapTransmitter(int k, int m, const std::string &keypair, uint8_t radio_port, const std::vector<std::string> &wlans);
|
||||
PcapTransmitter(int k, int m, const std::string &keypair, uint64_t epoch, uint32_t channel_id, const std::vector<std::string> &wlans);
|
||||
virtual ~PcapTransmitter();
|
||||
virtual void select_output(int idx) { current_output = idx; }
|
||||
private:
|
||||
virtual void inject_packet(const uint8_t *buf, size_t size);
|
||||
uint8_t radio_port;
|
||||
const uint32_t channel_id;
|
||||
int current_output;
|
||||
uint16_t ieee80211_seq;
|
||||
std::vector<pcap_t*> ppcap;
|
||||
@ -78,8 +80,9 @@ private:
|
||||
class UdpTransmitter : public Transmitter
|
||||
{
|
||||
public:
|
||||
UdpTransmitter(int k, int m, const std::string &keypair, const std::string &client_addr, int base_port) : Transmitter(k, m, keypair),\
|
||||
base_port(base_port)
|
||||
UdpTransmitter(int k, int m, const std::string &keypair, const std::string &client_addr, int base_port, uint64_t epoch, uint32_t channel_id): \
|
||||
Transmitter(k, m, keypair, epoch, channel_id), \
|
||||
base_port(base_port)
|
||||
{
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd < 0) throw std::runtime_error(string_format("Error opening socket: %s", strerror(errno)));
|
||||
|
@ -1,5 +1,20 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (C) 2017 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
/*
|
||||
* 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; version 3.
|
||||
*
|
||||
* 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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2017, 2018, 2019 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
// Copyright (C) 2017 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -67,9 +67,6 @@ extern std::string string_format(const char *format, ...);
|
||||
|
||||
#define MCS_KNOWN (IEEE80211_RADIOTAP_MCS_HAVE_MCS | IEEE80211_RADIOTAP_MCS_HAVE_BW | IEEE80211_RADIOTAP_MCS_HAVE_GI | IEEE80211_RADIOTAP_MCS_HAVE_STBC | IEEE80211_RADIOTAP_MCS_HAVE_FEC)
|
||||
|
||||
// Default is MCS#1 -- QPSK 1/2 40MHz SGI -- 30 Mbit/s
|
||||
// MCS_FLAGS = (IEEE80211_RADIOTAP_MCS_BW_40 | IEEE80211_RADIOTAP_MCS_SGI | (IEEE80211_RADIOTAP_MCS_STBC_1 << IEEE80211_RADIOTAP_MCS_STBC_SHIFT))
|
||||
|
||||
static uint8_t radiotap_header[] __attribute__((unused)) = {
|
||||
0x00, 0x00, // <-- radiotap version
|
||||
0x0d, 0x00, // <- radiotap header length
|
||||
@ -82,33 +79,42 @@ static uint8_t radiotap_header[] __attribute__((unused)) = {
|
||||
#define MCS_FLAGS_OFF 11
|
||||
#define MCS_IDX_OFF 12
|
||||
|
||||
//the last byte of the mac address is recycled as a port number
|
||||
#define SRC_MAC_LASTBYTE 15
|
||||
#define DST_MAC_LASTBYTE 21
|
||||
//the last four bytes used for channel_id
|
||||
#define SRC_MAC_THIRD_BYTE 12
|
||||
#define DST_MAC_THIRD_BYTE 18
|
||||
#define FRAME_SEQ_LB 22
|
||||
#define FRAME_SEQ_HB 23
|
||||
|
||||
// WFB-NG MAC address format: "W:B:X:X:X:X" where XXXX is channel_id
|
||||
// channel_id = (link_id << 8) + radio_port
|
||||
// First address byte 'W'(0x57) has two lower bits set that means that address is multicast and locally administred
|
||||
// See https://en.wikipedia.org/wiki/MAC_address for reference
|
||||
|
||||
static uint8_t ieee80211_header[] __attribute__((unused)) = {
|
||||
0x08, 0x01, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
|
||||
0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
|
||||
0x00, 0x00, // seq num << 4 + fragment num
|
||||
0x08, 0x01, 0x00, 0x00, // data frame, not protected, from STA to DS via an AP
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // receiver is broadcast
|
||||
0x57, 0x42, 0xaa, 0xbb, 0xcc, 0xdd, // last four bytes will be replaced by channel_id
|
||||
0x57, 0x42, 0xaa, 0xbb, 0xcc, 0xdd, // last four bytes will be replaced by channel_id
|
||||
0x00, 0x00, // (seq_num << 4) + fragment_num
|
||||
};
|
||||
|
||||
/*
|
||||
Wifibroadcast protocol:
|
||||
|
||||
radiotap_header
|
||||
ieee_80211_header
|
||||
wblock_hdr_t { packet_type, nonce = (block_idx << 8 + fragment_idx) }
|
||||
wpacket_hdr_t { flags, packet_size } #
|
||||
data #
|
||||
+-- encrypted
|
||||
WFB-NG protocol:
|
||||
|
||||
radiotap_header:
|
||||
ieee_80211_header:
|
||||
1. Data packet:
|
||||
wblock_hdr_t { packet_type = 1, nonce = (block_idx << 8) + fragment_idx }
|
||||
wpacket_hdr_t { flags, packet_size } #
|
||||
data #
|
||||
+-- encrypted and authenticated by session key
|
||||
2. Session packet:
|
||||
wsession_hdr_t { packet_type = 2, nonce = random() }
|
||||
wsession_data_t { epoch, channel_id, session_key } # -- encrypted and signed using rx and tx keys
|
||||
*/
|
||||
|
||||
// nonce: 56bit block_idx + 8bit fragment_idx
|
||||
// data nonce: 56bit block_idx + 8bit fragment_idx
|
||||
// session nonce: crypto_box_NONCEBYTES of random bytes
|
||||
|
||||
#define BLOCK_IDX_MASK ((1LLU << 56) - 1)
|
||||
#define MAX_BLOCK_IDX ((1LLU << 55) - 1)
|
||||
@ -137,15 +143,20 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8_t packet_type;
|
||||
uint8_t session_key_nonce[crypto_box_NONCEBYTES]; // random data
|
||||
uint8_t session_key_data[crypto_aead_chacha20poly1305_KEYBYTES + crypto_box_MACBYTES]; // encrypted session key
|
||||
} __attribute__ ((packed)) wsession_key_t;
|
||||
uint8_t session_nonce[crypto_box_NONCEBYTES]; // random data
|
||||
} __attribute__ ((packed)) wsession_hdr_t;
|
||||
|
||||
typedef struct{
|
||||
uint64_t epoch; // Drop session packets from old epoch
|
||||
uint32_t channel_id; // (link_id << 8) + port_number
|
||||
uint8_t session_key[crypto_aead_chacha20poly1305_KEYBYTES];
|
||||
} __attribute__ ((packed)) wsession_data_t;
|
||||
|
||||
// Data packet. Embed FEC-encoded data
|
||||
|
||||
typedef struct {
|
||||
uint8_t packet_type;
|
||||
uint64_t nonce; // big endian, nonce = block_idx << 8 + fragment_idx
|
||||
uint64_t data_nonce; // big endian, data_nonce = (block_idx << 8) + fragment_idx
|
||||
} __attribute__ ((packed)) wblock_hdr_t;
|
||||
|
||||
// Plain data packet after FEC decode
|
||||
|
@ -1,14 +1,31 @@
|
||||
### Stream allocation scheme:
|
||||
## Down streams (vehicle to GS): 0 - 127
|
||||
## Up streams (GS to vehicle): 128 - 255
|
||||
## Stream ranges:
|
||||
## 0 - 15: video streams, 0 is default video stream
|
||||
## 16 - 31: mavlink streams, 16 is default mavlink stream
|
||||
## 32 - 47: tunnel streams, 32 is default tunnel stream
|
||||
## All other ranges reserved for future use
|
||||
##
|
||||
|
||||
[path]
|
||||
conf_dir = '/etc'
|
||||
bin_dir = '/usr/bin'
|
||||
tmp_dir = '/tmp'
|
||||
|
||||
log_dir = '/var/log'
|
||||
|
||||
[common]
|
||||
debug = False
|
||||
version = '0.0.1.trunk'
|
||||
commit = None
|
||||
|
||||
log_file = None # Set to "wifibroadcast.log" to disable log to stdout
|
||||
link_id = "default" # It will be hashed and mapped to three bytes of MAC
|
||||
# You can use different link ids for multi-vehicle setup without stream remapping.
|
||||
# For that case need to have several instances of wifibroadcast.cfg on GS - one for each link (GS <-> droneX)
|
||||
# Redefine peer addresses, tunnel interfaces and tunnel addresses to not overlap
|
||||
# Copy and rename wifibroadcast@.gs service and set path to custom wfb config.
|
||||
|
||||
set_nm_unmanaged = True # Set radio interface in 'unmanaged state' in NetworkManager
|
||||
radio_mtu = 1445 # MAX_PAYLOAD_SIZE, don't change if doubt
|
||||
mavlink_agg_timeout = 0.1 # aggragate mavlink packets if less than radio_mtu but no longer than 100ms
|
||||
@ -17,13 +34,13 @@ tx_sel_delta = 3 # hysteresis for antenna selection, [dB]
|
||||
wifi_channel = 165 # radio channel @5825 MHz, range: 5815-5835 MHz, width 20MHz
|
||||
wifi_region = 'BO' # Set CRDA region
|
||||
wifi_txpower = None # Some cards don't support tx power settings
|
||||
#wifi_txpower = 58 # for 8812au
|
||||
#wifi_txpower = 58 # Doesn't affect 8812au drivers, use module parameter instead
|
||||
|
||||
[gs_mavlink]
|
||||
keypair = 'gs.key' # keypair generated by wfb-keygen
|
||||
stats_port = 8001 # used by wfb-cli
|
||||
stream_tx = 1 # radio port for mavlink tx
|
||||
stream_rx = 2 # radio port for mavlink rx
|
||||
stream_tx = 0x90 # radio port for mavlink tx
|
||||
stream_rx = 0x10 # radio port for mavlink rx
|
||||
fec_k = 1 # FEC K
|
||||
fec_n = 2 # FEC N
|
||||
fec_timeout = 0 # [ms], 0 to disable. If no new packets during timeout, emit one empty packet if FEC block is open
|
||||
@ -56,7 +73,7 @@ call_on_disarm = None # call program on disarm
|
||||
[gs_video]
|
||||
keypair = 'gs.key' # keypair generated by wfb-keygen
|
||||
stats_port = 8002 # used by wfb-cli
|
||||
stream = 3 # radio port for video stream
|
||||
stream = 0x0 # radio port for video stream
|
||||
fec_k = 8 # FEC K
|
||||
fec_n = 12 # FEC N
|
||||
peer = 'connect://127.0.0.1:5600' # outgoing connection for video sink (GS)
|
||||
@ -68,8 +85,8 @@ bandwidth = 20 # bandwidth 20 or 40 MHz
|
||||
[drone_mavlink]
|
||||
keypair = 'drone.key'
|
||||
stats_port = None
|
||||
stream_tx = 2
|
||||
stream_rx = 1
|
||||
stream_tx = 0x10
|
||||
stream_rx = 0x90
|
||||
port_rx = 14700
|
||||
port_tx = 14701
|
||||
fec_k = 1 # FEC K
|
||||
@ -100,7 +117,7 @@ call_on_disarm = None # call program on disarm
|
||||
[drone_video]
|
||||
keypair = 'drone.key'
|
||||
stats_port = None
|
||||
stream = 3
|
||||
stream = 0x0
|
||||
fec_k = 8 # FEC K
|
||||
fec_n = 12 # FEC N
|
||||
fec_timeout = 0 # [ms], 0 to disable. If no new packets during timeout, emit one empty packet if FEC block is open
|
||||
@ -120,8 +137,8 @@ mcs_index = 1 # mcs index
|
||||
[gs_tunnel]
|
||||
keypair = 'gs.key' # keypair generated by wfb-keygen
|
||||
stats_port = 8003 # used by wfb-cli
|
||||
stream_tx = 4 # radio port for tunnel tx
|
||||
stream_rx = 5 # radio port for tunnel rx
|
||||
stream_tx = 0x20 # radio port for tunnel tx
|
||||
stream_rx = 0xa0 # radio port for tunnel rx
|
||||
port_rx = 14800 # udp port for internal use
|
||||
port_tx = 14801 # udp port range (from port_tx to port_tx + number of wlans) for internal use
|
||||
fec_k = 1 # FEC K
|
||||
@ -144,8 +161,8 @@ mcs_index = 1 # mcs index
|
||||
[drone_tunnel]
|
||||
keypair = 'drone.key'
|
||||
stats_port = None
|
||||
stream_tx = 5
|
||||
stream_rx = 4
|
||||
stream_tx = 0xa0
|
||||
stream_rx = 0x20
|
||||
port_rx = 14900
|
||||
port_tx = 14901
|
||||
fec_k = 1 # FEC K
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2018, 2019 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
# Copyright (C) 2018 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
@ -1,6 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2018-2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
#
|
||||
# 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; version 3.
|
||||
#
|
||||
# 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, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import sys
|
||||
import time
|
||||
import struct
|
||||
@ -88,7 +105,7 @@ class PacketSink(DatagramProtocol):
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def run_test(port_in, port_out, size, count, rate):
|
||||
key = int(os.urandom(2).encode('hex'), 16)
|
||||
key = int.from_bytes(os.urandom(2), 'big')
|
||||
log.msg('Session: %d' % (key,))
|
||||
p1 = PacketSource(('127.0.0.1', port_in), size, count, rate, key)
|
||||
p2 = PacketSink(key)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2018, 2019 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
# Copyright (C) 2018 - 2022 Vasily Evseenko <svpcom@p2ptech.org>
|
||||
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
@ -23,9 +23,11 @@ import time
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import hashlib
|
||||
|
||||
from itertools import groupby
|
||||
from twisted.python import log, failure
|
||||
from twisted.python.logfile import LogFile
|
||||
from twisted.internet import reactor, defer, main as ti_main
|
||||
from twisted.internet.protocol import ProcessProtocol, DatagramProtocol, Protocol, Factory
|
||||
from twisted.protocols.basic import LineReceiver
|
||||
@ -287,26 +289,27 @@ def init_wlans(profile, wlans):
|
||||
|
||||
def init(profile, wlans):
|
||||
def _init_services(_):
|
||||
return defer.gatherResults([defer.maybeDeferred(init_mavlink, profile, wlans),
|
||||
defer.maybeDeferred(init_video, profile, wlans),
|
||||
defer.maybeDeferred(init_tunnel, profile, wlans)])\
|
||||
link_id = int.from_bytes(hashlib.sha1(settings.common.link_id.encode('utf-8')).digest()[:3], 'big')
|
||||
return defer.gatherResults([defer.maybeDeferred(init_mavlink, profile, wlans, link_id),
|
||||
defer.maybeDeferred(init_video, profile, wlans, link_id),
|
||||
defer.maybeDeferred(init_tunnel, profile, wlans, link_id)])\
|
||||
.addErrback(lambda f: f.trap(defer.FirstError) and f.value.subFailure)
|
||||
|
||||
return defer.maybeDeferred(init_wlans, profile, wlans).addCallback(_init_services)
|
||||
|
||||
|
||||
def init_mavlink(profile, wlans):
|
||||
def init_mavlink(profile, wlans, link_id):
|
||||
cfg = getattr(settings, '%s_mavlink' % (profile,))
|
||||
|
||||
cmd_rx = ('%s -p %d -u %d -K %s -k %d -n %d' % \
|
||||
cmd_rx = ('%s -p %d -u %d -K %s -k %d -n %d -i %d' % \
|
||||
(os.path.join(settings.path.bin_dir, 'wfb_rx'), cfg.stream_rx,
|
||||
cfg.port_rx, os.path.join(settings.path.conf_dir, cfg.keypair), cfg.fec_k, cfg.fec_n)).split() + wlans
|
||||
cfg.port_rx, os.path.join(settings.path.conf_dir, cfg.keypair), cfg.fec_k, cfg.fec_n, link_id)).split() + wlans
|
||||
|
||||
cmd_tx = ('%s -p %d -u %d -K %s -B %d -G %s -S %d -L %d -M %d -k %d -n %d -T %d' % \
|
||||
cmd_tx = ('%s -p %d -u %d -K %s -B %d -G %s -S %d -L %d -M %d -k %d -n %d -T %d -i %d' % \
|
||||
(os.path.join(settings.path.bin_dir, 'wfb_tx'),
|
||||
cfg.stream_tx, cfg.port_tx, os.path.join(settings.path.conf_dir, cfg.keypair),
|
||||
cfg.bandwidth, "short" if cfg.short_gi else "long", cfg.stbc, cfg.ldpc, cfg.mcs_index,
|
||||
cfg.fec_k, cfg.fec_n, cfg.fec_timeout)).split() + wlans
|
||||
cfg.fec_k, cfg.fec_n, cfg.fec_timeout, link_id)).split() + wlans
|
||||
|
||||
listen = None
|
||||
connect = None
|
||||
@ -397,7 +400,7 @@ def init_mavlink(profile, wlans):
|
||||
return defer.gatherResults(dl, consumeErrors=True).addBoth(_cleanup)\
|
||||
.addErrback(lambda f: f.trap(defer.FirstError) and f.value.subFailure)
|
||||
|
||||
def init_video(profile, wlans):
|
||||
def init_video(profile, wlans, link_id):
|
||||
cfg = getattr(settings, '%s_video' % (profile,))
|
||||
|
||||
if listen_re.match(cfg.peer):
|
||||
@ -406,11 +409,11 @@ def init_video(profile, wlans):
|
||||
log.msg('Listen for video stream %d on %s:%d' % (cfg.stream, listen[0], listen[1]))
|
||||
|
||||
# We don't use TX diversity for video streaming due to only one transmitter on the vehichle
|
||||
cmd = ('%s -p %d -u %d -K %s -B %d -G %s -S %d -L %d -M %d -k %d -n %d -T %d %s' % \
|
||||
cmd = ('%s -p %d -u %d -K %s -B %d -G %s -S %d -L %d -M %d -k %d -n %d -T %d -i %d %s' % \
|
||||
(os.path.join(settings.path.bin_dir, 'wfb_tx'), cfg.stream,
|
||||
listen[1], os.path.join(settings.path.conf_dir, cfg.keypair),
|
||||
cfg.bandwidth, "short" if cfg.short_gi else "long", cfg.stbc, cfg.ldpc, cfg.mcs_index,
|
||||
cfg.fec_k, cfg.fec_n, cfg.fec_timeout, wlans[0])).split()
|
||||
cfg.fec_k, cfg.fec_n, cfg.fec_timeout, link_id, wlans[0])).split()
|
||||
|
||||
df = TXProtocol(cmd, 'video tx').start()
|
||||
elif connect_re.match(cfg.peer):
|
||||
@ -422,11 +425,11 @@ def init_video(profile, wlans):
|
||||
if cfg.stats_port:
|
||||
reactor.listenTCP(cfg.stats_port, ant_f)
|
||||
|
||||
cmd = ('%s -p %d -c %s -u %d -K %s -k %d -n %d' % \
|
||||
cmd = ('%s -p %d -c %s -u %d -K %s -k %d -n %d -i %d' % \
|
||||
(os.path.join(settings.path.bin_dir, 'wfb_rx'),
|
||||
cfg.stream, connect[0], connect[1],
|
||||
os.path.join(settings.path.conf_dir, cfg.keypair),
|
||||
cfg.fec_k, cfg.fec_n)).split() + wlans
|
||||
cfg.fec_k, cfg.fec_n, link_id)).split() + wlans
|
||||
|
||||
df = RXProtocol(ant_f, cmd, 'video rx').start()
|
||||
else:
|
||||
@ -435,18 +438,18 @@ def init_video(profile, wlans):
|
||||
log.msg('Video: %s' % (' '.join(cmd),))
|
||||
return df
|
||||
|
||||
def init_tunnel(profile, wlans):
|
||||
def init_tunnel(profile, wlans, link_id):
|
||||
cfg = getattr(settings, '%s_tunnel' % (profile,))
|
||||
|
||||
cmd_rx = ('%s -p %d -u %d -K %s -k %d -n %d' % \
|
||||
cmd_rx = ('%s -p %d -u %d -K %s -k %d -n %d -i %d' % \
|
||||
(os.path.join(settings.path.bin_dir, 'wfb_rx'), cfg.stream_rx,
|
||||
cfg.port_rx, os.path.join(settings.path.conf_dir, cfg.keypair), cfg.fec_k, cfg.fec_n)).split() + wlans
|
||||
cfg.port_rx, os.path.join(settings.path.conf_dir, cfg.keypair), cfg.fec_k, cfg.fec_n, link_id)).split() + wlans
|
||||
|
||||
cmd_tx = ('%s -p %d -u %d -K %s -B %d -G %s -S %d -L %d -M %d -k %d -n %d -T %d' % \
|
||||
cmd_tx = ('%s -p %d -u %d -K %s -B %d -G %s -S %d -L %d -M %d -k %d -n %d -T %d -i %d' % \
|
||||
(os.path.join(settings.path.bin_dir, 'wfb_tx'),
|
||||
cfg.stream_tx, cfg.port_tx, os.path.join(settings.path.conf_dir, cfg.keypair),
|
||||
cfg.bandwidth, "short" if cfg.short_gi else "long", cfg.stbc, cfg.ldpc, cfg.mcs_index,
|
||||
cfg.fec_k, cfg.fec_n, cfg.fec_timeout)).split() + wlans
|
||||
cfg.fec_k, cfg.fec_n, cfg.fec_timeout, link_id)).split() + wlans
|
||||
|
||||
p_in = TUNTAPProtocol()
|
||||
p_tx_l = [UDPProxyProtocol(('127.0.0.1', cfg.port_tx + i)) for i, _ in enumerate(wlans)]
|
||||
@ -478,7 +481,13 @@ def init_tunnel(profile, wlans):
|
||||
.addErrback(lambda f: f.trap(defer.FirstError) and f.value.subFailure)
|
||||
|
||||
def main():
|
||||
log.startLogging(sys.stdout)
|
||||
if settings.common.log_file:
|
||||
log.startLogging(LogFile(settings.common.log_file,
|
||||
settings.path.log_dir,
|
||||
rotateLength=1024*1024,
|
||||
maxRotatedFiles=10))
|
||||
else:
|
||||
log.startLogging(sys.stdout)
|
||||
|
||||
log.msg('WFB version %s-%s' % (settings.common.version, settings.common.commit[:8]))
|
||||
profile, wlans = sys.argv[1], list(wlan for arg in sys.argv[2:] for wlan in arg.split())
|
||||
|
@ -37,8 +37,12 @@ class TXRXTestCase(unittest.TestCase):
|
||||
self.rx_ep = reactor.listenUDP(10002, self.rxp)
|
||||
self.tx_ep = reactor.listenUDP(10004, self.txp)
|
||||
|
||||
cmd_rx = [os.path.join(bindir, 'wfb_rx'), '-K', 'drone.key', '-a', '10001', '-u', '10002', 'wlan0']
|
||||
cmd_tx = [os.path.join(bindir, 'wfb_tx'), '-K', 'gs.key', '-u', '10003', '-D', '10004', '-T', '30', 'wlan0']
|
||||
link_id = int.from_bytes(os.urandom(3), 'big')
|
||||
epoch = int(time.time())
|
||||
cmd_rx = [os.path.join(bindir, 'wfb_rx'), '-K', 'drone.key', '-a', '10001', '-u', '10002',
|
||||
'-i', str(link_id), '-e', str(epoch), 'wlan0']
|
||||
cmd_tx = [os.path.join(bindir, 'wfb_tx'), '-K', 'gs.key', '-u', '10003', '-D', '10004', '-T', '30',
|
||||
'-i', str(link_id), '-e', str(epoch), 'wlan0']
|
||||
|
||||
self.rx_pp = RXProtocol(None, cmd_rx, 'debug rx')
|
||||
self.tx_pp = TXProtocol(cmd_tx, 'debug tx')
|
||||
|
Loading…
Reference in New Issue
Block a user