From fae4154598787cd6457264fe31b0639acf2ff0a7 Mon Sep 17 00:00:00 2001 From: lukasfriedrichsen <lukas.friedrichsen@hs-bochum.de> Date: Tue, 17 Jan 2017 23:08:45 +0100 Subject: [PATCH] commented source code (gui view still pending) --- Praktikum/VINF_MaerklinControl/bin/.gitignore | 1 + .../bin/server/ClientThread.class | Bin 2480 -> 2480 bytes .../bin/server/Engine.class | Bin 2509 -> 2413 bytes .../bin/server/HandleThread.class | Bin 2624 -> 2624 bytes .../bin/server/MaerklinProtocol.class | Bin 2646 -> 2646 bytes .../bin/server/MaerklinServer.class | Bin 4104 -> 4104 bytes .../server/MaerklinServerApplication.class | Bin 1040 -> 1040 bytes .../bin/server/ServerThread.class | Bin 2326 -> 2326 bytes .../bin/server/Switch.class | Bin 1915 -> 1819 bytes .../bin/server/UDPListener.class | Bin 4135 -> 4135 bytes .../bin/server/UpdateThread.class | Bin 2242 -> 2242 bytes .../src/common/Properties.java | 2 +- .../src/gui/model/Engine.java | 4 +- .../src/gui/model/Settings.java | 2 +- .../src/gui/model/Switch.java | 2 +- .../src/server/Engine.java | 20 ++- .../src/server/MaerklinProtocol.java | 15 ++ .../src/server/MaerklinServer.java | 146 ++++++++++++------ .../src/server/MaerklinServerApplication.java | 7 + .../src/server/Switch.java | 16 +- .../src/server/UDPListener.java | 31 +++- 21 files changed, 183 insertions(+), 63 deletions(-) diff --git a/Praktikum/VINF_MaerklinControl/bin/.gitignore b/Praktikum/VINF_MaerklinControl/bin/.gitignore index d0380dd..51adac1 100644 --- a/Praktikum/VINF_MaerklinControl/bin/.gitignore +++ b/Praktikum/VINF_MaerklinControl/bin/.gitignore @@ -1,2 +1,3 @@ /gui/ /server/ +/common/ diff --git a/Praktikum/VINF_MaerklinControl/bin/server/ClientThread.class b/Praktikum/VINF_MaerklinControl/bin/server/ClientThread.class index 87ad4494d5fb304483eaa093de83bbcc1a5259c5..b520937cae4530d4037535e6c1406d83e64c6f56 100644 GIT binary patch delta 196 zcmdlWyg_(E@WeSf6N5b`o+x4FWZ;@?&*;m`&A`LSz{nua!@$nKv3VxrK32(33@i+v z88{ifFo-gIWsqX{#-PUVok5r3$K(QbNp21XMg|53JqBY2uFX@}6ByGN85p=285x8a znHVG(nHkg>Ss3&fSsDBp*%$&CIT*qjIT>OYxfoIyxf!w;c^E1gc^MiQ`4|>5@-r-A z6k=G%$jPvcQIz2lqd3D=MoEU-jM5DE7-bmlGs-bMXOw67#;Cw3&Zsy!iZcuVRD~qw delta 196 zcmdlWyg_(E@Wgu0iNQJ(Pn0mTGjL3{XY}ReWZ>dtU}TWzVc=%q**ueRAFJeL1{Q`Z z44e#C8AKVbF-S37XHa9f!Jx}<b8-Q@BsUKOBLf429)mFh$L1;Q35;nB4;Z)@9x@0q zJYtYwc+8;A@Pt8+;VFYZ!!w2eh8GOs3@;gC7+x`?FuZ2SVtB()$?%q;f#Ds)LWcJY zix@sJtYdh|u#Mp>!zG6A3|AR`GTdhP&2W$555s+izYNbA{xN)G_|GWL$S^sIGYkNs CE;*F| diff --git a/Praktikum/VINF_MaerklinControl/bin/server/Engine.class b/Praktikum/VINF_MaerklinControl/bin/server/Engine.class index ddeb21d94820b3679bf8989d78b055a8e2a0c416..728dcfbfb291af49ba5d7f284c6d95d080eaaec2 100644 GIT binary patch literal 2413 zcmX^0Z`VEs1_l#`EOrJaMh4#E)S|M~B7N7q^vt|eb_Nzk27#=^vPAuy#JqHU|D>$c z<Pt^(_EfNRF(ZSh4_LOeBr`|fv8X7q(kHXH#F~+TGdMFnFR`SwD3y^x4VxMp9~7Ic z?W`FYI3UJ)x-c>@dNMNbL%1%PMXAXpnfZB)4BQZr;DXfD6h;Q_(v*ULqWqHl<op~) z21%HKzKN+t**TecFez(B1~!|_yv!0iMh0dL%`ip=7U%qwR4xWa24Nlseg+Xn1~v^( zPfw5xzfWdfs$XetQfg61Vp2{jBZH7nesW??SYlBohz}KHDaptzW@O-pSqTX(Yc2+6 z1}Tt{0-Owt3^F_ntPE`I404PN!dL={i$Rt_ik(4`kwF|966g-+Vo+d^0-2=3!@$eH z2hyO%!=TQf!N|azn3BTCAgTcgS){nJ){FvqOpAv>n?Z+>fx9@h1mZYQpt5LqYKDQN z^>`TcLDE8SX?P%mqz!o(j6l+SaA|Oeb26APn6WdMq9lpn%HopLTpk8<1`9?8=KRtU zc$&z}*AFPl%qs~lDN0SuwdP{5Vz6Onu!e;O*wL;P$*BdPxaDE6Ww2vp;7U&|@l7o* zPE1c_WDwENMDky7Nl|8Ax-}Pr1A`MggCoosR9ko$oEcmg8Q2Rz7U$%l1rgK;P((9j zrZ6&arXZ3QYcV8IF{Z*jfa*ePMh4#ClEma}-^2oNG62Pl4-W$;0~aF$YhG$OD1^D- z9x4V&2k<a(GjMS*1Tiv*_~k2<fzyxz+*U<Un1p~5j0-5P!+03N86p@NM3XZT^U_lx z@dl3=Mg~?5NFo)=OD#u}1X&i%!@vWwES8Z$3}G4ATMA`~Ii;zJAWPzT7!p912qIeo zj$TFvKDfb90pZNN<f7EXVyIhSqA96ZM7h(ElNz&zrY9qV5L^t&8+>p<sCit$`K3k4 zscxB|{KgIOnI0&|FeoxGGB7hRFt9RkfbtRpBLh1F0|OHS2Llr*+!;WCn}G{Nf&31Z z<7MDuU|;|xV}1q!21W)!1_lN*1{MZJ1_lNWEoK(x?F>R2!74?;>X;Z97$h0k8B`g> z7#J9MAnF*z86+4O7#Kmt1JsP?49pCy3=9nJTH6^UH!(;bXW-q<ARD=zL4GrXwAOA0 zg~;s;N?RF}H!(<SZDUXk*OK1Gps6LZjX_sSb{m7ias~k_mQ4)Ck}TU8EVnV(Z)9L( zP-ie>uw<}eU}gY0#fX82fq_ATfrUYnfr~+lL4-kvL7qXEK^>G=84MT<84MZB7>pP! z8H^dM8B7@57|g&<Hi0+`>SP86cLrCm_dzT-1}+AW2i+Om89=3zH3K(;2ZJXA3xgK} z1A_<y^M3{r1{QV(Mn*<P28I-N1}jhiXfx<QJ#ELp1lG@{CB2ow8$H;p7+4vs!EO+P zsDitJjlmb}21c;knHc;S7{F0r1&)qm49wtY^_FIt&%hzgx`2TjWWN7$1|4a(1q{+! zTNwOVK!U7W8T^+sh-<NcY5v^|R*^!1+Zlp=b@pp*VNllE!r%>3yNw|f<TOYynlbP) zFfiCNfC>tJ21f=V1}6q_24@C&1{Veu23H1k26qM>22Tck25$yS1|J4%20sQb27j<O z6d=xmd&8R{66_621}1Q@F@b}Poq?5$U4)&Rfe}<pGNAjeAL=`OX+h=}iy8Q(XG6Rf zwVVOsgBT1SL~Ub;L-;@roXSHOxEVqj1Q@~?gc%|jWEmnE<QbwF^cZ50T&fRusXjv@ z*rl>4E@fe05(YUli9rCvnZ69n;IuBS6}g2WO28;#D?=1gpu(KQ1WucL;DAYB;ATi< zkYY#zI{}nZ7#O6XPGDq6Cc=^w!j_~la5JPcNHJt!wIqch6`C~l85qItX9cB#HSi40 l1{Tag(##5XVH#G={^*(uv1(4osyPZ>a~W368DRHi0s!U-y*vN_ literal 2509 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 diff --git a/Praktikum/VINF_MaerklinControl/bin/server/HandleThread.class b/Praktikum/VINF_MaerklinControl/bin/server/HandleThread.class index b716bf9e72a489e3a5572a1845d5821058fad1b0..70ac4ae37d34ed43b35682bfaf3d7c4b19378421 100644 GIT binary patch delta 246 zcmX>gazJE5C@Zf80}G=i11F;u10SRH<|NkJO!bZoHjFL|&Wx@MZj2rbzKos>0gOHj z;f%fvQH=f!d5i%JeT+d2s~LkC)-n1sY-bE(*u@yZaE>vO;T>Z%!zacVhOdkf4F4G8 z85tQ98ATbB7)=>d7%dr78EqI78C@AO7(E!X7-JZ-8EY7G8QU217&{rW7$-3nGEQYI zW?UJ@Si*Rcv5fH?V>#nR#$v`>j8%+x8EY6nGS)H)GS)LmGd3{EG1f4tGd446F}5<< wF}5+qF?KK|F?KSgGPW}1G4?POGWIc5GEQKsVVuZR%Q%UtopH)$Ax=F;00F%>?f?J) delta 246 zcmX>gazJE5C@U{N0}G=711F;(10SQ%<|NkJO!eXnHjGjX&WzFwZj5pazKrq=0gOrv z;f%@*QH-h#d5mfdeT*6ms~I&J)-kFwY-iMA*u|*FaE?)*;T@wP!zV@~hOdlz4F4ES z85tSP8ATZ_7)=?i7%dsC8EqKN8C@Ce7(Eyr7-JY68EY7w8QU0L7&{pq7$-5hGfrjn zWLz1>=*4)F(TDLIqc7t{Mo-3Di~)>y8G{%<G6pjVGKMlqGlntAF$OWIGe$CLF-9}l wF~%^(F~%_^F~&2cGDb7yF(xq;GNv$9GNv)rFs3urGG;KfGiGfT;?!dV0Ebd8ZU6uP diff --git a/Praktikum/VINF_MaerklinControl/bin/server/MaerklinProtocol.class b/Praktikum/VINF_MaerklinControl/bin/server/MaerklinProtocol.class index 079482e9fb9cb8be301c625d735e2123fde8f0db..463513cf891565df613ad7889e2c109b8f12a0fa 100644 GIT binary patch delta 149 zcmca6a!q7|4lAoL0}F%bWJA`&ic$>x4AKmu3^EMT46+Pb3~~&H4Dt*)3<?Z+42lfJ z49b&5*&cJMGe|IKFeou-PG)3}=hS5oX3%4hWze6T$$m`Gm_dQTgu#))l%bNrjG=|W ze6j<_1wm^D9tIl*T?Si*Xa+lmGzR<0ik#O3of&u-To`m2Tp1D>+!%5g+$VEz`2heK CAQ-U# delta 149 zcmca6a!q7|4l64c0}BJsWJA`&iUJJ$41x@z3_=Xj48jar3?dAM45AD<3}Os<4B`yM z43d*Y*&cJsFi0@SGAJ>~O=e_|=Tu}6W>8{~Wl)}+$$m^wjX{AyoxzbogQ1c^lc9w{ zYqA5!1wmZ~9tJ%IT?T!IXa)m@GzP=Tik#O3O&E9>Oc`_;%oq|G%o%bREGBbs`2hg5 C{ueF) diff --git a/Praktikum/VINF_MaerklinControl/bin/server/MaerklinServer.class b/Praktikum/VINF_MaerklinControl/bin/server/MaerklinServer.class index afe7a4d2062fca83c9266f25ce3c80bae44dadef..5071b96bd11d0b906b01cf676c004fa20ab1c4ff 100644 GIT binary patch delta 338 zcmeBB=up`3n7iJVfrY_=frr6~L7c&bL5abYL6^ae!IHs)!I8m}!Gpnz!Jom0A&SA5 zA(g?8p@1QPp_(C(p^YJkVIo5?!yJYXhUE;Q44W9j81^!RGn`<EV7SZ>$#9P$is2<g zEW<~JIELR0@r<ktiH!UVNsN*V$&AVjDU7-dsf^|fX^f6~4C##C3>l1}44I7a3|Wks z4B3pu4Ec=Z3<ZqU426t!3`LCf48@F{3?+=c3}uri@H7fmF|adKGw?IiFo-kMGRQO3 zO;+OdWNl(#XK0>Wz<bECoq>a)gF%3yi$Q{+n?Zr0mqCM}kHLUp0)qv^L<R?jNemtg zlNkaSrZ7Y>Ol3%5n8uL7FrA@*VFp75!%T(-hFOz~`P^9NG4L_WpS+LHjdd{tAH$N# moc#5YD;Pu>RxxNXtY*+<Si_*lu$IA$VFiOd!-mNV`O^V!+e$tF delta 338 zcmeBB=up`3n7dw&frY`4frr7EL7c&qL5abPL6^at!IHs}!I8m=!Gpn?!JomFA&S9{ zA(g?Np@6}Wp_;*op^d?rVIqSI!yE=zhUE-y44W9-8TK-GFq~lUWVp=W#c+?oo8cvc zAHzome}>--0gS8+L5%zi!Hkj&A&kllp^Ul=VT|Ss;f#)Y3=xdp43UhX3{i~n4AG34 z3^9zw3<-?o42g`@3`vZ249Sf33@MDA45^I04C#|6@H7f$Gq5w{Fz_?vGKe$eF~~FI zPgdgfWG!Z3XDFFmz<bECf`Nmfl0kr>nn8l0hCzX$jzNQ=p22{jk->tYiNS%PnZbjh zg&}~Ul_7$mjUj=dogssvgQ0+-lc9p4i=ly`dvY<K8*4uUAH#&n`}o{gr!ep_Or6Zh lUoSb6L6l(*gBHVF23>}E40;Un8O#`FGT1XLn!J!d9ROQmMWO%z diff --git a/Praktikum/VINF_MaerklinControl/bin/server/MaerklinServerApplication.class b/Praktikum/VINF_MaerklinControl/bin/server/MaerklinServerApplication.class index 49cade3d83850e8a50e66f49229e30d5f0feb2be..7b3ecdb3eb9afda4fd94a8a74be2e6fda159bbc6 100644 GIT binary patch delta 63 zcmbQhF@a-)I5Q*XWC`Y4T|ovG1`!4x25|-f1}O#+1~~==26+Y*1_cHU21N#K1{DTF S22}<#1~mq22HDAnnEe0*Y6s8& delta 63 zcmbQhF@a-)I5Q*jWC`Y4U2X;z20jKJ20;b^1`!4k25|-j1_=fg21y1D1}O$@23ZC} S1~~>Z26+Z+2C>P9nEe3y;RkvE diff --git a/Praktikum/VINF_MaerklinControl/bin/server/ServerThread.class b/Praktikum/VINF_MaerklinControl/bin/server/ServerThread.class index 6be948c4b99495eecf0e236214e7c41563a5bc3a..4dba35bb006f200f8fe7a09c3e86644e8bc787a9 100644 GIT binary patch delta 104 zcmbOxG)-s&2Rr8h1{Q{c44e#yHVd+QGWs58;Ac3&Ai{8xL5ATpgA&6T21kao3<(UU z7*ZI{Gqf;VU}$By$k5AhiD4qcHHLW%*BMqb++f(vaD`zn!!?Fe4A&X1Gu&W!!f=z} LIm4~V%Q^A^3qc`| delta 104 zcmbOxG)-s&2Rr9l1{Q{O44e$>Hw&_RGWu?2;AhyvAi}VfL55*FgA&6I21kaS3<(U| z7*ZH^Gqf=5VQ6L8%h1cPk6|LiL56t@hZt5f9A?<faDZVi!$F2q42Kx5GaP1k!f=G) LIm6M(%Q^A^vf>}U diff --git a/Praktikum/VINF_MaerklinControl/bin/server/Switch.class b/Praktikum/VINF_MaerklinControl/bin/server/Switch.class index 7c0cfac672cecd1bf8ff2626284e237c0984424a..708496fe39adc0112d3d470eeddb417a11ed5c14 100644 GIT binary patch delta 1125 zcmey(H=B>^)W2Q(7#J8#7$PTfos(m;$;`_vv14Rl*3b-NWMFa5Pf6usU}O;DVc=sB zo-D!WV<HJ+@^dmUGD!0<urjc*GsrSB2xldhCF+-!Waj8Q78NB{`eYWDa52a*NU}31 zFfxcw+$S!{#URfh3DTy_!@$G93zAjkVNhdGpZuOtDN2)vL5o3~k%7B7wIsMavm`mg z(}j_NMZ;4w3}nA94}%^^S_m%fl3A3RT#}ie$H`#8V8qT~$jBf7c0^8MUb=p8WpPPr zE)Rn-gURG<CIvP#1`Bou^T`vLB$zE3tR}BvQd6{Huw!Sig*iPlUq7HIGp{7Lq$o8p zmxsZg!C~@eresF<$>Gc@oZdVP+zebC48D_Fm=%P~82mwD-~jSbAP++jgYe{S%vFpm zlMPuk>)9C?8Tc6Z85kJ^7#J8#8JHOu85kJYwU}A9GYD>EU|?Wk5Mf|o;9_86U|<ku zU}I2X5M^Ls;DIP(5MvN$U;rB-3^n2+12Y2)0|SGD)^-MoO$<`U8F+Uy$V6^uklV~4 zrL~(uK5{#Q;#LNwO$<_6+ZgIq!nLHgF=%MXY-7+_&cNrli9ug?8-wXK2J4Lsj11}w zh72YQW(>?=N9ZwdGcYiyGO#eHF>o=cGl(!~GRQM%F{m@>Fz7JoG8i)GF_<vuGng_M zFxWE~fgP#^aSYU<3=9qojtrm}0<oMJxat|07)%+s7@Qeg7?>Gc85kIZ8JPbwh%hj- zGcYnTGBCumGnj$YYcXg;J!r?k1P%-~E$OWcZs<W|#=y#84z^hgq6%&^8-oYfW=2rb zU|?eKWME)msb^qhFarmD9|JQ3GXn#It~ASh26pLL4BQ~|y_PfZ?`ANI6!O{5;ODEe zUuz44lGYXmH?1uUUfUP~K(<4|Mvj4<fq}uAfs?_8fsetKL6E_oL7KsVL6*UZL5IN^ z>>>q-1#lPXG6dIyog~e`1P%cva0sw6FmtkVGcYm)G4R9O33p~B0~0vvML{kAIg$k& zaU5FA+Zc2Z&Jkl^Wnf@%XJBXWVBlf!WZ-A;W)NZU1v>+hc0|F>sAm9M$-=<I&%(gS z5W)}&4P|`>MzB4sAm6Tmr$aWdU?7q?tYC9MX)p|{W-oNjVaS>V;JU-Xc0>RGSJIGv delta 1209 zcmbQu_nVLF)W2Q(7#J8#7!oFOopa#G$t*5O%}Xs}WDxNwPAw`+Ez%El3Gji6S~D`R z*<|Krme?^eFl%UrF*2|?=clA{F)%WS@GuB4h)(?GV<HV=334(pGRX2Uurjc*GsrVC z2xldhCF+-!Waj8Q78NB{f=uLMkYkW$XHa5f5TCeD+<}WhkwF@yO_hg%hk=)!L7kC7 z2-6K*3~CT%T09JV4E!KNba)ta8T2MEV^m@@;9)RiFq(XhQIgGshryJ=X!2V|@py9v zOLhheMg{?}D{>O^()EKYi%U{-c^Ir1tQi@Y^Giz@8AN@+(wX`C0Y#a4CBY>{sfoGP zTnx4h_UsIHFh78GyH+Hp7L;V>=kYK&FgQ+5W>RBwW^iR^aGBiCB*E;);68a3Q!=C9 zWIkpU&LAEJZU!z6hLFkD%nCxb3}K+~aR>P}f`=iJL3DC1a}^`&<QL4E^-LfiF)%Q& zGcYm;FbFa*G6*p+FqkqhGcbZgwU}A9GYD^FU|?Wk5My9q;9_86U|<knU}KPG5NBXu z;DIP(kYJExU;rB-3N_*Z12Y2)0|SG%)^-M|O$;)}8F+Uy$VF~vP}s~MqqUnsF>*VD z^459=6|LP2YLVL+G`2EmZeozp+Qy(At|h&VL0?N|8-ww320p({3}(997;LsNIBjHL zWH4f|VX$YgWnc!o$B2Q4fq_AmfrUYifr~+&L4-k(L7qX0L5o3|!H7YX!JI*j!G=Md z!Ja{b!GS@O!HYo~>~1ZH+ZgI04rgHSX7FGDB`Ofh6YNa~1}+9K25$yt1|J3n24M!~ z{|q7w%<K$|jEoEnS?mn9AmxS(Mo|CSF))F{hD}R)D}yh3i0Lt~GU$VC7K5mQhFCoV z0~>=s*k(osQwAdjCWZh81_l-eMh07OO!P4@GcYqSFz8CN%x7Sip2ffoGCy!R1OILY z+eo3{?F^y5I{US@FsNv4Ver-3!VtKPAsl2oBz)u;*cliYj2Ji>j2ZYCOc(?i%owB@ z%o$`EEE#kdtQhJ+k*EN%0qP_M23>|Iu#2P_n7|>x1P%dK24+rnZU#n%NCrU+XGStG zfm4Dg$ORxrvVbFxLyLJEgE7K6VhpSd3=Fmm><o4cJPh^>{Phfu3?dB9;E;i&B~hp| zK!MJ}z{C#<ifD!yXejG5FoNx21^IRjJXx}V1>KO0VTBsQ$PkNFb09>sIw(;?bbDdd J9S61}9spCnr~?21 diff --git a/Praktikum/VINF_MaerklinControl/bin/server/UDPListener.class b/Praktikum/VINF_MaerklinControl/bin/server/UDPListener.class index c116d862c6b31c41dc3fd90997f8b57dca65c1d7..b27ad59957a3ed2598c055c57492d9e9bc53263d 100644 GIT binary patch delta 311 zcmZ3kuv}q-KL@7-0}F#B0}q4L<Oq&!igFD64Dt*j3<?Zt42ldo3`z{949X0N3@Qvs z45|!i4C<5hIr|y4C-3JBW;B@mo=bGH2A3YA+2n98XGZJEv$=v99VWl$a$|IzY{u=* z>BYdq;LX6t;5WIAd$ndL0}DeK0|!Gm10O>KgBU|3gB(K?g9bx1Lli>{Lo7oqLmWdK zLlQ&6<S3qg-V_E7hBO8qhI9rIhSbg9c;++K=QHp#6flS|6fvkV6f@{BlrWewlrq>b zlrgw6lrzLIR4`;PR5BDYR5O$?lrz*Z)G;(N)H8H3G%ze=Xk=K+(8REfp_yS1Lo366 zh6aX{3>^$-7&;lQGITM#Vd!S~!O+9V$k4~g!qCOY$56;9#4v@?h+!(DF~c-QbA}lV K;+sYIg&6_6F+pbl delta 311 zcmZ3kuv}q-KL@8E0}F!?0}q4n<Oq&!iee1>4B`wT3=#}#43Z2w3{niH4AKmV3^EK! z46+Pq4DyrpIr|xvChzAAW>lN}o=bGH2A3YA*5q(5XGXorv$=v9jV8b6a$_``Y{u=* zX~n?9V9mhCU^lsqd$pzu0}F#I0|$c}10RDsgBXJcgB*h=g9d{aLllEILo9<2LmY!I zLlT4k<S3qg-XI1Jh7blGhEN6(hTzTLc;++K$1w0S#4?C5#51TdBrxbOBr=#XBr(`9 zBr~`&q%g!Vq%veMq%jmSWH6L4q%hPmWHU4}<S=wG<T5N|$YWT`kk7D<p@3lzLlMJ% zhFpe|45bWb7|Ix~GL$pCVW?pE!BEM_$WYD5!cfl0#}LOT#L&oS#L&cO%+Sne&d|yr KzFCA{m=OS+u01XQ diff --git a/Praktikum/VINF_MaerklinControl/bin/server/UpdateThread.class b/Praktikum/VINF_MaerklinControl/bin/server/UpdateThread.class index baf588be8710d5a1c39e4f5038ce009fd276d972..e6127497fd4f6c236051e375017e66a9e54e2711 100644 GIT binary patch delta 193 zcmX>kct~)A4J+>o1{TKE44jPX7=#$tZ}w#6VyfT5z{I$XftPVRg9PIa1|7zo3`UH* z7;G7LGdM8rWe8*3$B@CepP`QN0K){vgA5B94>7D^+`+Jw@d(2K#-j|U8ILhsV?56A zitz-)2gZ{OzZp+4{9`=BD8hJ_QH}8&qXFZ2Mk~e(jNXhF8N(QlGsZJsX3S!|!dS|9 zm9c^G8e_K-<8{V9#v6?Nj5ir)GTvgG%Xp7*4dZ>r^^6Y~H!wbA+`;&G@)!1V0A(pX A!~g&Q delta 193 zcmX>kct~)A4J&UM0}Ep%11Dn*gAilwW=~cwrurrZCdL*9UdC1i3C1=C9maMBBgPH} zTgFZX2gYuOFvcE+48~rDI>tVR35@*=3mGRctYK_p*vdGG;Q-@ghSQ8w7_Ko+Wq8Fn zjo}01bcWxIGZ_9c&SDf{oXx1lIET@IaW113<2*)h#`%n4j8hro85c5UF)m^(Wn9eI yz_^65TZwTgV;|!(#(u`-j58TmFwSLM!?=cVE#rE|b&MMr*E8;5+&K9Q`#AtAIyCwK diff --git a/Praktikum/VINF_MaerklinControl/src/common/Properties.java b/Praktikum/VINF_MaerklinControl/src/common/Properties.java index 3b4f180..f4fc6cb 100644 --- a/Praktikum/VINF_MaerklinControl/src/common/Properties.java +++ b/Praktikum/VINF_MaerklinControl/src/common/Properties.java @@ -3,7 +3,7 @@ package common; /* * In dieser Klasse werden alle klassenübergreifen verwendeten Werte einmalig deklariert, * so dass potentielle Änderungen lediglich einmalig an dieser Stelle durchgeführt werden - * müssen und Code-Vervielfachung vermieden wird. + * müssen und Code-Vervielfachung vermieden wird (Einhaltung des DRY-Prinzips). */ public class Properties { diff --git a/Praktikum/VINF_MaerklinControl/src/gui/model/Engine.java b/Praktikum/VINF_MaerklinControl/src/gui/model/Engine.java index bb1b390..49d87f6 100644 --- a/Praktikum/VINF_MaerklinControl/src/gui/model/Engine.java +++ b/Praktikum/VINF_MaerklinControl/src/gui/model/Engine.java @@ -12,7 +12,7 @@ import javafx.beans.property.StringProperty; import javafx.scene.image.Image; /* - * Model class for a Model Engine + * Modell-Klasse für einen Zug. */ public class Engine { @@ -54,7 +54,7 @@ public class Engine { return name; } - // Returns the maerklin-id + // Returns the Maerklin-ID public IntegerProperty getMaerklinID() { return id; } diff --git a/Praktikum/VINF_MaerklinControl/src/gui/model/Settings.java b/Praktikum/VINF_MaerklinControl/src/gui/model/Settings.java index f96f16b..fba05f5 100644 --- a/Praktikum/VINF_MaerklinControl/src/gui/model/Settings.java +++ b/Praktikum/VINF_MaerklinControl/src/gui/model/Settings.java @@ -7,7 +7,7 @@ import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; /* - * Model class for a Model Engine + * Modell-Klasse für die Einstellungen der App. */ public class Settings { private final ObjectProperty<InetSocketAddress> server; diff --git a/Praktikum/VINF_MaerklinControl/src/gui/model/Switch.java b/Praktikum/VINF_MaerklinControl/src/gui/model/Switch.java index 7f0b53f..7f76416 100644 --- a/Praktikum/VINF_MaerklinControl/src/gui/model/Switch.java +++ b/Praktikum/VINF_MaerklinControl/src/gui/model/Switch.java @@ -11,7 +11,7 @@ import javafx.beans.property.StringProperty; import javafx.beans.property.ObjectProperty; /* - * Model class for a Model Train Switch + * Modell-Klasse für eine Weiche. */ public class Switch{ diff --git a/Praktikum/VINF_MaerklinControl/src/server/Engine.java b/Praktikum/VINF_MaerklinControl/src/server/Engine.java index be0e29c..33c4503 100644 --- a/Praktikum/VINF_MaerklinControl/src/server/Engine.java +++ b/Praktikum/VINF_MaerklinControl/src/server/Engine.java @@ -3,17 +3,24 @@ package server; import java.util.ArrayList; +/* + * Diese Klasse stellt das Modell für einen Zug auf Serverseite dar. + * Weiterhin lassen sich über eine lokale Instanz des Maerklin-Protokolls + * Befehle an die Maerklin-C2-Steuerung senden. + */ public class Engine { + // Static array containing all created instances of the object static ArrayList<Engine> engines; private int engineID; int engineDirection; int engineSpeed; + // Private locale instance of the maerklin-protocol to send commands to the control-station private MaerklinProtocol udpProtocol; - private UDPListener listener; + // Constructor public Engine(){ this(0, 1, 0); @@ -29,12 +36,12 @@ public class Engine { engineSpeed = 0;*/ } + // Constructor with some initial data public Engine(int id, int direction, int speed){ if (engines == null) { engines = new ArrayList<Engine>(); } udpProtocol = new MaerklinProtocol(); - listener = new UDPListener(); engines.add(this); try { setEngineID(id); @@ -46,10 +53,12 @@ public class Engine { } } + // Sets the Maerklin-ID public void setEngineID(int newID){ engineID = newID; } + // Sets the engine-direction and sends the respective command to the control-station; a 3 as the direction-parameter causes a switch of the direction public void setEngineDirection(int newEngineDirection) throws Exception { if (newEngineDirection == 1 || newEngineDirection == 2){ engineDirection = newEngineDirection; @@ -69,6 +78,8 @@ public class Engine { udpProtocol.changeEngineDirection(engineID, engineDirection); } + + // Sets the engine-speed and sends the respective command to the control-station public void setEngineSpeed(int newEngineSpeed) throws Exception { if (newEngineSpeed <= 1000 && newEngineSpeed >= 0){ engineSpeed = newEngineSpeed; @@ -80,24 +91,29 @@ public class Engine { udpProtocol.changeEngineSpeed(engineID, engineSpeed); } + // Increases the engine-speed by 50 and calls changeEngineSpeed with the new speed-value public void increaseEngineSpeed() throws Exception { engineSpeed = engineSpeed+50; udpProtocol.changeEngineSpeed(engineID, engineSpeed); } + // Decreases the engine-speed by 50 and calls changeEngineSpeed with the new speed-value public void decreaseEngineSpeed() throws Exception{ engineSpeed = engineSpeed-50; udpProtocol.changeEngineSpeed(engineID, engineSpeed); } + // Returns the Maerklin-ID public int getEngineID(){ return engineID; } + // Returns the engine-direction public int getEngineDirection(){ return engineDirection; } + // Returns the engine-speed public int getEngineSpeed(){ return engineSpeed; } diff --git a/Praktikum/VINF_MaerklinControl/src/server/MaerklinProtocol.java b/Praktikum/VINF_MaerklinControl/src/server/MaerklinProtocol.java index 30a9770..e44d6ba 100644 --- a/Praktikum/VINF_MaerklinControl/src/server/MaerklinProtocol.java +++ b/Praktikum/VINF_MaerklinControl/src/server/MaerklinProtocol.java @@ -2,15 +2,25 @@ package server; import java.net.*; +/* + * Diese Klasse implementiert das Maerklin-Protokoll zur Kommunikation + * mit der Maerklin-C2-Steuerung. Die Datagramme werden mittels UDP + * gesendet; für jedes Datagram wird ein neuer Sockel geöffnet. + */ public class MaerklinProtocol { + // Setting the input-port of the maerklin-control-station private final static int port = 15731; + + // IP of the maerklin-control-station private final static String ip ="192.168.74.118"; + // Constructor public MaerklinProtocol(){ //Nothing to do... } + // Tries to open a UDP-socket and send the datagram to the maerklin-control-station private void writeDatagram(String ip, int port, byte[] data){ //System.out.printf("\nGesendet: " + DatatypeConverter.printHexBinary(data)); try(DatagramSocket socket = new DatagramSocket()){ @@ -24,16 +34,19 @@ public class MaerklinProtocol { } } + // Resets the emergency-stop (re-enables power) public void systemGo(){ byte[] out = {(byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x78, (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00}; this.writeDatagram(ip, port, out); } + // Emergency-stop (cuts the power) public void systemStop(){ byte[] out = {(byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x78, (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}; this.writeDatagram(ip, port, out); } + // Set engine-speed of the given engine to the given value public void changeEngineSpeed(int mfxAddress, int newEngineSpeed){ byte[] engineSpeed = {(byte) Math.floor(newEngineSpeed/256), (byte) Math.floor(newEngineSpeed%256)}; byte[] address = {(byte) Math.floor(mfxAddress/256), (byte) Math.floor(mfxAddress%256)}; @@ -41,6 +54,7 @@ public class MaerklinProtocol { this.writeDatagram(ip, port, out); } + // Set engine-direction of the given engine to the given value public void changeEngineDirection(int mfxAddress, int newEngineDirection){ byte engineDirection = (byte) Math.floor(newEngineDirection%256); byte[] address = {(byte) Math.floor(mfxAddress/256), (byte) Math.floor(mfxAddress%256)}; @@ -48,6 +62,7 @@ public class MaerklinProtocol { this.writeDatagram(ip, port, out); } + // Set the switch-direction of the given switch to the given value or move the turntable clockwise or counterclockwise public void changeSwitchDirection(int mfxAddress, int newSwitchDirection){ byte switchDirection = (byte) Math.floor(newSwitchDirection%256); byte[] address = {(byte) Math.floor(mfxAddress/256), (byte) Math.floor(mfxAddress%256)}; diff --git a/Praktikum/VINF_MaerklinControl/src/server/MaerklinServer.java b/Praktikum/VINF_MaerklinControl/src/server/MaerklinServer.java index c2774bd..63c137d 100644 --- a/Praktikum/VINF_MaerklinControl/src/server/MaerklinServer.java +++ b/Praktikum/VINF_MaerklinControl/src/server/MaerklinServer.java @@ -14,19 +14,33 @@ import javax.xml.bind.DatatypeConverter; import common.Properties; +/* + * MaerklinServer stellt die Hauptklasse des Servers dar. Alle verwendeten + * Objekte und Services (bspw. Executer-Services) werden initialisiert und + * der Server-Thread wird gestartet. Weiterhin implementiert diese Klasse + * das Maerklin-Protokoll und dient damit für alle anderen abgeleiteten oder + * erzeugten Objekte als Referenz für die Kommunikation mit dem Server. + * Grundlegende Funktionen wie der Notaus werden direkt von dieser Klasse + * umgesetzt. + */ public class MaerklinServer{ // Declaration of objects + + // List to monitor the registered clients ArrayList<Socket> clients; + // Control-elements and thread to handle new clients private MaerklinProtocol protocol; private UDPListener overwatch; private ServerThread serverThread; + // Executor-services to handle the threads final ExecutorService SERVER_THREAD_EXECUTOR; final ExecutorService CLIENT_THREAD_EXECUTOR; final ExecutorService UTILITY_THREAD_EXECUTOR; + // Accessories private Engine ice; private Engine lok; private Engine reichsbahn; @@ -43,6 +57,7 @@ public class MaerklinServer{ private Switch switch15; private Switch turntable; + // Constructor public MaerklinServer(){ // Initializing @@ -54,9 +69,9 @@ public class MaerklinServer{ overwatch = new UDPListener(); serverThread = new ServerThread(this); - SERVER_THREAD_EXECUTOR = Executors.newFixedThreadPool(2); - CLIENT_THREAD_EXECUTOR = Executors.newCachedThreadPool(); - UTILITY_THREAD_EXECUTOR = Executors.newCachedThreadPool(); + SERVER_THREAD_EXECUTOR = Executors.newFixedThreadPool(2); // Server- and listener-thread + CLIENT_THREAD_EXECUTOR = Executors.newCachedThreadPool(); // Client-threads + UTILITY_THREAD_EXECUTOR = Executors.newCachedThreadPool(); // Handle- and update-threads ice = new Engine(); lok = new Engine(); @@ -102,7 +117,7 @@ public class MaerklinServer{ } } - // Emergency stop + // Emergency stop; sets the speed of all engines to 0 out of safety reasons public void emergencyStop() throws Exception { protocol.systemStop(); ice.setEngineSpeed(0); @@ -110,12 +125,12 @@ public class MaerklinServer{ reichsbahn.setEngineSpeed(0); } - // Emergency stop + // Resets emergency stop public void start() throws Exception { protocol.systemGo(); } - // Initialize; setting ("safe") values + // Initialize; setting ("safe") values (engine speed to 0 and switch direction to straight) public void initialize() throws Exception { ice.setEngineDirection(1); ice.setEngineSpeed(0); @@ -148,11 +163,10 @@ public class MaerklinServer{ SERVER_THREAD_EXECUTOR.submit(serverThread); } - // Starts the thread to broadcast the current status + // Starts a thread to broadcast the current status for every registered client public void statusUpdate(){ for (Socket clientSocket : clients) { try { - //System.out.println("Updating client: "+clientSocket.getRemoteSocketAddress()); UTILITY_THREAD_EXECUTOR.submit(new UpdateThread(clientSocket.getOutputStream())); } catch (IOException e) { @@ -163,10 +177,15 @@ public class MaerklinServer{ } -//Opens a server-port and establishes a new handling-thread for every client that connects to the server +/* + * Diese Klasse öffnet einen Server-Port und erstellt einen neue Client-Thread-Instanz + * für jeden Client, der sich neu an dem Server anmeldet. + */ class ServerThread implements Runnable { // Declaration of objects + + // Instance of the server; serves to solve references private final MaerklinServer SERVER_INSTANCE; // Constructor @@ -174,6 +193,7 @@ class ServerThread implements Runnable { SERVER_INSTANCE = server; } + // Waits for clients to connect and submits a new client-thread afterwards @Override public void run() { try(ServerSocket serverSocket = new ServerSocket(Properties.PORT)){ @@ -190,6 +210,7 @@ class ServerThread implements Runnable { run(); } finally { + // Properly shuts down all running threads if the server is closed SERVER_INSTANCE.SERVER_THREAD_EXECUTOR.shutdownNow(); SERVER_INSTANCE.CLIENT_THREAD_EXECUTOR.shutdownNow(); SERVER_INSTANCE.UTILITY_THREAD_EXECUTOR.shutdownNow(); @@ -198,13 +219,23 @@ class ServerThread implements Runnable { } -// Handles the communication with the clients in the background +/* + * Die Klasse ClientThread verwaltet die Kommunikation mit dem Client + * im Hintergrund und öffnet bei eingehenden Befehlen einen neuen Handling-Thread. + */ class ClientThread implements Runnable { // Declaration of objects + + // Instance of the server; serves to solve references + private final MaerklinServer SERVER_INSTANCE; + + // Instance of the client-socket; serves to solve references private final Socket CLIENT; + + // Wrapper for the client-sockets' input-stream to buffer the incoming data private final BufferedInputStream IN_STREAM; - private final MaerklinServer SERVER_INSTANCE; + byte[] data; // Constructor @@ -216,40 +247,42 @@ class ClientThread implements Runnable { data = new byte[Properties.IN_BUFFER_SIZE]; } + // Checks if the client sends a session-abort-message passes client-requests to a handle-thread @Override public void run() { int buffer; while (true) { try { if (IN_STREAM.available() != 0) { - buffer = IN_STREAM.read(); - if ((byte) buffer == (byte) Properties.SESSION_ABORT) { + buffer = IN_STREAM.read(); // Reads one byte from the input-stream + if ((byte) buffer == (byte) Properties.SESSION_ABORT) { // Checks for a session-abort signal and potentially severs the connection potentially SERVER_INSTANCE.clients.remove(CLIENT); CLIENT.close(); System.out.println("Conenction to client "+CLIENT.getRemoteSocketAddress()+" aborted!"); return; } - else if ((byte) buffer == (byte) Properties.SEPERATOR) { - for (int i = 0; i < Properties.IN_BUFFER_SIZE; i++) { + else if ((byte) buffer == (byte) Properties.SEPERATOR) { // Checks for the beginning of a new datagram (all datagrams begin with a seperator-byte to mark their start) + for (int i = 0; i < Properties.IN_BUFFER_SIZE; i++) { // Tries to read the whole datagram buffer = IN_STREAM.read(); - if ((byte) buffer == (byte) Properties.SESSION_ABORT) { + if ((byte) buffer == (byte) Properties.SESSION_ABORT) { // Again checks for a session-abort signal from the client SERVER_INSTANCE.clients.remove(CLIENT); CLIENT.close(); System.out.println("Connection to client "+CLIENT.getRemoteSocketAddress()+" aborted!"); return; } else { - data[i] = (byte) (buffer%(1<<8)); + data[i] = (byte) (buffer%(1<<8)); // Typecast to byte through bitshift } } - SERVER_INSTANCE.UTILITY_THREAD_EXECUTOR.submit(new HandleThread(SERVER_INSTANCE, data)); + SERVER_INSTANCE.UTILITY_THREAD_EXECUTOR.submit(new HandleThread(SERVER_INSTANCE, data)); // Submits a new handle-thread for the datagram } } else { - Thread.sleep(10); + Thread.sleep(10); // Frees the resources until the next check } } catch (Exception e) { + // Unregister the client if an error occurers System.out.println("An error occured while reading the clients input-stream!"); SERVER_INSTANCE.clients.remove(CLIENT); System.out.println("Conenction to client "+CLIENT.getRemoteSocketAddress()+" aborted!"); @@ -260,11 +293,19 @@ class ClientThread implements Runnable { } -// Processes the incoming datagram and initializes appropriate actions +/* + * HandleThread verarbeitet Anfragen von den Clients und initiiert entsprechende Aktionen. + * Format des Datagrams: 1.+2. Byte: Maerklin-ID + * 3. Byte: Befehl + * 4.+5. Byte: potentielle Parameter + */ class HandleThread implements Runnable { - // Declaration of objects + // Declaration of objects// Declaration of objects + + // Instance of the server; serves to solve references private final MaerklinServer SERVER_INSTANCE; + byte[] data; // Constructor @@ -273,23 +314,24 @@ class HandleThread implements Runnable { data = incomingData; } + // Reads the command and initiates the according action @Override public void run() { try { - switch (data[2]) { - case Properties.SYSTEM_STOP: + switch (data[2]) { // Compare the command-byte to the values set in Properties + case Properties.SYSTEM_STOP: // Emergency-stop (cuts the power) //System.out.println("System stop"); SERVER_INSTANCE.emergencyStop(); break; - case Properties.SYSTEM_GO: + case Properties.SYSTEM_GO: // Resets the emergency-stop (re-enables power) //System.out.println("System go"); SERVER_INSTANCE.start(); break; - case Properties.GET_STATUS: + case Properties.GET_STATUS: // Status-update //System.out.println("Status update"); SERVER_INSTANCE.statusUpdate(); break; - case Properties.ENGINE_SET_SPEED: + case Properties.ENGINE_SET_SPEED: // Set engine-speed to the given value for (Engine train : Engine.engines) { if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) { //System.out.println("Set engine speed"); @@ -298,7 +340,7 @@ class HandleThread implements Runnable { } } break; - case Properties.ENGINE_INCREASE_SPEED: + case Properties.ENGINE_INCREASE_SPEED: // Increase the engine-speed by 50 for (Engine train : Engine.engines) { if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) { //System.out.println("Increase engine speed"); @@ -307,7 +349,7 @@ class HandleThread implements Runnable { } } break; - case Properties.ENGINE_DECREASE_SPEED: + case Properties.ENGINE_DECREASE_SPEED: // Decrease the engine-speed by 50 for (Engine train : Engine.engines) { if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) { //System.out.println("Decrease engine speed"); @@ -316,7 +358,7 @@ class HandleThread implements Runnable { } } break; - case Properties.ENGINE_SET_DIRECTION: + case Properties.ENGINE_SET_DIRECTION: // Set engine-direction to the given value for (Engine train : Engine.engines) { if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) { //System.out.println("Set engine direction"); @@ -325,7 +367,7 @@ class HandleThread implements Runnable { } } break; - case Properties.ENGINE_SWITCH_DIRECTION: + case Properties.ENGINE_SWITCH_DIRECTION: // Switch the engine-direction for (Engine train : Engine.engines) { if (train.getEngineID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) { //System.out.println("Switch engine direction"); @@ -334,7 +376,7 @@ class HandleThread implements Runnable { } } break; - case Properties.SWITCH_SET_DIRECTION: + case Properties.SWITCH_SET_DIRECTION: // Set the switch-direction to the given value or move the turntable clockwise or counterclockwise for (Switch sw : Switch.switches) { if (sw.getSwitchID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) { //System.out.println("Set switch direction"); @@ -343,7 +385,7 @@ class HandleThread implements Runnable { } } break; - case Properties.SWITCH_SWITCH_DIRECTION: + case Properties.SWITCH_SWITCH_DIRECTION: // Switch the switch-direction for (Switch sw : Switch.switches) { if (sw.getSwitchID() == ((data[0]&0xFF)*(1<<8)+(data[1]&0xFF))) { //System.out.println("Switch switch direction"); @@ -352,7 +394,7 @@ class HandleThread implements Runnable { } } break; - default: + default: // Command doesn't match any of the cases System.out.println("No viable command!\n"); } } @@ -363,11 +405,19 @@ class HandleThread implements Runnable { } -//Broadcasts the current status +/* + * Diese Klasse konvertiert bei Aufruf den aktuellen Status der (serverseitigen) + * Modelle in Byte-Format und wandelt diese unter Hinzufügen von Start- End- und + * Trenn-Bytes in ein Datagram um, dass an den Client gesendet wird. + */ class UpdateThread implements Runnable { // Declaration of objects + + // Output-stream of the client handled by the thread private final OutputStream OUT_STREAM; + + // Buffer for the datagram private byte[] outgoingData; // Constructor @@ -376,30 +426,30 @@ class UpdateThread implements Runnable { // Setting the broadcast-port OUT_STREAM = out; - // Initializing + // Initializing the buffer-array to the size of the datagram outgoingData = new byte[Properties.OUT_BUFFER_SIZE]; } - // Reads every registered objects data into outgoingData and broadcasts the status + // Reads every registered objects data into outgoingData and sends the status @Override public void run() { int position = 0; try { - outgoingData[position++] = Properties.SEPERATOR; + outgoingData[position++] = Properties.SEPERATOR; // Start-bytes outgoingData[position++] = Properties.SEPERATOR; for (Engine train : Engine.engines) { if (position >= Properties.OUT_BUFFER_SIZE-9) { Exception e = new Exception("Overload of registered elements! Update-buffer too small!"); throw e; } - outgoingData[position++] = (byte) ((train.getEngineID()/(1<<8))%(1<<8)); + outgoingData[position++] = (byte) ((train.getEngineID()/(1<<8))%(1<<8)); // Maerklin-ID outgoingData[position++] = (byte) ((train.getEngineID()%(1<<8))); - outgoingData[position++] = (byte) ((train.getEngineSpeed()/(1<<8))%(1<<8)); + outgoingData[position++] = (byte) ((train.getEngineSpeed()/(1<<8))%(1<<8)); // Speed outgoingData[position++] = (byte) ((train.getEngineSpeed()%(1<<8))); - outgoingData[position++] = (byte) ((train.getEngineDirection()%(1<<24))); - outgoingData[position++] = Properties.SEPERATOR; + outgoingData[position++] = (byte) ((train.getEngineDirection()%(1<<24))); // Direction + outgoingData[position++] = Properties.SEPERATOR; // Separator-byte between the engines } - outgoingData[position++] = Properties.SEPERATOR; + outgoingData[position++] = Properties.SEPERATOR; // Separator-bytes between the engines and the switches outgoingData[position++] = Properties.SEPERATOR; outgoingData[position++] = Properties.SEPERATOR; for (Switch sw : Switch.switches) { @@ -407,14 +457,14 @@ class UpdateThread implements Runnable { Exception e = new Exception("Overload of registered elements! Update-buffer too small!"); throw e; } - outgoingData[position++] = (byte) ((sw.getSwitchID()/(1<<8))%(1<<8)); + outgoingData[position++] = (byte) ((sw.getSwitchID()/(1<<8))%(1<<8)); // Maerklin-ID outgoingData[position++] = (byte) ((sw.getSwitchID()%(1<<8))); + outgoingData[position++] = (byte) 0x00; // Inserted two null-bytes to match the engines-format outgoingData[position++] = (byte) 0x00; - outgoingData[position++] = (byte) 0x00; - outgoingData[position++] = (byte) ((sw.getSwitchDirection()%(1<<24))); - outgoingData[position++] = Properties.SEPERATOR; + outgoingData[position++] = (byte) ((sw.getSwitchDirection()%(1<<24))); // Direction + outgoingData[position++] = Properties.SEPERATOR; // Separator-byte between the switches } - outgoingData[position++] = Properties.SEPERATOR; + outgoingData[position++] = Properties.SEPERATOR; // Stop-bytes outgoingData[position++] = Properties.SEPERATOR; outgoingData[position++] = Properties.SEPERATOR; outgoingData[position++] = Properties.SEPERATOR; @@ -425,7 +475,7 @@ class UpdateThread implements Runnable { } //System.out.printf("\nSende: " + DatatypeConverter.printHexBinary(outgoingData)); try { - OUT_STREAM.write(outgoingData, 0, Properties.OUT_BUFFER_SIZE); + OUT_STREAM.write(outgoingData, 0, Properties.OUT_BUFFER_SIZE); // Send the datagram to the client } catch (Exception e) { System.out.println("Communication-error whilst status-update!"); diff --git a/Praktikum/VINF_MaerklinControl/src/server/MaerklinServerApplication.java b/Praktikum/VINF_MaerklinControl/src/server/MaerklinServerApplication.java index 7bbd8c5..ec89c47 100644 --- a/Praktikum/VINF_MaerklinControl/src/server/MaerklinServerApplication.java +++ b/Praktikum/VINF_MaerklinControl/src/server/MaerklinServerApplication.java @@ -1,5 +1,11 @@ package server; + +/* + * MaerklinServerApplication startet den Server sowie den Listener, der + * die serverseitigen Modelle aktualisiert. Weiterhin initialisiert die Klasse + * zyklisch ein synchrones Status-Update für alle registrierten Clients. + */ public class MaerklinServerApplication { // Defining a threshold value for when the status-update is to be executed (in milliseconds) @@ -19,6 +25,7 @@ public class MaerklinServerApplication { // Starting the client-handling server.listen(); + // Periodically checks if the update-threshold has been exceeded and potentially initializes the status update through statusUpdate while (true){ if (System.currentTimeMillis()-timestamp >= updateThreshold) { server.statusUpdate(); diff --git a/Praktikum/VINF_MaerklinControl/src/server/Switch.java b/Praktikum/VINF_MaerklinControl/src/server/Switch.java index ea03fbf..d4880af 100644 --- a/Praktikum/VINF_MaerklinControl/src/server/Switch.java +++ b/Praktikum/VINF_MaerklinControl/src/server/Switch.java @@ -2,16 +2,23 @@ package server; import java.util.ArrayList; +/* + * Diese Klasse stellt das Modell für eine Weiche auf Serverseite dar. + * Weiterhin lassen sich über eine lokale Instanz des Maerklin-Protokolls + * Befehle an die Maerklin-C2-Steuerung senden. + */ public class Switch { + // Static array containing all created instances of the object static ArrayList<Switch> switches; private int switchID; int switchDirection; + // Private locale instance of the maerklin-protocol to send commands to the control-station private MaerklinProtocol udpProtocol; - private UDPListener listener; + // Constructor public Switch(){ this(0, 1); @@ -26,12 +33,12 @@ public class Switch { switchDirection = 1;*/ } + // Constructor with some initial data public Switch(int id, int direction){ if (switches == null) { switches = new ArrayList<Switch>(); } udpProtocol = new MaerklinProtocol(); - listener = new UDPListener(); switches.add(this); try { setSwitchID(id); @@ -42,10 +49,12 @@ public class Switch { } } + // Sets the Maerklin-ID public void setSwitchID(int newSwitchID){ switchID = newSwitchID; } + // Sets the switch-direction and sends the respective command to the control-station public void setSwitchDirection(int newSwitchDirection) throws Exception { if (newSwitchDirection == 0x01 || newSwitchDirection == 0x00){ switchDirection = newSwitchDirection; @@ -57,6 +66,7 @@ public class Switch { udpProtocol.changeSwitchDirection(switchID, switchDirection); } + // Changes the switch-direction and calls setSwitchDirection with the new vdirection-alue public void changeSwitchDirection() throws Exception { if (switchDirection == 0x00){ setSwitchDirection(0x01); @@ -66,10 +76,12 @@ public class Switch { } } + // Returns the Maerklin-ID public int getSwitchID(){ return switchID; } + // Returns the switch-direction public int getSwitchDirection(){ return switchDirection; } diff --git a/Praktikum/VINF_MaerklinControl/src/server/UDPListener.java b/Praktikum/VINF_MaerklinControl/src/server/UDPListener.java index 0cc8fe5..d5c3be0 100644 --- a/Praktikum/VINF_MaerklinControl/src/server/UDPListener.java +++ b/Praktikum/VINF_MaerklinControl/src/server/UDPListener.java @@ -4,20 +4,28 @@ import java.net.DatagramPacket; import java.net.DatagramSocket; import javax.xml.bind.DatatypeConverter; +/* + * Der UDPListener ist in der Lage auf den Ausgabe-Port der Maerklin-C2-Steuerung + * zu lauschen, ausgehende Datagramme zu verarbeiten und die serverseitigen Modelle + * zu updaten. Es ist sowohl eine "manuelle" Version wie auch eine Automatik (per + * Runnable) implementiert. + */ public class UDPListener implements Runnable{ // Defining the size of the datagrams received from the Maerklin-control-station public final static int MAERKLIN_DATAGRAM_SIZE = 13; - // Listener-port + // Setting the output-port of the maerklin-control-station private final static int port = 15730; private byte[] in; + // Constructor public UDPListener(){ in = new byte[MAERKLIN_DATAGRAM_SIZE]; } + // Listens for answers from the control-station and writes it to the array in public void listen(){ try(DatagramSocket socket = new DatagramSocket(port)){ socket.setReuseAddress(true); @@ -30,30 +38,38 @@ public class UDPListener implements Runnable{ } } + // Returns the last received datagram public byte[] getData(){ return in; } + // Decodes the engine-speed from the datagram public int getEngineSpeed(){ return ((in[9]&0xFF)*(1<<8)+(in[10]&0xFF)); } + + // Decodes the engine-direction from the datagram public int getEngineDirection(){ return (in[9]&0xFF); } + // Decodes the switch-direction from the datagram public int getSwitchDirection(){ return (in[9]&0xFF); } + // Decodes the Maerklin-ID from the datagram public int getAddress(){ return ((in[7]&0xFF)*(1<<8)+(in[8]&0xFF)); } + // Decodes the command from the datagram public int getCommand(){ return ((in[1]&0xFF)&0xFE); } + // Checks if the last received datagram is an answer from the control-station public boolean isAnswer(){ if ((in[1]&0x01) == 1){ return true; @@ -63,6 +79,7 @@ public class UDPListener implements Runnable{ } } + // Prints the last received datagram in human-readable form public void printData(byte[] data){ try{ byte[] kennung = new byte[4]; @@ -78,6 +95,7 @@ public class UDPListener implements Runnable{ } } + // Debugging-functionality public static void main(String args[]){ UDPListener testListener = new UDPListener(); while (true){ @@ -86,17 +104,18 @@ public class UDPListener implements Runnable{ } } + // Automatizes the listener-functionalit and updates the models' values with the received data @Override public void run() { //System.out.println("UDPListener start!"); - try(DatagramSocket socket = new DatagramSocket(port)){ + try(DatagramSocket socket = new DatagramSocket(port)){ // Tries to open a socket set to the output-port of the control-station socket.setReuseAddress(true); while (true){ DatagramPacket incomingData = new DatagramPacket(in, in.length); socket.receive(incomingData); in = incomingData.getData(); - if (isAnswer()){ - if (getCommand() == 0x08){ + if (isAnswer()){ // Checks if the datagram is an answer + if (getCommand() == 0x08){ // Engine-speed for (Engine train : Engine.engines){ if (train.getEngineID() == getAddress()){ train.engineSpeed = getEngineSpeed(); @@ -105,7 +124,7 @@ public class UDPListener implements Runnable{ } } } - else if (getCommand() == 0x0A){ + else if (getCommand() == 0x0A){ // Engine-direction for (Engine train : Engine.engines){ if (train.getEngineID() == getAddress()){ train.engineDirection = getEngineDirection(); @@ -115,7 +134,7 @@ public class UDPListener implements Runnable{ } } } - else if (getCommand() == 0x16){ + else if (getCommand() == 0x16){ // Switch-direction for (Switch sw : Switch.switches){ if (sw.getSwitchID() == getAddress()){ sw.switchDirection = getEngineDirection(); -- GitLab